llvm.org GIT mirror llvm / 26a4ba7
Adding a simple example of how to use the JIT. Contributed by Valery A. Khamenya. THANKS, Valery! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15622 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Spencer 15 years ago
6 changed file(s) with 504 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===--- HowToUseJIT.cpp - An example use of the JIT ----------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by Valery A. Khamenya and is distributed under the
5 // University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This tool provides a single point of access to the LLVM compilation tools.
10 // It has many options. To discover the options supported please refer to the
11 // tools' manual page (docs/CommandGuide/html/llvmc.html) or run the tool with
12 // the --help option.
13 //
14 //===------------------------------------------------------------------------===
15
16 // Goal:
17 // The goal of this snippet is to create in the memory
18 // the LLVM module consisting of two functions as follow:
19 //
20 // int add1(int x) {
21 // return x+1;
22 // }
23 //
24 // int foo() {
25 // return add1(10);
26 // }
27 //
28 // then compile the module via JIT, then execute the `foo'
29 // function and return result to a driver, i.e. to a "host program".
30 //
31 // Some remarks and questions:
32 //
33 // - could we invoke some code using noname functions too?
34 // e.g. evaluate "foo()+foo()" without fears to introduce
35 // conflict of temporary function name with some real
36 // existing function name?
37 //
38
39 #include
40
41 #include
42 #include
43 #include
44 #include
45 #include
46
47 #include "llvm/ExecutionEngine/ExecutionEngine.h"
48 #include "llvm/ExecutionEngine/GenericValue.h"
49
50
51 using namespace llvm;
52
53 int main() {
54
55 // Create some module to put our function into it.
56 Module *M = new Module("test");
57
58
59 // We are about to create the add1 function:
60 Function *Add1F;
61
62 {
63 // first create type for the single argument of add1 function:
64 // the type is 'int ()'
65 std::vector ArgT(1);
66 ArgT[0] = Type::IntTy;
67
68 // now create full type of the add1 function:
69 FunctionType *Add1T = FunctionType::get(Type::IntTy, // type of result
70 ArgT,
71 /*not vararg*/false);
72
73 // Now create the add1 function entry and
74 // insert this entry into module M
75 // (By passing a module as the last parameter to the Function constructor,
76 // it automatically gets appended to the Module.)
77 Add1F = new Function(Add1T,
78 Function::ExternalLinkage, // maybe too much
79 "add1", M);
80
81 // Add a basic block to the function... (again, it automatically inserts
82 // because of the last argument.)
83 BasicBlock *BB = new BasicBlock("EntryBlock of add1 function", Add1F);
84
85 // Get pointers to the constant `1'...
86 Value *One = ConstantSInt::get(Type::IntTy, 1);
87
88 // Get pointers to the integer argument of the add1 function...
89 assert(Add1F->abegin() != Add1F->aend()); // Make sure there's an arg
90 Argument &ArgX = Add1F->afront(); // Get the arg
91
92 // Create the add instruction... does not insert...
93 Instruction *Add = BinaryOperator::create(Instruction::Add, One, &ArgX,
94 "addresult");
95
96 // explicitly insert it into the basic block...
97 BB->getInstList().push_back(Add);
98
99 // Create the return instruction and add it to the basic block
100 BB->getInstList().push_back(new ReturnInst(Add));
101
102 // function add1 is ready
103 }
104
105
106 // now we going to create function `foo':
107 Function *FooF;
108
109 {
110 // Create the foo function type:
111 FunctionType *FooT =
112 FunctionType::get(Type::IntTy, // result has type: 'int ()'
113 std::vector(), // no arguments
114 /*not vararg*/false);
115
116 // create the entry for function `foo' and insert
117 // this entry into module M:
118 FooF =
119 new Function(FooT,
120 Function::ExternalLinkage, // too wide?
121 "foo", M);
122
123 // Add a basic block to the FooF function...
124 BasicBlock *BB = new BasicBlock("EntryBlock of add1 function", FooF);
125
126 // Get pointers to the constant `10'...
127 Value *Ten = ConstantSInt::get(Type::IntTy, 10);
128
129 // Put the argument Ten on stack and make call:
130 // ...
131 std::vector Params;
132 Params.push_back(Ten);
133 CallInst * Add1CallRes = new CallInst(Add1F, Params, "add1", BB);
134
135 // Create the return instruction and add it to the basic block
136 BB->getInstList().push_back(new ReturnInst(Add1CallRes));
137
138 }
139
140 // Now we going to create JIT ??
141 ExistingModuleProvider* MP = new ExistingModuleProvider(M);
142 ExecutionEngine* EE = ExecutionEngine::create( MP, true );
143
144 // Call the `foo' function with no arguments:
145 std::vector noargs;
146 GenericValue gv = EE->runFunction(FooF, noargs);
147
148 // import result of execution:
149 std::cout << "Result: " << gv.IntVal << std:: endl;
150
151 return 0;
152 }
0 ##===- projects/HowToUseJIT/Makefile -----------------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file was developed by Valery A. Khamenya and is distributed under
5 # the University of Illinois Open Source License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8 LEVEL = ../..
9 TOOLNAME = HowToUseJIT
10 USEDLIBS = lli-jit lli-interpreter codegen executionengine x86 selectiondag \
11 scalaropts analysis.a transformutils.a bcreader target.a vmcore \
12 support.a
13
14 include $(LEVEL)/Makefile.common
0 //===--- HowToUseJIT.cpp - An example use of the JIT ----------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by Valery A. Khamenya and is distributed under the
5 // University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This tool provides a single point of access to the LLVM compilation tools.
10 // It has many options. To discover the options supported please refer to the
11 // tools' manual page (docs/CommandGuide/html/llvmc.html) or run the tool with
12 // the --help option.
13 //
14 //===------------------------------------------------------------------------===
15
16 // Goal:
17 // The goal of this snippet is to create in the memory
18 // the LLVM module consisting of two functions as follow:
19 //
20 // int add1(int x) {
21 // return x+1;
22 // }
23 //
24 // int foo() {
25 // return add1(10);
26 // }
27 //
28 // then compile the module via JIT, then execute the `foo'
29 // function and return result to a driver, i.e. to a "host program".
30 //
31 // Some remarks and questions:
32 //
33 // - could we invoke some code using noname functions too?
34 // e.g. evaluate "foo()+foo()" without fears to introduce
35 // conflict of temporary function name with some real
36 // existing function name?
37 //
38
39 #include
40
41 #include
42 #include
43 #include
44 #include
45 #include
46
47 #include "llvm/ExecutionEngine/ExecutionEngine.h"
48 #include "llvm/ExecutionEngine/GenericValue.h"
49
50
51 using namespace llvm;
52
53 int main() {
54
55 // Create some module to put our function into it.
56 Module *M = new Module("test");
57
58
59 // We are about to create the add1 function:
60 Function *Add1F;
61
62 {
63 // first create type for the single argument of add1 function:
64 // the type is 'int ()'
65 std::vector ArgT(1);
66 ArgT[0] = Type::IntTy;
67
68 // now create full type of the add1 function:
69 FunctionType *Add1T = FunctionType::get(Type::IntTy, // type of result
70 ArgT,
71 /*not vararg*/false);
72
73 // Now create the add1 function entry and
74 // insert this entry into module M
75 // (By passing a module as the last parameter to the Function constructor,
76 // it automatically gets appended to the Module.)
77 Add1F = new Function(Add1T,
78 Function::ExternalLinkage, // maybe too much
79 "add1", M);
80
81 // Add a basic block to the function... (again, it automatically inserts
82 // because of the last argument.)
83 BasicBlock *BB = new BasicBlock("EntryBlock of add1 function", Add1F);
84
85 // Get pointers to the constant `1'...
86 Value *One = ConstantSInt::get(Type::IntTy, 1);
87
88 // Get pointers to the integer argument of the add1 function...
89 assert(Add1F->abegin() != Add1F->aend()); // Make sure there's an arg
90 Argument &ArgX = Add1F->afront(); // Get the arg
91
92 // Create the add instruction... does not insert...
93 Instruction *Add = BinaryOperator::create(Instruction::Add, One, &ArgX,
94 "addresult");
95
96 // explicitly insert it into the basic block...
97 BB->getInstList().push_back(Add);
98
99 // Create the return instruction and add it to the basic block
100 BB->getInstList().push_back(new ReturnInst(Add));
101
102 // function add1 is ready
103 }
104
105
106 // now we going to create function `foo':
107 Function *FooF;
108
109 {
110 // Create the foo function type:
111 FunctionType *FooT =
112 FunctionType::get(Type::IntTy, // result has type: 'int ()'
113 std::vector(), // no arguments
114 /*not vararg*/false);
115
116 // create the entry for function `foo' and insert
117 // this entry into module M:
118 FooF =
119 new Function(FooT,
120 Function::ExternalLinkage, // too wide?
121 "foo", M);
122
123 // Add a basic block to the FooF function...
124 BasicBlock *BB = new BasicBlock("EntryBlock of add1 function", FooF);
125
126 // Get pointers to the constant `10'...
127 Value *Ten = ConstantSInt::get(Type::IntTy, 10);
128
129 // Put the argument Ten on stack and make call:
130 // ...
131 std::vector Params;
132 Params.push_back(Ten);
133 CallInst * Add1CallRes = new CallInst(Add1F, Params, "add1", BB);
134
135 // Create the return instruction and add it to the basic block
136 BB->getInstList().push_back(new ReturnInst(Add1CallRes));
137
138 }
139
140 // Now we going to create JIT ??
141 ExistingModuleProvider* MP = new ExistingModuleProvider(M);
142 ExecutionEngine* EE = ExecutionEngine::create( MP, true );
143
144 // Call the `foo' function with no arguments:
145 std::vector noargs;
146 GenericValue gv = EE->runFunction(FooF, noargs);
147
148 // import result of execution:
149 std::cout << "Result: " << gv.IntVal << std:: endl;
150
151 return 0;
152 }
0 ##===- projects/HowToUseJIT/Makefile -----------------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file was developed by Valery A. Khamenya and is distributed under
5 # the University of Illinois Open Source License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8 LEVEL = ../..
9 TOOLNAME = HowToUseJIT
10 USEDLIBS = lli-jit lli-interpreter codegen executionengine x86 selectiondag \
11 scalaropts analysis.a transformutils.a bcreader target.a vmcore \
12 support.a
13
14 include $(LEVEL)/Makefile.common
0 //===--- HowToUseJIT.cpp - An example use of the JIT ----------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by Valery A. Khamenya and is distributed under the
5 // University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This tool provides a single point of access to the LLVM compilation tools.
10 // It has many options. To discover the options supported please refer to the
11 // tools' manual page (docs/CommandGuide/html/llvmc.html) or run the tool with
12 // the --help option.
13 //
14 //===------------------------------------------------------------------------===
15
16 // Goal:
17 // The goal of this snippet is to create in the memory
18 // the LLVM module consisting of two functions as follow:
19 //
20 // int add1(int x) {
21 // return x+1;
22 // }
23 //
24 // int foo() {
25 // return add1(10);
26 // }
27 //
28 // then compile the module via JIT, then execute the `foo'
29 // function and return result to a driver, i.e. to a "host program".
30 //
31 // Some remarks and questions:
32 //
33 // - could we invoke some code using noname functions too?
34 // e.g. evaluate "foo()+foo()" without fears to introduce
35 // conflict of temporary function name with some real
36 // existing function name?
37 //
38
39 #include
40
41 #include
42 #include
43 #include
44 #include
45 #include
46
47 #include "llvm/ExecutionEngine/ExecutionEngine.h"
48 #include "llvm/ExecutionEngine/GenericValue.h"
49
50
51 using namespace llvm;
52
53 int main() {
54
55 // Create some module to put our function into it.
56 Module *M = new Module("test");
57
58
59 // We are about to create the add1 function:
60 Function *Add1F;
61
62 {
63 // first create type for the single argument of add1 function:
64 // the type is 'int ()'
65 std::vector ArgT(1);
66 ArgT[0] = Type::IntTy;
67
68 // now create full type of the add1 function:
69 FunctionType *Add1T = FunctionType::get(Type::IntTy, // type of result
70 ArgT,
71 /*not vararg*/false);
72
73 // Now create the add1 function entry and
74 // insert this entry into module M
75 // (By passing a module as the last parameter to the Function constructor,
76 // it automatically gets appended to the Module.)
77 Add1F = new Function(Add1T,
78 Function::ExternalLinkage, // maybe too much
79 "add1", M);
80
81 // Add a basic block to the function... (again, it automatically inserts
82 // because of the last argument.)
83 BasicBlock *BB = new BasicBlock("EntryBlock of add1 function", Add1F);
84
85 // Get pointers to the constant `1'...
86 Value *One = ConstantSInt::get(Type::IntTy, 1);
87
88 // Get pointers to the integer argument of the add1 function...
89 assert(Add1F->abegin() != Add1F->aend()); // Make sure there's an arg
90 Argument &ArgX = Add1F->afront(); // Get the arg
91
92 // Create the add instruction... does not insert...
93 Instruction *Add = BinaryOperator::create(Instruction::Add, One, &ArgX,
94 "addresult");
95
96 // explicitly insert it into the basic block...
97 BB->getInstList().push_back(Add);
98
99 // Create the return instruction and add it to the basic block
100 BB->getInstList().push_back(new ReturnInst(Add));
101
102 // function add1 is ready
103 }
104
105
106 // now we going to create function `foo':
107 Function *FooF;
108
109 {
110 // Create the foo function type:
111 FunctionType *FooT =
112 FunctionType::get(Type::IntTy, // result has type: 'int ()'
113 std::vector(), // no arguments
114 /*not vararg*/false);
115
116 // create the entry for function `foo' and insert
117 // this entry into module M:
118 FooF =
119 new Function(FooT,
120 Function::ExternalLinkage, // too wide?
121 "foo", M);
122
123 // Add a basic block to the FooF function...
124 BasicBlock *BB = new BasicBlock("EntryBlock of add1 function", FooF);
125
126 // Get pointers to the constant `10'...
127 Value *Ten = ConstantSInt::get(Type::IntTy, 10);
128
129 // Put the argument Ten on stack and make call:
130 // ...
131 std::vector Params;
132 Params.push_back(Ten);
133 CallInst * Add1CallRes = new CallInst(Add1F, Params, "add1", BB);
134
135 // Create the return instruction and add it to the basic block
136 BB->getInstList().push_back(new ReturnInst(Add1CallRes));
137
138 }
139
140 // Now we going to create JIT ??
141 ExistingModuleProvider* MP = new ExistingModuleProvider(M);
142 ExecutionEngine* EE = ExecutionEngine::create( MP, true );
143
144 // Call the `foo' function with no arguments:
145 std::vector noargs;
146 GenericValue gv = EE->runFunction(FooF, noargs);
147
148 // import result of execution:
149 std::cout << "Result: " << gv.IntVal << std:: endl;
150
151 return 0;
152 }
0 ##===- projects/HowToUseJIT/Makefile -----------------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file was developed by Valery A. Khamenya and is distributed under
5 # the University of Illinois Open Source License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8 LEVEL = ../..
9 TOOLNAME = HowToUseJIT
10 USEDLIBS = lli-jit lli-interpreter codegen executionengine x86 selectiondag \
11 scalaropts analysis.a transformutils.a bcreader target.a vmcore \
12 support.a
13
14 include $(LEVEL)/Makefile.common