Valery, 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. 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. Misha: can you help out with "GenericValue" ? Thanks, Reid. Valery A.Khamenya wrote:> 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-------------- next part -------------- A non-text attachment was scrubbed... Name: valery.cpp Type: text/x-c++ Size: 4156 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20040809/9b8558c3/attachment.bin> -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: diffs URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20040809/9b8558c3/attachment.ksh> -------------- next part -------------- A non-text attachment was scrubbed... Name: reid.cpp Type: text/x-c++ Size: 4478 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20040809/9b8558c3/attachment-0001.bin>
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 -- http://llvm.cs.uiuc.edu/ http://nondot.org/sabre/
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 >
Reid Spencer, thank you for your quick responce, finally i got to my PC at home. You 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.hm, were the linkage requisites the problem by your side too?.. this is the magic string: g++ -L/usr/local/lib -L/usr/local/lib -o reid reid.o /usr/local/lib/lli-interpreter.o /usr/local/lib/lli-jit.o /usr/local/lib/codegen.o /usr/local/lib/executionengine.o /usr/local/lib/x86.o /usr/local/lib/selectiondag.o /usr/local/lib/scalaropts.o -lanalysis -ltransformutils /usr/local/lib/bcreader.o /usr/local/lib/vmcore.o /usr/local/lib/support.o -ltarget -export-dynamic -ldl (don't ask me why some modules are left as .o) Well. Compiled. Tested. Infinite loop in: GenericValue gv = EE->runFunction(FooF, noargs); you were really, really close, Reid, just a one mistake: < CallInst * Add1CallRes = new CallInst(FooF, Params, "foo", BB); > CallInst * Add1CallRes = new CallInst(Add1F, Params, "add1", BB); :-P> 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.> Misha: can you help out with "GenericValue" ?I got advice from Chris, thx. AND NOW IT WORKSSSSSS!!! HowToUseJIT.cpp is attached as finall version. ...well could anyone tell me whether JIT was really invoked in this code? What kind of optimization were applied by default (if any)? thanks. oh, and great thanks to Reid of course! -- Valery. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: HowToUseJIT.cpp URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20040810/5515016f/attachment.ksh>
vak wrote:> Well. Compiled. Tested. Infinite loop in: > > GenericValue gv = EE->runFunction(FooF, noargs); > > you were really, really close, Reid, just a one mistake: > > < CallInst * Add1CallRes = new CallInst(FooF, Params, "foo", BB); > > > CallInst * Add1CallRes = new CallInst(Add1F, Params, "add1", BB);Duh. Oops!> > I got advice from Chris, thx. > > AND NOW IT WORKSSSSSS!!! > > HowToUseJIT.cpp is attached as finall version. > > ...well could anyone tell me whether JIT was really invoked in this code? > What kind of optimization were applied by default (if any)?JIT should have been invoked (its a subclass of ExecutionEngine). I doubt any optimizations were applied. I'll leave that as an exercise for you to play with. Have a look at the PassManager.> > thanks. > > oh, and great thanks to Reid of course!Glad to help. Reid.
Valery, Your JIT sample program has been added to projects/HowToUseJIT. I have defaulted the license to the standard UIUC license. Let me know if that's not okay and I'll fix it. If you continue to work on this (providing a command line option to use either interpreter or JIT would be nice), please provide patches against these files and I'll commit them for you. Here's the commit list: http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20040809/016952.html http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20040809/016955.html http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20040809/016956.html Thanks again for contributing this! Reid. vak wrote:> Reid Spencer, > > thank you for your quick responce, finally i got to my PC at home. > > You 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. > > > hm, were the linkage requisites the problem by your side too?.. > > this is the magic string: > > g++ -L/usr/local/lib -L/usr/local/lib -o reid reid.o > /usr/local/lib/lli-interpreter.o /usr/local/lib/lli-jit.o > /usr/local/lib/codegen.o /usr/local/lib/executionengine.o > /usr/local/lib/x86.o /usr/local/lib/selectiondag.o > /usr/local/lib/scalaropts.o -lanalysis -ltransformutils > /usr/local/lib/bcreader.o /usr/local/lib/vmcore.o > /usr/local/lib/support.o -ltarget -export-dynamic -ldl > > (don't ask me why some modules are left as .o) > > Well. Compiled. Tested. Infinite loop in: > > GenericValue gv = EE->runFunction(FooF, noargs); > > you were really, really close, Reid, just a one mistake: > > < CallInst * Add1CallRes = new CallInst(FooF, Params, "foo", BB); > > > CallInst * Add1CallRes = new CallInst(Add1F, Params, "add1", BB); > > :-P > >> 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. > > >> Misha: can you help out with "GenericValue" ? > > > > I got advice from Chris, thx. > > AND NOW IT WORKSSSSSS!!! > > HowToUseJIT.cpp is attached as finall version. > > ...well could anyone tell me whether JIT was really invoked in this code? > What kind of optimization were applied by default (if any)? > > thanks. > > oh, and great thanks to Reid of course! > > -- > 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.) > 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... > assert(Add1F->abegin() != Add1F->aend()); // Make sure there's an arg > Argument &ArgX = Add1F->afront(); // Get the arg > > // 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 *FooF; > > { > // 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: > 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: > // ... > std::vector<Value*> Params; > Params.push_back(Ten); > CallInst * Add1CallRes = new CallInst(Add1F, Params, "add1", BB); > > // Create the return instruction and add it to the basic block > BB->getInstList().push_back(new ReturnInst(Add1CallRes)); > > } > > // Now we going to create JIT ?? > ExistingModuleProvider* MP = new ExistingModuleProvider(M); > ExecutionEngine* EE = ExecutionEngine::create( MP, true ); > > // Call the `foo' function with no arguments: > std::vector<GenericValue> noargs; > GenericValue gv = EE->runFunction(FooF, noargs); > > // import result of execution: > std::cout << "Result: " << gv.IntVal << std:: endl; > > return 0; > } > > > ------------------------------------------------------------------------ > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev