Skip to content

Commit d82e0ff

Browse files
committed
SILInliner: Critical edges have no code size impact.
I think unconditional branches should be free, period. They will mostly be removed during LLVM code gen. However, fixing this requires signficant adjustments to inlining heuristics to avoid microbenchmark regressions at -Osize. So, instead I am just making this less sensitive to critical edges for the sake of pipeline stability.
1 parent d1bfe02 commit d82e0ff

File tree

3 files changed

+31
-21
lines changed

3 files changed

+31
-21
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -802,10 +802,12 @@ static int getThreadingCost(SILInstruction *I) {
802802
return 0;
803803
}
804804

805+
static int maxBranchRecursionDepth = 6;
805806
/// couldSimplifyUsers - Check to see if any simplifications are possible if
806807
/// "Val" is substituted for BBArg. If so, return true, if nothing obvious
807808
/// is possible, return false.
808-
static bool couldSimplifyEnumUsers(SILArgument *BBArg, int Budget) {
809+
static bool couldSimplifyEnumUsers(SILArgument *BBArg, int Budget,
810+
int recursionDepth = 0) {
809811
SILBasicBlock *BB = BBArg->getParent();
810812
int BudgetForBranch = 100;
811813

@@ -833,6 +835,9 @@ static bool couldSimplifyEnumUsers(SILArgument *BBArg, int Budget) {
833835
}
834836

835837
if (auto *BI = dyn_cast<BranchInst>(User)) {
838+
if (recursionDepth >= maxBranchRecursionDepth) {
839+
return false;
840+
}
836841
if (BudgetForBranch > Budget) {
837842
BudgetForBranch = Budget;
838843
for (SILInstruction &I : *BB) {
@@ -844,7 +849,8 @@ static bool couldSimplifyEnumUsers(SILArgument *BBArg, int Budget) {
844849
if (BudgetForBranch > 0) {
845850
SILBasicBlock *DestBB = BI->getDestBB();
846851
unsigned OpIdx = UI->getOperandNumber();
847-
if (couldSimplifyEnumUsers(DestBB->getArgument(OpIdx), BudgetForBranch))
852+
if (couldSimplifyEnumUsers(DestBB->getArgument(OpIdx), BudgetForBranch,
853+
recursionDepth + 1))
848854
return true;
849855
}
850856
}

lib/SILOptimizer/Utils/SILInliner.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,11 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
790790
case SILInstructionKind::GetAsyncContinuationInst:
791791
return InlineCost::Free;
792792

793+
// Unconditional branch is free in empty blocks.
794+
case SILInstructionKind::BranchInst:
795+
return (I.getIterator() == I.getParent()->begin())
796+
? InlineCost::Free : InlineCost::Expensive;
797+
793798
case SILInstructionKind::AbortApplyInst:
794799
case SILInstructionKind::ApplyInst:
795800
case SILInstructionKind::TryApplyInst:
@@ -804,7 +809,6 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
804809
case SILInstructionKind::WitnessMethodInst:
805810
case SILInstructionKind::AssignInst:
806811
case SILInstructionKind::AssignByWrapperInst:
807-
case SILInstructionKind::BranchInst:
808812
case SILInstructionKind::CheckedCastBranchInst:
809813
case SILInstructionKind::CheckedCastValueBranchInst:
810814
case SILInstructionKind::CheckedCastAddrBranchInst:

test/SILOptimizer/inliner_spa.sil

+18-18
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ bb0:
1919
}
2020

2121
// CHECK-LABEL: SPA @test_if_then_else
22-
// CHECK-NEXT: bb0: length=1+0, d-entry=0, d-exit=2
22+
// CHECK-NEXT: bb0: length=1+0, d-entry=0, d-exit=1
2323
// CHECK-NEXT: bb1: length=3+0, d-entry=1, d-exit=3
24-
// CHECK-NEXT: bb2: length=1+0, d-entry=1, d-exit=1
25-
// CHECK-NEXT: bb3: length=0+0, d-entry=2, d-exit=0
24+
// CHECK-NEXT: bb2: length=0+0, d-entry=1, d-exit=0
25+
// CHECK-NEXT: bb3: length=0+0, d-entry=1, d-exit=0
2626

2727
sil @test_if_then_else : $@convention(thin) () -> () {
2828
bb0:
@@ -42,9 +42,9 @@ bb3:
4242
}
4343

4444
// CHECK-LABEL: SPA @test_simple_loop
45-
// CHECK-NEXT: bb0: length=1+0, d-entry=0, d-exit=34
46-
// CHECK-NEXT: bb1: length=3+30, d-entry=1, d-exit=33
47-
// CHECK-NEXT: bb2: length=0+0, d-entry=34, d-exit=0
45+
// CHECK-NEXT: bb0: length=0+0, d-entry=0, d-exit=33
46+
// CHECK-NEXT: bb1: length=3+30, d-entry=0, d-exit=33
47+
// CHECK-NEXT: bb2: length=0+0, d-entry=33, d-exit=0
4848
// CHECK-NEXT: Loop bb1:
4949
// CHECK-NEXT: bb1: length=3+0, d-entry=0, d-exit=3
5050

@@ -64,9 +64,9 @@ bb2:
6464

6565
// CHECK-LABEL: SPA @test_loop_with_bypass_edge
6666
// CHECK-NEXT: bb0: length=1+30, d-entry=0, d-exit=31
67-
// CHECK-NEXT: bb1: length=1+0, d-entry=31, d-exit=5
68-
// CHECK-NEXT: bb2: length=3+0, d-entry=32, d-exit=4
69-
// CHECK-NEXT: bb3: length=1+0, d-entry=35, d-exit=1
67+
// CHECK-NEXT: bb1: length=0+0, d-entry=31, d-exit=3
68+
// CHECK-NEXT: bb2: length=3+0, d-entry=31, d-exit=3
69+
// CHECK-NEXT: bb3: length=0+0, d-entry=34, d-exit=0
7070
// CHECK-NEXT: bb4: length=0+0, d-entry=31, d-exit=0
7171
// CHECK-NEXT: Loop bb2:
7272
// CHECK-NEXT: bb2: length=3+0, d-entry=0, d-exit=3
@@ -93,12 +93,12 @@ bb4:
9393

9494
// CHECK-LABEL: SPA @test_nested_loops
9595
// CHECK-NEXT: bb0: length=1+40, d-entry=0, d-exit=41
96-
// CHECK-NEXT: bb1: length=1+0, d-entry=41, d-exit=6
97-
// CHECK-NEXT: bb2: length=1+0, d-entry=42, d-exit=5
98-
// CHECK-NEXT: bb3: length=3+0, d-entry=43, d-exit=5
99-
// CHECK-NEXT: bb4: length=2+0, d-entry=43, d-exit=4
100-
// CHECK-NEXT: bb5: length=1+0, d-entry=45, d-exit=2
101-
// CHECK-NEXT: bb6: length=1+0, d-entry=46, d-exit=1
96+
// CHECK-NEXT: bb1: length=0+0, d-entry=41, d-exit=4
97+
// CHECK-NEXT: bb2: length=1+0, d-entry=41, d-exit=4
98+
// CHECK-NEXT: bb3: length=3+0, d-entry=42, d-exit=4
99+
// CHECK-NEXT: bb4: length=2+0, d-entry=42, d-exit=3
100+
// CHECK-NEXT: bb5: length=1+0, d-entry=44, d-exit=1
101+
// CHECK-NEXT: bb6: length=0+0, d-entry=45, d-exit=0
102102
// CHECK-NEXT: bb7: length=0+0, d-entry=41, d-exit=0
103103
// CHECK-NEXT: Loop bb2:
104104
// CHECK-NEXT: bb2: length=1+0, d-entry=0, d-exit=4
@@ -146,9 +146,9 @@ bb0:
146146
}
147147

148148
// CHECK-LABEL: SPA @test_call_of_noreturn_in_loop
149-
// CHECK-NEXT: bb0: length=1+0, d-entry=0, d-exit=133
150-
// CHECK-NEXT: bb1: length=12+120, d-entry=1, d-exit=132
151-
// CHECK-NEXT: bb2: length=0+0, d-entry=133, d-exit=0
149+
// CHECK-NEXT: bb0: length=0+0, d-entry=0, d-exit=132
150+
// CHECK-NEXT: bb1: length=12+120, d-entry=0, d-exit=132
151+
// CHECK-NEXT: bb2: length=0+0, d-entry=132, d-exit=0
152152
// CHECK-NEXT: Loop bb1:
153153
// CHECK-NEXT: bb1: length=12+0, d-entry=0, d-exit=12
154154
sil @test_call_of_noreturn_in_loop : $@convention(thin) () -> () {

0 commit comments

Comments
 (0)