New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Undefined temporary symbol" error in Kaleidoscope example #26314
Comments
assigned to @lhames |
I am working with Lang's example for dynamic recompilation Kaleidoscope-Orc-fully_lazy_with_recompile posted in http://lists.llvm.org/pipermail/llvm-dev/2015-September/090536.html. |
The file which contains the printf that triggers the error. LLVM ERROR: Undefined temporary symbol The symbol it fails on is .L.str |
Hi Revital, How are you compiling foo.c? Assuming you're using clang, can you attach the command-line you're running?
|
Hi Lang, I am using the following command line: clang -c -emit-llvm foo.c -m64 |
Hi Revital. Could you attach your compiled bitcode? I.e. the output of 'clang -c -emit-llvm -o foo.bc foo.c -m64', for both foo_v1.c and main.c ? Once I have the bitcode files I can reproduce the name mangling issue that I suspect is causing this. |
Hi Revital, Ahh - I think this is actually a straightforward issue: your @.str global is private. The JIT is using a linker under the hood, and symbols beginning with '.Lxxx' are linker-local. Such symbols are not visible outside the module that they're originally compiled in. That means that they're not visible to any optimized copy of a function in a new module. The trick is to promote all symbols to global linkage. Anything that was 'private' or 'static' should instead become 'hidden'. This should be done on the un-optimized version of the IR before it's codegen'd. The optimized version should use global-linkage decls to refer to these symbols. You may be able to use the makeAllSymbolsExternallyAccessible function from 'include/llvm/ExecutionEngine/Orc/IndirectionUtils.h' for this. Could you try that out and let me know if it fixes your issue? |
Hi Lang, Thanks for your answer! I added a call to makeAllSymbolsExternallyAccessible for the module. Now I get the following error which I'm not sure what triggers it: Mangler.cpp:37: void getNameWithPrefixImpl(llvm::raw_ostream&, const llvm::Twine&, {anonymous}::ManglerPrefixTy, const llvm::DataLayout&, char): Assertion `!Name.empty() && "getNameWithPrefix requires non-empty name"' failed. One more thing to mention is that str is handled in createLambdaResolver in the following findSymbol: if (auto Symbol = findSymbol(Name)) Here is the IR of the function: ; Function Attrs: noinline nounwind uwtable if.else: ; preds = %entry if.end: ; preds = %entry, %if.else |
I tried to debug the error and it seems that calling RuntimeDyld::SymbolInfo(Symbol.getAddress(), Symbol.getFlags for str somehow corrupted a pointer to another function. I am saving pointers to the original functions IR so I could generate different versions from them via CloneFunctions. After calling RuntimeDyld::SymbolInfo... stmt one of these pointers is corrupted and causes the ICE. This might not be related to the original error I posted. |
Hi Revital, That sounds like a different problem. I'm going to mark this bug as resolved. As for the problem you're seeing now: RuntimeDyld::SymbolInfo doesn't do anything interesting itself, but Symbol.getAddress() may run the materialization function for that symbol, which could cause all sorts of things to happen depending on how you set up your JIT stack. Have you run valgrind or an msan build of your project? This sounds like it could be a memory error in one of your data structures.
|
Thanks Lang! |
Lang, btw I looked at the failure with valgrind as you suggested and it seems that calling |
Hi Revital, Whether or not the LazyEmittingLayer deletes modules depends on how the Module is added to the layer. If you add a module to the layer as a std::unique_ptr then the layer will take ownership, and will delete the module once it's compiled (leaving your map with dangling pointers). If you add the module to the layer as a raw Module* (or a shared_ptr) then the layer will not take ownership: You will be responsible for deleting the Module. That means that you can keep it alive until you've re-compiled all functions in it. As a side note: Do you actually need the lazy-emitting layer for what you're doing? The name is misleading (I may rename it soon to avoid confusion) - it doesn't actually handle callbacks or lazy-compilation, it just defers emitting modules until the linker needs them. If you're using CompileOnDemand for true lazy compilation then the LazyEmittingLayer is almost certainly superfluous.
|
Hi Lang, I could not add the Module to addModuleSet in LazyEmittingLayer as Module * without getting an error. I highly appreciate it if you could tell me how that can be done. |
Patch for Orc Kaleidoscope lazy_codegen example. Are you getting a compile-time or runtime error? 'std::move' doesn't imply that the type has to be a unique_ptr. It should be interpreted as 'move this value (if possible)', which works just fine for raw pointers. I've had no trouble making the change locally. I did gloss over a detail: As you did when using unique_ptr, you should be adding a collection of Module* values (e.g. std::vector<Module*>) not a single Module*. See the attached patch for an example.
|
Lang, Thanks very much for the example and the help!! This indeed seems to be solving the compilation errors. |
Extended Description
I am trying to run toy program within the JIT as it is done in
Kaleidoscope examples.
I am compiling two files: main.c and foo.c where foo.c which is dynamically compiled contains
a call to printf.
When I ran the program I get "LLVM ERROR: Undefined temporary symbol" for symbol .L.str
and it seems to be related to the printf call within foo (when I remove the call the run completes fine)
Here's a snippet of the call from the IR:
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0))
The text was updated successfully, but these errors were encountered: