[llvm-commits] llvm-gcc: emit switch cases with a wide range as a conditional branch
Duncan Sands
baldrick at free.fr
Wed Mar 14 11:20:14 PDT 2007
Hi Reid, thanks for replying.
> > > Please use APInt's to do the subtraction, instead of constant
> > > folding. Reid should be able to help you with this.
> >
> > I don't understand why. If APInt's are much more efficient, then
> > shouldn't ConstantExpr:getSub be improved to detect this case and
> > directly use APInts itself?
>
> Currently, ConstantInt is implemented in terms of APInt. So, if you
> subtract two ConstantInt (via ConstantExpr), you are in essence just
> doing an APInt subtraction. However, having just looked at the constant
> folding code again, here's what happens:
>
> 1. Call to ConstantExpr::get which calls ConstantExpr::getTy which
> calls ConstantFoldBinaryInstruction.
> 2. 5 if statements and a switch in ConstantFoldBinaryInstruction
> 3. Extraction of APInt values from the ConstantInt operands to the
> ConstantExpr object.
> 4. APInt subtraction.
> 5. Construction of a new ConstantInt which involves at least (a)
> construction of an IntegerMapKeyType and (b) std::map lookup to
> see if the value already exists; and, if the value doesn't
> exist, will also involve (c) instantiation of an integer value
> representation object and (d) insertion into two maps (one
> forward, one inverse)
>
> I think this is Chris' point. You could replace all of that with just
> "APInt subtraction". #5 can be really expensive because of the map
> traversals and insertions, especially in programs with lots of constant
> values.
In most of the switch code #5 cannot be avoided, since the final result
needs to be a ConstantInt. However Range only needs to be turned into
a ConstantInt if the range is wide, so indeed one instance of #5 can be
avoided in the common case.
> > > + if (Range->getZExtValue() < 2*HOST_BITS_PER_WIDE_INT) {
> > >
> > > This is bad because it means llvm-gcc will produce different code
> > > based on thevalue of HOST_BITS... Please just say " < 64" or something.
>
> Since you are working with numbers of bits here and not with values
> requiring that number of bits, the range of values possible will always
> fit in a uint32_t. Is it possible just to use that instead of a
> ConstantInt? uint32_t Range = X - Y is way cheaper than any of the
> foregoing :)
Range is the case range, which can be arbitrarily big, so I'm afraid not.
> FYI: I'm contemplating making llvm-gcc represent CONSTANT_INT nodes with
> APInt so that it can handle integer constants of any bit width. This is
> a requirement for the work I'm doing for AutoESL.
This would make it hard to merge with mainline.
I am testing the following patch. While I was there, I made it agnostic
as to the signedness of the switch expression and cases (in Ada they can
be unsigned).
Ciao,
Duncan.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: switch.diff
Type: text/x-diff
Size: 3952 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20070314/4c3e2f14/attachment.diff>
More information about the llvm-commits
mailing list