LLVMdev Digest, Vol 77, Issue 41

Hi again,

thanks for the answers.

Well, the reason DSP compilers would benefit from the new type, is that fixed point numbers must not be optimized as integers - eg if two saturated fixed point constants would overflow in an addition operation, the result should as well be saturated. Doing this in a series of steps with intrinsics would be quite ridiculous as far as performance goes, because this is supported by the DSP in hardware in a single instruction :slight_smile:

What about perhaps introducing a new type, and allowing just minor extensions, while barring it from more heavy scattered code? I mean, the GVN pass works by just adding an enum entry and a switch case for each new instruction. But in other cases, there are more LOCs involved in lifting in new instructions. Then, these passes would be left untouched, for the sake of maintainability. These passes could be copied for fixed point versions. This would mean a just a little slower compiler (dual passes in some cases), for the case of a separation of the code that not everywone is interested in. Then, these passes could be run just by the DSP targets that need them, and the integer developers would not have to worry at all (perhaps by explicitly excluding fixed point instructions here and there, though).

Another idea is to introduce a scheme of intrinsics and perhaps handle optimizations in the backend as much as possible, as a first step. If this works well, and interest grows, maybe then the rest will follow?

My point is that there does not seem to be a great open source DSP compiler available, yet there is certainly some interest. GCC has passes that can handle DSP targets, but it is still not a DSP compiler as such, really. I think you have a chance to fill a need here which would invite even more people to work on the project. With fixed point support, a new DSPTargetMachine could be made which could really make a difference in the DSP domain as a DSP compiler! I have made extensions already - very simple - that seems to work great for VLIW scheduling and RA. It would be a pity not to give all this serious thought, I’d say.

regards,

Jonas

>
> > Hi Jonas,
> >
> > > I am investigating the possibilities of incorporating fixed
> > > point support into the LLVM I/R.
> >
> > I think you should write a rationale explaining why you want to
> > introduce new types etc rather than using the existing integer
> > types, with intrinsic functions for the operations, or some other
> > such scheme. Introducing new types is hard work and creates a
> > maintenance burden for everyone, since they will need to be
> > properly supported by all parts of the compiler forever more. It
> > is therefore important to give a cogent explanation of why this
> > is the best approach, why the benefits outweigh the costs, and so
> > forth.
>
> Also can't fixed point be handled entirely by the frontend?
> You store the scaling factor as an attribute on the type.
>
> When you perform operations that involve the same fixed point types
> you can perform them with integers, and when you need to perform
> conversions you emit the appropriate code to perform the
> conversions. The emitted LLVM IR needs to know nothing about the
> scaling factors involved.
> For saturation, etc. you can use the SSE intrinsics.
>
> Best regards,
> --Edwin

Hi again,

thanks for the answers.

Well, the reason DSP compilers would benefit from the new type, is
that fixed point numbers must not be optimized as integers - eg if
two saturated fixed point constants would overflow in an addition
operation, the result should as well be saturated. Doing this in a
series of steps with intrinsics would be quite ridiculous as far as
performance goes, because this is _supported by the DSP in hardware_
in a single instruction :slight_smile:

What about perhaps introducing a new type, and allowing just minor
extensions, while barring it from more heavy scattered code? I mean,
the GVN pass works by just adding an enum entry and a switch case for
each new instruction. But in other cases, there are more LOCs
involved in lifting in new instructions. Then, these passes would be
left untouched, for the sake of maintainability. These passes could
be copied for fixed point versions. This would mean a just a little
slower compiler (dual passes in some cases), for the case of a
separation of the code that not everywone is interested in. Then,
these passes could be run just by the DSP targets that need them, and
the integer developers would not have to worry at all (perhaps by
explicitly excluding fixed point instructions here and there,
though).

Ah now it makes sense: you want the existing optimizations (GVN,
instcombine, reassociation, etc.) applied to arithmetic ops on your
type.

Another idea is to introduce a scheme of intrinsics and perhaps
handle optimizations in the backend as much as possible, as a first
step. If this works well, and interest grows, maybe then the rest
will follow?

Yes maybe introducing your own intrinsics as suggested by Duncan
is best. You can lower the intrinsic to your hardware instruction
directly. Optimizers won't know what your intrinsic is, so they would
mostly skip them.

My point is that there does not seem to be a great open source DSP
compiler available, yet there is certainly some interest. GCC has
passes that can handle DSP targets, but it is still not a DSP
compiler as such, really. I think you have a chance to fill a need
here which would invite even more people to work on the project. With
fixed point support, a new DSPTargetMachine could be made which could
really make a difference in the DSP domain as a _DSP compiler_! I
have made extensions already - very simple - that seems to work great
for VLIW scheduling and RA. It would be a pity not to give all this
serious thought, I'd say.

Will existing passes keep working after you introduce this new type
(assuming they are run on a module which doesn't make use of the new
type)?

Best regards,
--Edwin

Isn't it better to add instructions for saturated and/or fixed point arithmetic? ... At least that would be consistent with the design of having separate instructions for signed and unsigned add etc.

- Morten

Yep. :slight_smile:

-Chris

Date: Fri, 26 Nov 2010 18:08:53 +0200
From: edwintorok@gmail.com
To: jnspaulsson@hotmail.com
CC: llvmdev@cs.uiuc.edu
Subject: Re: [LLVMdev] LLVMdev Digest, Vol 77, Issue 41

Hi Jonas,

I am investigating the possibilities of incorporating fixed
point support into the LLVM I/R.

I think you should write a rationale explaining why you want to
introduce new types etc rather than using the existing integer
types, with intrinsic functions for the operations, or some other
such scheme. Introducing new types is hard work and creates a
maintenance burden for everyone, since they will need to be
properly supported by all parts of the compiler forever more. It
is therefore important to give a cogent explanation of why this
is the best approach, why the benefits outweigh the costs, and so
forth.

Also can’t fixed point be handled entirely by the frontend?
You store the scaling factor as an attribute on the type.

When you perform operations that involve the same fixed point types
you can perform them with integers, and when you need to perform
conversions you emit the appropriate code to perform the
conversions. The emitted LLVM IR needs to know nothing about the
scaling factors involved.
For saturation, etc. you can use the SSE intrinsics.

Best regards,
–Edwin

Hi again,

thanks for the answers.

Well, the reason DSP compilers would benefit from the new type, is
that fixed point numbers must not be optimized as integers - eg if
two saturated fixed point constants would overflow in an addition
operation, the result should as well be saturated. Doing this in a
series of steps with intrinsics would be quite ridiculous as far as
performance goes, because this is supported by the DSP in hardware
in a single instruction :slight_smile:

What about perhaps introducing a new type, and allowing just minor
extensions, while barring it from more heavy scattered code? I mean,
the GVN pass works by just adding an enum entry and a switch case for
each new instruction. But in other cases, there are more LOCs
involved in lifting in new instructions. Then, these passes would be
left untouched, for the sake of maintainability. These passes could
be copied for fixed point versions. This would mean a just a little
slower compiler (dual passes in some cases), for the case of a
separation of the code that not everywone is interested in. Then,
these passes could be run just by the DSP targets that need them, and
the integer developers would not have to worry at all (perhaps by
explicitly excluding fixed point instructions here and there,
though).

Ah now it makes sense: you want the existing optimizations (GVN,
instcombine, reassociation, etc.) applied to arithmetic ops on your
type.

Another idea is to introduce a scheme of intrinsics and perhaps
handle optimizations in the backend as much as possible, as a first
step. If this works well, and interest grows, maybe then the rest
will follow?

Yes maybe introducing your own intrinsics as suggested by Duncan
is best. You can lower the intrinsic to your hardware instruction
directly. Optimizers won’t know what your intrinsic is, so they would
mostly skip them.

My point is that there does not seem to be a great open source DSP
compiler available, yet there is certainly some interest. GCC has
passes that can handle DSP targets, but it is still not a DSP
compiler as such, really. I think you have a chance to fill a need
here which would invite even more people to work on the project. With
fixed point support, a new DSPTargetMachine could be made which could
really make a difference in the DSP domain as a DSP compiler! I
have made extensions already - very simple - that seems to work great
for VLIW scheduling and RA. It would be a pity not to give all this
serious thought, I’d say.

Will existing passes keep working after you introduce this new type
(assuming they are run on a module which doesn’t make use of the new
type)?

Best regards,
–Edwin

Yes, the new type is simply a static object managed by Type and
LLVMContext. This is only referred to by Values of fixed point type.
New instructions should not interfer with existing passes, as opcodes
are switched and handled and would simply continue to be unaware of the
new opcodes.
 
My main concern is that code evolution demands following of the LLVM
release series of the future. So, even if this got done locally, it
would be a hassle to deal with if future releases did not include it at
all. So, even if only a small part of it got committed, like say all
parts that do not concern or disturb the optimizers - like the type and
instructions themselves, this would be better then nothing at all. If
then some other party wanted to contribute, this would not lead to
enormous merge aches.
 
regards,
 
/Jonas