mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-01 18:12:49 +00:00
change simplifycfg to not duplicate 'unwind' instructions. Hopefully
this will increase the likelihood of common code getting sunk towards the unwind. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83996 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bf07da0e27
commit
11f15dbb28
@ -1860,33 +1860,26 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
|
|||||||
} else if (isa<UnwindInst>(BB->begin())) {
|
} else if (isa<UnwindInst>(BB->begin())) {
|
||||||
// Check to see if the first instruction in this block is just an unwind.
|
// Check to see if the first instruction in this block is just an unwind.
|
||||||
// If so, replace any invoke instructions which use this as an exception
|
// If so, replace any invoke instructions which use this as an exception
|
||||||
// destination with call instructions, and any unconditional branch
|
// destination with call instructions.
|
||||||
// predecessor with an unwind.
|
|
||||||
//
|
//
|
||||||
SmallVector<BasicBlock*, 8> Preds(pred_begin(BB), pred_end(BB));
|
SmallVector<BasicBlock*, 8> Preds(pred_begin(BB), pred_end(BB));
|
||||||
while (!Preds.empty()) {
|
while (!Preds.empty()) {
|
||||||
BasicBlock *Pred = Preds.back();
|
BasicBlock *Pred = Preds.back();
|
||||||
if (BranchInst *BI = dyn_cast<BranchInst>(Pred->getTerminator())) {
|
if (InvokeInst *II = dyn_cast<InvokeInst>(Pred->getTerminator()))
|
||||||
if (BI->isUnconditional()) {
|
|
||||||
Pred->getInstList().pop_back(); // nuke uncond branch
|
|
||||||
new UnwindInst(Pred->getContext(), Pred); // Use unwind.
|
|
||||||
Changed = true;
|
|
||||||
}
|
|
||||||
} else if (InvokeInst *II = dyn_cast<InvokeInst>(Pred->getTerminator()))
|
|
||||||
if (II->getUnwindDest() == BB) {
|
if (II->getUnwindDest() == BB) {
|
||||||
// Insert a new branch instruction before the invoke, because this
|
// Insert a new branch instruction before the invoke, because this
|
||||||
// is now a fall through...
|
// is now a fall through.
|
||||||
BranchInst *BI = BranchInst::Create(II->getNormalDest(), II);
|
BranchInst *BI = BranchInst::Create(II->getNormalDest(), II);
|
||||||
Pred->getInstList().remove(II); // Take out of symbol table
|
Pred->getInstList().remove(II); // Take out of symbol table
|
||||||
|
|
||||||
// Insert the call now...
|
// Insert the call now.
|
||||||
SmallVector<Value*,8> Args(II->op_begin()+3, II->op_end());
|
SmallVector<Value*,8> Args(II->op_begin()+3, II->op_end());
|
||||||
CallInst *CI = CallInst::Create(II->getCalledValue(),
|
CallInst *CI = CallInst::Create(II->getCalledValue(),
|
||||||
Args.begin(), Args.end(),
|
Args.begin(), Args.end(),
|
||||||
II->getName(), BI);
|
II->getName(), BI);
|
||||||
CI->setCallingConv(II->getCallingConv());
|
CI->setCallingConv(II->getCallingConv());
|
||||||
CI->setAttributes(II->getAttributes());
|
CI->setAttributes(II->getAttributes());
|
||||||
// If the invoke produced a value, the Call now does instead
|
// If the invoke produced a value, the Call now does instead.
|
||||||
II->replaceAllUsesWith(CI);
|
II->replaceAllUsesWith(CI);
|
||||||
delete II;
|
delete II;
|
||||||
Changed = true;
|
Changed = true;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
; This testcase checks to see if the simplifycfg pass is converting invoke
|
|
||||||
; instructions to call instructions if the handler just rethrows the exception.
|
|
||||||
|
|
||||||
; RUN: opt < %s -simplifycfg -S | FileCheck %s
|
; RUN: opt < %s -simplifycfg -S | FileCheck %s
|
||||||
|
|
||||||
declare void @bar()
|
declare void @bar()
|
||||||
|
|
||||||
|
; This testcase checks to see if the simplifycfg pass is converting invoke
|
||||||
|
; instructions to call instructions if the handler just rethrows the exception.
|
||||||
define i32 @test1() {
|
define i32 @test1() {
|
||||||
; CHECK: @test1
|
; CHECK: @test1
|
||||||
; CHECK-NEXT: call void @bar()
|
; CHECK-NEXT: call void @bar()
|
||||||
@ -16,3 +15,19 @@ Ok: ; preds = %0
|
|||||||
Rethrow: ; preds = %0
|
Rethrow: ; preds = %0
|
||||||
unwind
|
unwind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; Verify that simplifycfg isn't duplicating 'unwind' instructions. Doing this
|
||||||
|
; is bad because it discourages commoning.
|
||||||
|
define i32 @test2(i1 %c) {
|
||||||
|
; CHECK: @test2
|
||||||
|
; CHECK: T:
|
||||||
|
; CHECK-NEXT: call void @bar()
|
||||||
|
; CHECK-NEXT: br label %F
|
||||||
|
br i1 %c, label %T, label %F
|
||||||
|
T:
|
||||||
|
call void @bar()
|
||||||
|
br label %F
|
||||||
|
F:
|
||||||
|
unwind
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user