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

Sanket Diwale via llvm-dev llvm-dev at lists.llvm.org
Tue Oct 19 06:15:45 PDT 2021

Thanks Aurthur.

That seems to have been the problem. I changed the code to use a new
instances for all the pass and analysis managers for every new module added
and that fixed the issue. Didn't try using the 'clear()' method since the
code seems to be working for now and I can move on to solving some other

Thanks a lot for your help.


On Mon, Oct 18, 2021 at 12:21 PM Arthur Eubanks <aeubanks at google.com> wrote:

> 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/20211019/98a3cfef/attachment.html>

More information about the llvm-dev mailing list