================
@@ -99,6 +104,77 @@ struct LoweringPreparePass
       cir::GlobalLinkageKind linkage = cir::GlobalLinkageKind::ExternalLinkage,
       cir::VisibilityKind visibility = cir::VisibilityKind::Default);
 
+  /// Handle static local variable initialization with guard variables.
+  void handleStaticLocal(cir::GlobalOp globalOp, cir::GetGlobalOp getGlobalOp);
+
+  /// Get or create __cxa_guard_acquire function.
+  cir::FuncOp getGuardAcquireFn(cir::PointerType guardPtrTy);
+
+  /// Get or create __cxa_guard_release function.
+  cir::FuncOp getGuardReleaseFn(cir::PointerType guardPtrTy);
+
+  /// Create a guard global variable for a static local.
+  cir::GlobalOp createGuardGlobalOp(CIRBaseBuilderTy &builder,
+                                    mlir::Location loc, llvm::StringRef name,
+                                    cir::IntType guardTy,
+                                    cir::GlobalLinkageKind linkage);
+
+  /// Get the guard variable for a static local declaration.
+  cir::GlobalOp
+  getStaticLocalDeclGuardAddress(cir::ASTVarDeclInterface varDecl) {
+    auto it = staticLocalDeclGuardMap.find(varDecl.getVarDecl());
+    if (it != staticLocalDeclGuardMap.end())
+      return it->second;
+    return nullptr;
+  }
+
+  /// Set the guard variable for a static local declaration.
+  void setStaticLocalDeclGuardAddress(cir::ASTVarDeclInterface varDecl,
+                                      cir::GlobalOp guard) {
+    staticLocalDeclGuardMap[varDecl.getVarDecl()] = guard;
+  }
+
+  /// Get or create the guard variable for a static local declaration.
+  cir::GlobalOp getOrCreateStaticLocalDeclGuardAddress(
+      CIRBaseBuilderTy &builder, cir::GlobalOp globalOp,
+      cir::ASTVarDeclInterface varDecl, cir::IntType guardTy,
+      clang::CharUnits guardAlignment) {
+    cir::GlobalOp guard = getStaticLocalDeclGuardAddress(varDecl);
+    if (!guard) {
+      // Mangle the name for the guard.
+      llvm::SmallString<256> guardName;
+      {
+        llvm::raw_svector_ostream out(guardName);
+        varDecl.mangleStaticGuardVariable(out);
+      }
+
+      // Create the guard variable with a zero-initializer.
+      guard = createGuardGlobalOp(builder, globalOp->getLoc(), guardName,
+                                  guardTy, globalOp.getLinkage());
+      guard.setInitialValueAttr(cir::IntAttr::get(guardTy, 0));
+      guard.setDSOLocal(globalOp.getDsoLocal());
+      guard.setAlignment(guardAlignment.getAsAlign().value());
+
+      // The ABI says: "It is suggested that it be emitted in the same COMDAT
+      // group as the associated data object." In practice, this doesn't work
+      // for non-ELF and non-Wasm object formats, so only do it for ELF and
+      // Wasm.
+      bool hasComdat = globalOp.getComdat();
+      const llvm::Triple &triple = astCtx->getTargetInfo().getTriple();
+      if (!varDecl.getVarDecl()->isLocalVarDecl() && hasComdat &&
+          (triple.isOSBinFormatELF() || triple.isOSBinFormatWasm())) {
+        globalOp->emitError("NYI: guard COMDAT for non-local variables");
----------------
bcardosolopes wrote:

This is a pass that runs after CIRGen (no more CGF or CGM), therefore we just 
use default MLIR error mechanism to bail.

https://github.com/llvm/llvm-project/pull/179828
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to