|
|
@ -20,7 +20,8 @@
|
|
|
|
#include <charconv>
|
|
|
|
#include <charconv>
|
|
|
|
#include <iostream>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
|
|
extern std::list<ThunkAST> scope;
|
|
|
|
extern llvm::Function *curFunc;
|
|
|
|
|
|
|
|
extern llvm::Value *curEnv;
|
|
|
|
|
|
|
|
|
|
|
|
int ThunkAST::tcount = 0;
|
|
|
|
int ThunkAST::tcount = 0;
|
|
|
|
int ThunkAST::envidx = 0;
|
|
|
|
int ThunkAST::envidx = 0;
|
|
|
@ -28,14 +29,14 @@ int ThunkAST::envidx = 0;
|
|
|
|
static inline auto loadEnv(LLVMState& llvmState, llvm::Value *index)
|
|
|
|
static inline auto loadEnv(LLVMState& llvmState, llvm::Value *index)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
auto ptrty = llvmState.inttype->getPointerTo();
|
|
|
|
auto ptrty = llvmState.inttype->getPointerTo();
|
|
|
|
auto gep = llvmState.builder.CreateGEP(ptrty, scope.back().env, {index});
|
|
|
|
auto gep = llvmState.builder.CreateGEP(ptrty, curEnv, {index});
|
|
|
|
return llvmState.builder.CreateLoad(ptrty, gep);
|
|
|
|
return llvmState.builder.CreateLoad(ptrty, gep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline auto storeEnv(LLVMState& llvmState, llvm::Value *index, llvm::Value *val)
|
|
|
|
static inline auto storeEnv(LLVMState& llvmState, llvm::Value *index, llvm::Value *val)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
auto ptrty = llvmState.inttype->getPointerTo();
|
|
|
|
auto ptrty = llvmState.inttype->getPointerTo();
|
|
|
|
auto var = llvmState.builder.CreateGEP(ptrty, scope.back().env, {index});
|
|
|
|
auto var = llvmState.builder.CreateGEP(ptrty, curEnv, {index});
|
|
|
|
return llvmState.builder.CreateStore(val, var);
|
|
|
|
return llvmState.builder.CreateStore(val, var);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -82,7 +83,7 @@ llvm::Value *PopAST::codegen(LLVMState& llvmState) const
|
|
|
|
Var v;
|
|
|
|
Var v;
|
|
|
|
|
|
|
|
|
|
|
|
if (name == "self") {
|
|
|
|
if (name == "self") {
|
|
|
|
v = {scope.back().func, true};
|
|
|
|
v = {curFunc, true};
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
auto index = llvm::ConstantInt::get(llvmState.inttype, ThunkAST::envidx++);
|
|
|
|
auto index = llvm::ConstantInt::get(llvmState.inttype, ThunkAST::envidx++);
|
|
|
|
auto pop = llvmState.createPop();
|
|
|
|
auto pop = llvmState.createPop();
|
|
|
@ -120,7 +121,7 @@ llvm::Value *CallAST::codegen(LLVMState& llvmState) const
|
|
|
|
bool couldRecur = Var::lookup("self").value != nullptr;
|
|
|
|
bool couldRecur = Var::lookup("self").value != nullptr;
|
|
|
|
auto localCount = Var::vars.back().size();
|
|
|
|
auto localCount = Var::vars.back().size();
|
|
|
|
if (!couldRecur || localCount == 0) {
|
|
|
|
if (!couldRecur || localCount == 0) {
|
|
|
|
return llvmState.builder.CreateCall(llvmState.ftype, fn, llvm::ArrayRef {scope.back().env});
|
|
|
|
return llvmState.builder.CreateCall(llvmState.ftype, fn, llvm::ArrayRef {curEnv});
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
int i;
|
|
|
|
int i;
|
|
|
|
auto ptrty = llvmState.inttype->getPointerTo();
|
|
|
|
auto ptrty = llvmState.inttype->getPointerTo();
|
|
|
@ -136,7 +137,7 @@ llvm::Value *CallAST::codegen(LLVMState& llvmState) const
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
auto call = llvmState.builder.CreateCall(llvmState.ftype, fn, llvm::ArrayRef {scope.back().env});
|
|
|
|
auto call = llvmState.builder.CreateCall(llvmState.ftype, fn, llvm::ArrayRef {curEnv});
|
|
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
i = 0;
|
|
|
|
for (auto& [_, v] : Var::vars.back()) {
|
|
|
|
for (auto& [_, v] : Var::vars.back()) {
|
|
|
@ -152,10 +153,15 @@ llvm::Value *CallAST::codegen(LLVMState& llvmState) const
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ThunkAST::ThunkAST(LLVMState& llvmState):
|
|
|
|
ThunkAST::ThunkAST():
|
|
|
|
ThunkAST(llvmState, std::string("__t") + std::to_string(tcount++)) {}
|
|
|
|
BaseAST(std::string("__t") + std::to_string(tcount++)) {}
|
|
|
|
|
|
|
|
|
|
|
|
ThunkAST::ThunkAST(LLVMState& llvmState, std::string n): BaseAST(n)
|
|
|
|
llvm::Value *ThunkAST::codegen(LLVMState& llvmState) const
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return func;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ThunkAST::beginGen(LLVMState& llvmState)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
parent = llvmState.builder.saveIP();
|
|
|
|
parent = llvmState.builder.saveIP();
|
|
|
|
func = llvmState.createFunction(name);
|
|
|
|
func = llvmState.createFunction(name);
|
|
|
@ -166,7 +172,7 @@ ThunkAST::ThunkAST(LLVMState& llvmState, std::string n): BaseAST(n)
|
|
|
|
llvmState.builder.SetInsertPoint(body);
|
|
|
|
llvmState.builder.SetInsertPoint(body);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
llvm::Value *ThunkAST::codegen(LLVMState& llvmState) const
|
|
|
|
void ThunkAST::endGen(LLVMState& llvmState)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
llvmState.builder.CreateRetVoid();
|
|
|
|
llvmState.builder.CreateRetVoid();
|
|
|
|
llvmState.builder.SetInsertPoint(entry);
|
|
|
|
llvmState.builder.SetInsertPoint(entry);
|
|
|
@ -182,6 +188,5 @@ llvm::Value *ThunkAST::codegen(LLVMState& llvmState) const
|
|
|
|
|
|
|
|
|
|
|
|
llvmState.builder.CreateBr(body);
|
|
|
|
llvmState.builder.CreateBr(body);
|
|
|
|
llvmState.builder.restoreIP(parent);
|
|
|
|
llvmState.builder.restoreIP(parent);
|
|
|
|
return func;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|