LLVM Discussion Forums

Thread safe approach to create Symbol in a mlir::FunctionPass Func

I found this example code in mlir\examples\toy\Ch7\mlir\LowerToLLVM.cpp:

static FlatSymbolRefAttr getOrInsertPrintf(PatternRewriter &rewriter,
ModuleOp module) {
auto *context = module.getContext();
if (module.lookupSymbolLLVM::LLVMFuncOp(“printf”))
return SymbolRefAttr::get(“printf”, context);

// Create a function declaration for printf, the signature is:
//   * `i32 (i8*, ...)`
auto llvmI32Ty = LLVM::LLVMType::getInt32Ty(context);
auto llvmI8PtrTy = LLVM::LLVMType::getInt8PtrTy(context);
auto llvmFnType = LLVM::LLVMType::getFunctionTy(llvmI32Ty, llvmI8PtrTy,

// Insert the printf function into the body of the parent module.
PatternRewriter::InsertionGuard insertGuard(rewriter);
rewriter.create<LLVM::LLVMFuncOp>(module.getLoc(), "printf", llvmFnType);
return SymbolRefAttr::get("printf", context);


AFAIK, FunctionPass is multi-threaded executed. Is it not thread safe? Is there a good way to create a global symbol in FunctionPass?


Passes cannot modify things in the parent region. If you want to modify the module, the pass should operate on the module. See https://mlir.llvm.org/docs/PassManagement/#operation-pass. Is there some reason why you want a FunctionPass here? You can have a module pass that still does things with the individual functions by walking them and then it is totally fine to modify the outer module because you control the whole thing and can regulate any concurrency (usually by not having any :grin:).

Understood. It’s exactly what I’m doing now via module pass. thank you for your prompt clarification!