diff options
author | Dan Gohman <gohman@apple.com> | 2007-06-15 14:38:12 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2007-06-15 14:38:12 +0000 |
commit | d19534add90a2a894af61523b830887097bb780b (patch) | |
tree | 5b56c9525ef1b3afea45d0fcfa14855ce3678855 /include/llvm | |
parent | 2c8c3a4a0df00eee39c28d827d43a1d5462b0671 (diff) | |
download | external_llvm-d19534add90a2a894af61523b830887097bb780b.tar.gz external_llvm-d19534add90a2a894af61523b830887097bb780b.tar.bz2 external_llvm-d19534add90a2a894af61523b830887097bb780b.zip |
Add a SCEV class and supporting code for sign-extend expressions.
This created an ambiguity for expandInTy to decide when to use
sign-extension or zero-extension, but it turns out that most of its callers
don't actually need a type conversion, now that LLVM types don't have
explicit signedness. Drop expandInTy in favor of plain expand, and change
the few places that actually need a type conversion to do it themselves.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37591 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
-rw-r--r-- | include/llvm/Analysis/ScalarEvolutionExpander.h | 43 | ||||
-rw-r--r-- | include/llvm/Analysis/ScalarEvolutionExpressions.h | 53 |
2 files changed, 63 insertions, 33 deletions
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 44e8fb0a9a..a5cc7138ca 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -78,13 +78,10 @@ namespace llvm { /// expandCodeFor - Insert code to directly compute the specified SCEV /// expression into the program. The inserted code is inserted into the /// specified block. - /// - /// If a particular value sign is required, a type may be specified for the - /// result. - Value *expandCodeFor(SCEVHandle SH, Instruction *IP, const Type *Ty = 0) { + Value *expandCodeFor(SCEVHandle SH, Instruction *IP) { // Expand the code for this SCEV. this->InsertPt = IP; - return expandInTy(SH, Ty); + return expand(SH); } /// InsertCastOfTo - Insert a cast of V to the specified type, doing what @@ -107,25 +104,6 @@ namespace llvm { return V; } - Value *expandInTy(SCEV *S, const Type *Ty) { - Value *V = expand(S); - if (Ty && V->getType() != Ty) { - if (isa<PointerType>(Ty) && V->getType()->isInteger()) - return InsertCastOfTo(Instruction::IntToPtr, V, Ty); - else if (Ty->isInteger() && isa<PointerType>(V->getType())) - return InsertCastOfTo(Instruction::PtrToInt, V, Ty); - else if (Ty->getPrimitiveSizeInBits() == - V->getType()->getPrimitiveSizeInBits()) - return InsertCastOfTo(Instruction::BitCast, V, Ty); - else if (Ty->getPrimitiveSizeInBits() > - V->getType()->getPrimitiveSizeInBits()) - return InsertCastOfTo(Instruction::ZExt, V, Ty); - else - return InsertCastOfTo(Instruction::Trunc, V, Ty); - } - return V; - } - Value *visitConstant(SCEVConstant *S) { return S->getValue(); } @@ -136,17 +114,21 @@ namespace llvm { } Value *visitZeroExtendExpr(SCEVZeroExtendExpr *S) { - Value *V = expandInTy(S->getOperand(), S->getType()); + Value *V = expand(S->getOperand()); return CastInst::createZExtOrBitCast(V, S->getType(), "tmp.", InsertPt); } + Value *visitSignExtendExpr(SCEVSignExtendExpr *S) { + Value *V = expand(S->getOperand()); + return CastInst::createSExtOrBitCast(V, S->getType(), "tmp.", InsertPt); + } + Value *visitAddExpr(SCEVAddExpr *S) { - const Type *Ty = S->getType(); - Value *V = expandInTy(S->getOperand(S->getNumOperands()-1), Ty); + Value *V = expand(S->getOperand(S->getNumOperands()-1)); // Emit a bunch of add instructions for (int i = S->getNumOperands()-2; i >= 0; --i) - V = InsertBinop(Instruction::Add, V, expandInTy(S->getOperand(i), Ty), + V = InsertBinop(Instruction::Add, V, expand(S->getOperand(i)), InsertPt); return V; } @@ -154,9 +136,8 @@ namespace llvm { Value *visitMulExpr(SCEVMulExpr *S); Value *visitSDivExpr(SCEVSDivExpr *S) { - const Type *Ty = S->getType(); - Value *LHS = expandInTy(S->getLHS(), Ty); - Value *RHS = expandInTy(S->getRHS(), Ty); + Value *LHS = expand(S->getLHS()); + Value *RHS = expand(S->getRHS()); return InsertBinop(Instruction::SDiv, LHS, RHS, InsertPt); } diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index af795377c2..dd6871fdd1 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -24,8 +24,8 @@ namespace llvm { enum SCEVTypes { // These should be ordered in terms of increasing complexity to make the // folders simpler. - scConstant, scTruncate, scZeroExtend, scAddExpr, scMulExpr, scSDivExpr, - scAddRecExpr, scUnknown, scCouldNotCompute + scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr, + scSDivExpr, scAddRecExpr, scUnknown, scCouldNotCompute }; //===--------------------------------------------------------------------===// @@ -166,6 +166,53 @@ namespace llvm { } }; + //===--------------------------------------------------------------------===// + /// SCEVSignExtendExpr - This class represents a sign extension of a small + /// integer value to a larger integer value. + /// + class SCEVSignExtendExpr : public SCEV { + SCEVHandle Op; + const Type *Ty; + SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty); + virtual ~SCEVSignExtendExpr(); + public: + /// get method - This just gets and returns a new SCEVSignExtend object + /// + static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); + + const SCEVHandle &getOperand() const { return Op; } + virtual const Type *getType() const { return Ty; } + + virtual bool isLoopInvariant(const Loop *L) const { + return Op->isLoopInvariant(L); + } + + virtual bool hasComputableLoopEvolution(const Loop *L) const { + return Op->hasComputableLoopEvolution(L); + } + + /// getValueRange - Return the tightest constant bounds that this value is + /// known to have. This method is only valid on integer SCEV objects. + virtual ConstantRange getValueRange() const; + + SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, + const SCEVHandle &Conc) const { + SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc); + if (H == Op) + return this; + return get(H, Ty); + } + + virtual void print(std::ostream &OS) const; + void print(std::ostream *OS) const { if (OS) print(*OS); } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVSignExtendExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scSignExtend; + } + }; + //===--------------------------------------------------------------------===// /// SCEVCommutativeExpr - This node is the base class for n'ary commutative @@ -503,6 +550,8 @@ namespace llvm { return ((SC*)this)->visitTruncateExpr((SCEVTruncateExpr*)S); case scZeroExtend: return ((SC*)this)->visitZeroExtendExpr((SCEVZeroExtendExpr*)S); + case scSignExtend: + return ((SC*)this)->visitSignExtendExpr((SCEVSignExtendExpr*)S); case scAddExpr: return ((SC*)this)->visitAddExpr((SCEVAddExpr*)S); case scMulExpr: |