diff options
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 150 |
1 files changed, 69 insertions, 81 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 8fe4191754..e1c9091587 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -226,7 +226,8 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic) { g->linker_rdynamic = rdynamic; } -static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val); +static void render_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val); +static void render_const_val_global(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val); static void set_debug_source_node(CodeGen *g, AstNode *node) { assert(node->block_context); @@ -862,11 +863,17 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { if (!type_has_bits(instruction->type_entry)) return nullptr; if (!instruction->llvm_value) { - assert(instruction->static_value.ok); + assert(instruction->static_value.special != ConstValSpecialRuntime); assert(instruction->type_entry); - instruction->llvm_value = gen_const_val(g, instruction->type_entry, &instruction->static_value); + render_const_val(g, instruction->type_entry, &instruction->static_value); + instruction->llvm_value = instruction->static_value.llvm_value; assert(instruction->llvm_value); } + if (instruction->static_value.special != ConstValSpecialRuntime) { + if (instruction->type_entry->id == TypeTableEntryIdPointer) { + return LLVMBuildLoad(g->builder, instruction->static_value.llvm_global, ""); + } + } return instruction->llvm_value; } @@ -1401,9 +1408,9 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, bool want_zeroes = false; ConstExprValue *const_val = &init_value->static_value; - if (!const_val->ok || const_val->special == ConstValSpecialOther) + if (const_val->special == ConstValSpecialRuntime || const_val->special == ConstValSpecialStatic) have_init_expr = true; - if (const_val->ok && const_val->special == ConstValSpecialZeroes) + if (const_val->special == ConstValSpecialZeroes) want_zeroes = true; if (have_init_expr) { @@ -1740,14 +1747,14 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) { } static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val) { - assert(const_val->ok); - switch (const_val->special) { + case ConstValSpecialRuntime: + zig_unreachable(); case ConstValSpecialUndef: return LLVMGetUndef(type_entry->type_ref); case ConstValSpecialZeroes: return LLVMConstNull(type_entry->type_ref); - case ConstValSpecialOther: + case ConstValSpecialStatic: break; } @@ -1814,7 +1821,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE continue; } fields[type_struct_field->gen_index] = gen_const_val(g, type_struct_field->type_entry, - const_val->data.x_struct.fields[i]); + &const_val->data.x_struct.fields[i]); } return LLVMConstNamedStruct(type_entry->type_ref, fields, type_entry->data.structure.gen_field_count); @@ -1829,8 +1836,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE uint64_t len = type_entry->data.array.len; LLVMValueRef *values = allocate<LLVMValueRef>(len); for (uint64_t i = 0; i < len; i += 1) { - ConstExprValue *field_value = const_val->data.x_array.fields[i]; - values[i] = gen_const_val(g, child_type, field_value); + ConstExprValue *elem_value = &const_val->data.x_array.elements[i]; + values[i] = gen_const_val(g, child_type, elem_value); } return LLVMConstArray(child_type->type_ref, values, len); } @@ -1878,29 +1885,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE case TypeTableEntryIdPointer: { TypeTableEntry *child_type = type_entry->data.pointer.child_type; - size_t len = const_val->data.x_ptr.len; - LLVMValueRef target_val; - if (len == 1) { - target_val = gen_const_val(g, child_type, const_val->data.x_ptr.ptr[0]); - } else if (len > 1) { - LLVMValueRef *values = allocate<LLVMValueRef>(len); - for (size_t i = 0; i < len; i += 1) { - values[i] = gen_const_val(g, child_type, const_val->data.x_ptr.ptr[i]); - } - target_val = LLVMConstArray(child_type->type_ref, values, len); - } else { - return LLVMGetUndef(type_entry->type_ref); - } - LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(target_val), ""); - LLVMSetInitializer(global_value, target_val); - LLVMSetLinkage(global_value, LLVMPrivateLinkage); - LLVMSetGlobalConstant(global_value, type_entry->data.pointer.is_const); - LLVMSetUnnamedAddr(global_value, true); - - if (len > 1) { - return LLVMConstBitCast(global_value, type_entry->type_ref); + + render_const_val_global(g, type_entry, const_val); + size_t index = const_val->data.x_ptr.index; + if (index == SIZE_MAX) { + render_const_val(g, child_type, const_val->data.x_ptr.base_ptr); + render_const_val_global(g, child_type, const_val->data.x_ptr.base_ptr); + return const_val->data.x_ptr.base_ptr->llvm_global; } else { - return global_value; + ConstExprValue *array_const_val = const_val->data.x_ptr.base_ptr; + TypeTableEntry *array_type = get_array_type(g, child_type, + array_const_val->data.x_array.size); + render_const_val(g, array_type, array_const_val); + render_const_val_global(g, array_type, array_const_val); + TypeTableEntry *usize = g->builtin_types.entry_usize; + LLVMValueRef indices[] = { + LLVMConstNull(usize->type_ref), + LLVMConstInt(usize->type_ref, index, false), + }; + LLVMValueRef ptr_val = LLVMConstInBoundsGEP(array_const_val->llvm_global, indices, 2); + return ptr_val; } } case TypeTableEntryIdErrorUnion: @@ -1945,27 +1949,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE zig_unreachable(); } -static void gen_const_globals(CodeGen *g) { - for (size_t i = 0; i < g->global_const_list.length; i += 1) { - AstNode *expr_node = g->global_const_list.at(i); - Expr *expr = get_resolved_expr(expr_node); - ConstExprValue *const_val = &expr->const_val; - assert(const_val->ok); - TypeTableEntry *type_entry = expr->type_entry; - - if (handle_is_ptr(type_entry)) { - LLVMValueRef init_val = gen_const_val(g, type_entry, const_val); - LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), ""); - LLVMSetInitializer(global_value, init_val); - LLVMSetLinkage(global_value, LLVMPrivateLinkage); - LLVMSetGlobalConstant(global_value, true); - LLVMSetUnnamedAddr(global_value, true); - expr->const_llvm_val = global_value; - } else { - expr->const_llvm_val = gen_const_val(g, type_entry, const_val); - } - assert(expr->const_llvm_val); +static void render_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val) { + if (!const_val->llvm_value) + const_val->llvm_value = gen_const_val(g, type_entry, const_val); + + if (const_val->llvm_global) + LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); +} + +static void render_const_val_global(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val) { + if (!const_val->llvm_global) { + LLVMValueRef global_value = LLVMAddGlobal(g->module, type_entry->type_ref, ""); + LLVMSetLinkage(global_value, LLVMInternalLinkage); + LLVMSetGlobalConstant(global_value, true); + LLVMSetUnnamedAddr(global_value, true); + + const_val->llvm_global = global_value; } + + if (const_val->llvm_value) + LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); } static void delete_unused_builtin_fns(CodeGen *g) { @@ -2096,9 +2099,6 @@ static void do_code_gen(CodeGen *g) { assert(!g->errors.length); delete_unused_builtin_fns(g); - - - gen_const_globals(g); generate_error_name_table(g); // Generate module level variables @@ -2107,8 +2107,8 @@ static void do_code_gen(CodeGen *g) { if (var->type->id == TypeTableEntryIdNumLitFloat) { // Generate debug info for it but that's it. - ConstExprValue *const_val = &get_resolved_expr(var->val_node)->const_val; - assert(const_val->ok); + ConstExprValue *const_val = &get_resolved_expr(var->val_node)->instruction->static_value; + assert(const_val->special != ConstValSpecialRuntime); TypeTableEntry *var_type = g->builtin_types.entry_f64; LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float); gen_global_var(g, var, init_val, var_type); @@ -2117,8 +2117,8 @@ static void do_code_gen(CodeGen *g) { if (var->type->id == TypeTableEntryIdNumLitInt) { // Generate debug info for it but that's it. - ConstExprValue *const_val = &get_resolved_expr(var->val_node)->const_val; - assert(const_val->ok); + ConstExprValue *const_val = &get_resolved_expr(var->val_node)->instruction->static_value; + assert(const_val->special != ConstValSpecialRuntime); TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ? g->builtin_types.entry_isize : g->builtin_types.entry_usize; LLVMValueRef init_val = LLVMConstInt(var_type->type_ref, @@ -2143,25 +2143,13 @@ static void do_code_gen(CodeGen *g) { LLVMSetLinkage(global_value, LLVMExternalLinkage); } else { AstNode *expr_node = var->decl_node->data.variable_declaration.expr; - LLVMValueRef init_val; - if (expr_node) { - Expr *expr = get_resolved_expr(expr_node); - ConstExprValue *const_val = &expr->const_val; - assert(const_val->ok); - TypeTableEntry *type_entry = expr->type_entry; - init_val = gen_const_val(g, type_entry, const_val); - } else { - init_val = LLVMConstNull(var->type->type_ref); - } - - global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), buf_ptr(&var->name)); - LLVMSetInitializer(global_value, init_val); - LLVMSetLinkage(global_value, LLVMInternalLinkage); - LLVMSetUnnamedAddr(global_value, true); - + IrInstruction *instruction = get_resolved_expr(expr_node)->instruction; + render_const_val(g, instruction->type_entry, &instruction->static_value); + render_const_val_global(g, instruction->type_entry, &instruction->static_value); + global_value = instruction->static_value.llvm_global; // TODO debug info for function pointers if (var->gen_is_const && var->type->id != TypeTableEntryIdFn) { - gen_global_var(g, var, init_val, var->type); + gen_global_var(g, var, instruction->static_value.llvm_value, var->type); } } @@ -3282,11 +3270,11 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { static void get_c_type_node(CodeGen *g, AstNode *type_node, Buf *out_buf) { Expr *expr = get_resolved_expr(type_node); - assert(expr->type_entry); - assert(expr->type_entry->id == TypeTableEntryIdMetaType); + assert(expr->instruction->type_entry); + assert(expr->instruction->type_entry->id == TypeTableEntryIdMetaType); - ConstExprValue *const_val = &expr->const_val; - assert(const_val->ok); + ConstExprValue *const_val = &expr->instruction->static_value; + assert(const_val->special != ConstValSpecialRuntime); TypeTableEntry *type_entry = const_val->data.x_type; |
