2019-11-02 17:53:15 -07:00
|
|
|
#include "llvm_context.hpp"
|
|
|
|
#include <llvm/IR/DerivedTypes.h>
|
|
|
|
|
2019-11-04 18:25:54 -08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void llvm_context::create_types() {
|
2019-11-04 18:25:54 -08:00
|
|
|
stack_type = StructType::create(ctx, "stack");
|
|
|
|
stack_ptr_type = PointerType::getUnqual(stack_type);
|
|
|
|
tag_type = IntegerType::getInt8Ty(ctx);
|
|
|
|
struct_types["node_base"] = StructType::create(ctx, "node_base");
|
|
|
|
struct_types["node_app"] = StructType::create(ctx, "node_app");
|
|
|
|
struct_types["node_num"] = StructType::create(ctx, "node_num");
|
|
|
|
struct_types["node_global"] = StructType::create(ctx, "node_global");
|
|
|
|
struct_types["node_ind"] = StructType::create(ctx, "node_ind");
|
|
|
|
struct_types["node_data"] = StructType::create(ctx, "node_data");
|
|
|
|
node_ptr_type = PointerType::getUnqual(struct_types.at("node_base"));
|
2019-11-05 00:42:33 -08:00
|
|
|
function_type = FunctionType::get(Type::getVoidTy(ctx), { stack_ptr_type }, false);
|
|
|
|
|
|
|
|
struct_types.at("node_base")->setBody(
|
|
|
|
IntegerType::getInt32Ty(ctx)
|
|
|
|
);
|
|
|
|
struct_types.at("node_app")->setBody(
|
|
|
|
struct_types.at("node_base"),
|
|
|
|
node_ptr_type,
|
|
|
|
node_ptr_type
|
|
|
|
);
|
|
|
|
struct_types.at("node_num")->setBody(
|
|
|
|
struct_types.at("node_base"),
|
|
|
|
IntegerType::getInt32Ty(ctx)
|
|
|
|
);
|
|
|
|
struct_types.at("node_global")->setBody(
|
|
|
|
struct_types.at("node_base"),
|
|
|
|
FunctionType::get(Type::getVoidTy(ctx), { stack_ptr_type }, false)
|
|
|
|
);
|
|
|
|
struct_types.at("node_ind")->setBody(
|
|
|
|
struct_types.at("node_base"),
|
|
|
|
node_ptr_type
|
|
|
|
);
|
|
|
|
struct_types.at("node_data")->setBody(
|
|
|
|
struct_types.at("node_base"),
|
|
|
|
IntegerType::getInt8Ty(ctx),
|
|
|
|
PointerType::getUnqual(node_ptr_type)
|
|
|
|
);
|
2019-11-02 17:53:15 -07:00
|
|
|
}
|
|
|
|
|
2019-11-05 00:42:33 -08:00
|
|
|
void llvm_context::create_functions() {
|
2019-11-04 18:25:54 -08:00
|
|
|
auto void_type = Type::getVoidTy(ctx);
|
2019-11-05 00:42:33 -08:00
|
|
|
auto sizet_type = IntegerType::get(ctx, sizeof(size_t) * 8);
|
2019-11-04 18:25:54 -08:00
|
|
|
functions["stack_init"] = Function::Create(
|
|
|
|
FunctionType::get(void_type, { stack_ptr_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_init",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["stack_free"] = Function::Create(
|
|
|
|
FunctionType::get(void_type, { stack_ptr_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_free",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["stack_push"] = Function::Create(
|
|
|
|
FunctionType::get(void_type, { stack_ptr_type, node_ptr_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_push",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["stack_pop"] = Function::Create(
|
|
|
|
FunctionType::get(node_ptr_type, { stack_ptr_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_push",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["stack_peek"] = Function::Create(
|
|
|
|
FunctionType::get(node_ptr_type, { stack_ptr_type, sizet_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_push",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["stack_popn"] = Function::Create(
|
|
|
|
FunctionType::get(void_type, { stack_ptr_type, sizet_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_push",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["stack_slide"] = Function::Create(
|
|
|
|
FunctionType::get(void_type, { stack_ptr_type, sizet_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_push",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["stack_update"] = Function::Create(
|
|
|
|
FunctionType::get(void_type, { stack_ptr_type, sizet_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_push",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["stack_alloc"] = Function::Create(
|
|
|
|
FunctionType::get(void_type, { stack_ptr_type, sizet_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_push",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["stack_pack"] = Function::Create(
|
|
|
|
FunctionType::get(void_type, { stack_ptr_type, sizet_type, tag_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_push",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["stack_split"] = Function::Create(
|
|
|
|
FunctionType::get(node_ptr_type, { stack_ptr_type, sizet_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"stack_push",
|
|
|
|
&module
|
|
|
|
);
|
2019-11-05 00:42:33 -08:00
|
|
|
|
|
|
|
auto int32_type = IntegerType::getInt32Ty(ctx);
|
|
|
|
functions["alloc_app"] = Function::Create(
|
|
|
|
FunctionType::get(node_ptr_type, { node_ptr_type, node_ptr_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"alloc_app",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["alloc_num"] = Function::Create(
|
|
|
|
FunctionType::get(node_ptr_type, { int32_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"alloc_num",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["alloc_global"] = Function::Create(
|
|
|
|
FunctionType::get(node_ptr_type, { function_type, int32_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"alloc_global",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
functions["alloc_ind"] = Function::Create(
|
|
|
|
FunctionType::get(node_ptr_type, { node_ptr_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"alloc_ind",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
|
|
|
|
functions["eval"] = Function::Create(
|
|
|
|
FunctionType::get(node_ptr_type, { node_ptr_type }, false),
|
|
|
|
Function::LinkageTypes::ExternalLinkage,
|
|
|
|
"eval",
|
|
|
|
&module
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Value* llvm_context::create_i8(int8_t i) {
|
|
|
|
return ConstantInt::get(ctx, APInt(8, i));
|
|
|
|
}
|
|
|
|
Value* llvm_context::create_i32(int32_t i) {
|
|
|
|
return ConstantInt::get(ctx, APInt(32, i));
|
|
|
|
}
|
|
|
|
Value* llvm_context::create_size(size_t i) {
|
|
|
|
return ConstantInt::get(ctx, APInt(sizeof(size_t) * 8, i));
|
|
|
|
}
|
|
|
|
|
|
|
|
Value* llvm_context::create_pop(Function* f) {
|
|
|
|
auto pop_f = functions.at("stack_pop");
|
|
|
|
return builder.CreateCall(pop_f, { f->arg_begin() });
|
|
|
|
}
|
|
|
|
Value* llvm_context::create_peek(Function* f, Value* off) {
|
|
|
|
auto peek_f = functions.at("stack_peek");
|
|
|
|
return builder.CreateCall(peek_f, { f->arg_begin(), off });
|
|
|
|
}
|
|
|
|
void llvm_context::create_push(Function* f, Value* v) {
|
|
|
|
auto push_f = functions.at("stack_push");
|
|
|
|
builder.CreateCall(push_f, { f->arg_begin(), v });
|
|
|
|
}
|
|
|
|
void llvm_context::create_popn(Function* f, Value* off) {
|
|
|
|
auto popn_f = functions.at("stack_popn");
|
|
|
|
builder.CreateCall(popn_f, { f->arg_begin(), off });
|
|
|
|
}
|
|
|
|
void llvm_context::create_update(Function* f, Value* off) {
|
|
|
|
auto update_f = functions.at("stack_update");
|
|
|
|
builder.CreateCall(update_f, { f->arg_begin(), off });
|
|
|
|
}
|
|
|
|
void llvm_context::create_pack(Function* f, Value* c, Value* t) {
|
|
|
|
auto pack_f = functions.at("stack_pack");
|
|
|
|
builder.CreateCall(pack_f, { f->arg_begin(), c, t });
|
|
|
|
}
|
|
|
|
void llvm_context::create_split(Function* f, Value* c) {
|
|
|
|
auto split_f = functions.at("stack_split");
|
|
|
|
builder.CreateCall(split_f, { f->arg_begin(), c });
|
|
|
|
}
|
|
|
|
void llvm_context::create_slide(Function* f, Value* off) {
|
|
|
|
auto slide_f = functions.at("stack_slide");
|
|
|
|
builder.CreateCall(slide_f, { f->arg_begin(), off });
|
|
|
|
}
|
|
|
|
void llvm_context::create_alloc(Function* f, Value* n) {
|
|
|
|
auto alloc_f = functions.at("stack_alloc");
|
|
|
|
builder.CreateCall(alloc_f, { f->arg_begin(), n });
|
|
|
|
}
|
|
|
|
|
|
|
|
Value* llvm_context::create_eval(Value* e) {
|
|
|
|
auto eval_f = functions.at("eval");
|
|
|
|
return builder.CreateCall(eval_f, { e });
|
|
|
|
}
|
|
|
|
|
|
|
|
Value* llvm_context::unwrap_num(Value* v) {
|
|
|
|
auto num_ptr_type = PointerType::getUnqual(struct_types.at("node_num"));
|
|
|
|
auto cast = builder.CreatePointerCast(v, num_ptr_type);
|
|
|
|
auto offset_0 = create_size(0);
|
|
|
|
auto offset_1 = create_size(1);
|
|
|
|
auto int_ptr = builder.CreateGEP(cast, { offset_0, offset_1 });
|
|
|
|
return builder.CreateLoad(int_ptr);
|
|
|
|
}
|
|
|
|
Value* llvm_context::create_num(Value* v) {
|
|
|
|
auto alloc_num_f = functions.at("alloc_num");
|
|
|
|
return builder.CreateCall(alloc_num_f, { v });
|
|
|
|
}
|
|
|
|
|
|
|
|
Value* llvm_context::create_global(Value* f, Value* a) {
|
|
|
|
auto alloc_global_f = functions.at("alloc_global");
|
|
|
|
return builder.CreateCall(alloc_global_f, { f, a });
|
|
|
|
}
|
|
|
|
|
|
|
|
Value* llvm_context::create_app(Value* l, Value* r) {
|
|
|
|
auto alloc_app_f = functions.at("alloc_app");
|
|
|
|
return builder.CreateCall(alloc_app_f, { l, r });
|
2019-11-02 17:53:15 -07:00
|
|
|
}
|