@@ -471,7 +471,8 @@ mlir::Value CIRGenModule::getGlobalValue(const Decl *D) {
471
471
mlir::cir::GlobalOp CIRGenModule::createGlobalOp (CIRGenModule &CGM,
472
472
mlir::Location loc,
473
473
StringRef name, mlir::Type t,
474
- bool isCst) {
474
+ bool isCst,
475
+ mlir::Operation *insertPoint) {
475
476
mlir::cir::GlobalOp g;
476
477
auto &builder = CGM.getBuilder ();
477
478
{
@@ -486,8 +487,12 @@ mlir::cir::GlobalOp CIRGenModule::createGlobalOp(CIRGenModule &CGM,
486
487
builder.setInsertionPoint (curCGF->CurFn );
487
488
488
489
g = builder.create <mlir::cir::GlobalOp>(loc, name, t, isCst);
489
- if (!curCGF)
490
- CGM.getModule ().push_back (g);
490
+ if (!curCGF) {
491
+ if (insertPoint)
492
+ CGM.getModule ().insert (insertPoint, g);
493
+ else
494
+ CGM.getModule ().push_back (g);
495
+ }
491
496
492
497
// Default to private until we can judge based on the initializer,
493
498
// since MLIR doesn't allow public declarations.
@@ -501,6 +506,35 @@ void CIRGenModule::setCommonAttributes(GlobalDecl GD, mlir::Operation *GV) {
501
506
assert (!UnimplementedFeature::setCommonAttributes ());
502
507
}
503
508
509
+ void CIRGenModule::replaceGlobal (mlir::cir::GlobalOp Old,
510
+ mlir::cir::GlobalOp New) {
511
+ assert (Old.getSymName () == New.getSymName () && " symbol names must match" );
512
+
513
+ // If the types does not match, update all references to Old to the new type.
514
+ auto OldTy = Old.getSymType ();
515
+ auto NewTy = New.getSymType ();
516
+ if (OldTy != NewTy) {
517
+ auto OldSymUses = Old.getSymbolUses (theModule.getOperation ());
518
+ if (OldSymUses.has_value ()) {
519
+ for (auto Use : *OldSymUses) {
520
+ auto *UserOp = Use.getUser ();
521
+ assert ((isa<mlir::cir::GetGlobalOp>(UserOp) ||
522
+ isa<mlir::cir::GlobalOp>(UserOp)) &&
523
+ " GlobalOp symbol user is neither a GetGlobalOp nor a GlobalOp" );
524
+
525
+ if (auto GGO = dyn_cast<mlir::cir::GetGlobalOp>(Use.getUser ())) {
526
+ auto UseOpResultValue = GGO.getAddr ();
527
+ UseOpResultValue.setType (
528
+ mlir::cir::PointerType::get (builder.getContext (), NewTy));
529
+ }
530
+ }
531
+ }
532
+ }
533
+
534
+ // Remove old global from the module.
535
+ Old.erase ();
536
+ }
537
+
504
538
// / If the specified mangled name is not in the module,
505
539
// / create and return an mlir GlobalOp with the specified type (TODO(cir):
506
540
// / address space).
@@ -592,11 +626,14 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef MangledName, mlir::Type Ty,
592
626
// mlir::SymbolTable::Visibility::Public is the default, no need to explicitly
593
627
// mark it as such.
594
628
auto GV = CIRGenModule::createGlobalOp (*this , loc, MangledName, Ty,
595
- /* isConstant=*/ false );
629
+ /* isConstant=*/ false ,
630
+ /* insertPoint=*/ Entry.getOperation ());
596
631
597
632
// If we already created a global with the same mangled name (but different
598
- // type) before, take its name and remove it from its parent.
599
- assert (!Entry && " not implemented" );
633
+ // type) before, replace it with the new global.
634
+ if (Entry) {
635
+ replaceGlobal (Entry, GV);
636
+ }
600
637
601
638
// This is the first use or definition of a mangled name. If there is a
602
639
// deferred decl with this name, remember that we need to emit it at the end
0 commit comments