aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2011-04-29 18:47:31 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2011-04-29 18:47:31 +0000
commitf15907feadb979daf30b2569954852778e501b2e (patch)
treed073b53c63f0ee80e5956efb3e7e0a9b23e08c3d /lib/Transforms
parent8a70192b510e2a0f05493b9212e998017f3d178d (diff)
downloadexternal_llvm-f15907feadb979daf30b2569954852778e501b2e.zip
external_llvm-f15907feadb979daf30b2569954852778e501b2e.tar.gz
external_llvm-f15907feadb979daf30b2569954852778e501b2e.tar.bz2
SimplifyCFG: Add CostRemaining parameter to DominatesMergePoint
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130527 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp47
1 files changed, 38 insertions, 9 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 1bddecb..e0125f7 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -201,11 +201,20 @@ static Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
/// which works well enough for us.
///
/// If AggressiveInsts is non-null, and if V does not dominate BB, we check to
-/// see if V (which must be an instruction) is cheap to compute and is
-/// non-trapping. If both are true, the instruction is inserted into the set
-/// and true is returned.
+/// see if V (which must be an instruction) and its recursive operands
+/// that do not dominate BB have a combined cost lower than CostRemaining and
+/// are non-trapping. If both are true, the instruction is inserted into the
+/// set and true is returned.
+///
+/// The cost for most non-trapping instructions is defined as 1 except for
+/// Select whose cost is 2.
+///
+/// After this function returns, CostRemaining is decreased by the cost of
+/// V plus its non-dominating operands. If that cost is greater than
+/// CostRemaining, false is returned and CostRemaining is undefined.
static bool DominatesMergePoint(Value *V, BasicBlock *BB,
- SmallPtrSet<Instruction*, 4> *AggressiveInsts) {
+ SmallPtrSet<Instruction*, 4> *AggressiveInsts,
+ unsigned &CostRemaining) {
Instruction *I = dyn_cast<Instruction>(V);
if (!I) {
// Non-instructions all dominate instructions, but not all constantexprs
@@ -232,12 +241,17 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
// instructions in the 'if region'.
if (AggressiveInsts == 0) return false;
+ // If we have seen this instruction before, don't count it again.
+ if (AggressiveInsts->count(I)) return true;
+
// Okay, it looks like the instruction IS in the "condition". Check to
// see if it's a cheap instruction to unconditionally compute, and if it
// only uses stuff defined outside of the condition. If so, hoist it out.
if (!I->isSafeToSpeculativelyExecute())
return false;
+ unsigned Cost = 0;
+
switch (I->getOpcode()) {
default: return false; // Cannot hoist this out safely.
case Instruction::Load:
@@ -246,11 +260,13 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
// predecessor.
if (PBB->getFirstNonPHIOrDbg() != I)
return false;
+ Cost = 1;
break;
case Instruction::GetElementPtr:
// GEPs are cheap if all indices are constant.
if (!cast<GetElementPtrInst>(I)->hasAllConstantIndices())
return false;
+ Cost = 1;
break;
case Instruction::Add:
case Instruction::Sub:
@@ -264,13 +280,23 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
case Instruction::Trunc:
case Instruction::ZExt:
case Instruction::SExt:
+ Cost = 1;
break; // These are all cheap and non-trapping instructions.
+
+ case Instruction::Select:
+ Cost = 2;
+ break;
}
- // Okay, we can only really hoist these out if their operands are not
- // defined in the conditional region.
+ if (Cost > CostRemaining)
+ return false;
+
+ CostRemaining -= Cost;
+
+ // Okay, we can only really hoist these out if their operands do
+ // not take us over the cost threshold.
for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i)
- if (!DominatesMergePoint(*i, BB, 0))
+ if (!DominatesMergePoint(*i, BB, AggressiveInsts, CostRemaining))
return false;
// Okay, it's safe to do this! Remember this instruction.
AggressiveInsts->insert(I);
@@ -1220,6 +1246,7 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
// instructions. While we are at it, keep track of the instructions
// that need to be moved to the dominating block.
SmallPtrSet<Instruction*, 4> AggressiveInsts;
+ unsigned MaxCostVal0 = 1, MaxCostVal1 = 1;
for (BasicBlock::iterator II = BB->begin(); isa<PHINode>(II);) {
PHINode *PN = cast<PHINode>(II++);
@@ -1229,8 +1256,10 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
continue;
}
- if (!DominatesMergePoint(PN->getIncomingValue(0), BB, &AggressiveInsts) ||
- !DominatesMergePoint(PN->getIncomingValue(1), BB, &AggressiveInsts))
+ if (!DominatesMergePoint(PN->getIncomingValue(0), BB, &AggressiveInsts,
+ MaxCostVal0) ||
+ !DominatesMergePoint(PN->getIncomingValue(1), BB, &AggressiveInsts,
+ MaxCostVal1))
return false;
}