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>