//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
-#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
+#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/Support/TargetFolder.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/Analysis/TargetFolder.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/ValueHandle.h"
#include <set>
namespace llvm {
- class TargetLowering;
+ class TargetTransformInfo;
+
+ /// Return true if the given expression is safe to expand in the sense that
+ /// all materialized values are safe to speculate.
+ bool isSafeToExpand(const SCEV *S, ScalarEvolution &SE);
/// SCEVExpander - This class uses information about analyze scalars to
/// rewrite expressions in canonical form.
// New instructions receive a name to identifies them with the current pass.
const char* IVName;
- std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
+ // InsertedExpressions caches Values for reuse, so must track RAUW.
+ std::map<std::pair<const SCEV *, Instruction *>, TrackingVH<Value> >
InsertedExpressions;
+ // InsertedValues only flags inserted instructions so needs no RAUW.
std::set<AssertingVH<Value> > InsertedValues;
std::set<AssertingVH<Value> > InsertedPostIncValues;
/// insert the IV increment at this position.
Instruction *IVIncInsertPos;
+ /// Phis that complete an IV chain. Reuse
+ std::set<AssertingVH<PHINode> > ChainedPhis;
+
/// CanonicalMode - When true, expressions are expanded in "canonical"
/// form. In particular, addrecs are expanded as arithmetic based on
/// a canonical induction variable. When false, expression are expanded
public:
/// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
explicit SCEVExpander(ScalarEvolution &se, const char *name)
- : SE(se), IVName(name), IVIncInsertLoop(0), IVIncInsertPos(0),
+ : SE(se), IVName(name), IVIncInsertLoop(nullptr), IVIncInsertPos(nullptr),
CanonicalMode(true), LSRMode(false),
- Builder(se.getContext(), TargetFolder(se.TD)) {
+ Builder(se.getContext(), TargetFolder(se.DL)) {
#ifndef NDEBUG
DebugType = "";
#endif
InsertedExpressions.clear();
InsertedValues.clear();
InsertedPostIncValues.clear();
+ ChainedPhis.clear();
}
/// getOrInsertCanonicalInductionVariable - This method returns the
/// starts at zero and steps by one on each iteration.
PHINode *getOrInsertCanonicalInductionVariable(const Loop *L, Type *Ty);
- /// hoistStep - Utility for hoisting an IV increment.
- static bool hoistStep(Instruction *IncV, Instruction *InsertPos,
- const DominatorTree *DT);
+ /// getIVIncOperand - Return the induction variable increment's IV operand.
+ Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos,
+ bool allowScale);
+
+ /// hoistIVInc - Utility for hoisting an IV increment.
+ bool hoistIVInc(Instruction *IncV, Instruction *InsertPos);
/// replaceCongruentIVs - replace congruent phis with their most canonical
/// representative. Return the number of phis eliminated.
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
SmallVectorImpl<WeakVH> &DeadInsts,
- const TargetLowering *TLI = NULL);
+ const TargetTransformInfo *TTI = nullptr);
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
void clearInsertPoint() {
Builder.ClearInsertionPoint();
}
+
+ /// isInsertedInstruction - Return true if the specified instruction was
+ /// inserted by the code rewriter. If so, the client should not modify the
+ /// instruction.
+ bool isInsertedInstruction(Instruction *I) const {
+ return InsertedValues.count(I) || InsertedPostIncValues.count(I);
+ }
+
+ void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); }
+
private:
LLVMContext &getContext() const { return SE.getContext(); }
/// expression into the program. The inserted code is inserted into the
/// SCEVExpander's current insertion point. If a type is specified, the
/// result will be expanded to have that type, with a cast if necessary.
- Value *expandCodeFor(const SCEV *SH, Type *Ty = 0);
-
- /// isInsertedInstruction - Return true if the specified instruction was
- /// inserted by the code rewriter. If so, the client should not modify the
- /// instruction.
- bool isInsertedInstruction(Instruction *I) const {
- return InsertedValues.count(I) || InsertedPostIncValues.count(I);
- }
+ Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr);
/// getRelevantLoop - Determine the most "relevant" loop for the given SCEV.
const Loop *getRelevantLoop(const SCEV *);
void rememberInstruction(Value *I);
- void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I);
-
bool isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
const Loop *L,
Type *ExpandTy,
- Type *IntTy);
+ Type *IntTy,
+ Type *&TruncTy,
+ bool &InvertStep);
Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
Type *ExpandTy, Type *IntTy, bool useSubtract);
};