mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-04 06:09:05 +00:00
Dig through multiple levels of AND to thread jumps if needed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50106 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d2368dc344
commit
ae65b3c791
@ -60,7 +60,7 @@ namespace {
|
||||
BasicBlock *FactorCommonPHIPreds(PHINode *PN, Constant *CstVal);
|
||||
|
||||
bool ProcessJumpOnPHI(PHINode *PN);
|
||||
bool ProcessJumpOnLogicalPHI(PHINode *PN, bool isAnd);
|
||||
bool ProcessBranchOnLogical(Value *V, BasicBlock *BB, bool isAnd);
|
||||
};
|
||||
char JumpThreading::ID = 0;
|
||||
RegisterPass<JumpThreading> X("jump-threading", "Jump Threading");
|
||||
@ -193,16 +193,10 @@ bool JumpThreading::ThreadBlock(BasicBlock *BB) {
|
||||
if (BinaryOperator *CondI = dyn_cast<BinaryOperator>(Condition)) {
|
||||
if ((CondI->getOpcode() == Instruction::And ||
|
||||
CondI->getOpcode() == Instruction::Or) &&
|
||||
isa<BranchInst>(BB->getTerminator())) {
|
||||
if (PHINode *PN = dyn_cast<PHINode>(CondI->getOperand(0)))
|
||||
if (PN->getParent() == BB &&
|
||||
ProcessJumpOnLogicalPHI(PN, CondI->getOpcode() == Instruction::And))
|
||||
return true;
|
||||
if (PHINode *PN = dyn_cast<PHINode>(CondI->getOperand(1)))
|
||||
if (PN->getParent() == BB &&
|
||||
ProcessJumpOnLogicalPHI(PN, CondI->getOpcode() == Instruction::And))
|
||||
return true;
|
||||
}
|
||||
isa<BranchInst>(BB->getTerminator()) &&
|
||||
ProcessBranchOnLogical(CondI, BB,
|
||||
CondI->getOpcode() == Instruction::And))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -270,8 +264,23 @@ bool JumpThreading::ProcessJumpOnPHI(PHINode *PN) {
|
||||
/// the predecessor corresponding to the 'false' will always jump to the false
|
||||
/// destination of the branch.
|
||||
///
|
||||
bool JumpThreading::ProcessJumpOnLogicalPHI(PHINode *PN, bool isAnd) {
|
||||
|
||||
bool JumpThreading::ProcessBranchOnLogical(Value *V, BasicBlock *BB,
|
||||
bool isAnd) {
|
||||
// If this is a binary operator tree of the same AND/OR opcode, check the
|
||||
// LHS/RHS.
|
||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
|
||||
if (isAnd && BO->getOpcode() == Instruction::And ||
|
||||
!isAnd && BO->getOpcode() == Instruction::Or) {
|
||||
if (ProcessBranchOnLogical(BO->getOperand(0), BB, isAnd))
|
||||
return true;
|
||||
if (ProcessBranchOnLogical(BO->getOperand(1), BB, isAnd))
|
||||
return true;
|
||||
}
|
||||
|
||||
// If this isn't a PHI node, we can't handle it.
|
||||
PHINode *PN = dyn_cast<PHINode>(V);
|
||||
if (!PN || PN->getParent() != BB) return false;
|
||||
|
||||
// We can only do the simplification for phi nodes of 'false' with AND or
|
||||
// 'true' with OR. See if we have any entries in the phi for this.
|
||||
unsigned PredNo = ~0U;
|
||||
@ -288,7 +297,6 @@ bool JumpThreading::ProcessJumpOnLogicalPHI(PHINode *PN, bool isAnd) {
|
||||
return false;
|
||||
|
||||
// See if the cost of duplicating this block is low enough.
|
||||
BasicBlock *BB = PN->getParent();
|
||||
unsigned JumpThreadCost = getJumpThreadDuplicationCost(BB);
|
||||
if (JumpThreadCost > Threshold) {
|
||||
DOUT << " Not threading BB '" << BB->getNameStart()
|
||||
|
33
test/Transforms/JumpThreading/and-and-cond.ll
Normal file
33
test/Transforms/JumpThreading/and-and-cond.ll
Normal file
@ -0,0 +1,33 @@
|
||||
; RUN: llvm-as < %s | opt -jump-threading -mem2reg -instcombine -simplifycfg | llvm-dis | grep {ret i32 %v1}
|
||||
; There should be no uncond branches left.
|
||||
; RUN: llvm-as < %s | opt -jump-threading -mem2reg -instcombine -simplifycfg | llvm-dis | not grep {br label}
|
||||
|
||||
declare i32 @f1()
|
||||
declare i32 @f2()
|
||||
declare void @f3()
|
||||
|
||||
define i32 @test(i1 %cond, i1 %cond2, i1 %cond3) {
|
||||
br i1 %cond, label %T1, label %F1
|
||||
|
||||
T1:
|
||||
%v1 = call i32 @f1()
|
||||
br label %Merge
|
||||
|
||||
F1:
|
||||
%v2 = call i32 @f2()
|
||||
br label %Merge
|
||||
|
||||
Merge:
|
||||
%A = phi i1 [true, %T1], [false, %F1]
|
||||
%B = phi i32 [%v1, %T1], [%v2, %F1]
|
||||
%C = and i1 %A, %cond2
|
||||
%D = and i1 %C, %cond3
|
||||
br i1 %D, label %T2, label %F2
|
||||
|
||||
T2:
|
||||
call void @f3()
|
||||
ret i32 %B
|
||||
|
||||
F2:
|
||||
ret i32 %B
|
||||
}
|
Loading…
Reference in New Issue
Block a user