forked from OSchip/llvm-project
clean up logic, convert std::set to SmallPtrSet, handle the case
when all 2-entry phis are simplified away. llvm-svn: 121760
This commit is contained in:
parent
5546da68bb
commit
9ac168d0ab
|
@ -199,7 +199,7 @@ static Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
|
||||||
/// non-trapping. If both are true, the instruction is inserted into the set
|
/// non-trapping. If both are true, the instruction is inserted into the set
|
||||||
/// and true is returned.
|
/// and true is returned.
|
||||||
static bool DominatesMergePoint(Value *V, BasicBlock *BB,
|
static bool DominatesMergePoint(Value *V, BasicBlock *BB,
|
||||||
std::set<Instruction*> *AggressiveInsts) {
|
SmallPtrSet<Instruction*, 4> *AggressiveInsts) {
|
||||||
Instruction *I = dyn_cast<Instruction>(V);
|
Instruction *I = dyn_cast<Instruction>(V);
|
||||||
if (!I) {
|
if (!I) {
|
||||||
// Non-instructions all dominate instructions, but not all constantexprs
|
// Non-instructions all dominate instructions, but not all constantexprs
|
||||||
|
@ -217,50 +217,49 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
|
||||||
|
|
||||||
// If this instruction is defined in a block that contains an unconditional
|
// If this instruction is defined in a block that contains an unconditional
|
||||||
// branch to BB, then it must be in the 'conditional' part of the "if
|
// branch to BB, then it must be in the 'conditional' part of the "if
|
||||||
// statement".
|
// statement". If not, it definitely dominates the region.
|
||||||
if (BranchInst *BI = dyn_cast<BranchInst>(PBB->getTerminator()))
|
BranchInst *BI = dyn_cast<BranchInst>(PBB->getTerminator());
|
||||||
if (BI->isUnconditional() && BI->getSuccessor(0) == BB) {
|
if (BI == 0 || BI->isConditional() || BI->getSuccessor(0) != BB)
|
||||||
if (!AggressiveInsts) return false;
|
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;
|
|
||||||
|
|
||||||
switch (I->getOpcode()) {
|
// If we aren't allowing aggressive promotion anymore, then don't consider
|
||||||
default: return false; // Cannot hoist this out safely.
|
// instructions in the 'if region'.
|
||||||
case Instruction::Load: {
|
if (AggressiveInsts == 0) return false;
|
||||||
// We have to check to make sure there are no instructions before the
|
|
||||||
// load in its basic block, as we are going to hoist the loop out to
|
// Okay, it looks like the instruction IS in the "condition". Check to
|
||||||
// its predecessor.
|
// see if it's a cheap instruction to unconditionally compute, and if it
|
||||||
BasicBlock::iterator IP = PBB->begin();
|
// only uses stuff defined outside of the condition. If so, hoist it out.
|
||||||
while (isa<DbgInfoIntrinsic>(IP))
|
if (!I->isSafeToSpeculativelyExecute())
|
||||||
IP++;
|
return false;
|
||||||
if (IP != BasicBlock::iterator(I))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Instruction::Add:
|
|
||||||
case Instruction::Sub:
|
|
||||||
case Instruction::And:
|
|
||||||
case Instruction::Or:
|
|
||||||
case Instruction::Xor:
|
|
||||||
case Instruction::Shl:
|
|
||||||
case Instruction::LShr:
|
|
||||||
case Instruction::AShr:
|
|
||||||
case Instruction::ICmp:
|
|
||||||
break; // These are all cheap and non-trapping instructions.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Okay, we can only really hoist these out if their operands are not
|
switch (I->getOpcode()) {
|
||||||
// defined in the conditional region.
|
default: return false; // Cannot hoist this out safely.
|
||||||
for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i)
|
case Instruction::Load:
|
||||||
if (!DominatesMergePoint(*i, BB, 0))
|
// We have to check to make sure there are no instructions before the
|
||||||
return false;
|
// load in its basic block, as we are going to hoist the load out to its
|
||||||
// Okay, it's safe to do this! Remember this instruction.
|
// predecessor.
|
||||||
AggressiveInsts->insert(I);
|
if (PBB->getFirstNonPHIOrDbg() != I)
|
||||||
}
|
return false;
|
||||||
|
break;
|
||||||
|
case Instruction::Add:
|
||||||
|
case Instruction::Sub:
|
||||||
|
case Instruction::And:
|
||||||
|
case Instruction::Or:
|
||||||
|
case Instruction::Xor:
|
||||||
|
case Instruction::Shl:
|
||||||
|
case Instruction::LShr:
|
||||||
|
case Instruction::AShr:
|
||||||
|
case Instruction::ICmp:
|
||||||
|
break; // These are all cheap and non-trapping instructions.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Okay, we can only really hoist these out if their operands are not
|
||||||
|
// defined in the conditional region.
|
||||||
|
for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i)
|
||||||
|
if (!DominatesMergePoint(*i, BB, 0))
|
||||||
|
return false;
|
||||||
|
// Okay, it's safe to do this! Remember this instruction.
|
||||||
|
AggressiveInsts->insert(I);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1164,7 +1163,7 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
|
||||||
// Loop over the PHI's seeing if we can promote them all to select
|
// Loop over the PHI's seeing if we can promote them all to select
|
||||||
// instructions. While we are at it, keep track of the instructions
|
// instructions. While we are at it, keep track of the instructions
|
||||||
// that need to be moved to the dominating block.
|
// that need to be moved to the dominating block.
|
||||||
std::set<Instruction*> AggressiveInsts;
|
SmallPtrSet<Instruction*, 4> AggressiveInsts;
|
||||||
|
|
||||||
BasicBlock::iterator AfterPHIIt = BB->begin();
|
BasicBlock::iterator AfterPHIIt = BB->begin();
|
||||||
while (isa<PHINode>(AfterPHIIt)) {
|
while (isa<PHINode>(AfterPHIIt)) {
|
||||||
|
@ -1179,17 +1178,23 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we folded the the first phi, PN dangles at this point. Refresh it. If
|
||||||
|
// we ran out of PHIs then we simplified them all.
|
||||||
|
PN = dyn_cast<PHINode>(BB->begin());
|
||||||
|
if (PN == 0) return true;
|
||||||
|
|
||||||
// If we all PHI nodes are promotable, check to make sure that all
|
// If we all PHI nodes are promotable, check to make sure that all
|
||||||
// instructions in the predecessor blocks can be promoted as well. If
|
// instructions in the predecessor blocks can be promoted as well. If
|
||||||
// not, we won't be able to get rid of the control flow, so it's not
|
// not, we won't be able to get rid of the control flow, so it's not
|
||||||
// worth promoting to select instructions.
|
// worth promoting to select instructions.
|
||||||
BasicBlock *DomBlock = 0, *IfBlock1 = 0, *IfBlock2 = 0;
|
BasicBlock *DomBlock = 0;
|
||||||
PN = cast<PHINode>(BB->begin());
|
BasicBlock *IfBlock1 = PN->getIncomingBlock(0);
|
||||||
BasicBlock *Pred = PN->getIncomingBlock(0);
|
BasicBlock *IfBlock2 = PN->getIncomingBlock(1);
|
||||||
if (cast<BranchInst>(Pred->getTerminator())->isUnconditional()) {
|
if (cast<BranchInst>(IfBlock1->getTerminator())->isConditional()) {
|
||||||
IfBlock1 = Pred;
|
IfBlock1 = 0;
|
||||||
DomBlock = *pred_begin(Pred);
|
} else {
|
||||||
for (BasicBlock::iterator I = Pred->begin(); !isa<TerminatorInst>(I); ++I)
|
DomBlock = *pred_begin(IfBlock1);
|
||||||
|
for (BasicBlock::iterator I = IfBlock1->begin();!isa<TerminatorInst>(I);++I)
|
||||||
if (!AggressiveInsts.count(I) && !isa<DbgInfoIntrinsic>(I)) {
|
if (!AggressiveInsts.count(I) && !isa<DbgInfoIntrinsic>(I)) {
|
||||||
// This is not an aggressive instruction that we can promote.
|
// This is not an aggressive instruction that we can promote.
|
||||||
// Because of this, we won't be able to get rid of the control
|
// Because of this, we won't be able to get rid of the control
|
||||||
|
@ -1198,11 +1203,11 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pred = PN->getIncomingBlock(1);
|
if (cast<BranchInst>(IfBlock2->getTerminator())->isConditional()) {
|
||||||
if (cast<BranchInst>(Pred->getTerminator())->isUnconditional()) {
|
IfBlock2 = 0;
|
||||||
IfBlock2 = Pred;
|
} else {
|
||||||
DomBlock = *pred_begin(Pred);
|
DomBlock = *pred_begin(IfBlock2);
|
||||||
for (BasicBlock::iterator I = Pred->begin(); !isa<TerminatorInst>(I); ++I)
|
for (BasicBlock::iterator I = IfBlock2->begin();!isa<TerminatorInst>(I);++I)
|
||||||
if (!AggressiveInsts.count(I) && !isa<DbgInfoIntrinsic>(I)) {
|
if (!AggressiveInsts.count(I) && !isa<DbgInfoIntrinsic>(I)) {
|
||||||
// This is not an aggressive instruction that we can promote.
|
// This is not an aggressive instruction that we can promote.
|
||||||
// Because of this, we won't be able to get rid of the control
|
// Because of this, we won't be able to get rid of the control
|
||||||
|
@ -1212,7 +1217,7 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(dbgs() << "FOUND IF CONDITION! " << *IfCond << " T: "
|
DEBUG(dbgs() << "FOUND IF CONDITION! " << *IfCond << " T: "
|
||||||
<< IfTrue->getName() << " F: " << IfFalse->getName() << "\n");
|
<< IfTrue->getName() << " F: " << IfFalse->getName() << "\n");
|
||||||
|
|
||||||
// If we can still promote the PHI nodes after this gauntlet of tests,
|
// If we can still promote the PHI nodes after this gauntlet of tests,
|
||||||
// do all of the PHI's now.
|
// do all of the PHI's now.
|
||||||
|
|
Loading…
Reference in New Issue