<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
Hi Marcus<br>
<br>
If I understand correctly, you are creating a module with a
declaration for an external function. Then you compile and load the
module with the ExecutionEngine JIT interface. The loader is
supposed to resolve your declaration to an existing definition in
the host program, right? Do you get the error message "Program used
external function '...' which could not be resolved!"?<br>
<br>
There is a variety of potential reasons here. The mystery that it
works for sqrt, but not for cos or sin, may be that something in
your host program exposes a definition with its unmangled name only
for sqrt, while the others are mangled or not exposed at all. After
all, your host program links to the C++ stdlib, which provides
multiple versions of all these functions with different signatures!<br>
<br>
In general, using host-process symbols directly can be dangerous and
hard to debug. Basically, you are relying on details of your host
compiler and linker. The correct way may be adding another module
with the stdlib implementation that your JITed code should use. The
simplest way may be keeping the host-process calls, but
expose your own wrappers explicitly by address. Using the Orc JIT
interface directly, a QND implementation with LLVM 5.0 looked like
this:<br>
<a class="moz-txt-link-freetext" href="https://github.com/weliveindetail/JitFromScratch/commit/e9988a834dd6c35c93268da6ece73a7cc472100a">https://github.com/weliveindetail/JitFromScratch/commit/e9988a834dd6c35c93268da6ece73a7cc472100a</a><br>
<br>
Note that on Windows you want to declare the wrappers as: <span
class="blob-code-inner"><span class="pl-k">extern</span> <span
class="pl-s"><span class="pl-pds">"</span>C<span class="pl-pds">"</span></span>
__declspec(dllexport)</span><br>
<div class="moz-cite-prefix"><br>
<blockquote type="cite">After many trials and errors we found out
that no LLVM example works (“4. Kaleidoscope: Adding JIT and
Optimizer Support”, “The Fibonacci project“). [...] It seems
that the LLVM JIT compiler cannot find external functions like
“sin” and “cos” nor intrinsic functions under Windows. Every
(tutorial) example crashes using them.</blockquote>
I can imagine this doesn't get tested so much on Windows.<br>
<br>
Best</div>
<div class="moz-cite-prefix">Stefan<br>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">Am 02.01.19 um 19:05 schrieb Dr. Marcus
Hoffmann:<br>
</div>
<blockquote type="cite"
cite="mid:572f890b-d4ec-1ae8-f355-b2daee541019@artsystems.de">Hello
Stefan, <br>
<br>
our software FluidSIM (<a class="moz-txt-link-abbreviated" href="http://www.fluidsim.de">www.fluidsim.de</a>) simulates pneumatic,
hydraulic and electric circuits. For the mathematical models we
use the language Modelica (<a class="moz-txt-link-abbreviated" href="http://www.modelica.org">www.modelica.org</a>). We developed our own
Modelica simulator which solves the dynamical created algebraic
differential equation systems. One tool is our small JIT compiler,
which compiles mathematical expressions like “2*x0 + sin(x1)” at
runtime. <br>
<br>
In the future we want to compile more complex expressions,
especially entire blocks, like <br>
X1 = 2*x0 +4 <br>
X2 = 3*sin(x1) <br>
X3 = x1 + x2 <br>
<br>
At the moment, we are evaluating the LLVM suite to replace our JIT
compiler. Our software runs under the Windows platform (32 and 64
Bit). We are using the Microsoft Visual Studio 2017 Version
15.9.4. <br>
For our evaluation we use LLVM 7.0.1. We created the LLVM suite
for 32 Bit with the cmake tools. We wrote a small parser and took
the LLVM tutorials as starting point to implement our LLVM JIT
compiler. All arithmetic expressions work fine. But we failed to
integrate external functions like “cos” and “sin”. Only “sqrt”
worked. After many trials and errors we found out that no LLVM
example works (“4. Kaleidoscope: Adding JIT and Optimizer
Support”, “The Fibonacci project“). <br>
<br>
It seems that the LLVM JIT compiler cannot find external functions
like “sin” and “cos” nor intrinsic functions under Windows. Every
(tutorial) example crashes using them. Is there any solution for
this problem (compiler switches, libraries to include, a simple
Visual Studio project)? <br>
<br>
The following code works for “sqrt” but not for “cos”. It just
encapsulates an external call. We use <br>
Microsoft Visual Studio 2017 Version 15.9.4. <br>
LLVM 7.0.1 <br>
Solution Configuration: Debug, 32 Bit, Switch: /MTd <br>
<br>
using namespace llvm; <br>
<br>
typedef double(__cdecl *JitCompiledFn)(double); <br>
<br>
int main() <br>
{ <br>
// "sqrt" works. <br>
//const char externalFnName[] = "sqrt"; <br>
<br>
// "cos", "sin", etc. fails. <br>
const char externalFnName[] = "cos"; <br>
<br>
InitializeNativeTarget(); <br>
InitializeNativeTargetAsmPrinter(); <br>
InitializeNativeTargetAsmParser(); <br>
<br>
LLVMContext context; <br>
<br>
IRBuilder<> builder(context); <br>
<br>
std::unique_ptr<llvm::Module> module(new
Module("TestModule", context)); <br>
Module* pModule = module.get(); <br>
<br>
auto externalFn_IR =
cast<Function>(pModule->getOrInsertFunction("externalFn",
Type::getDoubleTy(context), Type::getDoubleTy(context))); <br>
Value* x = externalFn_IR->arg_begin(); <br>
x->setName("x"); <br>
<br>
BasicBlock *entryBlock = BasicBlock::Create(context, "EntryBlock",
externalFn_IR); <br>
builder.SetInsertPoint(entryBlock); <br>
<br>
std::vector<Type *> args(1, Type::getDoubleTy(context)); <br>
FunctionType *FT = FunctionType::get(Type::getDoubleTy(context),
args, false); <br>
auto externalFn_llvm = Function::Create(FT,
Function::ExternalLinkage, externalFnName, pModule); <br>
auto ret = builder.CreateCall(externalFn_llvm, x); <br>
<br>
builder.CreateRet(ret); <br>
<br>
errs() << "Created Module:\n\n" << *pModule; <br>
<br>
auto jitCompiler =
EngineBuilder(std::move(module)).setOptLevel(CodeGenOpt::Level::Default).create();
<br>
<br>
JitCompiledFn externalFn =
(JitCompiledFn)jitCompiler->getFunctionAddress(externalFn_IR->getName());
<br>
<br>
errs() << "\n\nexternalFn(9.0) = "; <br>
<br>
double y = externalFn(9.0); <br>
<br>
errs() << y << "\n\n"; <br>
<br>
return 0; <br>
} <br>
<br>
<br>
<br>
Kind regards <br>
Marcus Hoffmann <br>
<br>
</blockquote>
</body>
</html>