mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
SILOptimizer: run the GlobalOpt pass in the mandatory pipeline.
Replace the dynamic initialization of trivial globals with statically initialized globals, even in -Onone. This is required to be able to use global variables in performance-annotated functions. Also, it's a small performance improvement for -Onone.
This commit is contained in:
@@ -1133,6 +1133,12 @@ static bool isLazilyEmittedFunction(SILFunction &f, SILModule &m) {
|
||||
if (hasCodeCoverageInstrumentation(f, m))
|
||||
return false;
|
||||
|
||||
// Needed by lldb to print global variables which are propagated by the
|
||||
// mandatory GlobalOpt.
|
||||
if (m.getOptions().OptMode == OptimizationMode::NoOptimization &&
|
||||
f.isGlobalInit())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -326,6 +326,12 @@ swift::getVariableOfStaticInitializer(SILFunction *InitFunc,
|
||||
return nullptr;
|
||||
HasStore = true;
|
||||
InitVal = cast<SingleValueInstruction>(SI->getSrc());
|
||||
} else if (auto *mt = dyn_cast<MetatypeInst>(&I)) {
|
||||
// Unused meta_type instructions are sometimes generated by SILGen.
|
||||
// Handle this case to not require to run DeadCodeElimination before
|
||||
// MandatoryGlobalOpt.
|
||||
if (!mt->use_empty())
|
||||
return nullptr;
|
||||
} else if (!SILGlobalVariable::isValidStaticInitializerInst(&I,
|
||||
I.getModule())) {
|
||||
return nullptr;
|
||||
|
||||
@@ -314,6 +314,10 @@ bool SILGlobalOpt::isAssignedOnlyOnceInInitializer(SILGlobalVariable *SILG,
|
||||
if (SILG->isLet())
|
||||
return true;
|
||||
|
||||
// Don't replace loads from `var` globals when compiled with -Onone.
|
||||
if (Module->getOptions().OptMode == OptimizationMode::NoOptimization)
|
||||
return false;
|
||||
|
||||
// If we should skip this, it is probably because there are multiple stores.
|
||||
// Return false if there are multiple stores or no stores.
|
||||
if (GlobalVarSkipProcessing.count(SILG) || !GlobalVarStore.count(SILG))
|
||||
@@ -768,10 +772,6 @@ bool SILGlobalOpt::run() {
|
||||
do {
|
||||
changed = false;
|
||||
for (auto &InitCalls : GlobalInitCallMap) {
|
||||
// Don't optimize functions that are marked with the opt.never attribute.
|
||||
if (!InitCalls.first->shouldOptimize())
|
||||
continue;
|
||||
|
||||
// Try to create a static initializer for the global and replace all uses
|
||||
// of the global by this constant value.
|
||||
changed |= optimizeInitializer(InitCalls.first, InitCalls.second);
|
||||
@@ -788,6 +788,10 @@ bool SILGlobalOpt::run() {
|
||||
optimizeGlobalAccess(Init.first, Init.second);
|
||||
}
|
||||
|
||||
/// Don't perform the remaining optimizations when compiled with -Onone.
|
||||
if (Module->getOptions().OptMode == OptimizationMode::NoOptimization)
|
||||
return HasChanged;
|
||||
|
||||
SmallVector<SILGlobalVariable *, 8> addrGlobals;
|
||||
for (auto &addrPair : GlobalAddrMap) {
|
||||
// Don't optimize functions that are marked with the opt.never attribute.
|
||||
|
||||
@@ -181,6 +181,7 @@ static void addMandatoryDiagnosticOptPipeline(SILPassPipelinePlan &P) {
|
||||
P.addDiagnoseLifetimeIssues();
|
||||
}
|
||||
|
||||
P.addGlobalOpt();
|
||||
P.addPerformanceDiagnostics();
|
||||
|
||||
// Canonical swift requires all non cond_br critical edges to be split.
|
||||
|
||||
@@ -22,13 +22,12 @@ public func use() -> Int {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: define {{.*}} @"$s31force_public_metadata_accessors3useSiyF"()
|
||||
// CHECK-NOT: define
|
||||
// CHECK: call {{.*}} %swift.metadata_response @"$s31force_public_metadata_accessors14FixedContainer{{.*}}LLOMa"
|
||||
|
||||
// FIXME: From within LLDB, this would be a forward declaration.
|
||||
// Unfortunately this is difficult to reproduce from source alone.
|
||||
// Really this should be a check for a non-internal "declare".
|
||||
// CHECK: define{{.*}} swiftcc %swift.metadata_response @"$s31force_public_metadata_accessors14FixedContainer{{.*}}LLOMa"
|
||||
|
||||
// CHECK: define {{.*}} @"$s31force_public_metadata_accessors3useSiyF"()
|
||||
// CHECK-NOT: define
|
||||
// CHECK: call {{.*}} %swift.metadata_response @"$s31force_public_metadata_accessors14FixedContainer{{.*}}LLOMa"
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ extension A {
|
||||
// CHECK: @"$s7globals2g3Sbvp" = hidden global [[BOOL]] zeroinitializer, align 1
|
||||
// CHECK: @"$s7globals2g6Sdvp" = hidden global [[DOUBLE]] zeroinitializer, align 8
|
||||
// CHECK: @"$s7globals2g7Sfvp" = hidden global [[FLOAT]] zeroinitializer, align 4
|
||||
// CHECK: @"$s7globals1AV3fooSivpZ" = hidden global [[INT]] zeroinitializer, align 8
|
||||
// CHECK: @"$s7globals1AV3fooSivpZ" = hidden global [[INT]] <{ i64 5 }>, align 8
|
||||
|
||||
// CHECK-NOT: g8
|
||||
// CHECK-NOT: g9
|
||||
@@ -53,5 +53,3 @@ extension A {
|
||||
// CHECK: define{{( dllexport)?}}{{( protected)?}} i32 @main(i32 %0, i8** %1) {{.*}} {
|
||||
// CHECK: store i64 {{.*}}, i64* getelementptr inbounds ([[INT]], [[INT]]* @"$s7globals2g0Sivp", i32 0, i32 0), align 8
|
||||
|
||||
// CHECK: define internal void @"{{.*}}WZ"() {{.*}} {
|
||||
// CHECK: store i64 5, i64* getelementptr inbounds (%TSi, %TSi* @"$s7globals1AV3fooSivpZ", i32 0, i32 0), align 8
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
// optimization passes don't run when compiling a .swiftinterface that was
|
||||
// generated with -Onone.
|
||||
|
||||
// OPT: GlobalOpt
|
||||
// UNOPT-NOT: GlobalOpt
|
||||
// OPT: AccessMarkerElimination
|
||||
// UNOPT-NOT: AccessMarkerElimination
|
||||
public func f() {}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ open class Cl {
|
||||
final func finalMethod() {}
|
||||
}
|
||||
|
||||
func initFunc() -> Int { return 3 }
|
||||
|
||||
struct Str : P {
|
||||
let x: Int
|
||||
|
||||
@@ -17,6 +19,9 @@ struct Str : P {
|
||||
return a + x
|
||||
}
|
||||
|
||||
static let s = 27
|
||||
static var s2 = 10 + s
|
||||
static var s3 = initFunc() // expected-error {{global/static variable initialization can cause locking}}
|
||||
}
|
||||
|
||||
struct AllocatingStr : P {
|
||||
@@ -107,3 +112,14 @@ func testRecursion(_ i: Int) -> Int {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
@_noLocks
|
||||
func testGlobal() -> Int {
|
||||
return Str.s + Str.s2
|
||||
}
|
||||
|
||||
@_noLocks
|
||||
func testGlobalWithComplexInit() -> Int {
|
||||
return Str.s3 // expected-note {{called from here}}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
// The only way to inspect the serialized module is sil-opt. The swift
|
||||
// driver will only output the SIL that it deserializes.
|
||||
|
||||
func initFunc() -> Int { return 42 }
|
||||
|
||||
@usableFromInline
|
||||
let MyConst = 42
|
||||
let MyConst = initFunc()
|
||||
@usableFromInline
|
||||
var MyVar = 3
|
||||
|
||||
|
||||
Reference in New Issue
Block a user