diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-10-20 01:13:39 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-10-20 01:13:39 -0400 |
| commit | a9a6f77a1f0a6e173d85fee42aec0a8d5e22a64d (patch) | |
| tree | b296c79800a216da4a9caa1c335be78d5f2ebd70 /src/codegen.cpp | |
| parent | 682511d1b22d50a77ff967d1d6415a68560cd49a (diff) | |
| download | zig-a9a6f77a1f0a6e173d85fee42aec0a8d5e22a64d.tar.gz zig-a9a6f77a1f0a6e173d85fee42aec0a8d5e22a64d.zip | |
add variable declaration initialization IR
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 2e232bacb7..cf412be0fc 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2811,6 +2811,59 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst zig_unreachable(); } +static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, + IrInstructionDeclVar *decl_var_instruction) +{ + VariableTableEntry *var = decl_var_instruction->var; + + if (!type_has_bits(var->type)) + return nullptr; + + IrInstruction *init_value = decl_var_instruction->init_value; + + bool have_init_expr = false; + bool want_zeroes = false; + + ConstExprValue *const_val = &init_value->static_value; + if (!const_val->ok || const_val->special == ConstValSpecialOther) + have_init_expr = true; + if (const_val->ok && const_val->special == ConstValSpecialZeroes) + want_zeroes = true; + + if (have_init_expr) { + gen_assign_raw(g, init_value->source_node, BinOpTypeAssign, var->value_ref, + ir_llvm_value(g, init_value), var->type, init_value->type_entry); + } else { + bool ignore_uninit = false; + // handle runtime stack allocation + bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base); + if (!ignore_uninit && (want_safe || want_zeroes)) { + TypeTableEntry *usize = g->builtin_types.entry_usize; + uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->type->type_ref); + uint64_t align_bytes = get_memcpy_align(g, var->type); + + // memset uninitialized memory to 0xa + LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); + LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), want_zeroes ? 0x00 : 0xaa, false); + LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, var->value_ref, ptr_u8, ""); + LLVMValueRef byte_count = LLVMConstInt(usize->type_ref, size_bytes, false); + LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(), align_bytes, false); + LLVMValueRef params[] = { + dest_ptr, + fill_char, + byte_count, + align_in_bytes, + LLVMConstNull(LLVMInt1Type()), // is volatile + }; + + LLVMBuildCall(g->builder, g->memset_fn_val, params, 5, ""); + } + } + + gen_var_debug_decl(g, var); + return nullptr; +} + static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) { set_debug_source_node(g, instruction->source_node); @@ -2821,7 +2874,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdReturn: return ir_render_return(g, executable, (IrInstructionReturn *)instruction); case IrInstructionIdDeclVar: - return nullptr; + return ir_render_decl_var(g, executable, (IrInstructionDeclVar *)instruction); case IrInstructionIdLoadVar: return ir_render_load_var(g, executable, (IrInstructionLoadVar *)instruction); case IrInstructionIdBinOp: |
