Sanket Diwale via llvm-dev
2021-Oct-17 00:36 UTC
[llvm-dev] Segmentation faults running the new llvm ModulePassManager with default pipeline
I am currently writing a frontend language compiling to LLVM IR using the LLVM c++ API (LLVM version 13), however I see some erratic behavior with segmentation faults when running the new ModulePassManager. Specifically I see the debugger halts execution in the llvm::EarlyCSEPass::run function call when a segmentation fault occurs. Can't see where exactly the seg fault happens inside this function as I am not currently using a debug build for the LLVM source code itself. I think the seg fault might have something to do with the way I set up my pass manager and run the pass manger on new instances of llvm::Module without any kind of reset to the pass analysis manager (not sure if this guess is correct though). I have highlighted my current code that sets up and runs the pass manager below. I would be grateful if you could give any insights into what I might be doing wrong and how it should be done correctly. Best, Sanket /* I have a "CodeGenerator" class object that holds the pass manager and the other related objects as public members */ class CodeGenerator { public: llvm::PassBuilder passBuilder; llvm::LoopAnalysisManager loopAnalysisManager; llvm::FunctionAnalysisManager functionAnalysisManager; llvm::CGSCCAnalysisManager cGSCCAnalysisManager; llvm::ModuleAnalysisManager moduleAnalysisManager; llvm::ModulePassManager modulePassManager; CodeGenerator(); // constructor for the class // other code that handles emitting the LLVM IR from the parsed AST of the front-end code // I keep the llvm::Module and llvm::Context instances to which the ir is emitted within this class as members llvm::orc::ThreadSafeContext Ctx; std::unique_ptr<llvm::Module> TheModule; } /* I initialize the ModulePassManager in the class constructor */CodeGenerator(): Ctx(std::make_unique<llvm::LLVMContext>()) {public: passBuilder.registerModuleAnalyses(moduleAnalysisManager); passBuilder.registerCGSCCAnalyses(cGSCCAnalysisManager); passBuilder.registerFunctionAnalyses(functionAnalysisManager); passBuilder.registerLoopAnalyses(loopAnalysisManager); passBuilder.crossRegisterProxies( loopAnalysisManager, functionAnalysisManager, cGSCCAnalysisManager, moduleAnalysisManager); modulePassManager passBuilder.buildPerModuleDefaultPipeline(llvm::PassBuilder::OptimizationLevel::O0); } After calling the constructor for the above class I initialize the Module to which the llvm ir is emitted. CodeGenerator CG = CodeGenerator(); CG.TheModule = std::make_unique<llvm::Module>("module_name", *(CG.Ctx.getContext())); // I parse my front end code and emit my llvm ir code to TheModule here // then I call the ModulePassManager here to optimize the module CG.modulePassManager.run(*CG.TheModule, CG.moduleAnalysisManager);// I move the optimized module to my JIT interpreterauto TSM llvm::orc::ThreadSafeModule(std::move(CG.TheModule),CG.Ctx);ExitOnErr(TheJIT->addModule(std::move(TSM))); // Then, I create a new instance of llvm::Module to emit some other ir code CG.TheModule = std::make_unique<llvm::Module>(ModuleName, *(CG.Ctx.getContext())); // emit ir // then call the optimizer again CG.modulePassManager.run(*CG.TheModule, CG.moduleAnalysisManager); // I repeat this several times changing TheModule to a new instance// of llvm::Module to contain some new ir code and run the optimizer. // one of these calls to CG.modulePassManager.run ends up giving the segmentation fault // there is no specific fixed instance of llvm::Module that this happens for// The segmentation fault seems to happen at random for any one of the instances, on some runs there is no seg fault // The ir being emitted is also not changed on any of the runs My suspicion is that CG.moduleAnalysisManager might need some kind of reset after I change the Module instance before I can run the ModulePassManager on the newly emitted ir. Or maybe I am missing something else in how the pass manager needs to be setup. Any help would be great. Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20211016/f47d1404/attachment.html>
Arthur Eubanks via llvm-dev
2021-Oct-18 16:21 UTC
[llvm-dev] Segmentation faults running the new llvm ModulePassManager with default pipeline
The issue is probably that the analyses are not being cleared between runs and you end up using stale analyses. I'd recommend that you use a new instance of all the pass/analysis managers every time you perform codegen. (if you really want, you could call the `clear()` method on all the analysis managers, but that's a bit more sketchy) On Sat, Oct 16, 2021 at 5:37 PM Sanket Diwale via llvm-dev < llvm-dev at lists.llvm.org> wrote:> I am currently writing a frontend language compiling to LLVM IR using the > LLVM c++ API (LLVM version 13), however I see some erratic behavior with > segmentation faults when running the new ModulePassManager. Specifically I > see the debugger halts execution in the llvm::EarlyCSEPass::run function > call when a segmentation fault occurs. Can't see where exactly the seg > fault happens inside this function as I am not currently using a debug > build for the LLVM source code itself. > > I think the seg fault might have something to do with the way I set up my > pass manager and run the pass manger on new instances of llvm::Module > without any kind of reset to the pass analysis manager (not sure if this > guess is correct though). I have highlighted my current code that sets up > and runs the pass manager below. I would be grateful if you could give any > insights into what I might be doing wrong and how it should be done > correctly. > > Best, Sanket > > /* > I have a "CodeGenerator" class object that holds the pass manager and the other related objects as public members > */ > class CodeGenerator { > > public: > llvm::PassBuilder passBuilder; > llvm::LoopAnalysisManager loopAnalysisManager; > llvm::FunctionAnalysisManager functionAnalysisManager; > llvm::CGSCCAnalysisManager cGSCCAnalysisManager; > llvm::ModuleAnalysisManager moduleAnalysisManager; > llvm::ModulePassManager modulePassManager; > CodeGenerator(); // constructor for the class > // other code that handles emitting the LLVM IR from the parsed AST of the front-end code > > // I keep the llvm::Module and llvm::Context instances to which the ir is emitted within this class as members > llvm::orc::ThreadSafeContext Ctx; > std::unique_ptr<llvm::Module> TheModule; > > } > /* > I initialize the ModulePassManager in the class constructor > */CodeGenerator(): Ctx(std::make_unique<llvm::LLVMContext>()) {public: > passBuilder.registerModuleAnalyses(moduleAnalysisManager); > passBuilder.registerCGSCCAnalyses(cGSCCAnalysisManager); > passBuilder.registerFunctionAnalyses(functionAnalysisManager); > passBuilder.registerLoopAnalyses(loopAnalysisManager); > passBuilder.crossRegisterProxies( > loopAnalysisManager, functionAnalysisManager, cGSCCAnalysisManager, > moduleAnalysisManager); > modulePassManager = passBuilder.buildPerModuleDefaultPipeline(llvm::PassBuilder::OptimizationLevel::O0); > } > > > After calling the constructor for the above class > > I initialize the Module to which the llvm ir is emitted. > > CodeGenerator CG = CodeGenerator(); > > CG.TheModule = std::make_unique<llvm::Module>("module_name", *(CG.Ctx.getContext())); > // I parse my front end code and emit my llvm ir code to TheModule here > // then I call the ModulePassManager here to optimize the module > CG.modulePassManager.run(*CG.TheModule, CG.moduleAnalysisManager);// I move the optimized module to my JIT interpreterauto TSM = llvm::orc::ThreadSafeModule(std::move(CG.TheModule),CG.Ctx);ExitOnErr(TheJIT->addModule(std::move(TSM))); > // Then, I create a new instance of llvm::Module to emit some other ir code > > CG.TheModule = std::make_unique<llvm::Module>(ModuleName, *(CG.Ctx.getContext())); > // emit ir > // then call the optimizer again > CG.modulePassManager.run(*CG.TheModule, CG.moduleAnalysisManager); > // I repeat this several times changing TheModule to a new instance// of llvm::Module to contain some new ir code and run the optimizer. > // one of these calls to CG.modulePassManager.run ends up giving the segmentation fault // there is no specific fixed instance of llvm::Module that this happens for// The segmentation fault seems to happen at random for any one of the instances, on some runs there is no seg fault // The ir being emitted is also not changed on any of the runs > > My suspicion is that CG.moduleAnalysisManager might need some kind of > reset after I change the Module instance before I can run the > ModulePassManager on the newly emitted ir. Or maybe I am missing something > else in how the pass manager needs to be setup. Any help would be great. > > Thanks. > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20211018/b2f71339/attachment.html>