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