mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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.
This commit is contained in:
@@ -802,10 +802,12 @@ static int getThreadingCost(SILInstruction *I) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int maxBranchRecursionDepth = 6;
|
||||||
/// couldSimplifyUsers - Check to see if any simplifications are possible if
|
/// couldSimplifyUsers - Check to see if any simplifications are possible if
|
||||||
/// "Val" is substituted for BBArg. If so, return true, if nothing obvious
|
/// "Val" is substituted for BBArg. If so, return true, if nothing obvious
|
||||||
/// is possible, return false.
|
/// is possible, return false.
|
||||||
static bool couldSimplifyEnumUsers(SILArgument *BBArg, int Budget) {
|
static bool couldSimplifyEnumUsers(SILArgument *BBArg, int Budget,
|
||||||
|
int recursionDepth = 0) {
|
||||||
SILBasicBlock *BB = BBArg->getParent();
|
SILBasicBlock *BB = BBArg->getParent();
|
||||||
int BudgetForBranch = 100;
|
int BudgetForBranch = 100;
|
||||||
|
|
||||||
@@ -833,6 +835,9 @@ static bool couldSimplifyEnumUsers(SILArgument *BBArg, int Budget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (auto *BI = dyn_cast<BranchInst>(User)) {
|
if (auto *BI = dyn_cast<BranchInst>(User)) {
|
||||||
|
if (recursionDepth >= maxBranchRecursionDepth) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (BudgetForBranch > Budget) {
|
if (BudgetForBranch > Budget) {
|
||||||
BudgetForBranch = Budget;
|
BudgetForBranch = Budget;
|
||||||
for (SILInstruction &I : *BB) {
|
for (SILInstruction &I : *BB) {
|
||||||
@@ -844,7 +849,8 @@ static bool couldSimplifyEnumUsers(SILArgument *BBArg, int Budget) {
|
|||||||
if (BudgetForBranch > 0) {
|
if (BudgetForBranch > 0) {
|
||||||
SILBasicBlock *DestBB = BI->getDestBB();
|
SILBasicBlock *DestBB = BI->getDestBB();
|
||||||
unsigned OpIdx = UI->getOperandNumber();
|
unsigned OpIdx = UI->getOperandNumber();
|
||||||
if (couldSimplifyEnumUsers(DestBB->getArgument(OpIdx), BudgetForBranch))
|
if (couldSimplifyEnumUsers(DestBB->getArgument(OpIdx), BudgetForBranch,
|
||||||
|
recursionDepth + 1))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -790,6 +790,11 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
|
|||||||
case SILInstructionKind::GetAsyncContinuationInst:
|
case SILInstructionKind::GetAsyncContinuationInst:
|
||||||
return InlineCost::Free;
|
return InlineCost::Free;
|
||||||
|
|
||||||
|
// Unconditional branch is free in empty blocks.
|
||||||
|
case SILInstructionKind::BranchInst:
|
||||||
|
return (I.getIterator() == I.getParent()->begin())
|
||||||
|
? InlineCost::Free : InlineCost::Expensive;
|
||||||
|
|
||||||
case SILInstructionKind::AbortApplyInst:
|
case SILInstructionKind::AbortApplyInst:
|
||||||
case SILInstructionKind::ApplyInst:
|
case SILInstructionKind::ApplyInst:
|
||||||
case SILInstructionKind::TryApplyInst:
|
case SILInstructionKind::TryApplyInst:
|
||||||
@@ -804,7 +809,6 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
|
|||||||
case SILInstructionKind::WitnessMethodInst:
|
case SILInstructionKind::WitnessMethodInst:
|
||||||
case SILInstructionKind::AssignInst:
|
case SILInstructionKind::AssignInst:
|
||||||
case SILInstructionKind::AssignByWrapperInst:
|
case SILInstructionKind::AssignByWrapperInst:
|
||||||
case SILInstructionKind::BranchInst:
|
|
||||||
case SILInstructionKind::CheckedCastBranchInst:
|
case SILInstructionKind::CheckedCastBranchInst:
|
||||||
case SILInstructionKind::CheckedCastValueBranchInst:
|
case SILInstructionKind::CheckedCastValueBranchInst:
|
||||||
case SILInstructionKind::CheckedCastAddrBranchInst:
|
case SILInstructionKind::CheckedCastAddrBranchInst:
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ bb0:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: SPA @test_if_then_else
|
// CHECK-LABEL: SPA @test_if_then_else
|
||||||
// CHECK-NEXT: bb0: length=1+0, d-entry=0, d-exit=2
|
// CHECK-NEXT: bb0: length=1+0, d-entry=0, d-exit=1
|
||||||
// CHECK-NEXT: bb1: length=3+0, d-entry=1, d-exit=3
|
// CHECK-NEXT: bb1: length=3+0, d-entry=1, d-exit=3
|
||||||
// CHECK-NEXT: bb2: length=1+0, d-entry=1, d-exit=1
|
// CHECK-NEXT: bb2: length=0+0, d-entry=1, d-exit=0
|
||||||
// CHECK-NEXT: bb3: length=0+0, d-entry=2, d-exit=0
|
// CHECK-NEXT: bb3: length=0+0, d-entry=1, d-exit=0
|
||||||
|
|
||||||
sil @test_if_then_else : $@convention(thin) () -> () {
|
sil @test_if_then_else : $@convention(thin) () -> () {
|
||||||
bb0:
|
bb0:
|
||||||
@@ -42,9 +42,9 @@ bb3:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: SPA @test_simple_loop
|
// CHECK-LABEL: SPA @test_simple_loop
|
||||||
// CHECK-NEXT: bb0: length=1+0, d-entry=0, d-exit=34
|
// CHECK-NEXT: bb0: length=0+0, d-entry=0, d-exit=33
|
||||||
// CHECK-NEXT: bb1: length=3+30, d-entry=1, d-exit=33
|
// CHECK-NEXT: bb1: length=3+30, d-entry=0, d-exit=33
|
||||||
// CHECK-NEXT: bb2: length=0+0, d-entry=34, d-exit=0
|
// CHECK-NEXT: bb2: length=0+0, d-entry=33, d-exit=0
|
||||||
// CHECK-NEXT: Loop bb1:
|
// CHECK-NEXT: Loop bb1:
|
||||||
// CHECK-NEXT: bb1: length=3+0, d-entry=0, d-exit=3
|
// CHECK-NEXT: bb1: length=3+0, d-entry=0, d-exit=3
|
||||||
|
|
||||||
@@ -64,9 +64,9 @@ bb2:
|
|||||||
|
|
||||||
// CHECK-LABEL: SPA @test_loop_with_bypass_edge
|
// CHECK-LABEL: SPA @test_loop_with_bypass_edge
|
||||||
// CHECK-NEXT: bb0: length=1+30, d-entry=0, d-exit=31
|
// CHECK-NEXT: bb0: length=1+30, d-entry=0, d-exit=31
|
||||||
// CHECK-NEXT: bb1: length=1+0, d-entry=31, d-exit=5
|
// CHECK-NEXT: bb1: length=0+0, d-entry=31, d-exit=3
|
||||||
// CHECK-NEXT: bb2: length=3+0, d-entry=32, d-exit=4
|
// CHECK-NEXT: bb2: length=3+0, d-entry=31, d-exit=3
|
||||||
// CHECK-NEXT: bb3: length=1+0, d-entry=35, d-exit=1
|
// CHECK-NEXT: bb3: length=0+0, d-entry=34, d-exit=0
|
||||||
// CHECK-NEXT: bb4: length=0+0, d-entry=31, d-exit=0
|
// CHECK-NEXT: bb4: length=0+0, d-entry=31, d-exit=0
|
||||||
// CHECK-NEXT: Loop bb2:
|
// CHECK-NEXT: Loop bb2:
|
||||||
// CHECK-NEXT: bb2: length=3+0, d-entry=0, d-exit=3
|
// CHECK-NEXT: bb2: length=3+0, d-entry=0, d-exit=3
|
||||||
@@ -93,12 +93,12 @@ bb4:
|
|||||||
|
|
||||||
// CHECK-LABEL: SPA @test_nested_loops
|
// CHECK-LABEL: SPA @test_nested_loops
|
||||||
// CHECK-NEXT: bb0: length=1+40, d-entry=0, d-exit=41
|
// CHECK-NEXT: bb0: length=1+40, d-entry=0, d-exit=41
|
||||||
// CHECK-NEXT: bb1: length=1+0, d-entry=41, d-exit=6
|
// CHECK-NEXT: bb1: length=0+0, d-entry=41, d-exit=4
|
||||||
// CHECK-NEXT: bb2: length=1+0, d-entry=42, d-exit=5
|
// CHECK-NEXT: bb2: length=1+0, d-entry=41, d-exit=4
|
||||||
// CHECK-NEXT: bb3: length=3+0, d-entry=43, d-exit=5
|
// CHECK-NEXT: bb3: length=3+0, d-entry=42, d-exit=4
|
||||||
// CHECK-NEXT: bb4: length=2+0, d-entry=43, d-exit=4
|
// CHECK-NEXT: bb4: length=2+0, d-entry=42, d-exit=3
|
||||||
// CHECK-NEXT: bb5: length=1+0, d-entry=45, d-exit=2
|
// CHECK-NEXT: bb5: length=1+0, d-entry=44, d-exit=1
|
||||||
// CHECK-NEXT: bb6: length=1+0, d-entry=46, d-exit=1
|
// CHECK-NEXT: bb6: length=0+0, d-entry=45, d-exit=0
|
||||||
// CHECK-NEXT: bb7: length=0+0, d-entry=41, d-exit=0
|
// CHECK-NEXT: bb7: length=0+0, d-entry=41, d-exit=0
|
||||||
// CHECK-NEXT: Loop bb2:
|
// CHECK-NEXT: Loop bb2:
|
||||||
// CHECK-NEXT: bb2: length=1+0, d-entry=0, d-exit=4
|
// CHECK-NEXT: bb2: length=1+0, d-entry=0, d-exit=4
|
||||||
@@ -146,9 +146,9 @@ bb0:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: SPA @test_call_of_noreturn_in_loop
|
// CHECK-LABEL: SPA @test_call_of_noreturn_in_loop
|
||||||
// CHECK-NEXT: bb0: length=1+0, d-entry=0, d-exit=133
|
// CHECK-NEXT: bb0: length=0+0, d-entry=0, d-exit=132
|
||||||
// CHECK-NEXT: bb1: length=12+120, d-entry=1, d-exit=132
|
// CHECK-NEXT: bb1: length=12+120, d-entry=0, d-exit=132
|
||||||
// CHECK-NEXT: bb2: length=0+0, d-entry=133, d-exit=0
|
// CHECK-NEXT: bb2: length=0+0, d-entry=132, d-exit=0
|
||||||
// CHECK-NEXT: Loop bb1:
|
// CHECK-NEXT: Loop bb1:
|
||||||
// CHECK-NEXT: bb1: length=12+0, d-entry=0, d-exit=12
|
// CHECK-NEXT: bb1: length=12+0, d-entry=0, d-exit=12
|
||||||
sil @test_call_of_noreturn_in_loop : $@convention(thin) () -> () {
|
sil @test_call_of_noreturn_in_loop : $@convention(thin) () -> () {
|
||||||
|
|||||||
Reference in New Issue
Block a user