@@ -224,7 +224,7 @@ static bool mayWriteTo(AliasAnalysis *AA, BasicCalleeAnalysis *BCA,
224
224
// / Returns true if \p sideEffectInst cannot be reordered with a call to a
225
225
// / global initializer.
226
226
static bool mayConflictWithGlobalInit (AliasAnalysis *AA,
227
- SILInstruction *sideEffectInst, ApplyInst *globalInitCall) {
227
+ SILInstruction *sideEffectInst, SILInstruction *globalInitCall) {
228
228
if (auto *SI = dyn_cast<StoreInst>(sideEffectInst)) {
229
229
return AA->mayReadOrWriteMemory (globalInitCall, SI->getDest ());
230
230
}
@@ -239,7 +239,7 @@ static bool mayConflictWithGlobalInit(AliasAnalysis *AA,
239
239
// / the call.
240
240
static bool mayConflictWithGlobalInit (AliasAnalysis *AA,
241
241
InstSet &sideEffectInsts,
242
- ApplyInst *globalInitCall,
242
+ SILInstruction *globalInitCall,
243
243
SILBasicBlock *preHeader, PostDominanceInfo *PD) {
244
244
if (!PD->dominates (globalInitCall->getParent (), preHeader))
245
245
return true ;
@@ -263,7 +263,7 @@ static bool mayConflictWithGlobalInit(AliasAnalysis *AA,
263
263
// / block).
264
264
static bool mayConflictWithGlobalInit (AliasAnalysis *AA,
265
265
ArrayRef<SILInstruction *> sideEffectInsts,
266
- ApplyInst *globalInitCall) {
266
+ SILInstruction *globalInitCall) {
267
267
for (auto *seInst : sideEffectInsts) {
268
268
assert (seInst->getParent () == globalInitCall->getParent ());
269
269
if (mayConflictWithGlobalInit (AA, seInst, globalInitCall))
@@ -864,7 +864,12 @@ void LoopTreeOptimization::analyzeCurrentLoop(
864
864
865
865
// Interesting instructions in the loop:
866
866
SmallVector<ApplyInst *, 8 > ReadOnlyApplies;
867
- SmallVector<ApplyInst *, 8 > globalInitCalls;
867
+
868
+ // Contains either:
869
+ // * an apply to the addressor of the global
870
+ // * a builtin "once" of the global initializer
871
+ SmallVector<SILInstruction *, 8 > globalInitCalls;
872
+
868
873
SmallVector<LoadInst *, 8 > Loads;
869
874
SmallVector<StoreInst *, 8 > Stores;
870
875
SmallVector<FixLifetimeInst *, 8 > FixLifetimes;
@@ -918,16 +923,27 @@ void LoopTreeOptimization::analyzeCurrentLoop(
918
923
// Check against side-effects within the same block.
919
924
// Side-effects in other blocks are checked later (after we
920
925
// scanned all blocks of the loop).
921
- !mayConflictWithGlobalInit (AA, sideEffectsInBlock, AI ))
922
- globalInitCalls.push_back (AI );
926
+ !mayConflictWithGlobalInit (AA, sideEffectsInBlock, &Inst ))
927
+ globalInitCalls.push_back (&Inst );
923
928
}
924
929
// check for array semantics and side effects - same as default
925
930
LLVM_FALLTHROUGH;
926
931
}
927
932
default :
928
933
if (auto fullApply = FullApplySite::isa (&Inst)) {
929
934
fullApplies.push_back (fullApply);
935
+ } else if (auto *bi = dyn_cast<BuiltinInst>(&Inst)) {
936
+ switch (bi->getBuiltinInfo ().ID ) {
937
+ case BuiltinValueKind::Once:
938
+ case BuiltinValueKind::OnceWithContext:
939
+ if (!mayConflictWithGlobalInit (AA, sideEffectsInBlock, &Inst))
940
+ globalInitCalls.push_back (&Inst);
941
+ break ;
942
+ default :
943
+ break ;
944
+ }
930
945
}
946
+
931
947
checkSideEffects (Inst, sideEffects, sideEffectsInBlock);
932
948
if (canHoistUpDefault (&Inst, Loop, DomTree, RunsOnHighLevelSIL)) {
933
949
HoistUp.insert (&Inst);
@@ -959,7 +975,7 @@ void LoopTreeOptimization::analyzeCurrentLoop(
959
975
postDomTree = PDA->get (Preheader->getParent ());
960
976
}
961
977
if (postDomTree->getRootNode ()) {
962
- for (ApplyInst *ginitCall : globalInitCalls) {
978
+ for (SILInstruction *ginitCall : globalInitCalls) {
963
979
// Check against side effects which are "before" (i.e. post-dominated
964
980
// by) the global initializer call.
965
981
if (!mayConflictWithGlobalInit (AA, sideEffects, ginitCall, Preheader,
0 commit comments