[llvm-commits] [llvm] r58625 - in /llvm/trunk: lib/Transforms/Scalar/IndVarSimplify.cpp test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll
Devang Patel
dpatel at apple.com
Mon Nov 17 13:34:02 PST 2008
On Nov 15, 2008, at 11:30 PM, Chris Lattner wrote:
>
> On Nov 3, 2008, at 10:32 AM, Devang Patel wrote:
>
>> Author: dpatel
>> Date: Mon Nov 3 12:32:19 2008
>> New Revision: 58625
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=58625&view=rev
>> Log:
>> Turn floating point IVs into integer IVs where possible.
>> This allows SCEV users to effectively calculate trip count.
>> LSR later on transforms back integer IVs to floating point IVs
>> later on to avoid int-to-float casts inside the loop.
>
> Very nice! This does great things to simple loops.
>
>> @@ -466,6 +467,7 @@
>> // auxillary induction variables.
>> std::vector<std::pair<PHINode*, SCEVHandle> > IndVars;
>>
>> + HandleFloatingPointIV(L);
>> for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); +
>> +I) {
>> PHINode *PN = cast<PHINode>(I);
>> if (PN->getType()->isInteger()) { // FIXME: when we have fast-
>> math, enable!
>
> This does an extra pass over all phi nodes in a loop. Since there
> can be many many of them, this is suboptimal. Would it be
> reasonable to make this happen at the same time when
> EliminatePointerRecurrence is called?
yes. done.
>
>
>> +/// HandleFloatingPointIV - If the loop has floating induction
>> variable
>> +/// then insert corresponding integer induction variable if
>> possible.
>> +void IndVarSimplify::HandleFloatingPointIV(Loop *L) {
>
> Please add a comment giving an example of the sort of loop this
> benefits. Something like this is sufficient:
>
> for (double i = 0; i < 10000; ++i)
> bar((int)i);
done.
>
>
>>
>> + BasicBlock *Header = L->getHeader();
>> + SmallVector <PHINode *, 4> FPHIs;
>> + Instruction *NonPHIInsn = NULL;
>> +
>> + // Collect all floating point IVs first.
>> + BasicBlock::iterator I = Header->begin();
>> + while(true) {
>> + if (!isa<PHINode>(I)) {
>> + NonPHIInsn = I;
>> + break;
>> + }
>> + PHINode *PH = cast<PHINode>(I);
>> + if (PH->getType()->isFloatingPoint())
>> + FPHIs.push_back(PH);
>> + ++I;
>> + }
>
> Why collect into a list and then handle all at once? It seems that
> you can just handle them on the fly like EliminatePointerRecurrence
> does.
done.
>> + FCmpInst *EC = dyn_cast<FCmpInst>(U1);
>> + if (!EC)
>> + EC = dyn_cast<FCmpInst>(U2);
>> + if (!EC) continue;
>> + bool skip = false;
>> + Instruction *Terminator = EC->getParent()->getTerminator();
>> + for(Value::use_iterator ECUI = EC->use_begin(), ECUE = EC-
>> >use_end();
>> + ECUI != ECUE; ++ECUI) {
>> + Instruction *U = cast<Instruction>(ECUI);
>> + if (U != Terminator) {
>> + skip = true;
>> + break;
>> + }
>> + }
>> + if (skip) continue;
>
> Instead of using a 'skip' bool, please factor this inner loop out
> into a static helper function. However, why do you even do this at
> all? Why not just see if Terminator is a cond branch whose
> condition is EC?
yup, why not :). Fixed.
I'll address rest of your comments in a separate commit.
Thanks!
-
Devang
More information about the llvm-commits
mailing list