Skip to content

Commit 0403a21

Browse files
committed
use the new side effects in the performance inliner
1 parent 13dad3a commit 0403a21

File tree

6 files changed

+25
-24
lines changed

6 files changed

+25
-24
lines changed

include/swift/SILOptimizer/Utils/PerformanceInlinerUtils.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ using namespace swift;
2828
extern llvm::cl::opt<bool> EnableSILInliningOfGenerics;
2929

3030
namespace swift {
31-
class SideEffectAnalysis;
31+
class BasicCalleeAnalysis;
3232

3333
// Controls the decision to inline functions with @_semantics, @effect and
3434
// global_init attributes.
@@ -45,7 +45,7 @@ SILFunction *getEligibleFunction(FullApplySite AI,
4545

4646
// Returns true if this is a pure call, i.e. the callee has no side-effects
4747
// and all arguments are constants.
48-
bool isPureCall(FullApplySite AI, SideEffectAnalysis *SEA);
48+
bool isPureCall(FullApplySite AI, BasicCalleeAnalysis *BCA);
4949

5050
/// Fundamental @_semantic tags provide additional semantics for optimization
5151
/// beyond what SIL analysis can discover from the function body. They should be

lib/SILOptimizer/Transforms/PerformanceInliner.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include "swift/AST/SemanticAttrs.h"
1616
#include "swift/SIL/MemAccessUtils.h"
1717
#include "swift/SIL/OptimizationRemark.h"
18-
#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h"
18+
#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h"
1919
#include "swift/SILOptimizer/PassManager/Passes.h"
2020
#include "swift/SILOptimizer/PassManager/Transforms.h"
2121
#include "swift/SILOptimizer/Utils/CFGOptUtils.h"
@@ -120,7 +120,7 @@ class SILPerformanceInliner {
120120

121121
DominanceAnalysis *DA;
122122
SILLoopAnalysis *LA;
123-
SideEffectAnalysis *SEA;
123+
BasicCalleeAnalysis *BCA;
124124

125125
// For keys of SILFunction and SILLoop.
126126
llvm::DenseMap<SILFunction *, ShortestPathAnalysis *> SPAs;
@@ -246,10 +246,10 @@ class SILPerformanceInliner {
246246
public:
247247
SILPerformanceInliner(StringRef PassName, SILOptFunctionBuilder &FuncBuilder,
248248
InlineSelection WhatToInline, DominanceAnalysis *DA,
249-
SILLoopAnalysis *LA, SideEffectAnalysis *SEA,
249+
SILLoopAnalysis *LA, BasicCalleeAnalysis *BCA,
250250
OptimizationMode OptMode, OptRemark::Emitter &ORE)
251251
: PassName(PassName), FuncBuilder(FuncBuilder),
252-
WhatToInline(WhatToInline), DA(DA), LA(LA), SEA(SEA), CBI(DA), ORE(ORE),
252+
WhatToInline(WhatToInline), DA(DA), LA(LA), BCA(BCA), CBI(DA), ORE(ORE),
253253
OptMode(OptMode) {}
254254

255255
bool inlineCallsIntoFunction(SILFunction *F);
@@ -352,7 +352,7 @@ bool SILPerformanceInliner::isProfitableToInline(
352352

353353
// It is always OK to inline a simple call.
354354
// TODO: May be consider also the size of the callee?
355-
if (isPureCall(AI, SEA)) {
355+
if (isPureCall(AI, BCA)) {
356356
OptRemark::Emitter::emitOrDebug(DEBUG_TYPE, &ORE, [&]() {
357357
using namespace OptRemark;
358358
return RemarkPassed("Inline", *AI.getInstruction())
@@ -1125,7 +1125,7 @@ class SILPerformanceInlinerPass : public SILFunctionTransform {
11251125
void run() override {
11261126
DominanceAnalysis *DA = PM->getAnalysis<DominanceAnalysis>();
11271127
SILLoopAnalysis *LA = PM->getAnalysis<SILLoopAnalysis>();
1128-
SideEffectAnalysis *SEA = PM->getAnalysis<SideEffectAnalysis>();
1128+
BasicCalleeAnalysis *BCA = PM->getAnalysis<BasicCalleeAnalysis>();
11291129
OptRemark::Emitter ORE(DEBUG_TYPE, *getFunction());
11301130

11311131
if (getOptions().InlineThreshold == 0) {
@@ -1137,7 +1137,7 @@ class SILPerformanceInlinerPass : public SILFunctionTransform {
11371137
SILOptFunctionBuilder FuncBuilder(*this);
11381138

11391139
SILPerformanceInliner Inliner(getID(), FuncBuilder, WhatToInline, DA, LA,
1140-
SEA, OptMode, ORE);
1140+
BCA, OptMode, ORE);
11411141

11421142
assert(getFunction()->isDefinition() &&
11431143
"Expected only functions with bodies!");

lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/SILOptimizer/Analysis/ArraySemantic.h"
14-
#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h"
14+
#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h"
1515
#include "swift/SILOptimizer/Utils/PerformanceInlinerUtils.h"
1616
#include "swift/AST/Module.h"
1717
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
@@ -933,14 +933,11 @@ static bool isConstantArg(Operand *Arg) {
933933
}
934934

935935

936-
bool swift::isPureCall(FullApplySite AI, SideEffectAnalysis *SEA) {
936+
bool swift::isPureCall(FullApplySite AI, BasicCalleeAnalysis *BCA) {
937937
// If a call has only constant arguments and the call is pure, i.e. has
938938
// no side effects, then we should always inline it.
939939
// This includes arguments which are objects initialized with constant values.
940-
FunctionSideEffects ApplyEffects;
941-
SEA->getCalleeEffects(ApplyEffects, AI);
942-
auto GE = ApplyEffects.getGlobalEffects();
943-
if (GE.mayRead() || GE.mayWrite() || GE.mayRetain() || GE.mayRelease())
940+
if (BCA->getMemoryBehavior(AI, /*observeRetains*/ true) != SILInstruction::MemoryBehavior::None)
944941
return false;
945942
// Check if all parameters are constant.
946943
auto Args = AI.getArgumentOperands().slice(AI.getNumIndirectSILResults());

test/SILOptimizer/assemblyvision_remark/attributes.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ public func failMatch() {
4040

4141
@_semantics("optremark")
4242
public func allocateInlineCallee() -> Klass {
43-
return Klass() // expected-remark {{Pure call. Always profitable to inline "main.Klass.__allocating_init()"}}
43+
return Klass() // expected-remark {{"main.Klass.__allocating_init()" inlined into "main.allocateInlineCallee()"}}
4444
// expected-remark @-1 {{heap allocated ref of type 'Klass'}}
4545
}
4646

4747
@_semantics("optremark.sil-inliner")
4848
public func allocateInlineCallee2() -> Klass {
49-
return Klass() // expected-remark {{Pure call. Always profitable to inline "main.Klass.__allocating_init()"}}
49+
return Klass() // expected-remark {{"main.Klass.__allocating_init()" inlined into "main.allocateInlineCallee2()"}}
5050
}
5151

5252
// This makes sure we don't emit any remarks if we do not have semantics.
@@ -58,14 +58,14 @@ public func allocateInlineCallee3() -> Klass {
5858
@_semantics("optremark.sil-assembly-vision-remark-gen")
5959
public func mix1() -> (Klass, Klass) {
6060
let x = getGlobal()
61-
return (x, Klass()) // expected-remark {{Pure call. Always profitable to inline "main.Klass.__allocating_init()"}}
61+
return (x, Klass()) // expected-remark {{"main.Klass.__allocating_init()" inlined into "main.mix1()"}}
6262
// expected-remark @-1:16 {{heap allocated ref of type 'Klass'}}
6363
}
6464

6565
@_semantics("optremark.sil-inliner")
6666
public func mix2() -> (Klass, Klass) {
6767
let x = getGlobal()
68-
return (x, Klass()) // expected-remark {{Pure call. Always profitable to inline "main.Klass.__allocating_init()"}}
68+
return (x, Klass()) // expected-remark {{"main.Klass.__allocating_init()" inlined into "main.mix2()"}}
6969
}
7070

7171
@_semantics("optremark.sil-assembly-vision-remark-gen")
@@ -77,7 +77,7 @@ public func mix3() -> (Klass, Klass) {
7777
@_semantics("optremark")
7878
public func mix4() -> (Klass, Klass) {
7979
let x = getGlobal()
80-
return (x, Klass()) // expected-remark {{Pure call. Always profitable to inline "main.Klass.__allocating_init()"}}
80+
return (x, Klass()) // expected-remark {{"main.Klass.__allocating_init()" inlined into "main.mix4()"}}
8181
// expected-remark @-1 {{heap allocated ref of type 'Klass'}}
8282
}
8383

@@ -89,6 +89,6 @@ public func mix5() -> (Klass, Klass) {
8989
@_assemblyVision
9090
public func mix4a() -> (Klass, Klass) {
9191
let x = getGlobal()
92-
return (x, Klass()) // expected-remark {{Pure call. Always profitable to inline "main.Klass.__allocating_init()"}}
92+
return (x, Klass()) // expected-remark {{"main.Klass.__allocating_init()" inlined into "main.mix4a()"}}
9393
// expected-remark @-1 {{heap allocated ref of type 'Klass'}}
9494
}

test/SILOptimizer/inline_heuristics.sil

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -sil-inline-generics=true -sil-partial-specialization=false -debug-only=sil-inliner 2>%t/log | %FileCheck %s
2+
// RUN: %target-sil-opt -enable-sil-verify-all %s -compute-side-effects -inline -sil-inline-generics=true -sil-partial-specialization=false -debug-only=sil-inliner 2>%t/log | %FileCheck %s
33
// RUN: %FileCheck %s --check-prefix=CHECK-LOG <%t/log
44
// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -sil-inline-generics=true -sil-partial-specialization=true -generic-specializer -debug-only=sil-inliner 2>%t/log | %FileCheck %s --check-prefix=CHECK-PARTIAL-SPECIALIZATION
55
// REQUIRES: asserts
66

7+
// REQUIRES: swift_in_compiler
8+
79
// This test checks the inline heuristics based on the debug log output of
810
// the performance inliner.
911
// Checking the final sil is just a goodie.

test/SILOptimizer/inliner_coldblocks.sil

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -sil-remarks=sil-inliner -o %t.sil 2>&1 | %FileCheck -check-prefix=REMARKS_PASSED %s
2+
// RUN: %target-sil-opt -enable-sil-verify-all %s -compute-side-effects -inline -sil-remarks=sil-inliner -o %t.sil 2>&1 | %FileCheck -check-prefix=REMARKS_PASSED %s
33
// RUN: %FileCheck %s < %t.sil
44
// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -sil-remarks-missed=sil-inliner -o /dev/null 2>&1 | %FileCheck -check-prefix=REMARKS_MISSED %s
55
// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -save-optimization-record-path %t.yaml -o /dev/null 2>&1 | %FileCheck -allow-empty -check-prefix=NO_REMARKS %s
@@ -9,6 +9,8 @@
99
// REMARKS_MISSED-NOT: remark:
1010
// NO_REMARKS-NOT: remark:
1111

12+
// REQUIRES: swift_in_compiler
13+
1214
sil_stage canonical
1315

1416
import Builtin
@@ -207,7 +209,7 @@ bb0:
207209
// YAML-NEXT: - Callee: '"update_global"'
208210
// YAML-NEXT: DebugLoc:
209211
// YAML: File: {{.*}}inliner_coldblocks.sil
210-
// YAML: Line: 20
212+
// YAML: Line: 22
211213
// YAML: Column: 6
212214
// YAML-NEXT: - String: ' inlined into '
213215
// YAML-NEXT: - Caller: '"regular_large_callee"'

0 commit comments

Comments
 (0)