00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
00015 #define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
00016
00017 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
00018 #include "llvm/Support/IRBuilder.h"
00019 #include "llvm/Support/TargetFolder.h"
00020 #include <set>
00021
00022 namespace llvm {
00029 class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
00030 ScalarEvolution &SE;
00031 std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
00032 InsertedExpressions;
00033 std::set<Value*> InsertedValues;
00034
00040 const Loop *PostIncLoop;
00041
00045 const Loop *IVIncInsertLoop;
00046
00049 Instruction *IVIncInsertPos;
00050
00055 bool CanonicalMode;
00056
00057 typedef IRBuilder<true, TargetFolder> BuilderType;
00058 BuilderType Builder;
00059
00060 friend struct SCEVVisitor<SCEVExpander, Value*>;
00061
00062 public:
00064 explicit SCEVExpander(ScalarEvolution &se)
00065 : SE(se), PostIncLoop(0), IVIncInsertLoop(0), CanonicalMode(true),
00066 Builder(se.getContext(), TargetFolder(se.TD)) {}
00067
00071 void clear() { InsertedExpressions.clear(); }
00072
00077 Value *getOrInsertCanonicalInductionVariable(const Loop *L, const Type *Ty);
00078
00082 Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *I) {
00083 BasicBlock::iterator IP = I;
00084 while (isInsertedInstruction(IP)) ++IP;
00085 Builder.SetInsertPoint(IP->getParent(), IP);
00086 return expandCodeFor(SH, Ty);
00087 }
00088
00090 void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
00091 assert(!CanonicalMode &&
00092 "IV increment positions are not supported in CanonicalMode");
00093 IVIncInsertLoop = L;
00094 IVIncInsertPos = Pos;
00095 }
00096
00101 void setPostInc(const Loop *L) {
00102 assert(!CanonicalMode &&
00103 "Post-inc expansion is not supported in CanonicalMode");
00104 PostIncLoop = L;
00105 }
00106
00110 void disableCanonicalMode() { CanonicalMode = false; }
00111
00112 private:
00113 LLVMContext &getContext() const { return SE.getContext(); }
00114
00117 Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS);
00118
00122 Value *InsertNoopCastOfTo(Value *V, const Type *Ty);
00123
00126 Value *expandAddToGEP(const SCEV *const *op_begin,
00127 const SCEV *const *op_end,
00128 const PointerType *PTy, const Type *Ty, Value *V);
00129
00130 Value *expand(const SCEV *S);
00131
00136 Value *expandCodeFor(const SCEV *SH, const Type *Ty = 0);
00137
00141 bool isInsertedInstruction(Instruction *I) const {
00142 return InsertedValues.count(I);
00143 }
00144
00145 Value *visitConstant(const SCEVConstant *S) {
00146 return S->getValue();
00147 }
00148
00149 Value *visitTruncateExpr(const SCEVTruncateExpr *S);
00150
00151 Value *visitZeroExtendExpr(const SCEVZeroExtendExpr *S);
00152
00153 Value *visitSignExtendExpr(const SCEVSignExtendExpr *S);
00154
00155 Value *visitAddExpr(const SCEVAddExpr *S);
00156
00157 Value *visitMulExpr(const SCEVMulExpr *S);
00158
00159 Value *visitUDivExpr(const SCEVUDivExpr *S);
00160
00161 Value *visitAddRecExpr(const SCEVAddRecExpr *S);
00162
00163 Value *visitSMaxExpr(const SCEVSMaxExpr *S);
00164
00165 Value *visitUMaxExpr(const SCEVUMaxExpr *S);
00166
00167 Value *visitUnknown(const SCEVUnknown *S) {
00168 return S->getValue();
00169 }
00170
00171 void rememberInstruction(Value *I);
00172
00173 void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I);
00174
00175 Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
00176 PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
00177 const Loop *L,
00178 const Type *ExpandTy,
00179 const Type *IntTy);
00180 };
00181 }
00182
00183 #endif