authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-19 21:34:18+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-19 21:34:18+02:00
log1b91478bffa021721cff2c19a6c8389c7dcb3e1d
tree9aa1e68a6f6db9410c68cfdaa8cf36103cd532a1
parent6b4f6ebd89c4788fde09dd5cde17f3cb54c6c656

Optimized field ptr ir for hot path and fix assignment bug


4 files changed, 176 insertions(+), 92 deletions(-)

src/all_types.hpp+1
......@@ -2226,6 +2226,7 @@ struct IrInstructionFieldPtr {
22262226 IrInstruction base;
22272227
22282228 IrInstruction *container_ptr;
2229 Buf *field_name_buffer;
22292230 IrInstruction *field_name_expr;
22302231 bool is_const;
22312232};
src/ir.cpp+160-85
......@@ -111,6 +111,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
111111static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
112112 VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr);
113113static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op);
114static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);
114115
115116ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
116117 assert(const_val->type->id == TypeTableEntryIdPointer);
......@@ -1033,11 +1034,12 @@ static IrInstruction *ir_build_elem_ptr_from(IrBuilder *irb, IrInstruction *old_
10331034 return new_instruction;
10341035}
10351036
1036static IrInstruction *ir_build_field_ptr_inner(IrBuilder *irb, Scope *scope, AstNode *source_node,
1037static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node,
10371038 IrInstruction *container_ptr, IrInstruction *field_name_expr)
10381039{
10391040 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);
10401041 instruction->container_ptr = container_ptr;
1042 instruction->field_name_buffer = nullptr;
10411043 instruction->field_name_expr = field_name_expr;
10421044
10431045 ir_ref_instruction(container_ptr, irb->current_basic_block);
......@@ -1049,8 +1051,14 @@ static IrInstruction *ir_build_field_ptr_inner(IrBuilder *irb, Scope *scope, Ast
10491051static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
10501052 IrInstruction *container_ptr, Buf *field_name)
10511053{
1052 IrInstruction *field_name_expr = ir_build_const_str_lit(irb, scope, source_node, field_name);
1053 return ir_build_field_ptr_inner(irb, scope, source_node, container_ptr, field_name_expr);
1054 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);
1055 instruction->container_ptr = container_ptr;
1056 instruction->field_name_buffer = field_name;
1057 instruction->field_name_expr = nullptr;
1058
1059 ir_ref_instruction(container_ptr, irb->current_basic_block);
1060
1061 return &instruction->base;
10541062}
10551063
10561064static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
......@@ -3532,7 +3540,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode
35323540 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
35333541}
35343542
3535static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
3543static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) {
35363544 assert(node->type == NodeTypeFieldAccessExpr);
35373545
35383546 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
......@@ -3542,11 +3550,7 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode
35423550 if (container_ref_instruction == irb->codegen->invalid_instruction)
35433551 return container_ref_instruction;
35443552
3545 IrInstruction *ptr_instruction = ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name);
3546 if (lval.is_ptr)
3547 return ptr_instruction;
3548
3549 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
3553 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name);
35503554}
35513555
35523556static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) {
......@@ -3577,7 +3581,7 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *
35773581 return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr);
35783582}
35793583
3580static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node) {
3584static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
35813585 assert(node->type == NodeTypeFnCallExpr);
35823586
35833587 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
......@@ -3609,7 +3613,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36093613 IrInstruction *arg = ir_gen_node(irb, arg_node, scope);
36103614 if (arg == irb->codegen->invalid_instruction)
36113615 return arg;
3612 return ir_build_typeof(irb, scope, node, arg);
3616
3617 IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg);
3618 return ir_lval_wrap(irb, scope, type_of, lval);
36133619 }
36143620 case BuiltinFnIdSetCold:
36153621 {
......@@ -3618,7 +3624,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36183624 if (arg0_value == irb->codegen->invalid_instruction)
36193625 return arg0_value;
36203626
3621 return ir_build_set_cold(irb, scope, node, arg0_value);
3627 IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value);
3628 return ir_lval_wrap(irb, scope, set_cold, lval);
36223629 }
36233630 case BuiltinFnIdSetRuntimeSafety:
36243631 {
......@@ -3627,7 +3634,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36273634 if (arg0_value == irb->codegen->invalid_instruction)
36283635 return arg0_value;
36293636
3630 return ir_build_set_runtime_safety(irb, scope, node, arg0_value);
3637 IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value);
3638 return ir_lval_wrap(irb, scope, set_safety, lval);
36313639 }
36323640 case BuiltinFnIdSetFloatMode:
36333641 {
......@@ -3641,7 +3649,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36413649 if (arg1_value == irb->codegen->invalid_instruction)
36423650 return arg1_value;
36433651
3644 return ir_build_set_float_mode(irb, scope, node, arg0_value, arg1_value);
3652 IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value, arg1_value);
3653 return ir_lval_wrap(irb, scope, set_float_mode, lval);
36453654 }
36463655 case BuiltinFnIdSizeof:
36473656 {
......@@ -3650,7 +3659,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36503659 if (arg0_value == irb->codegen->invalid_instruction)
36513660 return arg0_value;
36523661
3653 return ir_build_size_of(irb, scope, node, arg0_value);
3662 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value);
3663 return ir_lval_wrap(irb, scope, size_of, lval);
36543664 }
36553665 case BuiltinFnIdCtz:
36563666 {
......@@ -3659,7 +3669,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36593669 if (arg0_value == irb->codegen->invalid_instruction)
36603670 return arg0_value;
36613671
3662 return ir_build_ctz(irb, scope, node, arg0_value);
3672 IrInstruction *ctz = ir_build_ctz(irb, scope, node, arg0_value);
3673 return ir_lval_wrap(irb, scope, ctz, lval);
36633674 }
36643675 case BuiltinFnIdClz:
36653676 {
......@@ -3668,7 +3679,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36683679 if (arg0_value == irb->codegen->invalid_instruction)
36693680 return arg0_value;
36703681
3671 return ir_build_clz(irb, scope, node, arg0_value);
3682 IrInstruction *clz = ir_build_clz(irb, scope, node, arg0_value);
3683 return ir_lval_wrap(irb, scope, clz, lval);
36723684 }
36733685 case BuiltinFnIdImport:
36743686 {
......@@ -3677,11 +3689,13 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36773689 if (arg0_value == irb->codegen->invalid_instruction)
36783690 return arg0_value;
36793691
3680 return ir_build_import(irb, scope, node, arg0_value);
3692 IrInstruction *import = ir_build_import(irb, scope, node, arg0_value);
3693 return ir_lval_wrap(irb, scope, import, lval);
36813694 }
36823695 case BuiltinFnIdCImport:
36833696 {
3684 return ir_build_c_import(irb, scope, node);
3697 IrInstruction *c_import = ir_build_c_import(irb, scope, node);
3698 return ir_lval_wrap(irb, scope, c_import, lval);
36853699 }
36863700 case BuiltinFnIdCInclude:
36873701 {
......@@ -3695,7 +3709,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36953709 return irb->codegen->invalid_instruction;
36963710 }
36973711
3698 return ir_build_c_include(irb, scope, node, arg0_value);
3712 IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value);
3713 return ir_lval_wrap(irb, scope, c_include, lval);
36993714 }
37003715 case BuiltinFnIdCDefine:
37013716 {
......@@ -3714,7 +3729,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37143729 return irb->codegen->invalid_instruction;
37153730 }
37163731
3717 return ir_build_c_define(irb, scope, node, arg0_value, arg1_value);
3732 IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value);
3733 return ir_lval_wrap(irb, scope, c_define, lval);
37183734 }
37193735 case BuiltinFnIdCUndef:
37203736 {
......@@ -3728,7 +3744,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37283744 return irb->codegen->invalid_instruction;
37293745 }
37303746
3731 return ir_build_c_undef(irb, scope, node, arg0_value);
3747 IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value);
3748 return ir_lval_wrap(irb, scope, c_undef, lval);
37323749 }
37333750 case BuiltinFnIdMaxValue:
37343751 {
......@@ -3737,7 +3754,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37373754 if (arg0_value == irb->codegen->invalid_instruction)
37383755 return arg0_value;
37393756
3740 return ir_build_max_value(irb, scope, node, arg0_value);
3757 IrInstruction *max_value = ir_build_max_value(irb, scope, node, arg0_value);
3758 return ir_lval_wrap(irb, scope, max_value, lval);
37413759 }
37423760 case BuiltinFnIdMinValue:
37433761 {
......@@ -3746,7 +3764,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37463764 if (arg0_value == irb->codegen->invalid_instruction)
37473765 return arg0_value;
37483766
3749 return ir_build_min_value(irb, scope, node, arg0_value);
3767 IrInstruction *min_value = ir_build_min_value(irb, scope, node, arg0_value);
3768 return ir_lval_wrap(irb, scope, min_value, lval);
37503769 }
37513770 case BuiltinFnIdCompileErr:
37523771 {
......@@ -3755,7 +3774,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37553774 if (arg0_value == irb->codegen->invalid_instruction)
37563775 return arg0_value;
37573776
3758 return ir_build_compile_err(irb, scope, node, arg0_value);
3777 IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value);
3778 return ir_lval_wrap(irb, scope, compile_err, lval);
37593779 }
37603780 case BuiltinFnIdCompileLog:
37613781 {
......@@ -3768,7 +3788,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37683788 return irb->codegen->invalid_instruction;
37693789 }
37703790
3771 return ir_build_compile_log(irb, scope, node, actual_param_count, args);
3791 IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args);
3792 return ir_lval_wrap(irb, scope, compile_log, lval);
37723793 }
37733794 case BuiltinFnIdErrName:
37743795 {
......@@ -3777,7 +3798,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37773798 if (arg0_value == irb->codegen->invalid_instruction)
37783799 return arg0_value;
37793800
3780 return ir_build_err_name(irb, scope, node, arg0_value);
3801 IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value);
3802 return ir_lval_wrap(irb, scope, err_name, lval);
37813803 }
37823804 case BuiltinFnIdEmbedFile:
37833805 {
......@@ -3786,7 +3808,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37863808 if (arg0_value == irb->codegen->invalid_instruction)
37873809 return arg0_value;
37883810
3789 return ir_build_embed_file(irb, scope, node, arg0_value);
3811 IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value);
3812 return ir_lval_wrap(irb, scope, embed_file, lval);
37903813 }
37913814 case BuiltinFnIdCmpxchgWeak:
37923815 case BuiltinFnIdCmpxchgStrong:
......@@ -3821,9 +3844,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38213844 if (arg5_value == irb->codegen->invalid_instruction)
38223845 return arg5_value;
38233846
3824 return ir_build_cmpxchg(irb, scope, node, arg0_value, arg1_value,
3847 IrInstruction *cmpxchg = ir_build_cmpxchg(irb, scope, node, arg0_value, arg1_value,
38253848 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak),
38263849 nullptr, AtomicOrderUnordered, AtomicOrderUnordered);
3850 return ir_lval_wrap(irb, scope, cmpxchg, lval);
38273851 }
38283852 case BuiltinFnIdFence:
38293853 {
......@@ -3832,7 +3856,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38323856 if (arg0_value == irb->codegen->invalid_instruction)
38333857 return arg0_value;
38343858
3835 return ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered);
3859 IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered);
3860 return ir_lval_wrap(irb, scope, fence, lval);
38363861 }
38373862 case BuiltinFnIdDivExact:
38383863 {
......@@ -3846,7 +3871,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38463871 if (arg1_value == irb->codegen->invalid_instruction)
38473872 return arg1_value;
38483873
3849 return ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true);
3874 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true);
3875 return ir_lval_wrap(irb, scope, bin_op, lval);
38503876 }
38513877 case BuiltinFnIdDivTrunc:
38523878 {
......@@ -3860,7 +3886,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38603886 if (arg1_value == irb->codegen->invalid_instruction)
38613887 return arg1_value;
38623888
3863 return ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true);
3889 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true);
3890 return ir_lval_wrap(irb, scope, bin_op, lval);
38643891 }
38653892 case BuiltinFnIdDivFloor:
38663893 {
......@@ -3874,7 +3901,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38743901 if (arg1_value == irb->codegen->invalid_instruction)
38753902 return arg1_value;
38763903
3877 return ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true);
3904 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true);
3905 return ir_lval_wrap(irb, scope, bin_op, lval);
38783906 }
38793907 case BuiltinFnIdRem:
38803908 {
......@@ -3888,7 +3916,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38883916 if (arg1_value == irb->codegen->invalid_instruction)
38893917 return arg1_value;
38903918
3891 return ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true);
3919 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true);
3920 return ir_lval_wrap(irb, scope, bin_op, lval);
38923921 }
38933922 case BuiltinFnIdMod:
38943923 {
......@@ -3902,7 +3931,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39023931 if (arg1_value == irb->codegen->invalid_instruction)
39033932 return arg1_value;
39043933
3905 return ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true);
3934 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true);
3935 return ir_lval_wrap(irb, scope, bin_op, lval);
39063936 }
39073937 case BuiltinFnIdSqrt:
39083938 {
......@@ -3916,7 +3946,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39163946 if (arg1_value == irb->codegen->invalid_instruction)
39173947 return arg1_value;
39183948
3919 return ir_build_sqrt(irb, scope, node, arg0_value, arg1_value);
3949 IrInstruction *ir_sqrt = ir_build_sqrt(irb, scope, node, arg0_value, arg1_value);
3950 return ir_lval_wrap(irb, scope, ir_sqrt, lval);
39203951 }
39213952 case BuiltinFnIdTruncate:
39223953 {
......@@ -3930,7 +3961,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39303961 if (arg1_value == irb->codegen->invalid_instruction)
39313962 return arg1_value;
39323963
3933 return ir_build_truncate(irb, scope, node, arg0_value, arg1_value);
3964 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value);
3965 return ir_lval_wrap(irb, scope, truncate, lval);
39343966 }
39353967 case BuiltinFnIdIntType:
39363968 {
......@@ -3944,7 +3976,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39443976 if (arg1_value == irb->codegen->invalid_instruction)
39453977 return arg1_value;
39463978
3947 return ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
3979 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
3980 return ir_lval_wrap(irb, scope, int_type, lval);
39483981 }
39493982 case BuiltinFnIdMemcpy:
39503983 {
......@@ -3963,7 +3996,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39633996 if (arg2_value == irb->codegen->invalid_instruction)
39643997 return arg2_value;
39653998
3966 return ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value);
3999 IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value);
4000 return ir_lval_wrap(irb, scope, ir_memcpy, lval);
39674001 }
39684002 case BuiltinFnIdMemset:
39694003 {
......@@ -3982,7 +4016,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39824016 if (arg2_value == irb->codegen->invalid_instruction)
39834017 return arg2_value;
39844018
3985 return ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value);
4019 IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value);
4020 return ir_lval_wrap(irb, scope, ir_memset, lval);
39864021 }
39874022 case BuiltinFnIdMemberCount:
39884023 {
......@@ -3991,7 +4026,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39914026 if (arg0_value == irb->codegen->invalid_instruction)
39924027 return arg0_value;
39934028
3994 return ir_build_member_count(irb, scope, node, arg0_value);
4029 IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value);
4030 return ir_lval_wrap(irb, scope, member_count, lval);
39954031 }
39964032 case BuiltinFnIdMemberType:
39974033 {
......@@ -4006,7 +4042,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40064042 return arg1_value;
40074043
40084044
4009 return ir_build_member_type(irb, scope, node, arg0_value, arg1_value);
4045 IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value);
4046 return ir_lval_wrap(irb, scope, member_type, lval);
40104047 }
40114048 case BuiltinFnIdMemberName:
40124049 {
......@@ -4021,7 +4058,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40214058 return arg1_value;
40224059
40234060
4024 return ir_build_member_name(irb, scope, node, arg0_value, arg1_value);
4061 IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value);
4062 return ir_lval_wrap(irb, scope, member_name, lval);
40254063 }
40264064 case BuiltinFnIdField:
40274065 {
......@@ -4035,18 +4073,19 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40354073 if (arg1_value == irb->codegen->invalid_instruction)
40364074 return arg1_value;
40374075
4038 IrInstruction *ptr_instruction = ir_build_field_ptr_inner(irb, scope, node, arg0_value, arg1_value);
4039 //if (lval.is_ptr)
4040 // return ptr_instruction;
4076 IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value);
4077
4078 if (lval.is_ptr)
4079 return ptr_instruction;
40414080
40424081 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
40434082 }
40444083 case BuiltinFnIdBreakpoint:
4045 return ir_build_breakpoint(irb, scope, node);
4084 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval);
40464085 case BuiltinFnIdReturnAddress:
4047 return ir_build_return_address(irb, scope, node);
4086 return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval);
40484087 case BuiltinFnIdFrameAddress:
4049 return ir_build_frame_address(irb, scope, node);
4088 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval);
40504089 case BuiltinFnIdAlignOf:
40514090 {
40524091 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -4054,16 +4093,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40544093 if (arg0_value == irb->codegen->invalid_instruction)
40554094 return arg0_value;
40564095
4057 return ir_build_align_of(irb, scope, node, arg0_value);
4096 IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value);
4097 return ir_lval_wrap(irb, scope, align_of, lval);
40584098 }
40594099 case BuiltinFnIdAddWithOverflow:
4060 return ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd);
4100 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval);
40614101 case BuiltinFnIdSubWithOverflow:
4062 return ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub);
4102 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval);
40634103 case BuiltinFnIdMulWithOverflow:
4064 return ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul);
4104 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval);
40654105 case BuiltinFnIdShlWithOverflow:
4066 return ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl);
4106 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval);
40674107 case BuiltinFnIdTypeName:
40684108 {
40694109 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -4071,7 +4111,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40714111 if (arg0_value == irb->codegen->invalid_instruction)
40724112 return arg0_value;
40734113
4074 return ir_build_type_name(irb, scope, node, arg0_value);
4114 IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value);
4115 return ir_lval_wrap(irb, scope, type_name, lval);
40754116 }
40764117 case BuiltinFnIdCanImplicitCast:
40774118 {
......@@ -4085,7 +4126,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40854126 if (arg1_value == irb->codegen->invalid_instruction)
40864127 return arg1_value;
40874128
4088 return ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value);
4129 IrInstruction *can_implicit_cast = ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value);
4130 return ir_lval_wrap(irb, scope, can_implicit_cast, lval);
40894131 }
40904132 case BuiltinFnIdPanic:
40914133 {
......@@ -4094,7 +4136,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40944136 if (arg0_value == irb->codegen->invalid_instruction)
40954137 return arg0_value;
40964138
4097 return ir_build_panic(irb, scope, node, arg0_value);
4139 IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value);
4140 return ir_lval_wrap(irb, scope, panic, lval);
40984141 }
40994142 case BuiltinFnIdPtrCast:
41004143 {
......@@ -4108,7 +4151,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41084151 if (arg1_value == irb->codegen->invalid_instruction)
41094152 return arg1_value;
41104153
4111 return ir_build_ptr_cast(irb, scope, node, arg0_value, arg1_value);
4154 IrInstruction *ptr_cast = ir_build_ptr_cast(irb, scope, node, arg0_value, arg1_value);
4155 return ir_lval_wrap(irb, scope, ptr_cast, lval);
41124156 }
41134157 case BuiltinFnIdBitCast:
41144158 {
......@@ -4122,7 +4166,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41224166 if (arg1_value == irb->codegen->invalid_instruction)
41234167 return arg1_value;
41244168
4125 return ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
4169 IrInstruction *bit_cast = ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
4170 return ir_lval_wrap(irb, scope, bit_cast, lval);
41264171 }
41274172 case BuiltinFnIdIntToPtr:
41284173 {
......@@ -4136,7 +4181,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41364181 if (arg1_value == irb->codegen->invalid_instruction)
41374182 return arg1_value;
41384183
4139 return ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value);
4184 IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value);
4185 return ir_lval_wrap(irb, scope, int_to_ptr, lval);
41404186 }
41414187 case BuiltinFnIdPtrToInt:
41424188 {
......@@ -4145,7 +4191,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41454191 if (arg0_value == irb->codegen->invalid_instruction)
41464192 return arg0_value;
41474193
4148 return ir_build_ptr_to_int(irb, scope, node, arg0_value);
4194 IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value);
4195 return ir_lval_wrap(irb, scope, ptr_to_int, lval);
41494196 }
41504197 case BuiltinFnIdTagName:
41514198 {
......@@ -4155,7 +4202,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41554202 return arg0_value;
41564203
41574204 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value);
4158 return ir_build_tag_name(irb, scope, node, actual_tag);
4205 IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag);
4206 return ir_lval_wrap(irb, scope, tag_name, lval);
41594207 }
41604208 case BuiltinFnIdTagType:
41614209 {
......@@ -4164,7 +4212,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41644212 if (arg0_value == irb->codegen->invalid_instruction)
41654213 return arg0_value;
41664214
4167 return ir_build_tag_type(irb, scope, node, arg0_value);
4215 IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value);
4216 return ir_lval_wrap(irb, scope, tag_type, lval);
41684217 }
41694218 case BuiltinFnIdFieldParentPtr:
41704219 {
......@@ -4183,7 +4232,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41834232 if (arg2_value == irb->codegen->invalid_instruction)
41844233 return arg2_value;
41854234
4186 return ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr);
4235 IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr);
4236 return ir_lval_wrap(irb, scope, field_parent_ptr, lval);
41874237 }
41884238 case BuiltinFnIdOffsetOf:
41894239 {
......@@ -4197,7 +4247,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41974247 if (arg1_value == irb->codegen->invalid_instruction)
41984248 return arg1_value;
41994249
4200 return ir_build_offset_of(irb, scope, node, arg0_value, arg1_value);
4250 IrInstruction *offset_of = ir_build_offset_of(irb, scope, node, arg0_value, arg1_value);
4251 return ir_lval_wrap(irb, scope, offset_of, lval);
42014252 }
42024253 case BuiltinFnIdInlineCall:
42034254 case BuiltinFnIdNoInlineCall:
......@@ -4223,7 +4274,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42234274 }
42244275 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;
42254276
4226 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr);
4277 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr);
4278 return ir_lval_wrap(irb, scope, call, lval);
42274279 }
42284280 case BuiltinFnIdTypeId:
42294281 {
......@@ -4232,7 +4284,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42324284 if (arg0_value == irb->codegen->invalid_instruction)
42334285 return arg0_value;
42344286
4235 return ir_build_type_id(irb, scope, node, arg0_value);
4287 IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value);
4288 return ir_lval_wrap(irb, scope, type_id, lval);
42364289 }
42374290 case BuiltinFnIdShlExact:
42384291 {
......@@ -4246,7 +4299,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42464299 if (arg1_value == irb->codegen->invalid_instruction)
42474300 return arg1_value;
42484301
4249 return ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true);
4302 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true);
4303 return ir_lval_wrap(irb, scope, bin_op, lval);
42504304 }
42514305 case BuiltinFnIdShrExact:
42524306 {
......@@ -4260,7 +4314,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42604314 if (arg1_value == irb->codegen->invalid_instruction)
42614315 return arg1_value;
42624316
4263 return ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);
4317 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);
4318 return ir_lval_wrap(irb, scope, bin_op, lval);
42644319 }
42654320 case BuiltinFnIdSetEvalBranchQuota:
42664321 {
......@@ -4269,7 +4324,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42694324 if (arg0_value == irb->codegen->invalid_instruction)
42704325 return arg0_value;
42714326
4272 return ir_build_set_eval_branch_quota(irb, scope, node, arg0_value);
4327 IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value);
4328 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval);
42734329 }
42744330 case BuiltinFnIdAlignCast:
42754331 {
......@@ -4283,10 +4339,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42834339 if (arg1_value == irb->codegen->invalid_instruction)
42844340 return arg1_value;
42854341
4286 return ir_build_align_cast(irb, scope, node, arg0_value, arg1_value);
4342 IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value);
4343 return ir_lval_wrap(irb, scope, align_cast, lval);
42874344 }
42884345 case BuiltinFnIdOpaqueType:
4289 return ir_build_opaque_type(irb, scope, node);
4346 {
4347 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node);
4348 return ir_lval_wrap(irb, scope, opaque_type, lval);
4349 }
42904350 case BuiltinFnIdSetAlignStack:
42914351 {
42924352 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -4294,7 +4354,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42944354 if (arg0_value == irb->codegen->invalid_instruction)
42954355 return arg0_value;
42964356
4297 return ir_build_set_align_stack(irb, scope, node, arg0_value);
4357 IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value);
4358 return ir_lval_wrap(irb, scope, set_align_stack, lval);
42984359 }
42994360 case BuiltinFnIdArgType:
43004361 {
......@@ -4308,7 +4369,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43084369 if (arg1_value == irb->codegen->invalid_instruction)
43094370 return arg1_value;
43104371
4311 return ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);
4372 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);
4373 return ir_lval_wrap(irb, scope, arg_type, lval);
43124374 }
43134375 case BuiltinFnIdExport:
43144376 {
......@@ -4327,11 +4389,13 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43274389 if (arg2_value == irb->codegen->invalid_instruction)
43284390 return arg2_value;
43294391
4330 return ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value);
4392 IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value);
4393 return ir_lval_wrap(irb, scope, ir_export, lval);
43314394 }
43324395 case BuiltinFnIdErrorReturnTrace:
43334396 {
4334 return ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null);
4397 IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null);
4398 return ir_lval_wrap(irb, scope, error_return_trace, lval);
43354399 }
43364400 case BuiltinFnIdAtomicRmw:
43374401 {
......@@ -4390,11 +4454,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43904454 zig_unreachable();
43914455}
43924456
4393static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node) {
4457static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
43944458 assert(node->type == NodeTypeFnCallExpr);
43954459
43964460 if (node->data.fn_call_expr.is_builtin)
4397 return ir_gen_builtin_fn_call(irb, scope, node);
4461 return ir_gen_builtin_fn_call(irb, scope, node, lval);
43984462
43994463 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
44004464 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
......@@ -4420,7 +4484,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
44204484 }
44214485 }
44224486
4423 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator);
4487 IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator);
4488 return ir_lval_wrap(irb, scope, fn_call, lval);
44244489}
44254490
44264491static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -6436,7 +6501,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
64366501 case NodeTypeSymbol:
64376502 return ir_gen_symbol(irb, scope, node, lval);
64386503 case NodeTypeFnCallExpr:
6439 return ir_lval_wrap(irb, scope, ir_gen_fn_call(irb, scope, node), lval);
6504 return ir_gen_fn_call(irb, scope, node, lval);
64406505 case NodeTypeIfBoolExpr:
64416506 return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval);
64426507 case NodeTypePrefixOpExpr:
......@@ -6456,7 +6521,13 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
64566521 case NodeTypeReturnExpr:
64576522 return ir_gen_return(irb, scope, node, lval);
64586523 case NodeTypeFieldAccessExpr:
6459 return ir_gen_field_access(irb, scope, node, lval);
6524 {
6525 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node);
6526 if (lval.is_ptr)
6527 return ptr_instruction;
6528
6529 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
6530 }
64606531 case NodeTypeThisLiteral:
64616532 return ir_lval_wrap(irb, scope, ir_gen_this_literal(irb, scope, node), lval);
64626533 case NodeTypeBoolLiteral:
......@@ -13484,10 +13555,14 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
1348413555 zig_unreachable();
1348513556 }
1348613557
13487 IrInstruction *field_name_expr = field_ptr_instruction->field_name_expr->other;
13488 Buf *field_name = ir_resolve_str(ira, field_name_expr);
13489 if (!field_name)
13490 return ira->codegen->builtin_types.entry_invalid;
13558 Buf *field_name = field_ptr_instruction->field_name_buffer;
13559 if (!field_name) {
13560 IrInstruction *field_name_expr = field_ptr_instruction->field_name_expr->other;
13561 field_name = ir_resolve_str(ira, field_name_expr);
13562 if (!field_name)
13563 return ira->codegen->builtin_types.entry_invalid;
13564 }
13565
1349113566
1349213567 AstNode *source_node = field_ptr_instruction->base.source_node;
1349313568
src/ir_print.cpp+12-4
......@@ -358,10 +358,18 @@ static void ir_print_ptr_type_child(IrPrint *irp, IrInstructionPtrTypeChild *ins
358358}
359359
360360static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {
361 fprintf(irp->f, "fieldptr ");
362 ir_print_other_instruction(irp, instruction->container_ptr);
363 fprintf(irp->f, ".");
364 ir_print_other_instruction(irp, instruction->field_name_expr);
361 if (instruction->field_name_buffer) {
362 fprintf(irp->f, "fieldptr ");
363 ir_print_other_instruction(irp, instruction->container_ptr);
364 fprintf(irp->f, ".%s", buf_ptr(instruction->field_name_buffer));
365 } else {
366 assert(instruction->field_name_expr);
367 fprintf(irp->f, "@field(");
368 ir_print_other_instruction(irp, instruction->container_ptr);
369 fprintf(irp->f, ", ");
370 ir_print_other_instruction(irp, instruction->field_name_expr);
371 fprintf(irp->f, ")");
372 }
365373}
366374
367375static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {
test/cases/reflection.zig+3-3
......@@ -58,7 +58,7 @@ test "reflection: enum member types and names" {
5858}
5959
6060test "reflection: @field" {
61 const f = Foo {
61 var f = Foo {
6262 .one = 42,
6363 .two = true,
6464 .three = void{},
......@@ -70,12 +70,12 @@ test "reflection: @field" {
7070 assert(@field(f, "th" ++ "ree") == f.three);
7171 assert(@field(Foo, "const" ++ "ant") == Foo.constant);
7272 assert(@field(Bar, "O" ++ "ne") == Bar.One);
73 assert(@field(Bar, "O" ++ "ne") == Bar.One);
74 assert(@field(Bar, "O" ++ "ne") == Bar.One);
7573 assert(@field(Bar, "T" ++ "wo") == Bar.Two);
7674 assert(@field(Bar, "Th" ++ "ree") == Bar.Three);
7775 assert(@field(Bar, "F" ++ "our") == Bar.Four);
7876 assert(@field(reflection, "dum" ++ "my")(true, 1, 2) == dummy(true, 1, 2));
77 @field(f, "o" ++ "ne") = 4;
78 assert(f.one == 4);
7979}
8080
8181const Foo = struct {