llvm.org GIT mirror llvm / 01e223e
LowerSwitch: replace unreachable default with popular case destination SimplifyCFG currently does this transformation, but I'm planning to remove that to allow other passes, such as this one, to exploit the unreachable default. This patch takes care to keep track of what case values are unreachable even after the transformation, allowing for more efficient lowering. Differential Revision: http://reviews.llvm.org/D6697 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226934 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 4 years ago
3 changed file(s) with 251 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
3131 #define DEBUG_TYPE "lower-switch"
3232
3333 namespace {
34 struct IntRange {
35 int64_t Low, High;
36 };
37 // Return true iff R is covered by Ranges.
38 static bool IsInRanges(const IntRange &R,
39 const std::vector &Ranges) {
40 // Note: Ranges must be sorted, non-overlapping and non-adjacent.
41
42 // Find the first range whose High field is >= R.High,
43 // then check if the Low field is <= R.Low. If so, we
44 // have a Range that covers R.
45 auto I = std::lower_bound(
46 Ranges.begin(), Ranges.end(), R,
47 [](const IntRange &A, const IntRange &B) { return A.High < B.High; });
48 return I != Ranges.end() && I->Low <= R.Low;
49 }
50
3451 /// LowerSwitch Pass - Replace all SwitchInst instructions with chained branch
3552 /// instructions.
3653 class LowerSwitch : public FunctionPass {
6784 BasicBlock *switchConvert(CaseItr Begin, CaseItr End,
6885 ConstantInt *LowerBound, ConstantInt *UpperBound,
6986 Value *Val, BasicBlock *Predecessor,
70 BasicBlock *OrigBlock, BasicBlock *Default);
87 BasicBlock *OrigBlock, BasicBlock *Default,
88 const std::vector &UnreachableRanges);
7189 BasicBlock *newLeafBlock(CaseRange &Leaf, Value *Val, BasicBlock *OrigBlock,
7290 BasicBlock *Default);
7391 unsigned Clusterify(CaseVector &Cases, SwitchInst *SI);
171189 // LowerBound and UpperBound are used to keep track of the bounds for Val
172190 // that have already been checked by a block emitted by one of the previous
173191 // calls to switchConvert in the call stack.
174 BasicBlock *LowerSwitch::switchConvert(CaseItr Begin, CaseItr End,
175 ConstantInt *LowerBound,
176 ConstantInt *UpperBound, Value *Val,
177 BasicBlock *Predecessor,
178 BasicBlock *OrigBlock,
179 BasicBlock *Default) {
192 BasicBlock *
193 LowerSwitch::switchConvert(CaseItr Begin, CaseItr End, ConstantInt *LowerBound,
194 ConstantInt *UpperBound, Value *Val,
195 BasicBlock *Predecessor, BasicBlock *OrigBlock,
196 BasicBlock *Default,
197 const std::vector &UnreachableRanges) {
180198 unsigned Size = End - Begin;
181199
182200 if (Size == 1) {
211229 // the smallest, so there is always a case range that has at least
212230 // a smaller value.
213231 ConstantInt *NewLowerBound = cast(Pivot.Low);
214 ConstantInt *NewUpperBound;
215
216 // If we don't have a Default block then it means that we can never
217 // have a value outside of a case range, so set the UpperBound to the highest
218 // value in the LHS part of the case ranges.
219 if (Default != nullptr) {
220 // Because NewLowerBound is never the smallest representable integer
221 // it is safe here to subtract one.
222 NewUpperBound = ConstantInt::get(NewLowerBound->getContext(),
223 NewLowerBound->getValue() - 1);
224 } else {
225 CaseItr LastLHS = LHS.begin() + LHS.size() - 1;
226 NewUpperBound = cast(LastLHS->High);
232
233 // Because NewLowerBound is never the smallest representable integer
234 // it is safe here to subtract one.
235 ConstantInt *NewUpperBound = ConstantInt::get(NewLowerBound->getContext(),
236 NewLowerBound->getValue() - 1);
237
238 if (!UnreachableRanges.empty()) {
239 // Check if the gap between LHS's highest and NewLowerBound is unreachable.
240 int64_t GapLow = cast(LHS.back().High)->getSExtValue() + 1;
241 int64_t GapHigh = NewLowerBound->getSExtValue() - 1;
242 IntRange Gap = { GapLow, GapHigh };
243 if (GapHigh >= GapLow && IsInRanges(Gap, UnreachableRanges))
244 NewUpperBound = cast(LHS.back().High);
227245 }
228246
229247 DEBUG(dbgs() << "LHS Bounds ==> ";
251269
252270 BasicBlock *LBranch = switchConvert(LHS.begin(), LHS.end(), LowerBound,
253271 NewUpperBound, Val, NewNode, OrigBlock,
254 Default);
272 Default, UnreachableRanges);
255273 BasicBlock *RBranch = switchConvert(RHS.begin(), RHS.end(), NewLowerBound,
256274 UpperBound, Val, NewNode, OrigBlock,
257 Default);
275 Default, UnreachableRanges);
258276
259277 Function::iterator FI = OrigBlock;
260278 F->getBasicBlockList().insert(++FI, NewNode);
379397 Value *Val = SI->getCondition(); // The value we are switching on...
380398 BasicBlock* Default = SI->getDefaultDest();
381399
382 // If there is only the default destination, don't bother with the code below.
400 // If there is only the default destination, just branch.
383401 if (!SI->getNumCases()) {
384 BranchInst::Create(SI->getDefaultDest(), CurBlock);
385 CurBlock->getInstList().erase(SI);
402 BranchInst::Create(Default, CurBlock);
403 SI->eraseFromParent();
386404 return;
387405 }
388406
389 const bool DefaultIsUnreachable =
390 Default->size() == 1 && isa(Default->getTerminator());
407 // Prepare cases vector.
408 CaseVector Cases;
409 unsigned numCmps = Clusterify(Cases, SI);
410 DEBUG(dbgs() << "Clusterify finished. Total clusters: " << Cases.size()
411 << ". Total compares: " << numCmps << "\n");
412 DEBUG(dbgs() << "Cases: " << Cases << "\n");
413 (void)numCmps;
414
415 ConstantInt *LowerBound = nullptr;
416 ConstantInt *UpperBound = nullptr;
417 std::vector UnreachableRanges;
418
419 if (isa(Default->getFirstNonPHIOrDbg())) {
420 // Make the bounds tightly fitted around the case value range, becase we
421 // know that the value passed to the switch must be exactly one of the case
422 // values.
423 assert(!Cases.empty());
424 LowerBound = cast(Cases.front().Low);
425 UpperBound = cast(Cases.back().High);
426
427 DenseMap Popularity;
428 unsigned MaxPop = 0;
429 BasicBlock *PopSucc = nullptr;
430
431 IntRange R = { INT64_MIN, INT64_MAX };
432 UnreachableRanges.push_back(R);
433 for (const auto &I : Cases) {
434 int64_t Low = cast(I.Low)->getSExtValue();
435 int64_t High = cast(I.High)->getSExtValue();
436
437 IntRange &LastRange = UnreachableRanges.back();
438 if (LastRange.Low == Low) {
439 // There is nothing left of the previous range.
440 UnreachableRanges.pop_back();
441 } else {
442 // Terminate the previous range.
443 assert(Low > LastRange.Low);
444 LastRange.High = Low - 1;
445 }
446 if (High != INT64_MAX) {
447 IntRange R = { High + 1, INT64_MAX };
448 UnreachableRanges.push_back(R);
449 }
450
451 // Count popularity.
452 int64_t N = High - Low + 1;
453 unsigned &Pop = Popularity[I.BB];
454 if ((Pop += N) > MaxPop) {
455 MaxPop = Pop;
456 PopSucc = I.BB;
457 }
458 }
459 #ifndef NDEBUG
460 /* UnreachableRanges should be sorted and the ranges non-adjacent. */
461 for (auto I = UnreachableRanges.begin(), E = UnreachableRanges.end();
462 I != E; ++I) {
463 assert(I->Low <= I->High);
464 auto Next = I + 1;
465 if (Next != E) {
466 assert(Next->Low > I->High);
467 }
468 }
469 #endif
470
471 // Use the most popular block as the new default, reducing the number of
472 // cases.
473 assert(MaxPop > 0 && PopSucc);
474 Default = PopSucc;
475 for (CaseItr I = Cases.begin(); I != Cases.end();) {
476 if (I->BB == PopSucc)
477 I = Cases.erase(I);
478 else
479 ++I;
480 }
481
482 // If there are no cases left, just branch.
483 if (Cases.empty()) {
484 BranchInst::Create(Default, CurBlock);
485 SI->eraseFromParent();
486 return;
487 }
488 }
489
391490 // Create a new, empty default block so that the new hierarchy of
392491 // if-then statements go to this and the PHI nodes are happy.
393 // if the default block is set as an unreachable we avoid creating one
394 // because will never be a valid target.
395 BasicBlock *NewDefault = nullptr;
396 if (!DefaultIsUnreachable) {
397 NewDefault = BasicBlock::Create(SI->getContext(), "NewDefault");
398 F->getBasicBlockList().insert(Default, NewDefault);
399
400 BranchInst::Create(Default, NewDefault);
401 }
492 BasicBlock *NewDefault = BasicBlock::Create(SI->getContext(), "NewDefault");
493 F->getBasicBlockList().insert(Default, NewDefault);
494 BranchInst::Create(Default, NewDefault);
495
402496 // If there is an entry in any PHI nodes for the default edge, make sure
403497 // to update them as well.
404498 for (BasicBlock::iterator I = Default->begin(); isa(I); ++I) {
408502 PN->setIncomingBlock((unsigned)BlockIdx, NewDefault);
409503 }
410504
411 // Prepare cases vector.
412 CaseVector Cases;
413 unsigned numCmps = Clusterify(Cases, SI);
414
415 DEBUG(dbgs() << "Clusterify finished. Total clusters: " << Cases.size()
416 << ". Total compares: " << numCmps << "\n");
417 DEBUG(dbgs() << "Cases: " << Cases << "\n");
418 (void)numCmps;
419
420 ConstantInt *UpperBound = nullptr;
421 ConstantInt *LowerBound = nullptr;
422
423 // Optimize the condition where Default is an unreachable block. In this case
424 // we can make the bounds tightly fitted around the case value ranges,
425 // because we know that the value passed to the switch should always be
426 // exactly one of the case values.
427 if (DefaultIsUnreachable) {
428 CaseItr LastCase = Cases.begin() + Cases.size() - 1;
429 UpperBound = cast(LastCase->High);
430 LowerBound = cast(Cases.begin()->Low);
431 }
432505 BasicBlock *SwitchBlock =
433506 switchConvert(Cases.begin(), Cases.end(), LowerBound, UpperBound, Val,
434 OrigBlock, OrigBlock, NewDefault);
507 OrigBlock, OrigBlock, NewDefault, UnreachableRanges);
435508
436509 // Branch to our shiny new if-then stuff...
437510 BranchInst::Create(SwitchBlock, OrigBlock);
438511
439512 // We are now done with the switch instruction, delete it.
513 BasicBlock *OldDefault = SI->getDefaultDest();
440514 CurBlock->getInstList().erase(SI);
441515
442 pred_iterator PI = pred_begin(Default), E = pred_end(Default);
443 // If the Default block has no more predecessors just remove it
444 if (PI == E) {
445 DeleteDeadBlock(Default);
446 }
447 }
516 // If the Default block has no more predecessors just remove it.
517 if (pred_begin(OldDefault) == pred_end(OldDefault))
518 DeleteDeadBlock(OldDefault);
519 }
0 ; RUN: opt < %s -lowerswitch -S | FileCheck %s
1 ; CHECK-NOT: {{.*}}icmp eq{{.*}}
1 ;
2 ; The switch is lowered with a single icmp.
3 ; CHECK: icmp
4 ; CHECK-NOT: icmp
25 ;
36 ;int foo(int a) {
47 ;
1316 ;
1417 ;}
1518
16 define i32 @foo(i32 %a) nounwind ssp uwtable {
19 define i32 @foo(i32 %a) {
1720 %1 = alloca i32, align 4
1821 %2 = alloca i32, align 4
1922 store i32 %a, i32* %2, align 4
0 ; RUN: opt %s -lowerswitch -S | FileCheck %s
1
2 define void @foo(i32 %x, i32* %p) {
3 ; Cases 2 and 4 are removed and become the new default case.
4 ; It is now enough to use two icmps to lower the switch.
5 ;
6 ; CHECK-LABEL: @foo
7 ; CHECK: icmp slt i32 %x, 5
8 ; CHECK: icmp eq i32 %x, 1
9 ; CHECK-NOT: icmp
10 ;
11 entry:
12 switch i32 %x, label %default [
13 i32 1, label %bb0
14 i32 2, label %popular
15 i32 4, label %popular
16 i32 5, label %bb1
17 ]
18 bb0:
19 store i32 0, i32* %p
20 br label %exit
21 bb1:
22 store i32 1, i32* %p
23 br label %exit
24 popular:
25 store i32 2, i32* %p
26 br label %exit
27 exit:
28 ret void
29 default:
30 unreachable
31 }
32
33 define void @unreachable_gap(i64 %x, i32* %p) {
34 ; Cases 6 and INT64_MAX become the new default, but we still exploit the fact
35 ; that 3-4 is unreachable, so four icmps is enough.
36
37 ; CHECK-LABEL: @unreachable_gap
38 ; CHECK: icmp slt i64 %x, 2
39 ; CHECK: icmp slt i64 %x, 5
40 ; CHECK: icmp eq i64 %x, 5
41 ; CHECK: icmp slt i64 %x, 1
42 ; CHECK-NOT: icmp
43
44 entry:
45 switch i64 %x, label %default [
46 i64 -9223372036854775808, label %bb0
47 i64 1, label %bb1
48 i64 2, label %bb2
49 i64 5, label %bb3
50 i64 6, label %bb4
51 i64 9223372036854775807, label %bb4
52 ]
53 bb0:
54 store i32 0, i32* %p
55 br label %exit
56 bb1:
57 store i32 1, i32* %p
58 br label %exit
59 bb2:
60 store i32 2, i32* %p
61 br label %exit
62 bb3:
63 store i32 3, i32* %p
64 br label %exit
65 bb4:
66 store i32 4, i32* %p
67 br label %exit
68 exit:
69 ret void
70 default:
71 unreachable
72 }
73
74
75
76 define void @nocases(i32 %x, i32* %p) {
77 ; Don't fall over when there are no cases.
78 ;
79 ; CHECK-LABEL: @nocases
80 ; CHECK-LABEL: entry
81 ; CHECK-NEXT: br label %default
82 ;
83 entry:
84 switch i32 %x, label %default [
85 ]
86 default:
87 unreachable
88 }
89
90 define void @nocasesleft(i32 %x, i32* %p) {
91 ; Cases 2 and 4 are removed and we are left with no cases.
92 ;
93 ; CHECK-LABEL: @nocasesleft
94 ; CHECK-LABEL: entry
95 ; CHECK-NEXT: br label %popular
96 ;
97 entry:
98 switch i32 %x, label %default [
99 i32 2, label %popular
100 i32 4, label %popular
101 ]
102 popular:
103 store i32 2, i32* %p
104 br label %exit
105 exit:
106 ret void
107 default:
108 unreachable
109 }