Skip to content

Commit 3290833

Browse files
authored
Merge pull request swiftlang#39974 from eeckstein/mandatory-globalopt
SILOptimizer: run the GlobalOpt pass in the mandatory pipeline.
2 parents 78de7d1 + c578c93 commit 3290833

File tree

9 files changed

+46
-14
lines changed

9 files changed

+46
-14
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,12 @@ static bool isLazilyEmittedFunction(SILFunction &f, SILModule &m) {
11331133
if (hasCodeCoverageInstrumentation(f, m))
11341134
return false;
11351135

1136+
// Needed by lldb to print global variables which are propagated by the
1137+
// mandatory GlobalOpt.
1138+
if (m.getOptions().OptMode == OptimizationMode::NoOptimization &&
1139+
f.isGlobalInit())
1140+
return false;
1141+
11361142
return true;
11371143
}
11381144

lib/SIL/IR/SILGlobalVariable.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,12 @@ swift::getVariableOfStaticInitializer(SILFunction *InitFunc,
326326
return nullptr;
327327
HasStore = true;
328328
InitVal = cast<SingleValueInstruction>(SI->getSrc());
329+
} else if (auto *mt = dyn_cast<MetatypeInst>(&I)) {
330+
// Unused meta_type instructions are sometimes generated by SILGen.
331+
// Handle this case to not require to run DeadCodeElimination before
332+
// MandatoryGlobalOpt.
333+
if (!mt->use_empty())
334+
return nullptr;
329335
} else if (!SILGlobalVariable::isValidStaticInitializerInst(&I,
330336
I.getModule())) {
331337
return nullptr;

lib/SILOptimizer/IPO/GlobalOpt.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,10 @@ bool SILGlobalOpt::isAssignedOnlyOnceInInitializer(SILGlobalVariable *SILG,
314314
if (SILG->isLet())
315315
return true;
316316

317+
// Don't replace loads from `var` globals when compiled with -Onone.
318+
if (Module->getOptions().OptMode == OptimizationMode::NoOptimization)
319+
return false;
320+
317321
// If we should skip this, it is probably because there are multiple stores.
318322
// Return false if there are multiple stores or no stores.
319323
if (GlobalVarSkipProcessing.count(SILG) || !GlobalVarStore.count(SILG))
@@ -768,10 +772,6 @@ bool SILGlobalOpt::run() {
768772
do {
769773
changed = false;
770774
for (auto &InitCalls : GlobalInitCallMap) {
771-
// Don't optimize functions that are marked with the opt.never attribute.
772-
if (!InitCalls.first->shouldOptimize())
773-
continue;
774-
775775
// Try to create a static initializer for the global and replace all uses
776776
// of the global by this constant value.
777777
changed |= optimizeInitializer(InitCalls.first, InitCalls.second);
@@ -788,6 +788,10 @@ bool SILGlobalOpt::run() {
788788
optimizeGlobalAccess(Init.first, Init.second);
789789
}
790790

791+
/// Don't perform the remaining optimizations when compiled with -Onone.
792+
if (Module->getOptions().OptMode == OptimizationMode::NoOptimization)
793+
return HasChanged;
794+
791795
SmallVector<SILGlobalVariable *, 8> addrGlobals;
792796
for (auto &addrPair : GlobalAddrMap) {
793797
// Don't optimize functions that are marked with the opt.never attribute.

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ static void addMandatoryDiagnosticOptPipeline(SILPassPipelinePlan &P) {
181181
P.addDiagnoseLifetimeIssues();
182182
}
183183

184+
P.addGlobalOpt();
184185
P.addPerformanceDiagnostics();
185186

186187
// Canonical swift requires all non cond_br critical edges to be split.

test/IRGen/force_public_metadata_accessors.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,12 @@ public func use() -> Int {
2222
}
2323
}
2424

25-
// CHECK: define {{.*}} @"$s31force_public_metadata_accessors3useSiyF"()
26-
// CHECK-NOT: define
27-
// CHECK: call {{.*}} %swift.metadata_response @"$s31force_public_metadata_accessors14FixedContainer{{.*}}LLOMa"
28-
2925
// FIXME: From within LLDB, this would be a forward declaration.
3026
// Unfortunately this is difficult to reproduce from source alone.
3127
// Really this should be a check for a non-internal "declare".
3228
// CHECK: define{{.*}} swiftcc %swift.metadata_response @"$s31force_public_metadata_accessors14FixedContainer{{.*}}LLOMa"
3329

30+
// CHECK: define {{.*}} @"$s31force_public_metadata_accessors3useSiyF"()
31+
// CHECK-NOT: define
32+
// CHECK: call {{.*}} %swift.metadata_response @"$s31force_public_metadata_accessors14FixedContainer{{.*}}LLOMa"
3433

test/IRGen/globals.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,11 @@ extension A {
4545
// CHECK: @"$s7globals2g3Sbvp" = hidden global [[BOOL]] zeroinitializer, align 1
4646
// CHECK: @"$s7globals2g6Sdvp" = hidden global [[DOUBLE]] zeroinitializer, align 8
4747
// CHECK: @"$s7globals2g7Sfvp" = hidden global [[FLOAT]] zeroinitializer, align 4
48-
// CHECK: @"$s7globals1AV3fooSivpZ" = hidden global [[INT]] zeroinitializer, align 8
48+
// CHECK: @"$s7globals1AV3fooSivpZ" = hidden global [[INT]] <{ i64 5 }>, align 8
4949

5050
// CHECK-NOT: g8
5151
// CHECK-NOT: g9
5252

5353
// CHECK: define{{( dllexport)?}}{{( protected)?}} i32 @main(i32 %0, i8** %1) {{.*}} {
5454
// CHECK: store i64 {{.*}}, i64* getelementptr inbounds ([[INT]], [[INT]]* @"$s7globals2g0Sivp", i32 0, i32 0), align 8
5555

56-
// CHECK: define internal void @"{{.*}}WZ"() {{.*}} {
57-
// CHECK: store i64 5, i64* getelementptr inbounds (%TSi, %TSi* @"$s7globals1AV3fooSivpZ", i32 0, i32 0), align 8

test/ModuleInterface/optimization-level.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// optimization passes don't run when compiling a .swiftinterface that was
1111
// generated with -Onone.
1212

13-
// OPT: GlobalOpt
14-
// UNOPT-NOT: GlobalOpt
13+
// OPT: AccessMarkerElimination
14+
// UNOPT-NOT: AccessMarkerElimination
1515
public func f() {}
1616

test/SILOptimizer/performance-annotations.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,18 @@ open class Cl {
1010
final func finalMethod() {}
1111
}
1212

13+
func initFunc() -> Int { return 3 }
14+
1315
struct Str : P {
1416
let x: Int
1517

1618
func protoMethod(_ a: Int) -> Int {
1719
return a + x
1820
}
1921

22+
static let s = 27
23+
static var s2 = 10 + s
24+
static var s3 = initFunc() // expected-error {{global/static variable initialization can cause locking}}
2025
}
2126

2227
struct AllocatingStr : P {
@@ -107,3 +112,14 @@ func testRecursion(_ i: Int) -> Int {
107112
}
108113
return 0
109114
}
115+
116+
@_noLocks
117+
func testGlobal() -> Int {
118+
return Str.s + Str.s2
119+
}
120+
121+
@_noLocks
122+
func testGlobalWithComplexInit() -> Int {
123+
return Str.s3 // expected-note {{called from here}}
124+
}
125+

test/Serialization/global_init.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
// The only way to inspect the serialized module is sil-opt. The swift
1313
// driver will only output the SIL that it deserializes.
1414

15+
func initFunc() -> Int { return 42 }
16+
1517
@usableFromInline
16-
let MyConst = 42
18+
let MyConst = initFunc()
1719
@usableFromInline
1820
var MyVar = 3
1921

0 commit comments

Comments
 (0)