Valery, 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. Thanks, Reid. On Mon, 2004-08-09 at 06:37, Misha Brukman wrote:> On Mon, Aug 09, 2004 at 12:32:33PM +0400, Valery A.Khamenya wrote: > > Hi Reid, > > > > > I agree that there could be more examples of JIT-based interpreters, > > > and I like your idea. When can you have it ready? :) > > > > soon, if you could just help me to get through some sticky places :) > > > > Agreed? (if "yes" then you could simply answer me privately and I will > > send you my concrete questions) > > Please feel free to send all LLVM-related questions to LLVM-dev. You > will get your response faster and possibly with more details than if you > send to any single person. :)-------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20040809/895fa954/attachment.sig>
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. -------------- next part -------------- A non-text attachment was scrubbed... Name: t.cpp Type: text/x-c++ Size: 4156 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20040809/251e24ce/attachment.bin>
Valery, First response of several. I don't know why the demo page at UIUC is unavailable but there is an enhanced copy of it running on the mirror at http://llvm.x10sys.com/demo/ if you ever need it. Running it produced the following LLVM equivalent for the C code in your example. implementation ; Functions: int %add1(int %x) { entry: %tmp.1 = add int %x, 1 ; <int> [#uses=1] ret int %tmp.1 } int %foo() { entry: ret int 11 } 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
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>