LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 2606 - global variables declared in module A but defined in module B are not resolved by the JIT
Summary: global variables declared in module A but defined in module B are not resolve...
Status: CONFIRMED
Alias: None
Product: libraries
Classification: Unclassified
Component: Generic Execution Engine Support (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
: 3143 (view as bug list)
Depends on:
Blocks:
 
Reported: 2008-07-29 10:16 PDT by Paul Redmond
Modified: 2010-08-11 22:11 PDT (History)
8 users (show)

See Also:
Fixed By Commit(s):


Attachments
modified HowToUseJIT.cpp which reproduces the problem (4.46 KB, text/x-c++src)
2008-07-29 10:16 PDT, Paul Redmond
Details
2.7 version of testcase (4.92 KB, text/x-c++src)
2010-02-16 05:30 PST, Garrison Venn
Details
test case which shows cross module function linkage problem (12.07 KB, text/x-c++src)
2010-02-16 05:36 PST, Garrison Venn
Details
a work in progress proposed patch (9.61 KB, patch)
2010-02-16 05:46 PST, Garrison Venn
Details
Replace use of JITResolver::forceEmitFunctionStub(...) with JITResolver::getLazyFunctionStub(...). (7.04 KB, patch)
2010-02-19 05:55 PST, Garrison Venn
Details
Forgot to revert JITResolver::JITCompilerFn(...) in 4254 (6.80 KB, patch)
2010-02-19 09:51 PST, Garrison Venn
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Redmond 2008-07-29 10:16:47 PDT
Created attachment 1868 [details]
modified HowToUseJIT.cpp which reproduces the problem

If you declare and use a global variable in module A and define it in module B the execution engine will not resolve the symbol in module A.

The attached modified version of HowToUseJIT.cpp shows this problem. You can manually work around this limitation by explicitly calling addGlobalMapping on the declaration using the same pointer that's mapped to the definition.
Comment 1 Chris Lattner 2008-10-16 01:10:58 PDT
Hi Paul, can you propose a patch?  This should be easy if you are interested.
Comment 2 Nick Lewycky 2008-11-29 12:32:37 PST
*** Bug 3143 has been marked as a duplicate of this bug. ***
Comment 3 Nick Lewycky 2008-11-29 12:33:06 PST
The duped bug, pr3143 has a proposed patch.
Comment 4 Nick Lewycky 2008-11-29 13:36:24 PST
Benjamin Scarlet reports that my patch doesn't work for him due to recursive compilation.

I think that there's a second bug here; calling getPointerToFunction on F() that contains a call to F2() should be getting a stub for F2, not trying to compile the whole function.
Comment 5 Garrison Venn 2010-02-16 05:30:02 PST
Created attachment 4238 [details]
2.7 version of testcase

This is a 2.7 version of HowToUseJIT.cpp which reproduces the problem.
Comment 6 Garrison Venn 2010-02-16 05:36:30 PST
Created attachment 4239 [details]
test case which shows cross module function linkage problem

This is a test case which shows the issue when trying to find functions defined in other modules, without using ExecutionEngine::addGlobalMapping(...). This test case was only tested on OS 10.6.2 and Linux, gcc 4.1.2.

To build on OS X 10.6.2 use:

g++ -g twoModuleCallTest.cpp `llvm-config --cppflags --ldflags --libs core \
jit native` -o twoModuleCallTest

On Linux use:

g++ -g -rdynamic twoModuleCallTest.cpp `llvm-config --cppflags --ldflags --libs core \
jit native` -o twoModuleCallTest
Comment 7 Garrison Venn 2010-02-16 05:46:06 PST
Created attachment 4240 [details]
a work in progress proposed patch

This patch is my first attempt at solving the above test cases. Although it works on 32bit LINUX (gcc 4.1.2), and 64bit OS X 10.6.2, the patch needs to be refined as it has taken some liberties with the code. I will also submit this to llvm.dev to start a discussion.
Comment 8 Garrison Venn 2010-02-19 05:55:41 PST
Created attachment 4254 [details]
Replace use of JITResolver::forceEmitFunctionStub(...) with JITResolver::getLazyFunctionStub(...).

Modified 4240 with replacement of JITResolver::forceEmitFunctionStub(...) with JITResolver::getLazyFunctionStub(...) as per discussion in llvm.dev list. Olivier Meurant
pointed out flaws with attachment 4240 [details]'s approach concerning functions. Other issues
still remain.
Comment 9 Garrison Venn 2010-02-19 09:51:48 PST
Created attachment 4257 [details]
Forgot to revert JITResolver::JITCompilerFn(...) in 4254

Same comment as given in 4254 additionally with JITResolver::JITCompilerFn(...) reverted.
Comment 10 Kenneth Uildriks 2010-06-01 14:26:21 PDT
(In reply to comment #9)
> Created an attachment (id=4257) [details]
> Forgot to revert JITResolver::JITCompilerFn(...) in 4254
> 
> Same comment as given in 4254 additionally with JITResolver::JITCompilerFn(...)
> reverted.

Now that multiple execution engine instances can exist, a usable workaround involves having one execution engine per module, with LazyFunctionCreators installed to resolve cross-module calls and JIT them.  I don't know how heavy each ExecutionEngine instance is, though.

Perhaps a better idea would be to add a LazyFunctionCreator variant that returns Function instances rather than native function pointers.  Obviously that won't be helpful for native library lookup, but you can not only resolve IR functions cross module, but you can also *emit* IR functions on demand more easily.