================
@@ -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