diff options
Diffstat (limited to 'include/llvm/Analysis/ScalarEvolutionExpander.h')
-rw-r--r-- | include/llvm/Analysis/ScalarEvolutionExpander.h | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index b9939168a99d3..2fa856a32f7df 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -80,9 +80,49 @@ namespace llvm { /// already in "expanded" form. bool LSRMode; - typedef IRBuilder<true, TargetFolder> BuilderType; + typedef IRBuilder<TargetFolder> BuilderType; BuilderType Builder; + // RAII object that stores the current insertion point and restores it when + // the object is destroyed. This includes the debug location. Duplicated + // from InsertPointGuard to add SetInsertPoint() which is used to updated + // InsertPointGuards stack when insert points are moved during SCEV + // expansion. + class SCEVInsertPointGuard { + IRBuilderBase &Builder; + AssertingVH<BasicBlock> Block; + BasicBlock::iterator Point; + DebugLoc DbgLoc; + SCEVExpander *SE; + + SCEVInsertPointGuard(const SCEVInsertPointGuard &) = delete; + SCEVInsertPointGuard &operator=(const SCEVInsertPointGuard &) = delete; + + public: + SCEVInsertPointGuard(IRBuilderBase &B, SCEVExpander *SE) + : Builder(B), Block(B.GetInsertBlock()), Point(B.GetInsertPoint()), + DbgLoc(B.getCurrentDebugLocation()), SE(SE) { + SE->InsertPointGuards.push_back(this); + } + + ~SCEVInsertPointGuard() { + // These guards should always created/destroyed in FIFO order since they + // are used to guard lexically scoped blocks of code in + // ScalarEvolutionExpander. + assert(SE->InsertPointGuards.back() == this); + SE->InsertPointGuards.pop_back(); + Builder.restoreIP(IRBuilderBase::InsertPoint(Block, Point)); + Builder.SetCurrentDebugLocation(DbgLoc); + } + + BasicBlock::iterator GetInsertPoint() const { return Point; } + void SetInsertPoint(BasicBlock::iterator I) { Point = I; } + }; + + /// Stack of pointers to saved insert points, used to keep insert points + /// consistent when instructions are moved. + SmallVector<SCEVInsertPointGuard *, 8> InsertPointGuards; + #ifndef NDEBUG const char *DebugType; #endif @@ -101,6 +141,11 @@ namespace llvm { #endif } + ~SCEVExpander() { + // Make sure the insert point guard stack is consistent. + assert(InsertPointGuards.empty()); + } + #ifndef NDEBUG void setDebugType(const char* s) { DebugType = s; } #endif @@ -162,6 +207,15 @@ namespace llvm { Value *expandEqualPredicate(const SCEVEqualPredicate *Pred, Instruction *Loc); + /// \brief Generates code that evaluates if the \p AR expression will + /// overflow. + Value *generateOverflowCheck(const SCEVAddRecExpr *AR, Instruction *Loc, + bool Signed); + + /// \brief A specialized variant of expandCodeForPredicate, handling the + /// case when we are expanding code for a SCEVWrapPredicate. + Value *expandWrapPredicate(const SCEVWrapPredicate *P, Instruction *Loc); + /// \brief A specialized variant of expandCodeForPredicate, handling the /// case when we are expanding code for a SCEVUnionPredicate. Value *expandUnionPredicate(const SCEVUnionPredicate *Pred, @@ -254,6 +308,9 @@ namespace llvm { const SCEV *const *op_end, PointerType *PTy, Type *Ty, Value *V); + /// \brief Find a previous Value in ExprValueMap for expand. + Value *FindValueInExprValueMap(const SCEV *S, const Instruction *InsertPt); + Value *expand(const SCEV *S); /// \brief Insert code to directly compute the specified SCEV expression @@ -306,6 +363,11 @@ namespace llvm { bool &InvertStep); Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L, Type *ExpandTy, Type *IntTy, bool useSubtract); + + void hoistBeforePos(DominatorTree *DT, Instruction *InstToHoist, + Instruction *Pos, PHINode *LoopPhi); + + void fixupInsertPoints(Instruction *I); }; } |