mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 11:13:08 +00:00
add variable declaration initialization IR
This commit is contained in:
parent
682511d1b2
commit
a9a6f77a1f
@ -3615,9 +3615,6 @@ static VariableTableEntry *add_local_var_shadowable(CodeGen *g, AstNode *source_
|
|||||||
// TODO replace _anon with @anon and make sure all tests still pass
|
// TODO replace _anon with @anon and make sure all tests still pass
|
||||||
buf_init_from_str(&variable_entry->name, "_anon");
|
buf_init_from_str(&variable_entry->name, "_anon");
|
||||||
}
|
}
|
||||||
if (context->fn_entry) {
|
|
||||||
context->fn_entry->variable_list.append(variable_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
variable_entry->is_const = is_const;
|
variable_entry->is_const = is_const;
|
||||||
variable_entry->decl_node = source_node;
|
variable_entry->decl_node = source_node;
|
||||||
|
|||||||
@ -2811,6 +2811,59 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
|
|||||||
zig_unreachable();
|
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) {
|
static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
|
||||||
set_debug_source_node(g, instruction->source_node);
|
set_debug_source_node(g, instruction->source_node);
|
||||||
|
|
||||||
@ -2821,7 +2874,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
|||||||
case IrInstructionIdReturn:
|
case IrInstructionIdReturn:
|
||||||
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
|
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
|
||||||
case IrInstructionIdDeclVar:
|
case IrInstructionIdDeclVar:
|
||||||
return nullptr;
|
return ir_render_decl_var(g, executable, (IrInstructionDeclVar *)instruction);
|
||||||
case IrInstructionIdLoadVar:
|
case IrInstructionIdLoadVar:
|
||||||
return ir_render_load_var(g, executable, (IrInstructionLoadVar *)instruction);
|
return ir_render_load_var(g, executable, (IrInstructionLoadVar *)instruction);
|
||||||
case IrInstructionIdBinOp:
|
case IrInstructionIdBinOp:
|
||||||
|
|||||||
@ -586,9 +586,6 @@ static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, Buf *
|
|||||||
// TODO replace _anon with @anon and make sure all tests still pass
|
// TODO replace _anon with @anon and make sure all tests still pass
|
||||||
buf_init_from_str(&variable_entry->name, "_anon");
|
buf_init_from_str(&variable_entry->name, "_anon");
|
||||||
}
|
}
|
||||||
if (node->block_context->fn_entry) {
|
|
||||||
node->block_context->fn_entry->variable_list.append(variable_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
variable_entry->is_const = is_const;
|
variable_entry->is_const = is_const;
|
||||||
variable_entry->decl_node = node;
|
variable_entry->decl_node = node;
|
||||||
@ -2177,6 +2174,10 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
|
|||||||
}
|
}
|
||||||
ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value);
|
ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value);
|
||||||
|
|
||||||
|
BlockContext *scope = decl_var_instruction->base.source_node->block_context;
|
||||||
|
if (scope->fn_entry)
|
||||||
|
scope->fn_entry->variable_list.append(var);
|
||||||
|
|
||||||
return ira->codegen->builtin_types.entry_void;
|
return ira->codegen->builtin_types.entry_void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user