[llvm-commits] [llvm] r133982 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
Andrew Trick
atrick at apple.com
Mon Jun 27 19:49:20 PDT 2011
Author: atrick
Date: Mon Jun 27 21:49:20 2011
New Revision: 133982
URL: http://llvm.org/viewvc/llvm-project?rev=133982&view=rev
Log:
indvars --disable-iv-rewrite: Defer evaluating s/zext until SCEV
evaluates all other IV exprs.
Modified:
llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=133982&r1=133981&r2=133982&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Mon Jun 27 21:49:20 2011
@@ -86,21 +86,13 @@
DominatorTree *DT;
TargetData *TD;
- PHINode *CurrIV; // Current IV being simplified.
-
- // Instructions processed by SimplifyIVUsers for CurrIV.
- SmallPtrSet<Instruction*,16> Simplified;
-
- // Use-def pairs if IVUsers waiting to be processed for CurrIV.
- SmallVector<std::pair<Instruction*, Instruction*>, 8> SimpleIVUsers;
-
SmallVector<WeakVH, 16> DeadInsts;
bool Changed;
public:
static char ID; // Pass identification, replacement for typeid
IndVarSimplify() : LoopPass(ID), IU(0), LI(0), SE(0), DT(0), TD(0),
- CurrIV(0), Changed(false) {
+ Changed(false) {
initializeIndVarSimplifyPass(*PassRegistry::getPassRegistry());
}
@@ -132,7 +124,6 @@
void EliminateIVRemainder(BinaryOperator *Rem,
Value *IVOperand,
bool IsSigned);
- void pushIVUsers(Instruction *Def);
bool isSimpleIVUser(Instruction *I, const Loop *L);
void RewriteNonIntegerIVs(Loop *L);
@@ -1030,7 +1021,10 @@
/// pushIVUsers - Add all uses of Def to the current IV's worklist.
///
-void IndVarSimplify::pushIVUsers(Instruction *Def) {
+static void pushIVUsers(
+ Instruction *Def,
+ SmallPtrSet<Instruction*,16> &Simplified,
+ SmallVectorImpl< std::pair<Instruction*,Instruction*> > &SimpleIVUsers) {
for (Value::use_iterator UI = Def->use_begin(), E = Def->use_end();
UI != E; ++UI) {
@@ -1079,50 +1073,70 @@
/// Once DisableIVRewrite is default, LSR will be the only client of IVUsers.
///
void IndVarSimplify::SimplifyIVUsersNoRewrite(Loop *L, SCEVExpander &Rewriter) {
- // Simplification is performed independently for each IV, as represented by a
- // loop header phi. Each round of simplification first iterates through the
- // SimplifyIVUsers worklist, then determines whether the current IV should be
- // widened. Widening adds a new phi to LoopPhis, inducing another round of
- // simplification on the wide IV.
+ std::map<PHINode *, WideIVInfo> WideIVMap;
+
SmallVector<PHINode*, 8> LoopPhis;
for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I) {
LoopPhis.push_back(cast<PHINode>(I));
}
+ // Each round of simplification iterates through the SimplifyIVUsers worklist
+ // for all current phis, then determines whether any IVs can be
+ // widened. Widening adds new phis to LoopPhis, inducing another round of
+ // simplification on the wide IVs.
while (!LoopPhis.empty()) {
- CurrIV = LoopPhis.pop_back_val();
- Simplified.clear();
- assert(SimpleIVUsers.empty() && "expect empty IV users list");
-
- WideIVInfo WI;
+ // Evaluate as many IV expressions as possible before widening any IVs. This
+ // forces SCEV to propagate no-wrap flags before evaluating sign/zero
+ // extension. The first time SCEV attempts to normalize sign/zero extension,
+ // the result becomes final. So for the most predictable results, we delay
+ // evaluation of sign/zero extend evaluation until needed, and avoid running
+ // other SCEV based analysis prior to SimplifyIVUsersNoRewrite.
+ do {
+ PHINode *CurrIV = LoopPhis.pop_back_val();
+
+ // Information about sign/zero extensions of CurrIV.
+ WideIVInfo WI;
+
+ // Instructions processed by SimplifyIVUsers for CurrIV.
+ SmallPtrSet<Instruction*,16> Simplified;
+
+ // Use-def pairs if IVUsers waiting to be processed for CurrIV.
+ SmallVector<std::pair<Instruction*, Instruction*>, 8> SimpleIVUsers;
+
+ pushIVUsers(CurrIV, Simplified, SimpleIVUsers);
+
+ while (!SimpleIVUsers.empty()) {
+ Instruction *UseInst, *Operand;
+ tie(UseInst, Operand) = SimpleIVUsers.pop_back_val();
- pushIVUsers(CurrIV);
-
- while (!SimpleIVUsers.empty()) {
- Instruction *UseInst, *Operand;
- tie(UseInst, Operand) = SimpleIVUsers.pop_back_val();
-
- if (EliminateIVUser(UseInst, Operand)) {
- pushIVUsers(Operand);
- continue;
- }
- if (CastInst *Cast = dyn_cast<CastInst>(UseInst)) {
- bool IsSigned = Cast->getOpcode() == Instruction::SExt;
- if (IsSigned || Cast->getOpcode() == Instruction::ZExt) {
- CollectExtend(Cast, IsSigned, WI, SE, TD);
+ if (EliminateIVUser(UseInst, Operand)) {
+ pushIVUsers(Operand, Simplified, SimpleIVUsers);
+ continue;
+ }
+ if (CastInst *Cast = dyn_cast<CastInst>(UseInst)) {
+ bool IsSigned = Cast->getOpcode() == Instruction::SExt;
+ if (IsSigned || Cast->getOpcode() == Instruction::ZExt) {
+ CollectExtend(Cast, IsSigned, WI, SE, TD);
+ }
+ continue;
+ }
+ if (isSimpleIVUser(UseInst, L)) {
+ pushIVUsers(UseInst, Simplified, SimpleIVUsers);
}
- continue;
}
- if (isSimpleIVUser(UseInst, L)) {
- pushIVUsers(UseInst);
+ if (WI.WidestNativeType) {
+ WideIVMap[CurrIV] = WI;
}
- }
- if (WI.WidestNativeType) {
- WidenIV Widener(CurrIV, WI, LI, SE, DT, DeadInsts);
+ } while(!LoopPhis.empty());
+
+ for (std::map<PHINode *, WideIVInfo>::const_iterator I = WideIVMap.begin(),
+ E = WideIVMap.end(); I != E; ++I) {
+ WidenIV Widener(I->first, I->second, LI, SE, DT, DeadInsts);
if (PHINode *WidePhi = Widener.CreateWideIV(Rewriter)) {
Changed = true;
LoopPhis.push_back(WidePhi);
}
}
+ WideIVMap.clear();
}
}
@@ -1145,8 +1159,6 @@
DT = &getAnalysis<DominatorTree>();
TD = getAnalysisIfAvailable<TargetData>();
- CurrIV = NULL;
- Simplified.clear();
DeadInsts.clear();
Changed = false;
@@ -1160,6 +1172,11 @@
SCEVExpander Rewriter(*SE);
// Eliminate redundant IV users.
+ //
+ // Simplification works best when run before other consumers of SCEV. We
+ // attempt to avoid evaluating SCEVs for sign/zero extend operations until
+ // other expressions involving loop IVs have been evaluated. This helps SCEV
+ // propagate no-wrap flags before normalizing sign/zero extension.
if (DisableIVRewrite) {
Rewriter.disableCanonicalMode();
SimplifyIVUsersNoRewrite(L, Rewriter);
More information about the llvm-commits
mailing list