From 2dfb1ebee2bc215271e5416b723d746af319621b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 26 May 2017 23:31:38 -0400 Subject: const global values can reference each other Before, if you did something like: ``` const hi1 = "hi"; const hi2 = hi1; ``` This would create the "hi" data twice in the built object. But since the value is const we don't have to duplicate the data, now we take advantage of this fact. closes #336 --- src/ir.cpp | 63 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 24 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 82899fbf97..8e1a974359 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -553,6 +553,7 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no special_instruction->base.source_node = source_node; special_instruction->base.debug_id = exec_next_debug_id(irb->exec); special_instruction->base.owner_bb = irb->current_basic_block; + special_instruction->base.value.global_refs = allocate(1); return special_instruction; } @@ -3210,7 +3211,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco variable_entry->mem_slot_index = SIZE_MAX; variable_entry->is_comptime = is_comptime; variable_entry->src_arg_index = SIZE_MAX; - variable_entry->value = allocate(1); + variable_entry->value = create_const_vals(1); if (name) { buf_init_from_buf(&variable_entry->name, name); @@ -6565,6 +6566,14 @@ static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableE } } +static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { + ConstGlobalRefs *global_refs = dest->global_refs; + *dest = *src; + if (!same_global_refs) { + dest->global_refs = global_refs; + } +} + static void eval_const_expr_implicit_cast(CastOp cast_op, ConstExprValue *other_val, TypeTableEntry *other_type, ConstExprValue *const_val, TypeTableEntry *new_type) @@ -6576,7 +6585,13 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, case CastOpNoCast: zig_unreachable(); case CastOpNoop: - *const_val = *other_val; + { + copy_const_val(const_val, other_val, other_val->special == ConstValSpecialStatic); + const_val->type = new_type; + break; + } + case CastOpNumLitToConcrete: + const_val->data.x_bignum = other_val->data.x_bignum; const_val->type = new_type; break; case CastOpResizeSlice: @@ -7188,7 +7203,7 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction } IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type); - result->value = *val; + result->value.data.x_bignum = val->data.x_bignum; result->value.type = wanted_type; return result; } @@ -7613,7 +7628,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst (actual_type->id == TypeTableEntryIdNumLitInt && wanted_type->id == TypeTableEntryIdInt)) { - op = CastOpNoop; + op = CastOpNumLitToConcrete; } else if (wanted_type->id == TypeTableEntryIdInt) { op = CastOpFloatToInt; } else if (wanted_type->id == TypeTableEntryIdFloat) { @@ -7741,7 +7756,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc if (pointee->special != ConstValSpecialRuntime) { IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, source_instruction->source_node, child_type); - result->value = *pointee; + copy_const_val(&result->value, pointee, ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst); return result; } } @@ -8584,7 +8599,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * result_type = get_pointer_to_type(ira->codegen, child_type, true); - out_array_val = allocate(1); + out_array_val = create_const_vals(1); out_array_val->special = ConstValSpecialStatic; out_array_val->type = get_array_type(ira->codegen, child_type, new_len); out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; @@ -8592,7 +8607,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * out_val->data.x_ptr.data.base_array.array_val = out_array_val; out_val->data.x_ptr.data.base_array.elem_index = 0; } - out_array_val->data.x_array.s_none.elements = allocate(new_len); + out_array_val->data.x_array.s_none.elements = create_const_vals(new_len); expand_undef_array(ira->codegen, op1_array_val); @@ -8648,7 +8663,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); uint64_t new_array_len = array_len.data.x_uint; - out_val->data.x_array.s_none.elements = allocate(new_array_len); + out_val->data.x_array.s_none.elements = create_const_vals(new_array_len); expand_undef_array(ira->codegen, array_val); @@ -9139,7 +9154,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal GenericFnTypeId *generic_id = allocate(1); generic_id->fn_entry = fn_entry; generic_id->param_count = 0; - generic_id->params = allocate(new_fn_arg_count); + generic_id->params = create_const_vals(new_fn_arg_count); size_t next_proto_i = 0; if (first_arg_ptr) { @@ -9451,7 +9466,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value); if (pointee->type == child_type) { ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); - *out_val = *pointee; + copy_const_val(out_val, pointee, value->value.data.x_ptr.mut == ConstPtrMutComptimeConst); return child_type; } } @@ -10118,7 +10133,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source // TODO instead of allocating this every time, put it in the tld value and we can reference // the same one every time - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); const_val->special = ConstValSpecialStatic; const_val->type = fn_entry->type_entry; const_val->data.x_fn.fn_entry = fn_entry; @@ -10162,7 +10177,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru } } else if (container_type->id == TypeTableEntryIdArray) { if (buf_eql_str(field_name, "len")) { - ConstExprValue *len_val = allocate(1); + ConstExprValue *len_val = create_const_vals(1); init_const_usize(ira->codegen, len_val, container_type->data.array.len); TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize; @@ -10185,7 +10200,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val); if (buf_eql_str(field_name, "len")) { - ConstExprValue *len_val = allocate(1); + ConstExprValue *len_val = create_const_vals(1); size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index; init_const_usize(ira->codegen, len_val, len); @@ -10258,7 +10273,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru } else if (child_type->id == TypeTableEntryIdPureError) { auto err_table_entry = ira->codegen->error_table.maybe_get(field_name); if (err_table_entry) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); const_val->special = ConstValSpecialStatic; const_val->type = child_type; const_val->data.x_pure_err = err_table_entry->value; @@ -11346,7 +11361,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira, case TypeTableEntryIdPureError: if (pointee_val) { ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); - *out_val = *pointee_val; + copy_const_val(out_val, pointee_val, true); out_val->type = target_type; return target_type; } @@ -11583,7 +11598,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru ConstExprValue const_val = {}; const_val.special = ConstValSpecialStatic; const_val.type = container_type; - const_val.data.x_struct.fields = allocate(actual_field_count); + const_val.data.x_struct.fields = create_const_vals(actual_field_count); for (size_t i = 0; i < instr_field_count; i += 1) { IrInstructionContainerInitFieldsField *field = &fields[i]; @@ -11624,7 +11639,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru if (!field_val) return ira->codegen->builtin_types.entry_invalid; - const_val.data.x_struct.fields[field_index] = *field_val; + copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); } else { first_non_const_instruction = casted_field_value; const_val.special = ConstValSpecialRuntime; @@ -11698,7 +11713,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira ConstExprValue const_val = {}; const_val.special = ConstValSpecialStatic; const_val.type = fixed_size_array_type; - const_val.data.x_array.s_none.elements = allocate(elem_count); + const_val.data.x_array.s_none.elements = create_const_vals(elem_count); bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); @@ -11723,7 +11738,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira if (!elem_val) return ira->codegen->builtin_types.entry_invalid; - const_val.data.x_array.s_none.elements[i] = *elem_val; + copy_const_val(&const_val.data.x_array.s_none.elements[i], elem_val, true); } else { first_non_const_instruction = casted_arg; const_val.special = ConstValSpecialRuntime; @@ -11950,7 +11965,7 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); } ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - *out_val = *err->cached_error_name_val; + copy_const_val(out_val, err->cached_error_name_val, true); return str_type; } @@ -12133,7 +12148,7 @@ static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstru type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, &type_entry->name); } ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - *out_val = *type_entry->cached_const_name_val; + copy_const_val(out_val, type_entry->cached_const_name_val, true); return out_val->type; } @@ -12809,7 +12824,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio } ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - out_val->data.x_struct.fields = allocate(2); + out_val->data.x_struct.fields = create_const_vals(2); ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; @@ -13370,7 +13385,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc return ira->codegen->builtin_types.entry_invalid; ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - *out_val = *val; + copy_const_val(out_val, val, false); out_val->type = dest_type; return dest_type; } @@ -13696,7 +13711,7 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl ira->new_irb.exec = new_exec; ira->exec_context.mem_slot_count = ira->old_irb.exec->mem_slot_count; - ira->exec_context.mem_slot_list = allocate(ira->exec_context.mem_slot_count); + ira->exec_context.mem_slot_list = create_const_vals(ira->exec_context.mem_slot_count); IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); -- cgit v1.2.3