mirror of
https://github.com/RPCSX/llvm.git
synced 2025-05-13 10:56:01 +00:00
[JumpThread] Do RAUW in case Cond folds to a constant in the CFG
Summary: [JumpThread] Do RAUW in case Cond folds to a constant in the CFG Reviewers: sanjoy Reviewed By: sanjoy Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D32407 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301804 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
195d3fa988
commit
fc533c3fb3
@ -1250,6 +1250,8 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB,
|
||||
|
||||
BasicBlock *OnlyDest = nullptr;
|
||||
BasicBlock *MultipleDestSentinel = (BasicBlock*)(intptr_t)~0ULL;
|
||||
Constant *OnlyVal = nullptr;
|
||||
Constant *MultipleVal = (Constant *)(intptr_t)~0ULL;
|
||||
|
||||
for (const auto &PredValue : PredValues) {
|
||||
BasicBlock *Pred = PredValue.second;
|
||||
@ -1277,10 +1279,17 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB,
|
||||
}
|
||||
|
||||
// If we have exactly one destination, remember it for efficiency below.
|
||||
if (PredToDestList.empty())
|
||||
if (PredToDestList.empty()) {
|
||||
OnlyDest = DestBB;
|
||||
else if (OnlyDest != DestBB)
|
||||
OnlyVal = Val;
|
||||
} else {
|
||||
if (OnlyDest != DestBB)
|
||||
OnlyDest = MultipleDestSentinel;
|
||||
// It possible we have same destination, but different value, e.g. default
|
||||
// case in switchinst.
|
||||
if (Val != OnlyVal)
|
||||
OnlyVal = MultipleVal;
|
||||
}
|
||||
|
||||
PredToDestList.push_back(std::make_pair(Pred, DestBB));
|
||||
}
|
||||
@ -1310,11 +1319,18 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB,
|
||||
|
||||
// If the condition is now dead due to the removal of the old terminator,
|
||||
// erase it.
|
||||
auto *CondInst = dyn_cast<Instruction>(Cond);
|
||||
if (CondInst && CondInst->use_empty())
|
||||
if (auto *CondInst = dyn_cast<Instruction>(Cond)) {
|
||||
if (CondInst->use_empty() && !CondInst->mayHaveSideEffects())
|
||||
CondInst->eraseFromParent();
|
||||
// FIXME: in case this instruction is defined in the current BB and it
|
||||
// resolves to a single value from all predecessors, we can do RAUW.
|
||||
else if (OnlyVal && OnlyVal != MultipleVal &&
|
||||
CondInst->getParent() == BB) {
|
||||
// If we just learned Cond is the same value for all uses of the
|
||||
// condition, replace it with a constant value
|
||||
CondInst->replaceAllUsesWith(OnlyVal);
|
||||
if (!CondInst->mayHaveSideEffects())
|
||||
CondInst->eraseFromParent();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -133,3 +133,60 @@ L3:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure we can do the RAUW for %add...
|
||||
;
|
||||
; CHECK-LABEL: @rauw_if_possible(
|
||||
; CHECK: call void @f4(i32 96)
|
||||
define void @rauw_if_possible(i32 %value) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %value, 32
|
||||
br i1 %cmp, label %L0, label %L3
|
||||
L0:
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
%add = add i32 %value, 64
|
||||
switch i32 %add, label %L3 [
|
||||
i32 32, label %L1
|
||||
i32 96, label %L2
|
||||
]
|
||||
|
||||
L1:
|
||||
call void @f3()
|
||||
ret void
|
||||
L2:
|
||||
call void @f4(i32 %add)
|
||||
ret void
|
||||
L3:
|
||||
call void @f3()
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure we can NOT do the RAUW for %add...
|
||||
;
|
||||
; CHECK-LABEL: @rauw_if_possible2(
|
||||
; CHECK: call void @f4(i32 %add)
|
||||
define void @rauw_if_possible2(i32 %value) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %value, 32
|
||||
%add = add i32 %value, 64
|
||||
br i1 %cmp, label %L0, label %L2
|
||||
L0:
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
switch i32 %add, label %L3 [
|
||||
i32 32, label %L1
|
||||
i32 96, label %L2
|
||||
]
|
||||
|
||||
L1:
|
||||
call void @f3()
|
||||
ret void
|
||||
L2:
|
||||
call void @f4(i32 %add)
|
||||
ret void
|
||||
L3:
|
||||
call void @f3()
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user