diff options
| -rw-r--r-- | llvm/lib/Transforms/Scalar/JumpThreading.cpp | 26 | ||||
| -rw-r--r-- | llvm/test/Transforms/JumpThreading/select.ll | 30 |
2 files changed, 46 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 5c16b2c5de0..087ce8ac50d 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -286,6 +286,21 @@ static unsigned getJumpThreadDuplicationCost(const BasicBlock *BB, // FIXME: THREADING will delete values that are just used to compute the // branch, so they shouldn't count against the duplication cost. + unsigned Bonus = 0; + const TerminatorInst *BBTerm = BB->getTerminator(); + // Threading through a switch statement is particularly profitable. If this + // block ends in a switch, decrease its cost to make it more likely to happen. + if (isa<SwitchInst>(BBTerm)) + Bonus = 6; + + // The same holds for indirect branches, but slightly more so. + if (isa<IndirectBrInst>(BBTerm)) + Bonus = 8; + + // Bump the threshold up so the early exit from the loop doesn't skip the + // terminator-based Size adjustment at the end. + Threshold += Bonus; + // Sum up the cost of each instruction until we get to the terminator. Don't // include the terminator because the copy won't include it. unsigned Size = 0; @@ -326,16 +341,7 @@ static unsigned getJumpThreadDuplicationCost(const BasicBlock *BB, } } - // Threading through a switch statement is particularly profitable. If this - // block ends in a switch, decrease its cost to make it more likely to happen. - if (isa<SwitchInst>(I)) - Size = Size > 6 ? Size-6 : 0; - - // The same holds for indirect branches, but slightly more so. - if (isa<IndirectBrInst>(I)) - Size = Size > 8 ? Size-8 : 0; - - return Size; + return Size > Bonus ? Size - Bonus : 0; } /// FindLoopHeaders - We do not want jump threading to turn proper loop diff --git a/llvm/test/Transforms/JumpThreading/select.ll b/llvm/test/Transforms/JumpThreading/select.ll index d0df7725f72..595cacbcbf5 100644 --- a/llvm/test/Transforms/JumpThreading/select.ll +++ b/llvm/test/Transforms/JumpThreading/select.ll @@ -91,6 +91,36 @@ L3: } +; Jump threading of indirectbr with select as address. Test increased +; duplication threshold for cases where indirectbr is being threaded +; through. + +; CHECK-LABEL: @test_indirectbr_thresh( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 %cond, label %L1, label %L3 +; CHECK-NOT: indirectbr +define void @test_indirectbr_thresh(i1 %cond, i8* %address) nounwind { +entry: + br i1 %cond, label %L0, label %L3 +L0: + %indirect.goto.dest = select i1 %cond, i8* blockaddress(@test_indirectbr_thresh, %L1), i8* %address + call void @quux() + call void @quux() + call void @quux() + indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3] + +L1: + call void @foo() + ret void +L2: + call void @bar() + ret void +L3: + call void @baz() + ret void +} + + ; A more complicated case: the condition is a select based on a comparison. ; CHECK-LABEL: @test_switch_cmp( |

