mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-29 13:32:33 +00:00
SimplifyCFG: Add CostRemaining parameter to DominatesMergePoint
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130527 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8a70192b51
commit
f15907fead
@ -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;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
define i32 @test(i1 %a, i1 %b) {
|
||||
; CHECK: br i1 %a
|
||||
br i1 %a, label %M, label %O
|
||||
; CHECK: O:
|
||||
O: ; preds = %0
|
||||
; CHECK: select i1 %b, i32 0, i32 1
|
||||
; CHECK-NOT: phi
|
||||
|
Loading…
x
Reference in New Issue
Block a user