[llvm-dev] IRMover asserts "mapping to a source type" when repeatedly linking - usage or LLVM bug?
Duncan P. N. Exon Smith via llvm-dev
llvm-dev at lists.llvm.org
Mon Mar 26 16:44:05 PDT 2018
> On Mar 23, 2018, at 16:11, Andres Freund via llvm-dev <llvm-dev at lists.llvm.org> wrote:
>
> Hi,
>
> (sorry if the CC's are inappropriate, they seemed relevant based on a
> git log of IRMover.cpp)
>
> I'm using LLVM to implement Just-in-Time compilation for PostgreSQL. One
> part of that is doing inlining of operators. For that I'm using bitcode
> pre-generated using clang.
>
> The current code uses a single LLVMContext & Orc to generate the
> code. That largely workes well. But inlining presents a bit of a
> problem.
>
> (end of setup)
>
> I've tried two approaches to inlining:
>
> In the first I'm, lazily, caching the source modules, and CloneModule()
> them before handing them to IRMover to inline necessary function into
> the target module. That works well in release builds, but occasionally
> triggers an assert in debug mode ("mapping to a source type"). More on
> the assert later.
>
> The second approach is to *not* cache modules but re-read them from disk
> (or memory, but that's irrelevant here). That works without any sort of
> asserts, but "leaks" memory because everytime a module is re-read from
> disk it re-creates types (cf BitcodeReader.cpp:parseTypeTableBody()).
> Creating a different LLVMContext for every single expression used seems
> infeasible, and fixing LLVM to have type lifetimes bound to Modules
> seems daunting.
The idea would be to fix LLVM to have LLVMContext lifetime bound to llvm::Module (perhaps, reference-counted), but yes, it's a big project.
Can you GC the types in the LLVMContext? IIRC, LLVMContext has a list of the modules using it. You could GC "every so often" to clean up unused types (assuming they get discarded). (It's possible we even have API for that already.)
> Therefore the first approach seems preferable by far.
>
> What I'm observing is that creating the same Module contents (modulo
> some constants) twice and then inlining a number of Modules
It's not exactly clear to me what you mean by "inlining a module". Are you linking one module into another, and then inlining those functions? Or just linking?
> (selectively, but that seems unrelated), works the first time, but
> crashes the second with the "mapping to a source type" assertion.
>
> I'm not 100% sure yet, but my understanding of what happens is the
> following:
>
> 1) "main1" module gets created
> 2) inlinining loads module "a", clones it, links module "a'" into
> "main1". This module contains an opaque struct definition "t" that is now
> referenced by "main1'".
> 3) inlinining loads module "b", clones it, links module "b'" into
> "main1'". This module has a *non-opaque* definition of "t". Thus "t",
> as referenced by "main1'", gets its type "t" completed (via
> linkDefinedTypeBodies()).
> 4) "main2" module gets created
> 5) inlining clones module "a". As types are global to a context, "t" now
> has a body, *and* the body appears to be from the source module
> (actually "b'"). "mapping to a source type" is the result.
When exactly does "mapping to a source type" fire?
- When cloning?
- When linking the clone into another module?
If the latter, which module did you link the cloned "a" into?
> As far as I can tell, which doesn't say much, I don't know this code
> well, the code actually handles this situation correctly. It's just the
> assert that triggers that is problematic.
The assertion seems valid to me for the usual case of linking one module into another.
> Am I doing something unsupported here or is this a bug?
It seems strange to link module "X" into module "Y" more than once, even transitively. It sounds like you're doing that, and I suppose that's likely what's causing the trouble.
> As far as I can tell there unfortunately is no tool in LLVM that allows
> to conveniently create a reproducer, unfortunately.
Contributions welcome :).
> I can write a
> short-ish C++ program if that helps.
>
> Greetings,
>
> Andres Freund
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
More information about the llvm-dev
mailing list