aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-10-15 04:59:28 +0000
committerChris Lattner <sabre@nondot.org>2009-10-15 04:59:28 +0000
commit2ee743b53b32ffc57739abc83667a0c15bb43a71 (patch)
tree9660c27bc8c3e974f87ba447291c28f783634844
parente2cc1ad2306599fcff8d1bb9ce517cf0c632f602 (diff)
only try to fold constantexpr operands when the worklist is first populated,
don't bother every time going around the main worklist. This speeds up a release-asserts opt -std-compile-opts on 403.gcc by about 4% (1.5s). It seems to speed up the most expensive instances of instcombine by ~10%. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84171 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp45
1 files changed, 30 insertions, 15 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 8366cd6855..f635af3974 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -12676,16 +12676,19 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
/// many instructions are dead or constant). Additionally, if we find a branch
/// whose condition is a known constant, we only visit the reachable successors.
///
-static void AddReachableCodeToWorklist(BasicBlock *BB,
+static bool AddReachableCodeToWorklist(BasicBlock *BB,
SmallPtrSet<BasicBlock*, 64> &Visited,
InstCombiner &IC,
const TargetData *TD) {
+ bool MadeIRChange = false;
SmallVector<BasicBlock*, 256> Worklist;
Worklist.push_back(BB);
std::vector<Instruction*> InstrsForInstCombineWorklist;
InstrsForInstCombineWorklist.reserve(128);
+ SmallPtrSet<ConstantExpr*, 64> FoldedConstants;
+
while (!Worklist.empty()) {
BB = Worklist.back();
Worklist.pop_back();
@@ -12714,6 +12717,29 @@ static void AddReachableCodeToWorklist(BasicBlock *BB,
Inst->eraseFromParent();
continue;
}
+
+
+
+ if (TD) {
+ // See if we can constant fold its operands.
+ for (User::op_iterator i = Inst->op_begin(), e = Inst->op_end();
+ i != e; ++i) {
+ ConstantExpr *CE = dyn_cast<ConstantExpr>(i);
+ if (CE == 0) continue;
+
+ // If we already folded this constant, don't try again.
+ if (!FoldedConstants.insert(CE))
+ continue;
+
+ Constant *NewC =
+ ConstantFoldConstantExpression(CE, BB->getContext(), TD);
+ if (NewC && NewC != CE) {
+ *i = NewC;
+ MadeIRChange = true;
+ }
+ }
+ }
+
InstrsForInstCombineWorklist.push_back(Inst);
}
@@ -12755,6 +12781,8 @@ static void AddReachableCodeToWorklist(BasicBlock *BB,
// some N^2 behavior in pathological cases.
IC.Worklist.AddInitialGroup(&InstrsForInstCombineWorklist[0],
InstrsForInstCombineWorklist.size());
+
+ return MadeIRChange;
}
bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
@@ -12768,7 +12796,7 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
// the reachable instructions. Ignore blocks that are not reachable. Keep
// track of which blocks we visit.
SmallPtrSet<BasicBlock*, 64> Visited;
- AddReachableCodeToWorklist(F.begin(), Visited, *this, TD);
+ MadeIRChange |= AddReachableCodeToWorklist(F.begin(), Visited, *this, TD);
// Do a quick scan over the function. If we find any blocks that are
// unreachable, remove any instructions inside of them. This prevents
@@ -12787,7 +12815,6 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
MadeIRChange = true;
}
-
// If I is not void type then replaceAllUsesWith undef.
// This allows ValueHandlers and custom metadata to adjust itself.
if (!I->getType()->isVoidTy())
@@ -12823,18 +12850,6 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
continue;
}
- if (TD) {
- // See if we can constant fold its operands.
- for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i)
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(i))
- if (Constant *NewC = ConstantFoldConstantExpression(CE,
- F.getContext(), TD))
- if (NewC != CE) {
- *i = NewC;
- MadeIRChange = true;
- }
- }
-
// See if we can trivially sink this instruction to a successor basic block.
if (I->hasOneUse()) {
BasicBlock *BB = I->getParent();