mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 22:20:37 +00:00
- Insert new instructions before DomBlock's terminator,
which is simpler than finding a place to insert in BB. - Don't perform the 'if condition hoisting' xform on certain i1 PHIs, as it interferes with switch formation. This re-fixes "example 7", without breaking the world hopefully. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121764 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
60d410d7bb
commit
3aff13b82a
@ -1168,11 +1168,11 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
|
|||||||
// that need to be moved to the dominating block.
|
// that need to be moved to the dominating block.
|
||||||
SmallPtrSet<Instruction*, 4> AggressiveInsts;
|
SmallPtrSet<Instruction*, 4> AggressiveInsts;
|
||||||
|
|
||||||
BasicBlock::iterator AfterPHIIt = BB->begin();
|
for (BasicBlock::iterator II = BB->begin(); isa<PHINode>(II);) {
|
||||||
while (isa<PHINode>(AfterPHIIt)) {
|
PHINode *PN = cast<PHINode>(II++);
|
||||||
PHINode *PN = cast<PHINode>(AfterPHIIt++);
|
|
||||||
if (Value *V = SimplifyInstruction(PN, TD)) {
|
if (Value *V = SimplifyInstruction(PN, TD)) {
|
||||||
PN->replaceAllUsesWith(V);
|
PN->replaceAllUsesWith(V);
|
||||||
|
PN->eraseFromParent();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1186,6 +1186,14 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
|
|||||||
PN = dyn_cast<PHINode>(BB->begin());
|
PN = dyn_cast<PHINode>(BB->begin());
|
||||||
if (PN == 0) return true;
|
if (PN == 0) return true;
|
||||||
|
|
||||||
|
// Don't fold i1 branches on PHIs which contain binary operators. These can
|
||||||
|
// often be turned into switches and other things.
|
||||||
|
if (PN->getType()->isIntegerTy(1) &&
|
||||||
|
(isa<BinaryOperator>(PN->getIncomingValue(0)) ||
|
||||||
|
isa<BinaryOperator>(PN->getIncomingValue(1)) ||
|
||||||
|
isa<BinaryOperator>(IfCond)))
|
||||||
|
return false;
|
||||||
|
|
||||||
// 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
|
||||||
@ -1224,15 +1232,16 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
|
|||||||
|
|
||||||
// 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.
|
||||||
|
Instruction *InsertPt = DomBlock->getTerminator();
|
||||||
|
|
||||||
// Move all 'aggressive' instructions, which are defined in the
|
// Move all 'aggressive' instructions, which are defined in the
|
||||||
// conditional parts of the if's up to the dominating block.
|
// conditional parts of the if's up to the dominating block.
|
||||||
if (IfBlock1)
|
if (IfBlock1)
|
||||||
DomBlock->getInstList().splice(DomBlock->getTerminator(),
|
DomBlock->getInstList().splice(InsertPt,
|
||||||
IfBlock1->getInstList(), IfBlock1->begin(),
|
IfBlock1->getInstList(), IfBlock1->begin(),
|
||||||
IfBlock1->getTerminator());
|
IfBlock1->getTerminator());
|
||||||
if (IfBlock2)
|
if (IfBlock2)
|
||||||
DomBlock->getInstList().splice(DomBlock->getTerminator(),
|
DomBlock->getInstList().splice(InsertPt,
|
||||||
IfBlock2->getInstList(), IfBlock2->begin(),
|
IfBlock2->getInstList(), IfBlock2->begin(),
|
||||||
IfBlock2->getTerminator());
|
IfBlock2->getTerminator());
|
||||||
|
|
||||||
@ -1241,7 +1250,7 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
|
|||||||
Value *TrueVal = PN->getIncomingValue(PN->getIncomingBlock(0) == IfFalse);
|
Value *TrueVal = PN->getIncomingValue(PN->getIncomingBlock(0) == IfFalse);
|
||||||
Value *FalseVal = PN->getIncomingValue(PN->getIncomingBlock(0) == IfTrue);
|
Value *FalseVal = PN->getIncomingValue(PN->getIncomingBlock(0) == IfTrue);
|
||||||
|
|
||||||
Value *NV = SelectInst::Create(IfCond, TrueVal, FalseVal, "", AfterPHIIt);
|
Value *NV = SelectInst::Create(IfCond, TrueVal, FalseVal, "", InsertPt);
|
||||||
PN->replaceAllUsesWith(NV);
|
PN->replaceAllUsesWith(NV);
|
||||||
NV->takeName(PN);
|
NV->takeName(PN);
|
||||||
PN->eraseFromParent();
|
PN->eraseFromParent();
|
||||||
|
@ -11,20 +11,6 @@ declare void @use(i1)
|
|||||||
|
|
||||||
declare void @use.upgrd.1(i32)
|
declare void @use.upgrd.1(i32)
|
||||||
|
|
||||||
define void @test2(i1 %c, i1 %d, i32 %V, i32 %V2) {
|
|
||||||
; <label>:0
|
|
||||||
br i1 %d, label %X, label %F
|
|
||||||
X: ; preds = %0
|
|
||||||
br i1 %c, label %T, label %F
|
|
||||||
T: ; preds = %X
|
|
||||||
br label %F
|
|
||||||
F: ; preds = %T, %X, %0
|
|
||||||
%B1 = phi i1 [ true, %0 ], [ false, %T ], [ false, %X ] ; <i1> [#uses=1]
|
|
||||||
%I7 = phi i32 [ %V, %0 ], [ %V2, %T ], [ %V2, %X ] ; <i32> [#uses=1]
|
|
||||||
call void @use( i1 %B1 )
|
|
||||||
call void @use.upgrd.1( i32 %I7 )
|
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test(i1 %c, i32 %V, i32 %V2) {
|
define void @test(i1 %c, i32 %V, i32 %V2) {
|
||||||
; <label>:0
|
; <label>:0
|
||||||
|
@ -253,21 +253,21 @@ lor.end: ; preds = %lor.rhs, %lor.lhs.f
|
|||||||
ret i32 %conv46
|
ret i32 %conv46
|
||||||
|
|
||||||
; CHECK: @test9
|
; CHECK: @test9
|
||||||
; HECK: %cmp = icmp ult i8 %c, 33
|
; CHECK: %cmp = icmp ult i8 %c, 33
|
||||||
; HECK: br i1 %cmp, label %lor.end, label %switch.early.test
|
; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test
|
||||||
|
|
||||||
; HECK: switch.early.test:
|
; CHECK: switch.early.test:
|
||||||
; HECK: switch i8 %c, label %lor.rhs [
|
; CHECK: switch i8 %c, label %lor.rhs [
|
||||||
; HECK: i8 46, label %lor.end
|
; CHECK: i8 92, label %lor.end
|
||||||
; HECK: i8 44, label %lor.end
|
; CHECK: i8 62, label %lor.end
|
||||||
; HECK: i8 58, label %lor.end
|
; CHECK: i8 60, label %lor.end
|
||||||
; HECK: i8 59, label %lor.end
|
; CHECK: i8 59, label %lor.end
|
||||||
; HECK: i8 60, label %lor.end
|
; CHECK: i8 58, label %lor.end
|
||||||
; HECK: i8 62, label %lor.end
|
; CHECK: i8 46, label %lor.end
|
||||||
; HECK: i8 34, label %lor.end
|
; CHECK: i8 44, label %lor.end
|
||||||
; HECK: i8 92, label %lor.end
|
; CHECK: i8 34, label %lor.end
|
||||||
; HECK: i8 39, label %lor.end
|
; CHECK: i8 39, label %lor.end
|
||||||
; HECK: ]
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test10(i32 %mode, i1 %Cond) {
|
define i32 @test10(i32 %mode, i1 %Cond) {
|
||||||
|
Loading…
Reference in New Issue
Block a user