@@ -581,25 +581,43 @@ StringOptimization::getStringFromStaticLet(SILValue value) {
581
581
auto *load = dyn_cast<LoadInst>(value);
582
582
if (!load)
583
583
return StringInfo::unknown ();
584
-
585
- auto *pta = dyn_cast<PointerToAddressInst>(load->getOperand ());
586
- if (!pta)
587
- return StringInfo::unknown ();
588
-
589
- auto *addressorCall = dyn_cast<ApplyInst>(pta->getOperand ());
590
- if (!addressorCall)
591
- return StringInfo::unknown ();
592
-
593
- SILFunction *addressorFunc = addressorCall->getReferencedFunctionOrNull ();
594
- if (!addressorFunc)
595
- return StringInfo::unknown ();
596
-
597
- // The addressor function has a builtin.once call to the initializer.
598
- BuiltinInst *onceCall = nullptr ;
599
- SILFunction *initializer = findInitializer (addressorFunc, onceCall);
600
- if (!initializer)
584
+
585
+ SILFunction *initializer = nullptr ;
586
+ auto *globalAddr = dyn_cast<GlobalAddrInst>(load->getOperand ());
587
+ if (globalAddr) {
588
+ // The global accessor is inlined.
589
+
590
+ // Usually the global_addr is immediately preceeded by a call to
591
+ // `builtin "once"` which initializes the global.
592
+ SILInstruction *prev = globalAddr->getPreviousInstruction ();
593
+ if (!prev)
594
+ return StringInfo::unknown ();
595
+ auto *bi = dyn_cast<BuiltinInst>(prev);
596
+ if (!bi || bi->getBuiltinInfo ().ID != BuiltinValueKind::Once)
597
+ return StringInfo::unknown ();
598
+ initializer = getCalleeOfOnceCall (bi);
599
+ } else {
600
+ // The global accessor is not inlined, yet.
601
+
602
+ auto *pta = dyn_cast<PointerToAddressInst>(load->getOperand ());
603
+ if (!pta)
604
+ return StringInfo::unknown ();
605
+
606
+ auto *addressorCall = dyn_cast<ApplyInst>(pta->getOperand ());
607
+ if (!addressorCall)
608
+ return StringInfo::unknown ();
609
+
610
+ SILFunction *addressorFunc = addressorCall->getReferencedFunctionOrNull ();
611
+ if (!addressorFunc)
612
+ return StringInfo::unknown ();
613
+
614
+ // The addressor function has a builtin.once call to the initializer.
615
+ BuiltinInst *onceCall = nullptr ;
616
+ initializer = findInitializer (addressorFunc, onceCall);
617
+ }
618
+ if (!initializer || !initializer->isGlobalInitOnceFunction ())
601
619
return StringInfo::unknown ();
602
-
620
+
603
621
if (initializer->size () != 1 )
604
622
return StringInfo::unknown ();
605
623
@@ -618,7 +636,10 @@ StringOptimization::getStringFromStaticLet(SILValue value) {
618
636
}
619
637
if (!gAddr || !gAddr ->getReferencedGlobal ()->isLet ())
620
638
return StringInfo::unknown ();
621
-
639
+
640
+ if (globalAddr && globalAddr->getReferencedGlobal () != gAddr ->getReferencedGlobal ())
641
+ return StringInfo::unknown ();
642
+
622
643
Operand *gUse = gAddr ->getSingleUse ();
623
644
auto *store = dyn_cast<StoreInst>(gUse ->getUser ());
624
645
if (!store || store->getDest () != gAddr )
0 commit comments