@@ -2634,6 +2634,23 @@ void IRGenSILFunction::visitGlobalAddrInst(GlobalAddrInst *i) {
2634
2634
setLoweredAddress (i, addr);
2635
2635
}
2636
2636
2637
+ // / Returns true if \p val has no other uses than ref_element_addr or
2638
+ // / ref_tail_addr.
2639
+ static bool hasOnlyProjections (SILValue val) {
2640
+ for (Operand *use : val->getUses ()) {
2641
+ SILInstruction *user = use->getUser ();
2642
+ if (auto *upCast = dyn_cast<UpcastInst>(user)) {
2643
+ if (!hasOnlyProjections (upCast))
2644
+ return false ;
2645
+ continue ;
2646
+ }
2647
+ if (isa<RefElementAddrInst>(user) || isa<RefTailAddrInst>(user))
2648
+ continue ;
2649
+ return false ;
2650
+ }
2651
+ return true ;
2652
+ }
2653
+
2637
2654
void IRGenSILFunction::visitGlobalValueInst (GlobalValueInst *i) {
2638
2655
SILGlobalVariable *var = i->getReferencedGlobal ();
2639
2656
assert (var->isInitializedObject () &&
@@ -2645,17 +2662,19 @@ void IRGenSILFunction::visitGlobalValueInst(GlobalValueInst *i) {
2645
2662
2646
2663
llvm::Value *Ref = IGM.getAddrOfSILGlobalVariable (var, ti,
2647
2664
NotForDefinition).getAddress ();
2648
-
2649
- auto ClassType = loweredTy.getASTType ();
2650
- llvm::Value *Metadata =
2651
- emitClassHeapMetadataRef (*this , ClassType, MetadataValueType::TypeMetadata,
2652
- MetadataState::Complete);
2653
- llvm::Value *CastAddr = Builder.CreateBitCast (Ref, IGM.RefCountedPtrTy );
2654
- llvm::Value *InitRef = emitInitStaticObjectCall (Metadata, CastAddr, " staticref" );
2655
- InitRef = Builder.CreateBitCast (InitRef, Ref->getType ());
2656
-
2665
+ // We don't need to initialize the global object if it's never used for
2666
+ // something which can access the object header.
2667
+ if (!hasOnlyProjections (i)) {
2668
+ auto ClassType = loweredTy.getASTType ();
2669
+ llvm::Value *Metadata =
2670
+ emitClassHeapMetadataRef (*this , ClassType, MetadataValueType::TypeMetadata,
2671
+ MetadataState::Complete);
2672
+ llvm::Value *CastAddr = Builder.CreateBitCast (Ref, IGM.RefCountedPtrTy );
2673
+ llvm::Value *InitRef = emitInitStaticObjectCall (Metadata, CastAddr, " staticref" );
2674
+ Ref = Builder.CreateBitCast (InitRef, Ref->getType ());
2675
+ }
2657
2676
Explosion e;
2658
- e.add (InitRef );
2677
+ e.add (Ref );
2659
2678
setLoweredExplosion (i, e);
2660
2679
}
2661
2680
0 commit comments