Skip to content

Commit 3335ba5

Browse files
committed
Update isAssignedOnlyOnceInInitializer to be more correct
1 parent 46bc50d commit 3335ba5

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

lib/SILOptimizer/IPO/GlobalOpt.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ class SILGlobalOpt {
104104
bool run();
105105

106106
protected:
107+
/// Checks if a given global variable is assigned only once.
108+
bool isAssignedOnlyOnceInInitializer(SILGlobalVariable *SILG);
109+
107110
/// If this is a call to a global initializer, map it.
108111
void collectGlobalInitCall(ApplyInst *AI);
109112

@@ -595,15 +598,18 @@ static SILFunction *genGetterFromInit(SILOptFunctionBuilder &FunctionBuilder,
595598
return GetterF;
596599
}
597600

598-
/// Checks if a given global variable is assigned only once.
599-
static bool isAssignedOnlyOnceInInitializer(SILGlobalVariable *SILG) {
601+
bool SILGlobalOpt::isAssignedOnlyOnceInInitializer(SILGlobalVariable *SILG) {
600602
if (SILG->isLet())
601603
return true;
602-
// TODO: If we can prove that a given global variable
603-
// is assigned only once, during initialization, then
604-
// we can treat it as if it is a let.
605-
// If this global is internal or private, it should be
606-
return false;
604+
605+
// If we should skip this, it is probably because there are multiple stores.
606+
// Return false if there are multiple stores or no stores.
607+
if (GlobalVarSkipProcessing.count(SILG) || !GlobalVarStore.count(SILG))
608+
return false;
609+
610+
// Otherwise, return true if this can't be used externally (false, otherwise).
611+
return !isPossiblyUsedExternally(SILG->getLinkage(),
612+
SILG->getModule().isWholeModule());
607613
}
608614

609615
/// Replace load sequence which may contain

test/SILOptimizer/globalopt_global_propagation.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,25 @@ let IT2 = (100, 200, 300)
227227
public func test_let_tuple_wrapped_ints() -> Int {
228228
return IT1.0.0 + IT2.1
229229
}
230+
231+
class Foo {
232+
fileprivate static var x: Int = 0
233+
}
234+
235+
// CHECK-LABEL: sil @$s28globalopt_global_propagation25test_optimize_init_staticSiyF
236+
// CHECK: bb0:
237+
// CHECK-NOT: global_addr
238+
// CHECK-NEXT: integer_literal
239+
// CHECK-NEXT: struct
240+
// CHECK-NEXT: return
241+
242+
// CHECK-WMO-LABEL: sil @$s28globalopt_global_propagation25test_optimize_init_staticSiyF
243+
// CHECK-WMO: bb0:
244+
// CHECK-WMO-NOT: global_addr
245+
// CHECK-WMO-NEXT: integer_literal
246+
// CHECK-WMO-NEXT: struct
247+
// CHECK-WMO-NEXT: return
248+
public func test_optimize_init_static() -> Int {
249+
return Foo.x
250+
}
251+

0 commit comments

Comments
 (0)