@@ -539,70 +539,98 @@ CIRGenModule::getOrCreateStaticVarDecl(const VarDecl &D,
539
539
// / Add the initializer for 'D' to the global variable that has already been
540
540
// / created for it. If the initializer has a different type than GV does, this
541
541
// / may free GV and return a different one. Otherwise it just returns GV.
542
- cir::GlobalOp CIRGenFunction::addInitializerToStaticVarDecl (
543
- const VarDecl &D, cir::GlobalOp GV, cir::GetGlobalOp GVAddr) {
542
+ cir::GlobalOp
543
+ CIRGenFunction::addInitializerToStaticVarDecl (const VarDecl &varDecl,
544
+ cir::GlobalOp globalOp,
545
+ cir::GetGlobalOp getGlobalOp) {
544
546
ConstantEmitter emitter (*this );
545
- mlir::TypedAttr Init =
546
- mlir::dyn_cast<mlir::TypedAttr>(emitter.tryEmitForInitializer (D));
547
- assert (Init && " Expected typed attribute" );
547
+ mlir::Attribute init = emitter.tryEmitForInitializer (varDecl);
548
548
549
549
// If constant emission failed, then this should be a C++ static
550
550
// initializer.
551
- if (!Init ) {
551
+ if (!init ) {
552
552
if (!getLangOpts ().CPlusPlus )
553
- CGM.ErrorUnsupported (D .getInit (), " constant l-value expression" );
554
- else if (D .hasFlexibleArrayInit (getContext ()))
555
- CGM.ErrorUnsupported (D .getInit (), " flexible array initializer" );
553
+ CGM.ErrorUnsupported (varDecl .getInit (), " constant l-value expression" );
554
+ else if (varDecl .hasFlexibleArrayInit (getContext ()))
555
+ CGM.ErrorUnsupported (varDecl .getInit (), " flexible array initializer" );
556
556
else {
557
557
// Since we have a static initializer, this global variable can't
558
558
// be constant.
559
- GV.setConstant (false );
560
- llvm_unreachable (" C++ guarded init it NYI" );
559
+ globalOp.setConstant (false );
560
+
561
+ emitCXXGuardedInit (varDecl, globalOp, /* performInit*/ true );
562
+ getGlobalOp.setStaticLocal (true );
561
563
}
562
- return GV ;
564
+ return globalOp ;
563
565
}
564
566
567
+ auto typedInit = mlir::cast<mlir::TypedAttr>(init);
568
+
565
569
#ifndef NDEBUG
566
- CharUnits VarSize = CGM.getASTContext ().getTypeSizeInChars (D.getType ()) +
567
- D.getFlexibleArrayInitChars (getContext ());
568
- CharUnits CstSize = CharUnits::fromQuantity (
569
- CGM.getDataLayout ().getTypeAllocSize (Init.getType ()));
570
- assert (VarSize == CstSize && " Emitted constant has unexpected size" );
570
+ CharUnits varSize =
571
+ CGM.getASTContext ().getTypeSizeInChars (varDecl.getType ()) +
572
+ varDecl.getFlexibleArrayInitChars (getContext ());
573
+ CharUnits cstSize = CharUnits::fromQuantity (
574
+ CGM.getDataLayout ().getTypeAllocSize (typedInit.getType ()));
575
+ assert (varSize == cstSize && " Emitted constant has unexpected size" );
571
576
#endif
572
577
573
578
// The initializer may differ in type from the global. Rewrite
574
579
// the global to match the initializer. (We have to do this
575
580
// because some types, like unions, can't be completely represented
576
581
// in the LLVM type system.)
577
- if (GV.getSymType () != Init.getType ()) {
578
- GV.setSymType (Init.getType ());
582
+ // NOTE(CIR): This was removed in OG since opaque pointers made it trivial. We
583
+ // need it since we still have typed pointers.
584
+ if (globalOp.getSymType () != typedInit.getType ()) {
585
+ globalOp.setSymType (typedInit.getType ());
586
+
587
+ cir::GlobalOp oldGlobalOp = globalOp;
588
+ globalOp =
589
+ builder.createGlobal (CGM.getModule (), getLoc (varDecl.getSourceRange ()),
590
+ oldGlobalOp.getName (), typedInit.getType (),
591
+ oldGlobalOp.getConstant (), globalOp.getLinkage ());
592
+ // FIXME(cir): OG codegen inserts new GV before old one, we probably don't
593
+ // need that?
594
+ globalOp.setVisibility (oldGlobalOp.getVisibility ());
595
+ globalOp.setGlobalVisibilityAttr (oldGlobalOp.getGlobalVisibilityAttr ());
596
+ globalOp.setInitialValueAttr (init);
597
+ globalOp.setTlsModelAttr (oldGlobalOp.getTlsModelAttr ());
598
+ globalOp.setDSOLocal (oldGlobalOp.getDsolocal ());
599
+ assert (!cir::MissingFeatures::setComdat ());
600
+ assert (!cir::MissingFeatures::addressSpaceInGlobalVar ());
579
601
580
602
// Normally this should be done with a call to CGM.replaceGlobal(OldGV, GV),
581
603
// but since at this point the current block hasn't been really attached,
582
604
// there's no visibility into the GetGlobalOp corresponding to this Global.
583
605
// Given those constraints, thread in the GetGlobalOp and update it
584
606
// directly.
585
- GVAddr.getAddr ().setType (
586
- getBuilder ().getPointerTo (Init.getType (), GV.getAddrSpaceAttr ()));
607
+ getGlobalOp.getAddr ().setType (getBuilder ().getPointerTo (
608
+ typedInit.getType (), globalOp.getAddrSpaceAttr ()));
609
+
610
+ // Replace all uses of the old global with the new global
611
+ oldGlobalOp->replaceAllUsesWith (globalOp);
612
+
613
+ // Erase the old global, since it is no longer used.
614
+ oldGlobalOp->erase ();
587
615
}
588
616
589
- bool NeedsDtor =
590
- D .needsDestruction (getContext ()) == QualType::DK_cxx_destructor;
617
+ bool needsDtor =
618
+ varDecl .needsDestruction (getContext ()) == QualType::DK_cxx_destructor;
591
619
592
- GV .setConstant (
593
- CGM.isTypeConstant (D .getType (), /* ExcludeCtor=*/ true , !NeedsDtor ));
594
- GV .setInitialValueAttr (Init );
620
+ globalOp .setConstant (
621
+ CGM.isTypeConstant (varDecl .getType (), /* ExcludeCtor=*/ true , !needsDtor ));
622
+ globalOp .setInitialValueAttr (init );
595
623
596
- emitter.finalize (GV );
624
+ emitter.finalize (globalOp );
597
625
598
- if (NeedsDtor ) {
626
+ if (needsDtor ) {
599
627
// We have a constant initializer, but a nontrivial destructor. We still
600
628
// need to perform a guarded "initialization" in order to register the
601
629
// destructor.
602
630
llvm_unreachable (" C++ guarded init is NYI" );
603
631
}
604
632
605
- return GV ;
633
+ return globalOp ;
606
634
}
607
635
608
636
void CIRGenFunction::emitStaticVarDecl (const VarDecl &D,
0 commit comments