[LLVMdev] API on JIT, code snippets
Reid Spencer
reid at x10sys.com
Mon Aug 9 15:25:30 PDT 2004
Chris: I guess if I'd have looked into it for more than 30 seconds, I might
have discovered the fact that GenericValue was a union. Anyway, thanks for the
help.
Valery: hopefully that should do it .. let us know if there's more help you need.
Reid.
Chris Lattner wrote:
> On Mon, 9 Aug 2004, Reid Spencer wrote:
>
>
>>Attached are three files: "valery.cpp" which contains your original, "reid.cpp"
>>which contains corrections to most of the FIXME items and "diffs" which shows
>>the differences between them. The differences should be instructive on what to
>>do. You were really, really close .. just a few details changing. The code in
>>"reid.cpp" compiles but I haven't tested it. I'll leave that to you.
>
>
> Cool, thanks Reid!
>
>
>>There is only one remaining item that I don't know how to do. After
>>ExecutionEngine::runFunction, you want to extract the result int value from the
>>function. The runFunction method returns a GenericValue but I don't see an
>>obvious way to get an actual value from this class.
>
>
> I'm not Misha, but if you have a GenericValue that is an int, just use
> GV.IntVal to get at it. GenericValue is just a union (defined in
> include/llvm/ExecutionEngine/GenericValue.h), which can represent any
> first-class value that LLVM functions can return.
>
> -Chris
>
>
>>>Reid wrote:
>>>
>>>
>>>
>>>>I have to agree with Misha on this. None of us knows "everything" about
>>>>LLVM and as you can see, Misha responded three hours before I did :).
>>>>Asking questions here is encouraged, so please feel free to post them on
>>>>LLVMdev. We'll always help where we can.
>>>
>>>
>>>well, OK :)
>>>
>>>Please find the attachment with the first approach to
>>>such an example i've meant. This snippet is based on
>>>ModuleMaker as you could see.
>>>
>>>You will find "FIXME!" at positions where I fail to find
>>>answer in 10-15 minutes. Code is compilable at least.
>>>
>>>So... PING!
>>>Who gives PONG?
>>>:)
>>>
>>>--
>>>Valery.
>>>
>>>
>>>------------------------------------------------------------------------
>>>
>>>/*
>>>Goal:
>>> The goal of this snippet is to create in the memory
>>> the LLVM module consisting of two functions as follow:
>>>
>>>
>>>int add1(int x) {
>>> return x+1;
>>>}
>>>
>>>int foo() {
>>> return add1(10);
>>>}
>>>
>>>
>>>then compile the module via JIT, then execute the `foo'
>>>function and return result to a driver, i.e. to a "host program".
>>>
>>>Some remarks and questions:
>>>
>>>- could we invoke some code using noname functions too?
>>> e.g. evaluate "foo()+foo()" without fears to introduce
>>> conflict of temporary function name with some real
>>> existing function name?
>>>
>>>- it would be nice to copy-paste here a LLVM code of the
>>> above given C-portion, ...but see the next comment :)
>>>
>>>- http://llvm.cs.uiuc.edu/demo/index.cgi is the shortest way
>>> to obtain LLVM code :) but it is down:
>>> "The demo page is currently unavailable.
>>> [tools: ( gccas llvm-dis gccld ) failed sanity check]"
>>> LOL
>>>
>>>
>>>*/
>>>
>>>#include <iostream>
>>>
>>>#include <llvm/Module.h>
>>>#include <llvm/DerivedTypes.h>
>>>#include <llvm/Constants.h>
>>>#include <llvm/Instructions.h>
>>>#include <llvm/ModuleProvider.h>
>>>
>>>#include "llvm/ExecutionEngine/ExecutionEngine.h"
>>>#include "llvm/ExecutionEngine/GenericValue.h"
>>>
>>>
>>>using namespace llvm;
>>>
>>>int main() {
>>>
>>> // Create some module to put our function into it.
>>> Module *M = new Module("test");
>>>
>>>
>>> // We are about to create the add1 function:
>>> Function *Add1F;
>>>
>>> {
>>> // first create type for the single argument of add1 function:
>>> // the type is 'int ()'
>>> std::vector<const Type*> ArgT(1);
>>> ArgT[0] = Type::IntTy;
>>>
>>> // now create full type of the add1 function:
>>> FunctionType *Add1T = FunctionType::get(Type::IntTy, // type of result: int ()'
>>> ArgT,
>>> /*not vararg*/false);
>>>
>>> // Now create the add1 function entry and
>>> // insert this entry into module M
>>> // (By passing a module as the last parameter to the Function constructor,
>>> // it automatically gets appended to the Module.)
>>> Function *Add1F = new Function(Add1T,
>>> Function::ExternalLinkage, // maybe too much
>>> "add1", M);
>>>
>>> // Add a basic block to the function... (again, it automatically inserts
>>> // because of the last argument.)
>>> BasicBlock *BB = new BasicBlock("EntryBlock of add1 function", Add1F);
>>>
>>> // Get pointers to the constant `1'...
>>> Value *One = ConstantSInt::get(Type::IntTy, 1);
>>>
>>> // Get pointers to the integer argument of the add1 function...
>>> Value *ArgX = 0; // FIXME!!
>>>
>>>
>>> // Create the add instruction... does not insert...
>>> Instruction *Add = BinaryOperator::create(Instruction::Add, One, ArgX,
>>> "addresult");
>>>
>>> // explicitly insert it into the basic block...
>>> BB->getInstList().push_back(Add);
>>>
>>> // Create the return instruction and add it to the basic block
>>> BB->getInstList().push_back(new ReturnInst(Add));
>>>
>>> // function add1 is ready
>>> }
>>>
>>>
>>> // now we going to create function `foo':
>>> Function *Foo;
>>>
>>> {
>>> // Create the foo function type:
>>> FunctionType *FooT =
>>> FunctionType::get(Type::IntTy, // result has type: 'int ()'
>>> std::vector<const Type*>(), // no arguments
>>> /*not vararg*/false);
>>>
>>> // create the entry for function `foo' and insert
>>> // this entry into module M:
>>> Function *FooF =
>>> new Function(FooT,
>>> Function::ExternalLinkage, // too wide?
>>> "foo", M);
>>>
>>> // Add a basic block to the FooF function...
>>> BasicBlock *BB = new BasicBlock("EntryBlock of add1 function", FooF);
>>>
>>> // Get pointers to the constant `10'...
>>> Value *Ten = ConstantSInt::get(Type::IntTy, 10);
>>>
>>> // Put the argument Ten on stack and make call:
>>> // ...
>>> Instruction *Add1CallRes = 0; // FIXME!!!
>>>
>>> // Create the return instruction and add it to the basic block
>>> BB->getInstList().push_back(new ReturnInst(Add1CallRes));
>>>
>>> }
>>>
>>> // Now we going to create JIT ??
>>> // FIXME!
>>>
>>>
>>> // compile M module ??
>>> // FIXME!
>>>
>>> // create Execution Engine ??
>>> ModuleProvider *MP = 0;
>>> ExecutionEngine *EE = ExecutionEngine::create(MP, true);
>>>
>>> // Call the `foo' function with no arguments:
>>> std::vector<GenericValue> noargs;
>>> GenericValue gv = EE->runFunction(Foo, noargs);
>>>
>>> // import result of execution:
>>> // FIXME!
>>>}
>>>
>>>
>>>------------------------------------------------------------------------
>>>
>>>_______________________________________________
>>>LLVM Developers mailing list
>>>LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
>>>http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>>
>
> -Chris
>
More information about the llvm-dev
mailing list