-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmodule.cpp
More file actions
executable file
·100 lines (87 loc) · 3.21 KB
/
module.cpp
File metadata and controls
executable file
·100 lines (87 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include <vector>
using namespace llvm;
// the upgraded context system differs from the oriely book
static LLVMContext Context ;
static Module *ModuleOb = new Module("my compiler", Context);
static std::vector<std::string> FunArgs;
Function *createFunc(IRBuilder<> &Builder, std::string Name) {
Type *u32Ty = Type::getInt32Ty(Context);
Type *vecTy = VectorType::get(u32Ty, 2, false);
Type *ptrTy = vecTy->getPointerTo(0);
FunctionType *funcType =
FunctionType::get(Builder.getInt32Ty(), ptrTy, false);
Function *fooFunc =
Function::Create(funcType, Function::ExternalLinkage, Name, ModuleOb);
return fooFunc;
}
Function *createMainFunc(IRBuilder<> &Builder, std::string Name) {
FunctionType *funcType =
FunctionType::get(Builder.getInt32Ty(), false);
Function *fooFunc =
Function::Create(funcType, Function::ExternalLinkage, Name, ModuleOb);
return fooFunc;
}
void setFuncArgs(Function *fooFunc, std::vector<std::string> FunArgs) {
unsigned Idx = 0;
Function::arg_iterator AI, AE;
for (AI = fooFunc->arg_begin(), AE = fooFunc->arg_end(); AI != AE;
++AI, ++Idx)
AI->setName(FunArgs[Idx]);
}
BasicBlock *createBB(Function *fooFunc, std::string Name) {
return BasicBlock::Create(Context, Name, fooFunc);
}
GlobalVariable *createGlob(IRBuilder<> &Builder, std::string Name) {
ModuleOb->getOrInsertGlobal(Name, Builder.getInt32Ty());
GlobalVariable *gVar = ModuleOb->getNamedGlobal(Name);
gVar->setLinkage(GlobalValue::CommonLinkage);
gVar->setAlignment(MaybeAlign(4));
return gVar;
}
Value *createArith(IRBuilder<> &Builder, Value *L, Value *R) {
return Builder.CreateMul(L, R, "multmp");
}
Value *getGEP(IRBuilder<> &Builder, Value *Base, ArrayRef<Value *> Offset) {
return Builder.CreateGEP(Base, Offset, "a1");
}
Value *getLoad(IRBuilder<> &Builder, Value *Address) {
return Builder.CreateLoad(Address, "load");
}
void getStore(IRBuilder<> &Builder, Value *Address, Value *V) {
Builder.CreateStore(V, Address);
}
void buildMain() {
static IRBuilder<> Builder(Context);
GlobalVariable *gVar = createGlob(Builder, "x");
Function *fooFunc = createMainFunc(Builder, "main");
BasicBlock *entry = createBB(fooFunc, "entry");
Builder.SetInsertPoint(entry);
Value *val = Builder.getInt32(0);
Builder.CreateRet(val);
verifyFunction(*fooFunc);
}
void buildModule() {
static IRBuilder<> Builder(Context);
Function *fooFunc = createFunc(Builder, "main");
setFuncArgs(fooFunc, FunArgs);
Value *Base = fooFunc->arg_begin();
BasicBlock *entry = createBB(fooFunc, "entry");
Builder.SetInsertPoint(entry);
Value *gep = getGEP(Builder, Base, {Builder.getInt32(0), Builder.getInt32(1)});
Value *load = getLoad(Builder, gep);
Value *constant = Builder.getInt32(16);
Value *val = createArith(Builder, load, constant);
getStore(Builder, gep, val);
Builder.CreateRet(val);
verifyFunction(*fooFunc);
}
int main(int argc, char *argv[]) {
FunArgs.push_back("a");
buildMain();
ModuleOb->print(errs(), nullptr);
return 0;
}