PR9450: Make switch optimization in SimplifyCFG not dependent on the ordering

of pointers in an std::map.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127650 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2011-03-15 02:23:35 +00:00
parent bf34a5ec22
commit b1a6eab655
2 changed files with 66 additions and 15 deletions

View File

@ -2211,17 +2211,28 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) {
// If the default value is unreachable, figure out the most popular // If the default value is unreachable, figure out the most popular
// destination and make it the default. // destination and make it the default.
if (SI->getSuccessor(0) == BB) { if (SI->getSuccessor(0) == BB) {
std::map<BasicBlock*, unsigned> Popularity; std::map<BasicBlock*, std::pair<unsigned, unsigned> > Popularity;
for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) {
Popularity[SI->getSuccessor(i)]++; std::pair<unsigned, unsigned>& entry =
Popularity[SI->getSuccessor(i)];
if (entry.first == 0) {
entry.first = 1;
entry.second = i;
} else {
entry.first++;
}
}
// Find the most popular block. // Find the most popular block.
unsigned MaxPop = 0; unsigned MaxPop = 0;
unsigned MaxIndex = 0;
BasicBlock *MaxBlock = 0; BasicBlock *MaxBlock = 0;
for (std::map<BasicBlock*, unsigned>::iterator for (std::map<BasicBlock*, std::pair<unsigned, unsigned> >::iterator
I = Popularity.begin(), E = Popularity.end(); I != E; ++I) { I = Popularity.begin(), E = Popularity.end(); I != E; ++I) {
if (I->second > MaxPop) { if (I->second.first > MaxPop ||
MaxPop = I->second; (I->second.first == MaxPop && MaxIndex > I->second.second)) {
MaxPop = I->second.first;
MaxIndex = I->second.second;
MaxBlock = I->first; MaxBlock = I->first;
} }
} }

View File

@ -1,33 +1,73 @@
; RUN: opt < %s -simplifycfg -S | not grep unreachable ; RUN: opt < %s -simplifycfg -S | FileCheck %s
define void @test1(i1 %C, i1* %BP) { define void @test1(i1 %C, i1* %BP) {
; CHECK: @test1
; CHECK: entry:
; CHECK-NEXT: ret void
entry:
br i1 %C, label %T, label %F br i1 %C, label %T, label %F
T: ; preds = %0 T:
store i1 %C, i1* %BP store i1 %C, i1* %BP
unreachable unreachable
F: ; preds = %0 F:
ret void ret void
} }
define void @test2() { define void @test2() {
; CHECK: @test2
; CHECK: entry:
; CHECK-NEXT: call void @test2()
; CHECK-NEXT: ret void
entry:
invoke void @test2( ) invoke void @test2( )
to label %N unwind label %U to label %N unwind label %U
U: ; preds = %0 U:
unreachable unreachable
N: ; preds = %0 N:
ret void ret void
} }
define i32 @test3(i32 %v) { define i32 @test3(i32 %v) {
; CHECK: @test3
; CHECK: entry:
; CHECK-NEXT: [[CMP:%[A-Za-z0-9]+]] = icmp eq i32 %v, 2
; CHECK-NEXT: select i1 [[CMP]], i32 2, i32 1
; CHECK-NEXT: ret
entry:
switch i32 %v, label %default [ switch i32 %v, label %default [
i32 1, label %U i32 1, label %U
i32 2, label %T i32 2, label %T
] ]
default: ; preds = %0 default:
ret i32 1 ret i32 1
U: ; preds = %0 U:
unreachable unreachable
T: ; preds = %0 T:
ret i32 2 ret i32 2
} }
; PR9450
define i32 @test4(i32 %v) {
; CHECK: entry:
; CHECK-NEXT: switch i32 %v, label %T [
; CHECK-NEXT: i32 3, label %V
; CHECK-NEXT: i32 2, label %U
; CHECK-NEXT: ]
entry:
br label %SWITCH
V:
ret i32 7
SWITCH:
switch i32 %v, label %default [
i32 1, label %T
i32 2, label %U
i32 3, label %V
]
default:
unreachable
U:
ret i32 1
T:
ret i32 2
}