authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-11 21:37:47-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-11 21:37:47-04:00
logce11d6d16cf388ec7abff9680ee3a263185a9986
tree1176e1ff7c0b9ec94fc124c35922826a305a60fd
parent30c4add85a0f4af727ad7cf8f2134114329d0f07

ir: refactor lvalues


3 files changed, 44 insertions(+), 50 deletions(-)

src/all_types.hpp+5-6
......@@ -2005,12 +2005,6 @@ struct IrBasicBlock {
20052005 IrInstruction *must_be_comptime_source_instr;
20062006};
20072007
2008struct LVal {
2009 bool is_ptr;
2010 bool is_const;
2011 bool is_volatile;
2012};
2013
20142008enum IrInstructionId {
20152009 IrInstructionIdInvalid,
20162010 IrInstructionIdBr,
......@@ -2972,6 +2966,11 @@ struct IrInstructionTypeName {
29722966 IrInstruction *type_value;
29732967};
29742968
2969enum LVal {
2970 LValNone,
2971 LValPtr,
2972};
2973
29752974struct IrInstructionDeclRef {
29762975 IrInstruction base;
29772976
src/ir.cpp+37-40
......@@ -39,9 +39,6 @@ struct IrAnalyze {
3939 IrBasicBlock *const_predecessor_bb;
4040};
4141
42static const LVal LVAL_NONE = { false, false, false };
43static const LVal LVAL_PTR = { true, false, false };
44
4542enum ConstCastResultId {
4643 ConstCastResultIdOk,
4744 ConstCastResultIdErrSet,
......@@ -3164,7 +3161,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
31643161 case ReturnKindError:
31653162 {
31663163 assert(expr_node);
3167 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR);
3164 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
31683165 if (err_union_ptr == irb->codegen->invalid_instruction)
31693166 return irb->codegen->invalid_instruction;
31703167 IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr);
......@@ -3192,7 +3189,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
31923189
31933190 ir_set_cursor_at_end_and_append_block(irb, continue_block);
31943191 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false);
3195 if (lval.is_ptr)
3192 if (lval == LValPtr)
31963193 return unwrapped_ptr;
31973194 else
31983195 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr);
......@@ -3357,7 +3354,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no
33573354}
33583355
33593356static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) {
3360 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LVAL_PTR);
3357 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr);
33613358 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
33623359
33633360 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction)
......@@ -3368,7 +3365,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node)
33683365}
33693366
33703367static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
3371 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LVAL_PTR);
3368 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr);
33723369 if (lvalue == irb->codegen->invalid_instruction)
33733370 return lvalue;
33743371 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue);
......@@ -3470,7 +3467,7 @@ static IrInstruction *ir_gen_maybe_ok_or(IrBuilder *irb, Scope *parent_scope, As
34703467 AstNode *op1_node = node->data.bin_op_expr.op1;
34713468 AstNode *op2_node = node->data.bin_op_expr.op2;
34723469
3473 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LVAL_PTR);
3470 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr);
34743471 if (maybe_ptr == irb->codegen->invalid_instruction)
34753472 return irb->codegen->invalid_instruction;
34763473
......@@ -3657,7 +3654,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
36573654
36583655 Buf *variable_name = node->data.symbol_expr.symbol;
36593656
3660 if (buf_eql_str(variable_name, "_") && lval.is_ptr) {
3657 if (buf_eql_str(variable_name, "_") && lval == LValPtr) {
36613658 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node);
36623659 const_instruction->base.value.type = get_pointer_to_type(irb->codegen,
36633660 irb->codegen->builtin_types.entry_void, false);
......@@ -3669,8 +3666,8 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
36693666 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
36703667 if (primitive_table_entry) {
36713668 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value);
3672 if (lval.is_ptr) {
3673 return ir_build_ref(irb, scope, node, value, lval.is_const, lval.is_volatile);
3669 if (lval == LValPtr) {
3670 return ir_build_ref(irb, scope, node, value, false, false);
36743671 } else {
36753672 return value;
36763673 }
......@@ -3679,7 +3676,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
36793676 VariableTableEntry *var = find_variable(irb->codegen, scope, variable_name);
36803677 if (var) {
36813678 IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, node, var);
3682 if (lval.is_ptr)
3679 if (lval == LValPtr)
36833680 return var_ptr;
36843681 else
36853682 return ir_build_load_ptr(irb, scope, node, var_ptr);
......@@ -3705,7 +3702,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode
37053702 assert(node->type == NodeTypeArrayAccessExpr);
37063703
37073704 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
3708 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LVAL_PTR);
3705 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr);
37093706 if (array_ref_instruction == irb->codegen->invalid_instruction)
37103707 return array_ref_instruction;
37113708
......@@ -3716,7 +3713,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode
37163713
37173714 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,
37183715 subscript_instruction, true, PtrLenSingle);
3719 if (lval.is_ptr)
3716 if (lval == LValPtr)
37203717 return ptr_instruction;
37213718
37223719 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
......@@ -3728,7 +3725,7 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode
37283725 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
37293726 Buf *field_name = node->data.field_access_expr.field_name;
37303727
3731 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LVAL_PTR);
3728 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr);
37323729 if (container_ref_instruction == irb->codegen->invalid_instruction)
37333730 return container_ref_instruction;
37343731
......@@ -4386,7 +4383,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43864383 case BuiltinFnIdField:
43874384 {
43884385 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4389 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LVAL_PTR);
4386 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr);
43904387 if (arg0_value == irb->codegen->invalid_instruction)
43914388 return arg0_value;
43924389
......@@ -4397,7 +4394,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43974394
43984395 IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value);
43994396
4400 if (lval.is_ptr)
4397 if (lval == LValPtr)
44014398 return ptr_instruction;
44024399
44034400 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
......@@ -4928,18 +4925,18 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, Ast
49284925}
49294926
49304927static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id) {
4931 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LVAL_NONE);
4928 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone);
49324929}
49334930
49344931static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval) {
4935 if (!lval.is_ptr)
4932 if (lval != LValPtr)
49364933 return value;
49374934 if (value == irb->codegen->invalid_instruction)
49384935 return value;
49394936
49404937 // We needed a pointer to a value, but we got a value. So we create
49414938 // an instruction which just makes a const pointer of it.
4942 return ir_build_ref(irb, scope, value->source_node, value, lval.is_const, lval.is_volatile);
4939 return ir_build_ref(irb, scope, value->source_node, value, false, false);
49434940}
49444941
49454942static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -5001,7 +4998,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
50014998static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node,
50024999 LVal lval)
50035000{
5004 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR);
5001 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
50055002 if (err_union_ptr == irb->codegen->invalid_instruction)
50065003 return irb->codegen->invalid_instruction;
50075004
......@@ -5009,7 +5006,7 @@ static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode
50095006 if (payload_ptr == irb->codegen->invalid_instruction)
50105007 return irb->codegen->invalid_instruction;
50115008
5012 if (lval.is_ptr)
5009 if (lval == LValPtr)
50135010 return payload_ptr;
50145011
50155012 return ir_build_load_ptr(irb, scope, source_node, payload_ptr);
......@@ -5046,7 +5043,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
50465043 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval);
50475044 case PrefixOpAddrOf: {
50485045 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
5049 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR), lval);
5046 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval);
50505047 }
50515048 }
50525049 zig_unreachable();
......@@ -5186,7 +5183,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
51865183 } else {
51875184 payload_scope = scope;
51885185 }
5189 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, scope, LVAL_PTR);
5186 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, scope, LValPtr);
51905187 if (err_val_ptr == irb->codegen->invalid_instruction)
51915188 return err_val_ptr;
51925189 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr);
......@@ -5269,7 +5266,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
52695266 VariableTableEntry *payload_var = ir_create_var(irb, symbol_node, scope, var_symbol,
52705267 true, false, false, is_comptime);
52715268 Scope *child_scope = payload_var->child_scope;
5272 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, scope, LVAL_PTR);
5269 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, scope, LValPtr);
52735270 if (maybe_val_ptr == irb->codegen->invalid_instruction)
52745271 return maybe_val_ptr;
52755272 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr);
......@@ -5413,7 +5410,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
54135410 }
54145411 assert(elem_node->type == NodeTypeSymbol);
54155412
5416 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LVAL_PTR);
5413 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr);
54175414 if (array_val_ptr == irb->codegen->invalid_instruction)
54185415 return array_val_ptr;
54195416
......@@ -5700,7 +5697,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
57005697 AstNode *else_node = node->data.test_expr.else_node;
57015698 bool var_is_ptr = node->data.test_expr.var_is_ptr;
57025699
5703 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR);
5700 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
57045701 if (maybe_val_ptr == irb->codegen->invalid_instruction)
57055702 return maybe_val_ptr;
57065703
......@@ -5778,7 +5775,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
57785775 Buf *var_symbol = node->data.if_err_expr.var_symbol;
57795776 Buf *err_symbol = node->data.if_err_expr.err_symbol;
57805777
5781 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LVAL_PTR);
5778 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr);
57825779 if (err_val_ptr == irb->codegen->invalid_instruction)
57835780 return err_val_ptr;
57845781
......@@ -5904,7 +5901,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
59045901 assert(node->type == NodeTypeSwitchExpr);
59055902
59065903 AstNode *target_node = node->data.switch_expr.expr;
5907 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LVAL_PTR);
5904 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr);
59085905 if (target_value_ptr == irb->codegen->invalid_instruction)
59095906 return target_value_ptr;
59105907 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr);
......@@ -6277,7 +6274,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
62776274 AstNode *start_node = slice_expr->start;
62786275 AstNode *end_node = slice_expr->end;
62796276
6280 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LVAL_PTR);
6277 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr);
62816278 if (ptr_value == irb->codegen->invalid_instruction)
62826279 return irb->codegen->invalid_instruction;
62836280
......@@ -6311,11 +6308,11 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
63116308 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));
63126309 return irb->codegen->invalid_instruction;
63136310 }
6314 return ir_gen_err_assert_ok(irb, parent_scope, node, op1_node, LVAL_NONE);
6311 return ir_gen_err_assert_ok(irb, parent_scope, node, op1_node, LValNone);
63156312 }
63166313
63176314
6318 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LVAL_PTR);
6315 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr);
63196316 if (err_union_ptr == irb->codegen->invalid_instruction)
63206317 return irb->codegen->invalid_instruction;
63216318
......@@ -6868,7 +6865,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
68686865 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node);
68696866 if (ptr_instruction == irb->codegen->invalid_instruction)
68706867 return ptr_instruction;
6871 if (lval.is_ptr)
6868 if (lval == LValPtr)
68726869 return ptr_instruction;
68736870
68746871 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
......@@ -6884,12 +6881,12 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
68846881 case NodeTypeUnwrapOptional: {
68856882 AstNode *expr_node = node->data.unwrap_optional.expr;
68866883
6887 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR);
6884 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
68886885 if (maybe_ptr == irb->codegen->invalid_instruction)
68896886 return irb->codegen->invalid_instruction;
68906887
68916888 IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, scope, node, maybe_ptr, true);
6892 if (lval.is_ptr)
6889 if (lval == LValPtr)
68936890 return unwrapped_ptr;
68946891
68956892 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr);
......@@ -6959,7 +6956,7 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc
69596956}
69606957
69616958static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {
6962 return ir_gen_node_extra(irb, node, scope, LVAL_NONE);
6959 return ir_gen_node_extra(irb, node, scope, LValNone);
69636960}
69646961
69656962static void invalidate_exec(IrExecutable *exec) {
......@@ -7089,7 +7086,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
70897086 irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup");
70907087 }
70917088
7092 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LVAL_NONE);
7089 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone);
70937090 assert(result);
70947091 if (irb->exec->invalid)
70957092 return false;
......@@ -19752,7 +19749,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
1975219749 Tld *tld = instruction->tld;
1975319750 LVal lval = instruction->lval;
1975419751
19755 resolve_top_level_decl(ira->codegen, tld, lval.is_ptr, instruction->base.source_node);
19752 resolve_top_level_decl(ira->codegen, tld, lval == LValPtr, instruction->base.source_node);
1975619753 if (tld->resolution == TldResolutionInvalid)
1975719754 return ira->codegen->builtin_types.entry_invalid;
1975819755
......@@ -19773,7 +19770,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
1977319770 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node);
1977419771 }
1977519772
19776 if (lval.is_ptr) {
19773 if (lval == LValPtr) {
1977719774 ir_link_new_instruction(var_ptr, &instruction->base);
1977819775 return var_ptr->value.type;
1977919776 } else {
......@@ -19794,7 +19791,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
1979419791
1979519792 IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope,
1979619793 instruction->base.source_node, fn_entry);
19797 if (lval.is_ptr) {
19794 if (lval == LValPtr) {
1979819795 IrInstruction *ptr_instr = ir_get_ref(ira, &instruction->base, ref_instruction, true, false);
1979919796 ir_link_new_instruction(ptr_instr, &instruction->base);
1980019797 return ptr_instr->value.type;
src/ir_print.cpp+2-4
......@@ -1005,10 +1005,8 @@ static void ir_print_ptr_type(IrPrint *irp, IrInstructionPtrType *instruction) {
10051005}
10061006
10071007static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) {
1008 const char *ptr_str = instruction->lval.is_ptr ? "ptr " : "";
1009 const char *const_str = instruction->lval.is_const ? "const " : "";
1010 const char *volatile_str = instruction->lval.is_volatile ? "volatile " : "";
1011 fprintf(irp->f, "declref %s%s%s%s", const_str, volatile_str, ptr_str, buf_ptr(instruction->tld->name));
1008 const char *ptr_str = (instruction->lval == LValPtr) ? "ptr " : "";
1009 fprintf(irp->f, "declref %s%s", ptr_str, buf_ptr(instruction->tld->name));
10121010}
10131011
10141012static void ir_print_panic(IrPrint *irp, IrInstructionPanic *instruction) {