[llvm-dev] Segmentation faults running the new llvm ModulePassManager with default pipeline

Arthur Eubanks via llvm-dev llvm-dev at lists.llvm.org
Mon Oct 18 09:21:29 PDT 2021

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>

More information about the llvm-dev mailing list