diff --git a/code/compiler/13/compiler.cpp b/code/compiler/13/compiler.cpp index c94b156..71db20e 100644 --- a/code/compiler/13/compiler.cpp +++ b/code/compiler/13/compiler.cpp @@ -87,11 +87,11 @@ void compiler::create_llvm_binop(binop op) { instructions.push_back(instruction_ptr(new instruction_binop(op))); instructions.push_back(instruction_ptr(new instruction_update(2))); instructions.push_back(instruction_ptr(new instruction_pop(2))); - ctx.builder.SetInsertPoint(&new_function->getEntryBlock()); + ctx.get_builder().SetInsertPoint(&new_function->getEntryBlock()); for(auto& instruction : instructions) { instruction->gen_llvm(ctx, new_function); } - ctx.builder.CreateRetVoid(); + ctx.get_builder().CreateRetVoid(); } void compiler::create_llvm_bool(bool b) { @@ -99,11 +99,11 @@ void compiler::create_llvm_bool(bool b) { std::vector instructions; instructions.push_back(instruction_ptr(new instruction_pushint(b))); instructions.push_back(instruction_ptr(new instruction_update(0))); - ctx.builder.SetInsertPoint(&new_function->getEntryBlock()); + ctx.get_builder().SetInsertPoint(&new_function->getEntryBlock()); for(auto& instruction : instructions) { instruction->gen_llvm(ctx, new_function); } - ctx.builder.CreateRetVoid(); + ctx.get_builder().CreateRetVoid(); } void compiler::generate_llvm() { @@ -136,8 +136,8 @@ void compiler::output_llvm(const std::string& into) { target->createTargetMachine(targetTriple, cpu, features, options, llvm::Optional())); - ctx.module.setDataLayout(targetMachine->createDataLayout()); - ctx.module.setTargetTriple(targetTriple); + ctx.get_module().setDataLayout(targetMachine->createDataLayout()); + ctx.get_module().setTargetTriple(targetTriple); std::error_code ec; llvm::raw_fd_ostream file(into, ec, llvm::sys::fs::F_None); @@ -149,7 +149,7 @@ void compiler::output_llvm(const std::string& into) { if (targetMachine->addPassesToEmitFile(pm, file, NULL, type)) { throw compiler_error("failed to add passes to pass manager"); } else { - pm.run(ctx.module); + pm.run(ctx.get_module()); file.close(); } } diff --git a/code/compiler/13/global_scope.cpp b/code/compiler/13/global_scope.cpp index 62b45cc..9ffc4cb 100644 --- a/code/compiler/13/global_scope.cpp +++ b/code/compiler/13/global_scope.cpp @@ -16,11 +16,11 @@ void global_function::declare_llvm(llvm_context& ctx) { } void global_function::generate_llvm(llvm_context& ctx) { - ctx.builder.SetInsertPoint(&generated_function->getEntryBlock()); + ctx.get_builder().SetInsertPoint(&generated_function->getEntryBlock()); for(auto& instruction : instructions) { instruction->gen_llvm(ctx, generated_function); } - ctx.builder.CreateRetVoid(); + ctx.get_builder().CreateRetVoid(); } void global_constructor::generate_llvm(llvm_context& ctx) { @@ -29,11 +29,11 @@ void global_constructor::generate_llvm(llvm_context& ctx) { std::vector instructions; instructions.push_back(instruction_ptr(new instruction_pack(tag, arity))); instructions.push_back(instruction_ptr(new instruction_update(0))); - ctx.builder.SetInsertPoint(&new_function->getEntryBlock()); + ctx.get_builder().SetInsertPoint(&new_function->getEntryBlock()); for (auto& instruction : instructions) { instruction->gen_llvm(ctx, new_function); } - ctx.builder.CreateRetVoid(); + ctx.get_builder().CreateRetVoid(); } global_function& global_scope::add_function( diff --git a/code/compiler/13/instruction.cpp b/code/compiler/13/instruction.cpp index afe80aa..7fd8c0c 100644 --- a/code/compiler/13/instruction.cpp +++ b/code/compiler/13/instruction.cpp @@ -24,9 +24,9 @@ void instruction_pushglobal::print(int indent, std::ostream& to) const { } void instruction_pushglobal::gen_llvm(llvm_context& ctx, Function* f) const { - auto& global_f = ctx.custom_functions.at("f_" + name); - auto arity = ctx.create_i32(global_f->arity); - ctx.create_push(f, ctx.create_global(f, global_f->function, arity)); + auto& global_f = ctx.get_custom_function(name); + auto arity = ctx.create_i32(global_f.arity); + ctx.create_push(f, ctx.create_global(f, global_f.function, arity)); } void instruction_push::print(int indent, std::ostream& to) const { @@ -101,17 +101,17 @@ void instruction_jump::print(int indent, std::ostream& to) const { void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const { auto top_node = ctx.create_peek(f, ctx.create_size(0)); auto tag = ctx.unwrap_data_tag(top_node); - auto safety_block = BasicBlock::Create(ctx.ctx, "safety", f); - auto switch_op = ctx.builder.CreateSwitch(tag, safety_block, tag_mappings.size()); + auto safety_block = ctx.create_basic_block("safety", f); + auto switch_op = ctx.get_builder().CreateSwitch(tag, safety_block, tag_mappings.size()); std::vector blocks; for(auto& branch : branches) { - auto branch_block = BasicBlock::Create(ctx.ctx, "branch", f); - ctx.builder.SetInsertPoint(branch_block); + auto branch_block = ctx.create_basic_block("branch", f); + ctx.get_builder().SetInsertPoint(branch_block); for(auto& instruction : branch) { instruction->gen_llvm(ctx, f); } - ctx.builder.CreateBr(safety_block); + ctx.get_builder().CreateBr(safety_block); blocks.push_back(branch_block); } @@ -119,7 +119,7 @@ void instruction_jump::gen_llvm(llvm_context& ctx, Function* f) const { switch_op->addCase(ctx.create_i8(mapping.first), blocks[mapping.second]); } - ctx.builder.SetInsertPoint(safety_block); + ctx.get_builder().SetInsertPoint(safety_block); } void instruction_if::print(int indent, std::ostream& to) const { @@ -140,25 +140,25 @@ void instruction_if::gen_llvm(llvm_context& ctx, llvm::Function* f) const { auto top_node = ctx.create_peek(f, ctx.create_size(0)); auto num = ctx.unwrap_num(top_node); - auto nonzero_block = BasicBlock::Create(ctx.ctx, "nonzero", f); - auto zero_block = BasicBlock::Create(ctx.ctx, "zero", f); - auto resume_block = BasicBlock::Create(ctx.ctx, "resume", f); - auto switch_op = ctx.builder.CreateSwitch(num, nonzero_block, 2); + auto nonzero_block = ctx.create_basic_block("nonzero", f); + auto zero_block = ctx.create_basic_block("zero", f); + auto resume_block = ctx.create_basic_block("resume", f); + auto switch_op = ctx.get_builder().CreateSwitch(num, nonzero_block, 2); switch_op->addCase(ctx.create_i32(0), zero_block); - ctx.builder.SetInsertPoint(nonzero_block); + ctx.get_builder().SetInsertPoint(nonzero_block); for(auto& instruction : on_true) { instruction->gen_llvm(ctx, f); } - ctx.builder.CreateBr(resume_block); + ctx.get_builder().CreateBr(resume_block); - ctx.builder.SetInsertPoint(zero_block); + ctx.get_builder().SetInsertPoint(zero_block); for(auto& instruction : on_false) { instruction->gen_llvm(ctx, f); } - ctx.builder.CreateBr(resume_block); + ctx.get_builder().CreateBr(resume_block); - ctx.builder.SetInsertPoint(resume_block); + ctx.get_builder().SetInsertPoint(resume_block); } void instruction_slide::print(int indent, std::ostream& to) const { @@ -180,13 +180,13 @@ void instruction_binop::gen_llvm(llvm_context& ctx, Function* f) const { auto right_int = ctx.unwrap_num(ctx.create_pop(f)); llvm::Value* result; switch(op) { - case PLUS: result = ctx.builder.CreateAdd(left_int, right_int); break; - case MINUS: result = ctx.builder.CreateSub(left_int, right_int); break; - case TIMES: result = ctx.builder.CreateMul(left_int, right_int); break; - case DIVIDE: result = ctx.builder.CreateSDiv(left_int, right_int); break; - case MODULO: result = ctx.builder.CreateSRem(left_int, right_int); break; - case EQUALS: result = ctx.builder.CreateICmpEQ(left_int, right_int); break; - case LESS_EQUALS: result = ctx.builder.CreateICmpSLE(left_int, right_int); break; + case PLUS: result = ctx.get_builder().CreateAdd(left_int, right_int); break; + case MINUS: result = ctx.get_builder().CreateSub(left_int, right_int); break; + case TIMES: result = ctx.get_builder().CreateMul(left_int, right_int); break; + case DIVIDE: result = ctx.get_builder().CreateSDiv(left_int, right_int); break; + case MODULO: result = ctx.get_builder().CreateSRem(left_int, right_int); break; + case EQUALS: result = ctx.get_builder().CreateICmpEQ(left_int, right_int); break; + case LESS_EQUALS: result = ctx.get_builder().CreateICmpSLE(left_int, right_int); break; } ctx.create_push(f, ctx.create_num(f, result)); } diff --git a/code/compiler/13/llvm_context.cpp b/code/compiler/13/llvm_context.cpp index 8416e4e..75f62a4 100644 --- a/code/compiler/13/llvm_context.cpp +++ b/code/compiler/13/llvm_context.cpp @@ -163,6 +163,18 @@ void llvm_context::create_functions() { ); } +IRBuilder<>& llvm_context::get_builder() { + return builder; +} + +Module& llvm_context::get_module() { + return module; +} + +BasicBlock* llvm_context::create_basic_block(const std::string& name, llvm::Function* f) { + return BasicBlock::Create(ctx, name, f); +} + ConstantInt* llvm_context::create_i8(int8_t i) { return ConstantInt::get(ctx, APInt(8, i)); } @@ -254,7 +266,7 @@ Value* llvm_context::create_app(Function* f, Value* l, Value* r) { return create_track(f, alloc_app_call); } -llvm::Function* llvm_context::create_custom_function(std::string name, int32_t arity) { +llvm::Function* llvm_context::create_custom_function(const std::string& name, int32_t arity) { auto void_type = llvm::Type::getVoidTy(ctx); auto new_function = llvm::Function::Create( function_type, @@ -271,3 +283,7 @@ llvm::Function* llvm_context::create_custom_function(std::string name, int32_t a return new_function; } + +llvm_context::custom_function& llvm_context::get_custom_function(const std::string& name) { + return *custom_functions.at("f_" + name); +} diff --git a/code/compiler/13/llvm_context.hpp b/code/compiler/13/llvm_context.hpp index fbe4cc1..e1bdc7c 100644 --- a/code/compiler/13/llvm_context.hpp +++ b/code/compiler/13/llvm_context.hpp @@ -7,66 +7,75 @@ #include #include -struct llvm_context { - struct custom_function { - llvm::Function* function; - int32_t arity; - }; +class llvm_context { + public: + struct custom_function { + llvm::Function* function; + int32_t arity; + }; - using custom_function_ptr = std::unique_ptr; + using custom_function_ptr = std::unique_ptr; - llvm::LLVMContext ctx; - llvm::IRBuilder<> builder; - llvm::Module module; + private: + llvm::LLVMContext ctx; + llvm::IRBuilder<> builder; + llvm::Module module; - std::map custom_functions; - std::map functions; - std::map struct_types; + std::map custom_functions; + std::map functions; + std::map struct_types; - llvm::StructType* stack_type; - llvm::StructType* gmachine_type; - llvm::PointerType* stack_ptr_type; - llvm::PointerType* gmachine_ptr_type; - llvm::PointerType* node_ptr_type; - llvm::IntegerType* tag_type; - llvm::FunctionType* function_type; + llvm::StructType* stack_type; + llvm::StructType* gmachine_type; + llvm::PointerType* stack_ptr_type; + llvm::PointerType* gmachine_ptr_type; + llvm::PointerType* node_ptr_type; + llvm::IntegerType* tag_type; + llvm::FunctionType* function_type; - llvm_context() - : builder(ctx), module("bloglang", ctx) { - create_types(); - create_functions(); - } + void create_types(); + void create_functions(); - void create_types(); - void create_functions(); + public: + llvm_context() + : builder(ctx), module("bloglang", ctx) { + create_types(); + create_functions(); + } - llvm::ConstantInt* create_i8(int8_t); - llvm::ConstantInt* create_i32(int32_t); - llvm::ConstantInt* create_size(size_t); + llvm::IRBuilder<>& get_builder(); + llvm::Module& get_module(); - llvm::Value* create_pop(llvm::Function*); - llvm::Value* create_peek(llvm::Function*, llvm::Value*); - void create_push(llvm::Function*, llvm::Value*); - void create_popn(llvm::Function*, llvm::Value*); - void create_update(llvm::Function*, llvm::Value*); - void create_pack(llvm::Function*, llvm::Value*, llvm::Value*); - void create_split(llvm::Function*, llvm::Value*); - void create_slide(llvm::Function*, llvm::Value*); - void create_alloc(llvm::Function*, llvm::Value*); - llvm::Value* create_track(llvm::Function*, llvm::Value*); + llvm::BasicBlock* create_basic_block(const std::string& name, llvm::Function* f); - void create_unwind(llvm::Function*); + llvm::ConstantInt* create_i8(int8_t); + llvm::ConstantInt* create_i32(int32_t); + llvm::ConstantInt* create_size(size_t); - llvm::Value* unwrap_gmachine_stack_ptr(llvm::Value*); + llvm::Value* create_pop(llvm::Function*); + llvm::Value* create_peek(llvm::Function*, llvm::Value*); + void create_push(llvm::Function*, llvm::Value*); + void create_popn(llvm::Function*, llvm::Value*); + void create_update(llvm::Function*, llvm::Value*); + void create_pack(llvm::Function*, llvm::Value*, llvm::Value*); + void create_split(llvm::Function*, llvm::Value*); + void create_slide(llvm::Function*, llvm::Value*); + void create_alloc(llvm::Function*, llvm::Value*); + llvm::Value* create_track(llvm::Function*, llvm::Value*); - llvm::Value* unwrap_num(llvm::Value*); - llvm::Value* create_num(llvm::Function*, llvm::Value*); + void create_unwind(llvm::Function*); - llvm::Value* unwrap_data_tag(llvm::Value*); + llvm::Value* unwrap_gmachine_stack_ptr(llvm::Value*); - llvm::Value* create_global(llvm::Function*, llvm::Value*, llvm::Value*); + llvm::Value* unwrap_num(llvm::Value*); + llvm::Value* create_num(llvm::Function*, llvm::Value*); - llvm::Value* create_app(llvm::Function*, llvm::Value*, llvm::Value*); + llvm::Value* unwrap_data_tag(llvm::Value*); - llvm::Function* create_custom_function(std::string name, int32_t arity); + llvm::Value* create_global(llvm::Function*, llvm::Value*, llvm::Value*); + + llvm::Value* create_app(llvm::Function*, llvm::Value*, llvm::Value*); + + llvm::Function* create_custom_function(const std::string& name, int32_t arity); + custom_function& get_custom_function(const std::string& name); };