Hi everyone,
In debugging an LLVM based system with a runtime module loaded from bitcode, I
ran into a strange error when trying to use getLazyBitcodeModule instead of just
ParseBitcodeFile (when loading lazily I get an "Invalid CALL" during
bitcode deserialization). I can't decide if this is a "bug" or
just a "you shouldn't use Module/Inliner like this".
The problem is related to using templates (and thereby linkonce_odr) with lazy
deserialization. I've reduced it down to a simple test (also attached as
bitcode_input.cc):
template<typename T>
class SomeContainer {
public:
T* getPtr() { return data; }
T* data;
};
extern "C"
float* RunStuff(void) {
SomeContainer<float> emptyContainer;
return emptyContainer.getPtr();
}
This code is compiled via clang into llvm bitcode (clang++ -emit-llvm -c
bitcode_input.cc -o test.bc), and then loaded at runtime via
getLazyBitcodeModule (see load_bitcode.cc). After "loading" the
bitcode, I emit a new function that just calls RunStuff. I then run the Inliner
on the full module, and then ask the JIT for getPointerToFunction on my emitted
function. At this point, when generating native code, I get an Invalid CALL when
it tries to deserialize RunStuff. So the overall process is:
- Read bitcode from .bc file.
- Add a new Function to the Module that calls RunStuff.
- Run the Inliner over the Module.
- Ask a JIT for getPointerToFunction(emittedFunc)
After digging a bit (verified by dumping the module in load_bitcode.cc before
and after inlining), the problem comes from the Inliner removing
SomeContainer::getPtr because it believes ("incorrectly") that
it's unused (lib/Transforms/IPO/Inliner.cpp:539 in TOT). When the bitcode
reader tries to materialize RunStuff, the call to getPtr fails to deserialize
properly. It seems to me that removeDeadFunctions should exit early if it runs
into _any_ functions that are still materializable as they may contain unseen
calls. At the same time, I'm no expert on the linkonce_odr rules, so I'm
not sure if this is really a "bug" or just a different design
decision.
Steps to reproduce (with LLVM and clang TOT):
clang++ -emit-llvm -c bitcode_input.cc -o test.bc
clang++ `llvm-config --cxxflags --ldflags --libs` load_bitcode.cc
./a.out
Solomon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: load_bitcode.cc
Type: application/octet-stream
Size: 2108 bytes
Desc: not available
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20110701/739e7ba2/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bitcode_input.cc
Type: application/octet-stream
Size: 211 bytes
Desc: not available
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20110701/739e7ba2/attachment-0001.obj>
-------------- next part --------------