authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-21 16:09:14-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-21 16:09:14-05:00
logcbce61a209897598cf093180ef6b5d71c9566d6a
tree57af17f813a3a23008feb7e636e4613076d91b80
parent1066004b79d014b4c3d10da19c84c679e21b88e5
signaturelock-open Commit is signed but in an unrecognized format.

better field access of types which have one possible value

* When you do field access of a type which only has one possible value, the result is comptime-known. * StorePtr instructions which operate on pointers to types which only have one possible value, the result is a comptime no-op. closes #1554

2 files changed, 30 insertions(+), 10 deletions(-)

src/ir.cpp+22-10
......@@ -13779,16 +13779,26 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1377913779 return ir_const_void(ira, source_instr);
1378013780 }
1378113781
13782 ZigType *child_type = ptr->value.type->data.pointer.child_type;
13783
1378213784 if (ptr->value.type->data.pointer.is_const && !source_instr->is_gen) {
1378313785 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
1378413786 return ira->codegen->invalid_instruction;
1378513787 }
1378613788
13787 ZigType *child_type = ptr->value.type->data.pointer.child_type;
1378813789 IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type);
1378913790 if (value == ira->codegen->invalid_instruction)
1379013791 return ira->codegen->invalid_instruction;
1379113792
13793 switch (type_has_one_possible_value(ira->codegen, child_type)) {
13794 case OnePossibleValueInvalid:
13795 return ira->codegen->invalid_instruction;
13796 case OnePossibleValueYes:
13797 return ir_const_void(ira, source_instr);
13798 case OnePossibleValueNo:
13799 break;
13800 }
13801
1379213802 if (instr_is_comptime(ptr) && ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
1379313803 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst) {
1379413804 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
......@@ -13809,15 +13819,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1380913819 bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar;
1381013820 copy_const_val(dest_val, &value->value, same_global_refs);
1381113821 if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) {
13812 switch (type_has_one_possible_value(ira->codegen, child_type)) {
13813 case OnePossibleValueInvalid:
13814 return ira->codegen->invalid_instruction;
13815 case OnePossibleValueNo:
13816 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr;
13817 break;
13818 case OnePossibleValueYes:
13819 break;
13820 }
13822 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr;
1382113823 }
1382213824 return ir_const_void(ira, source_instr);
1382313825 }
......@@ -15346,6 +15348,16 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
1534615348 if (bare_type->id == ZigTypeIdStruct) {
1534715349 TypeStructField *field = find_struct_type_field(bare_type, field_name);
1534815350 if (field) {
15351 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) {
15352 case OnePossibleValueInvalid:
15353 return ira->codegen->invalid_instruction;
15354 case OnePossibleValueYes: {
15355 IrInstruction *elem = ir_const(ira, source_instr, field->type_entry);
15356 return ir_get_ref(ira, source_instr, elem, false, false);
15357 }
15358 case OnePossibleValueNo:
15359 break;
15360 }
1534915361 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);
1535015362 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
1535115363 uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host;
test/stage1/behavior/struct.zig+8
......@@ -491,3 +491,11 @@ test "non-byte-aligned array inside packed struct" {
491491 S.doTheTest();
492492 comptime S.doTheTest();
493493}
494
495test "packed struct with u0 field access" {
496 const S = packed struct {
497 f0: u0,
498 };
499 var s = S{ .f0 = 0 };
500 comptime expect(s.f0 == 0);
501}