[llvm-dev] JIT compiler, Windows, external functions like cos

Dr. Marcus Hoffmann via llvm-dev llvm-dev at lists.llvm.org
Wed Jan 2 09:44:15 PST 2019


Hello LLVM team,

our software FluidSIM (www.fluidsim.de) simulates pneumatic, hydraulic 
and electric circuits. For the mathematical models we use the language 
Modelica (www.modelica.org). 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.

In the future we want to compile more complex expressions, especially 
entire blocks, like
X1 = 2*x0 +4
X2 = 3*sin(x1)
X3 = x1 + x2

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.
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“).

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)?

The following code works for “sqrt” but not for “cos”. It just 
encapsulates an external call. We use
Microsoft Visual Studio 2017 Version 15.9.4.
LLVM 7.0.1
Solution Configuration: Debug, 32 Bit, Switch: /MTd

using namespace llvm;

typedef double(__cdecl *JitCompiledFn)(double);

int main()
{
// "sqrt" works.
//const char externalFnName[] = "sqrt";

// "cos", "sin", etc. fails.
const char externalFnName[] = "cos";

InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();

LLVMContext context;

IRBuilder<> builder(context);

std::unique_ptr<llvm::Module> module(new Module("TestModule", context));
Module* pModule = module.get();

auto externalFn_IR = 
cast<Function>(pModule->getOrInsertFunction("externalFn", 
Type::getDoubleTy(context), Type::getDoubleTy(context)));
Value* x = externalFn_IR->arg_begin();
x->setName("x");

BasicBlock *entryBlock = BasicBlock::Create(context, "EntryBlock", 
externalFn_IR);
builder.SetInsertPoint(entryBlock);

std::vector<Type *> args(1, Type::getDoubleTy(context));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(context), args, 
false);
auto externalFn_llvm = Function::Create(FT, Function::ExternalLinkage, 
externalFnName, pModule);
auto ret = builder.CreateCall(externalFn_llvm, x);

builder.CreateRet(ret);

errs() << "Created Module:\n\n" << *pModule;

auto jitCompiler = 
EngineBuilder(std::move(module)).setOptLevel(CodeGenOpt::Level::Default).create();

JitCompiledFn externalFn = 
(JitCompiledFn)jitCompiler->getFunctionAddress(externalFn_IR->getName());

errs() << "\n\nexternalFn(9.0) = ";

double y = externalFn(9.0);

errs() << y << "\n\n";

return 0;
}



Kind regards
Marcus Hoffmann



-- 

Dr. Marcus Hoffmann
Art Systems Software GmbH
Hudeweg 13, 33102 Paderborn
Registergericht: Amtsgericht Paderborn, HRB 2776
Geschäftsführer: Dr. Daniel Curatolo, Dr. Marcus Hoffmann
Prof. Dr. Benno Stein

http://www.artsystems.de



More information about the llvm-dev mailing list