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
|
#include "ast.hpp"
int ThunkAST::tcount = 0;
NumberAST::NumberAST(const std::string& n): BaseAST(n) {}
llvm::Value *NumberAST::codegen(LLVMState& llvmState) const
{
auto val = llvmState.createInt(std::stoi(name));
return llvmState.builder.CreateStore(val, llvmState.createPush());
}
PushAST::PushAST(const std::string& n): BaseAST(n) {}
llvm::Value *PushAST::codegen(LLVMState& llvmState) const
{
if (auto [var, thunk] = Var::lookup(name); var) {
auto dsget = llvmState.createPush();
if (!thunk)
var = llvmState.builder.CreateLoad(llvmState.inttype, var);
return llvmState.builder.CreateStore(var, dsget);
} else {
return nullptr;
}
}
PopAST::PopAST(const std::string& n): BaseAST(n) {}
llvm::Value *PopAST::codegen(LLVMState& llvmState) const
{
auto gep = llvmState.createPop();
auto var = llvmState.createVariable(name);
auto load = llvmState.builder.CreateLoad(llvmState.inttype, gep);
llvmState.builder.CreateStore(load, var, false);
return Var::addLocal(name, var).value;
}
CallAST::CallAST(const std::string& n): BaseAST(n) {}
llvm::Value *CallAST::codegen(LLVMState& llvmState) const
{
if (auto [var, call] = Var::lookup(name); var) {
if (call) {
return llvmState.builder.CreateCall(llvmState.ftype, var);
} else {
auto val = llvmState.builder.CreateLoad(llvmState.inttype, var);
auto cast = llvmState.builder.CreateIntToPtr(val,
llvmState.inttype->getPointerTo());
return llvmState.builder.CreateCall(llvmState.ftype, cast);
}
} else {
auto func = llvmState.createFunction(name);
Var::addGlobal(name, Var {func, true});
return llvmState.builder.CreateCall(llvmState.ftype, func);
}
}
ThunkAST::ThunkAST(LLVMState& llvmState):
ThunkAST(llvmState, std::string("__t") + std::to_string(tcount++)) {}
ThunkAST::ThunkAST(LLVMState& llvmState, std::string n): BaseAST(n)
{
parent = llvmState.builder.saveIP();
func = llvmState.createFunction(name);
auto BB = llvmState.createEntry(func);
llvmState.builder.SetInsertPoint(BB);
}
llvm::Value *ThunkAST::codegen(LLVMState& llvmState) const
{
llvmState.builder.CreateRetVoid();
llvmState.builder.restoreIP(parent);
return func;
}
|