diff options
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 5207b228df..f2d7c8bb6a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5,18 +5,18 @@ * See http://opensource.org/licenses/MIT */ +#include "analyze.hpp" +#include "ast_render.hpp" #include "codegen.hpp" -#include "hash_map.hpp" -#include "zig_llvm.hpp" -#include "os.hpp" #include "config.h" -#include "error.hpp" -#include "analyze.hpp" #include "errmsg.hpp" +#include "error.hpp" +#include "hash_map.hpp" +#include "link.hpp" +#include "os.hpp" #include "parseh.hpp" -#include "ast_render.hpp" #include "target.hpp" -#include "link.hpp" +#include "zig_llvm.hpp" #include <stdio.h> #include <errno.h> @@ -65,6 +65,8 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { g->is_test_build = false; g->want_h_file = true; + g->invalid_instruction = allocate<IrInstruction>(1); + // the error.Ok value g->error_decls.append(nullptr); @@ -235,6 +237,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b static LLVMValueRef gen_unwrap_maybe(CodeGen *g, AstNode *node, LLVMValueRef maybe_struct_ref); static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1, LLVMValueRef val2, TypeTableEntry *type_entry, bool exact); +static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val); static TypeTableEntry *get_type_for_type_node(AstNode *node) { Expr *expr = get_resolved_expr(node); @@ -249,6 +252,10 @@ static void set_debug_source_node(CodeGen *g, AstNode *node) { ZigLLVMSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, node->block_context->di_scope); } +static void ir_set_debug(CodeGen *g, IrInstruction *instruction) { + set_debug_source_node(g, instruction->source_node); +} + static void clear_debug_source_node(CodeGen *g) { ZigLLVMClearCurrentDebugLocation(g->builder); } @@ -2792,6 +2799,47 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) { return nullptr; } +static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) { + ir_set_debug(g, &return_instruction->base); + LLVMBuildRet(g->builder, return_instruction->value->llvm_value); + return nullptr; +} + +static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) { + switch (instruction->id) { + case IrInstructionIdInvalid: + zig_unreachable(); + case IrInstructionIdConst: + return gen_const_val(g, instruction->type_entry, &instruction->static_value); + case IrInstructionIdReturn: + return ir_render_return(g, executable, (IrInstructionReturn *)instruction); + case IrInstructionIdCondBr: + case IrInstructionIdSwitchBr: + case IrInstructionIdPhi: + case IrInstructionIdBinOp: + case IrInstructionIdLoadVar: + case IrInstructionIdStoreVar: + case IrInstructionIdCall: + case IrInstructionIdBuiltinCall: + zig_panic("TODO render more IR instructions to LLVM"); + } + zig_unreachable(); +} + +static void ir_render(CodeGen *g, FnTableEntry *fn_entry) { + assert(fn_entry); + IrExecutable *executable = &fn_entry->ir_executable; + assert(executable->basic_block_count > 0); + for (size_t i = 0; i < executable->basic_block_count; i += 1) { + IrBasicBlock *current_block = executable->basic_block_list[i]; + for (IrInstruction *instruction = current_block->first; instruction != nullptr; + instruction = instruction->next) + { + instruction->llvm_value = ir_render_instruction(g, executable, instruction); + } + } +} + static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) { assert(block_node->type == NodeTypeBlock); @@ -3836,6 +3884,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE return LLVMConstStruct(fields, 2, false); } } + case TypeTableEntryIdVoid: + return nullptr; case TypeTableEntryIdInvalid: case TypeTableEntryIdMetaType: case TypeTableEntryIdUnreachable: @@ -3843,7 +3893,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE case TypeTableEntryIdNumLitInt: case TypeTableEntryIdUndefLit: case TypeTableEntryIdNullLit: - case TypeTableEntryIdVoid: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdGenericFn: @@ -4199,7 +4248,6 @@ static void do_code_gen(CodeGen *g) { } ImportTableEntry *import = fn_table_entry->import_entry; - AstNode *fn_def_node = fn_table_entry->fn_def_node; LLVMValueRef fn = fn_table_entry->fn_value; g->cur_fn = fn_table_entry; if (handle_is_ptr(fn_table_entry->type_entry->data.fn.fn_type_id.return_type)) { @@ -4307,9 +4355,7 @@ static void do_code_gen(CodeGen *g) { gen_var_debug_decl(g, variable); } - - TypeTableEntry *implicit_return_type = fn_def_node->data.fn_def.implicit_return_type; - gen_block(g, fn_def_node->data.fn_def.body, implicit_return_type); + ir_render(g, fn_table_entry); } assert(!g->errors.length); @@ -4967,7 +5013,6 @@ static void init(CodeGen *g, Buf *source_path) { define_builtin_types(g); define_builtin_fns(g); - } void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code) { @@ -5078,6 +5123,7 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou if (g->verbose) { fprintf(stderr, "\nCode Generation:\n"); fprintf(stderr, "------------------\n"); + } do_code_gen(g); |
