[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