diff options
author | Dan Gohman <gohman@apple.com> | 2009-09-26 16:11:57 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-09-26 16:11:57 +0000 |
commit | c70c37794fbff2c615d4f9dc3b6adf9583b855dc (patch) | |
tree | 985e38013dcf7bdf938042fdefec440e5c4e6e25 /lib | |
parent | 3548ea8e905269e819fdd4c7fab42142b745c6c5 (diff) | |
download | external_llvm-c70c37794fbff2c615d4f9dc3b6adf9583b855dc.zip external_llvm-c70c37794fbff2c615d4f9dc3b6adf9583b855dc.tar.gz external_llvm-c70c37794fbff2c615d4f9dc3b6adf9583b855dc.tar.bz2 |
Fix a case where ScalarEvolution was expanding pointer arithmetic
to inttoptr/ptrtoint unnecessarily.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82864 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/ScalarEvolutionExpander.cpp | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index 3472470..fd37d7b 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -508,20 +508,37 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin, } Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { + int NumOperands = S->getNumOperands(); const Type *Ty = SE.getEffectiveSCEVType(S->getType()); - Value *V = expand(S->getOperand(S->getNumOperands()-1)); + + // Find the index of an operand to start with. Choose the operand with + // pointer type, if there is one, or the last operand otherwise. + int PIdx = 0; + for (; PIdx != NumOperands - 1; ++PIdx) + if (isa<PointerType>(S->getOperand(PIdx)->getType())) break; + + // Expand code for the operand that we chose. + Value *V = expand(S->getOperand(PIdx)); // Turn things like ptrtoint+arithmetic+inttoptr into GEP. See the // comments on expandAddToGEP for details. if (const PointerType *PTy = dyn_cast<PointerType>(V->getType())) { + // Take the operand at PIdx out of the list. const SmallVectorImpl<const SCEV *> &Ops = S->getOperands(); - return expandAddToGEP(&Ops[0], &Ops[Ops.size() - 1], PTy, Ty, V); + SmallVector<const SCEV *, 8> NewOps; + NewOps.insert(NewOps.end(), Ops.begin(), Ops.begin() + PIdx); + NewOps.insert(NewOps.end(), Ops.begin() + PIdx + 1, Ops.end()); + // Make a GEP. + return expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, V); } + // Otherwise, we'll expand the rest of the SCEVAddExpr as plain integer + // arithmetic. V = InsertNoopCastOfTo(V, Ty); // Emit a bunch of add instructions - for (int i = S->getNumOperands()-2; i >= 0; --i) { + for (int i = NumOperands-1; i >= 0; --i) { + if (i == PIdx) continue; Value *W = expandCodeFor(S->getOperand(i), Ty); V = InsertBinop(Instruction::Add, V, W); } |