authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-10-23 01:33:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-10-23 01:33:23-04:00
log44d6f8ffd8eac02747fa0f915b925bb2112570dd
treec639d5e548cf25e01255226821dc0245509e71de
parentd7a2b05a813a7badf0606726c9a4b1423befd437

IR supports variable assignment


5 files changed, 106 insertions(+), 68 deletions(-)

src/all_types.hpp+6
...@@ -1645,4 +1645,10 @@ struct IrInstructionUnreachable {...@@ -1645,4 +1645,10 @@ struct IrInstructionUnreachable {
1645 IrInstruction base;1645 IrInstruction base;
1646};1646};
16471647
1648enum LValPurpose {
1649 LValPurposeNone,
1650 LValPurposeAssign,
1651 LValPurposeAddressOf,
1652};
1653
1648#endif1654#endif
src/analyze.cpp-5
...@@ -2700,11 +2700,6 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import,...@@ -2700,11 +2700,6 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import,
2700 return return_type;2700 return return_type;
2701}2701}
27022702
2703enum LValPurpose {
2704 LValPurposeAssign,
2705 LValPurposeAddressOf,
2706};
2707
2708static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,2703static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
2709 AstNode *node, LValPurpose purpose)2704 AstNode *node, LValPurpose purpose)
2710{2705{
src/codegen.cpp+5
...@@ -2808,6 +2808,9 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,...@@ -2808,6 +2808,9 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
2808 if (!type_has_bits(var->type))2808 if (!type_has_bits(var->type))
2809 return nullptr;2809 return nullptr;
28102810
2811 if (var->ref_count == 0)
2812 return nullptr;
2813
2811 IrInstruction *init_value = decl_var_instruction->init_value;2814 IrInstruction *init_value = decl_var_instruction->init_value;
28122815
2813 bool have_init_expr = false;2816 bool have_init_expr = false;
...@@ -4348,6 +4351,8 @@ static void do_code_gen(CodeGen *g) {...@@ -4348,6 +4351,8 @@ static void do_code_gen(CodeGen *g) {
4348 if (!type_has_bits(var->type)) {4351 if (!type_has_bits(var->type)) {
4349 continue;4352 continue;
4350 }4353 }
4354 if (var->ref_count == 0)
4355 continue;
43514356
4352 if (var->block_context->node->type == NodeTypeFnDef) {4357 if (var->block_context->node->type == NodeTypeFnDef) {
4353 assert(var->gen_arg_index != SIZE_MAX);4358 assert(var->gen_arg_index != SIZE_MAX);
src/ir.cpp+85-62
...@@ -24,7 +24,7 @@ struct IrAnalyze {...@@ -24,7 +24,7 @@ struct IrAnalyze {
24};24};
2525
26static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope);26static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope);
27static IrInstruction *ir_gen_lvalue(IrBuilder *irb, AstNode *node, BlockContext *scope);27static IrInstruction *ir_gen_lvalue(IrBuilder *irb, AstNode *node, BlockContext *scope, LValPurpose purpose);
2828
29static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) {29static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) {
30 assert(basic_block);30 assert(basic_block);
...@@ -293,37 +293,6 @@ static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_...@@ -293,37 +293,6 @@ static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_
293 return &const_instruction->base;293 return &const_instruction->base;
294}294}
295295
296static IrInstruction *ir_build_const_ptr(IrBuilder *irb, AstNode *source_node, ConstExprValue *pointee) {
297 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
298 const_instruction->base.static_value.ok = true;
299 const_instruction->base.static_value.data.x_ptr.len = 1;
300 const_instruction->base.static_value.data.x_ptr.is_c_str = false;
301 const_instruction->base.static_value.data.x_ptr.ptr = allocate<ConstExprValue *>(1);
302 const_instruction->base.static_value.data.x_ptr.ptr[0] = pointee;
303 return &const_instruction->base;
304}
305
306static IrInstruction *ir_build_const_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
307 ConstExprValue *pointee)
308{
309 IrInstruction *new_instruction = ir_build_const_ptr(irb, old_instruction->source_node, pointee);
310 ir_link_new_instruction(new_instruction, old_instruction);
311 return new_instruction;
312}
313
314static IrInstruction *ir_build_const(IrBuilder *irb, AstNode *source_node, ConstExprValue *value) {
315 IrInstructionConst *instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
316 instruction->base.static_value = *value;
317 instruction->base.static_value.ok = true;
318 return &instruction->base;
319}
320
321static IrInstruction *ir_build_const_from(IrBuilder *irb, IrInstruction *old_instruction, ConstExprValue *value) {
322 IrInstruction *new_instruction = ir_build_const(irb, old_instruction->source_node, value);
323 ir_link_new_instruction(new_instruction, old_instruction);
324 return new_instruction;
325}
326
327static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBinOp op_id,296static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBinOp op_id,
328 IrInstruction *op1, IrInstruction *op2)297 IrInstruction *op1, IrInstruction *op2)
329{298{
...@@ -515,6 +484,14 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, AstNode *source_node,...@@ -515,6 +484,14 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, AstNode *source_node,
515 return &instruction->base;484 return &instruction->base;
516}485}
517486
487static IrInstruction *ir_build_store_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
488 IrInstruction *ptr, IrInstruction *value)
489{
490 IrInstruction *new_instruction = ir_build_store_ptr(irb, old_instruction->source_node, ptr, value);
491 ir_link_new_instruction(new_instruction, old_instruction);
492 return new_instruction;
493}
494
518static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node,495static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node,
519 VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value)496 VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value)
520{497{
...@@ -688,8 +665,21 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, AstNode *node, IrBinOp op...@@ -688,8 +665,21 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, AstNode *node, IrBinOp op
688 return ir_build_bin_op(irb, node, op_id, op1, op2);665 return ir_build_bin_op(irb, node, op_id, op1, op2);
689}666}
690667
668static IrInstruction *ir_gen_assign(IrBuilder *irb, AstNode *node) {
669 IrInstruction *lvalue = ir_gen_lvalue(irb, node->data.bin_op_expr.op1, node->block_context, LValPurposeAssign);
670 if (lvalue == irb->codegen->invalid_instruction)
671 return lvalue;
672
673 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, node->block_context);
674 if (rvalue == irb->codegen->invalid_instruction)
675 return rvalue;
676
677 ir_build_store_ptr(irb, node, lvalue, rvalue);
678 return ir_build_const_void(irb, node);
679}
680
691static IrInstruction *ir_gen_assign_op(IrBuilder *irb, AstNode *node, IrBinOp op_id) {681static IrInstruction *ir_gen_assign_op(IrBuilder *irb, AstNode *node, IrBinOp op_id) {
692 IrInstruction *lvalue = ir_gen_lvalue(irb, node->data.bin_op_expr.op1, node->block_context);682 IrInstruction *lvalue = ir_gen_lvalue(irb, node->data.bin_op_expr.op1, node->block_context, LValPurposeAssign);
693 if (lvalue == irb->codegen->invalid_instruction)683 if (lvalue == irb->codegen->invalid_instruction)
694 return lvalue;684 return lvalue;
695 IrInstruction *op1 = ir_build_load_ptr(irb, node->data.bin_op_expr.op1, lvalue);685 IrInstruction *op1 = ir_build_load_ptr(irb, node->data.bin_op_expr.op1, lvalue);
...@@ -709,7 +699,7 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) {...@@ -709,7 +699,7 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) {
709 case BinOpTypeInvalid:699 case BinOpTypeInvalid:
710 zig_unreachable();700 zig_unreachable();
711 case BinOpTypeAssign:701 case BinOpTypeAssign:
712 zig_panic("TODO gen IR for assignment");702 return ir_gen_assign(irb, node);
713 case BinOpTypeAssignTimes:703 case BinOpTypeAssignTimes:
714 return ir_gen_assign_op(irb, node, IrBinOpMult);704 return ir_gen_assign_op(irb, node, IrBinOpMult);
715 case BinOpTypeAssignTimesWrap:705 case BinOpTypeAssignTimesWrap:
...@@ -809,9 +799,9 @@ static IrInstruction *ir_gen_num_lit(IrBuilder *irb, AstNode *node) {...@@ -809,9 +799,9 @@ static IrInstruction *ir_gen_num_lit(IrBuilder *irb, AstNode *node) {
809}799}
810800
811static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node,801static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node,
812 bool pointer_only, BlockContext *scope)802 LValPurpose lval, BlockContext *scope)
813{803{
814 resolve_top_level_decl(irb->codegen, decl_node, pointer_only);804 resolve_top_level_decl(irb->codegen, decl_node, lval);
815 TopLevelDecl *tld = get_as_top_level_decl(decl_node);805 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
816 if (tld->resolution == TldResolutionInvalid)806 if (tld->resolution == TldResolutionInvalid)
817 return irb->codegen->invalid_instruction;807 return irb->codegen->invalid_instruction;
...@@ -843,27 +833,33 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstN...@@ -843,27 +833,33 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstN
843 }833 }
844}834}
845835
846static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, bool pointer_only) {836static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose lval) {
847 assert(node->type == NodeTypeSymbol);837 assert(node->type == NodeTypeSymbol);
848838
849 if (node->data.symbol_expr.override_type_entry)839 if (node->data.symbol_expr.override_type_entry) {
850 return ir_build_const_type(irb, node, node->data.symbol_expr.override_type_entry);840 zig_panic("TODO have parseh directly generate IR");
841 }
851842
852 Buf *variable_name = node->data.symbol_expr.symbol;843 Buf *variable_name = node->data.symbol_expr.symbol;
853844
854 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);845 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
855 if (primitive_table_entry)846 if (primitive_table_entry) {
856 return ir_build_const_type(irb, node, primitive_table_entry->value);847 return ir_build_const_type(irb, node, primitive_table_entry->value);
848 }
857849
858 VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name);850 VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name);
859 if (var) {851 if (var) {
860 IrInstruction *var_ptr = ir_build_var_ptr(irb, node, var);852 IrInstruction *var_ptr = ir_build_var_ptr(irb, node, var);
861 return ir_build_load_ptr(irb, node, var_ptr);853 if (lval != LValPurposeNone)
854 return var_ptr;
855 else
856 return ir_build_load_ptr(irb, node, var_ptr);
862 }857 }
863858
864 AstNode *decl_node = find_decl(node->block_context, variable_name);859 AstNode *decl_node = find_decl(node->block_context, variable_name);
865 if (decl_node)860 if (decl_node) {
866 return ir_gen_decl_ref(irb, node, decl_node, pointer_only, node->block_context);861 return ir_gen_decl_ref(irb, node, decl_node, lval, node->block_context);
862 }
867863
868 if (node->owner->any_imports_failed) {864 if (node->owner->any_imports_failed) {
869 // skip the error message since we had a failing import in this file865 // skip the error message since we had a failing import in this file
...@@ -1144,9 +1140,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) {...@@ -1144,9 +1140,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) {
1144 return ir_build_const_void(irb, node);1140 return ir_build_const_void(irb, node);
1145}1141}
11461142
1147static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context,1143static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, LValPurpose lval) {
1148 bool pointer_only)
1149{
1150 assert(block_context);1144 assert(block_context);
1151 node->block_context = block_context;1145 node->block_context = block_context;
11521146
...@@ -1158,7 +1152,7 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont...@@ -1158,7 +1152,7 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont
1158 case NodeTypeNumberLiteral:1152 case NodeTypeNumberLiteral:
1159 return ir_gen_num_lit(irb, node);1153 return ir_gen_num_lit(irb, node);
1160 case NodeTypeSymbol:1154 case NodeTypeSymbol:
1161 return ir_gen_symbol(irb, node, pointer_only);1155 return ir_gen_symbol(irb, node, lval);
1162 case NodeTypeFnCallExpr:1156 case NodeTypeFnCallExpr:
1163 return ir_gen_fn_call(irb, node);1157 return ir_gen_fn_call(irb, node);
1164 case NodeTypeIfBoolExpr:1158 case NodeTypeIfBoolExpr:
...@@ -1215,16 +1209,15 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont...@@ -1215,16 +1209,15 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont
1215}1209}
12161210
1217static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope) {1211static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope) {
1218 bool pointer_only_no = false;1212 return ir_gen_node_extra(irb, node, scope, LValPurposeNone);
1219 return ir_gen_node_extra(irb, node, scope, pointer_only_no);
1220}1213}
12211214
1222static IrInstruction *ir_gen_lvalue(IrBuilder *irb, AstNode *node, BlockContext *scope) {1215static IrInstruction *ir_gen_lvalue(IrBuilder *irb, AstNode *node, BlockContext *scope, LValPurpose lval) {
1223 assert(scope);1216 assert(scope);
1224 node->block_context = scope;1217 node->block_context = scope;
1225 switch (node->type) {1218 switch (node->type) {
1226 case NodeTypeSymbol:1219 case NodeTypeSymbol:
1227 zig_panic("TODO symbol lvalue");1220 return ir_gen_symbol(irb, node, lval);
1228 case NodeTypeArrayAccessExpr:1221 case NodeTypeArrayAccessExpr:
1229 zig_panic("TODO array access lvalue");1222 zig_panic("TODO array access lvalue");
1230 case NodeTypeFieldAccessExpr:1223 case NodeTypeFieldAccessExpr:
...@@ -1281,7 +1274,7 @@ static IrInstruction *ir_gen_lvalue(IrBuilder *irb, AstNode *node, BlockContext...@@ -1281,7 +1274,7 @@ static IrInstruction *ir_gen_lvalue(IrBuilder *irb, AstNode *node, BlockContext
1281}1274}
12821275
1283static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext *scope,1276static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext *scope,
1284 IrExecutable *ir_executable, bool add_return, bool pointer_only)1277 IrExecutable *ir_executable, bool add_return, LValPurpose lval)
1285{1278{
1286 assert(node->owner);1279 assert(node->owner);
12871280
...@@ -1295,7 +1288,7 @@ static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext...@@ -1295,7 +1288,7 @@ static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext
1295 // Entry block gets a reference because we enter it to begin.1288 // Entry block gets a reference because we enter it to begin.
1296 ir_ref_bb(irb->current_basic_block);1289 ir_ref_bb(irb->current_basic_block);
12971290
1298 IrInstruction *result = ir_gen_node_extra(irb, node, scope, pointer_only);1291 IrInstruction *result = ir_gen_node_extra(irb, node, scope, lval);
1299 assert(result);1292 assert(result);
13001293
1301 if (result == g->invalid_instruction)1294 if (result == g->invalid_instruction)
...@@ -1309,8 +1302,7 @@ static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext...@@ -1309,8 +1302,7 @@ static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext
13091302
1310IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, BlockContext *scope, IrExecutable *ir_executable) {1303IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, BlockContext *scope, IrExecutable *ir_executable) {
1311 bool add_return_no = false;1304 bool add_return_no = false;
1312 bool pointer_only_no = false;1305 return ir_gen_add_return(codegen, node, scope, ir_executable, add_return_no, LValPurposeNone);
1313 return ir_gen_add_return(codegen, node, scope, ir_executable, add_return_no, pointer_only_no);
1314}1306}
13151307
1316IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {1308IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {
...@@ -1324,8 +1316,7 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {...@@ -1324,8 +1316,7 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {
1324 BlockContext *scope = fn_def_node->data.fn_def.block_context;1316 BlockContext *scope = fn_def_node->data.fn_def.block_context;
13251317
1326 bool add_return_yes = true;1318 bool add_return_yes = true;
1327 bool pointer_only_no = false;1319 return ir_gen_add_return(codegn, body_node, scope, ir_executable, add_return_yes, LValPurposeNone);
1328 return ir_gen_add_return(codegn, body_node, scope, ir_executable, add_return_yes, pointer_only_no);
1329}1320}
13301321
1331/*1322/*
...@@ -1620,6 +1611,11 @@ static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) {...@@ -1620,6 +1611,11 @@ static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) {
1620 return ir_build_bb_from(&ira->new_irb, old_bb);1611 return ir_build_bb_from(&ira->new_irb, old_bb);
1621}1612}
16221613
1614static ConstExprValue *ir_get_out_val(IrInstruction *instruction) {
1615 instruction->other = instruction;
1616 return &instruction->static_value;
1617}
1618
1623static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,1619static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
1624 IrInstruction *dest_type, IrInstruction *value)1620 IrInstruction *dest_type, IrInstruction *value)
1625{1621{
...@@ -1972,8 +1968,7 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp...@@ -1972,8 +1968,7 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp
1972 ConstExprValue *op1_val = &casted_op1->static_value;1968 ConstExprValue *op1_val = &casted_op1->static_value;
1973 ConstExprValue *op2_val = &casted_op2->static_value;1969 ConstExprValue *op2_val = &casted_op2->static_value;
1974 if (op1_val->ok && op2_val->ok) {1970 if (op1_val->ok && op2_val->ok) {
1975 ConstExprValue *out_val = &bin_op_instruction->base.static_value;1971 ConstExprValue *out_val = ir_get_out_val(&bin_op_instruction->base);
1976 bin_op_instruction->base.other = &bin_op_instruction->base;
19771972
1978 assert(op1->type_entry->id == TypeTableEntryIdBool);1973 assert(op1->type_entry->id == TypeTableEntryIdBool);
1979 assert(op2->type_entry->id == TypeTableEntryIdBool);1974 assert(op2->type_entry->id == TypeTableEntryIdBool);
...@@ -3909,7 +3904,13 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct...@@ -3909,7 +3904,13 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct
3909 ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];3904 ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
3910 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, var_ptr_instruction->var->type, false);3905 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, var_ptr_instruction->var->type, false);
3911 if (mem_slot->ok) {3906 if (mem_slot->ok) {
3912 ir_build_const_ptr_from(&ira->new_irb, &var_ptr_instruction->base, mem_slot);3907 ConstExprValue *out_val = ir_get_out_val(&var_ptr_instruction->base);
3908
3909 out_val->ok = true;
3910 out_val->data.x_ptr.len = 1;
3911 out_val->data.x_ptr.is_c_str = false;
3912 out_val->data.x_ptr.ptr = allocate<ConstExprValue *>(1);
3913 out_val->data.x_ptr.ptr[0] = mem_slot;
3913 return ptr_type;3914 return ptr_type;
3914 }3915 }
39153916
...@@ -3927,7 +3928,8 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc...@@ -3927,7 +3928,8 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc
3927 if (ptr->static_value.ok) {3928 if (ptr->static_value.ok) {
3928 ConstExprValue *pointee = ptr->static_value.data.x_ptr.ptr[0];3929 ConstExprValue *pointee = ptr->static_value.data.x_ptr.ptr[0];
3929 if (pointee->ok) {3930 if (pointee->ok) {
3930 ir_build_const_from(&ira->new_irb, &load_ptr_instruction->base, pointee);3931 ConstExprValue *out_val = ir_get_out_val(&load_ptr_instruction->base);
3932 *out_val = *pointee;
3931 return child_type;3933 return child_type;
3932 }3934 }
3933 }3935 }
...@@ -3941,6 +3943,27 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc...@@ -3941,6 +3943,27 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc
3941 }3943 }
3942}3944}
39433945
3946static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstructionStorePtr *store_ptr_instruction) {
3947 IrInstruction *ptr = store_ptr_instruction->ptr->other;
3948 IrInstruction *value = store_ptr_instruction->value->other;
3949
3950 TypeTableEntry *child_type = ptr->type_entry->data.pointer.child_type;
3951 IrInstruction *casted_value = ir_get_casted_value(ira, value, child_type);
3952 if (casted_value == ira->codegen->invalid_instruction)
3953 return ira->codegen->builtin_types.entry_invalid;
3954
3955 if (ptr->static_value.ok && casted_value->static_value.ok) {
3956 ConstExprValue *dest_val = ptr->static_value.data.x_ptr.ptr[0];
3957 if (dest_val->ok) {
3958 *dest_val = casted_value->static_value;
3959 return ira->codegen->builtin_types.entry_void;
3960 }
3961 }
3962
3963 ir_build_store_ptr_from(&ira->new_irb, &store_ptr_instruction->base, ptr, casted_value);
3964 return ira->codegen->builtin_types.entry_void;
3965}
3966
3944static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {3967static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
3945 switch (instruction->id) {3968 switch (instruction->id) {
3946 case IrInstructionIdInvalid:3969 case IrInstructionIdInvalid:
...@@ -3958,7 +3981,7 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -3958,7 +3981,7 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
3958 case IrInstructionIdLoadPtr:3981 case IrInstructionIdLoadPtr:
3959 return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction);3982 return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction);
3960 case IrInstructionIdStorePtr:3983 case IrInstructionIdStorePtr:
3961 zig_panic("TODO store ptr");3984 return ir_analyze_instruction_store_ptr(ira, (IrInstructionStorePtr *)instruction);
3962 case IrInstructionIdFieldPtr:3985 case IrInstructionIdFieldPtr:
3963 zig_panic("TODO field ptr");3986 zig_panic("TODO field ptr");
3964 case IrInstructionIdElemPtr:3987 case IrInstructionIdElemPtr:
src/ir_print.cpp+10-1
...@@ -326,6 +326,13 @@ static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {...@@ -326,6 +326,13 @@ static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {
326 ir_print_other_instruction(irp, instruction->ptr);326 ir_print_other_instruction(irp, instruction->ptr);
327}327}
328328
329static void ir_print_store_ptr(IrPrint *irp, IrInstructionStorePtr *instruction) {
330 fprintf(irp->f, "*");
331 ir_print_other_instruction(irp, instruction->ptr);
332 fprintf(irp->f, " = ");
333 ir_print_other_instruction(irp, instruction->value);
334}
335
329static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {336static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
330 ir_print_prefix(irp, instruction);337 ir_print_prefix(irp, instruction);
331 switch (instruction->id) {338 switch (instruction->id) {
...@@ -382,8 +389,10 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -382,8 +389,10 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
382 case IrInstructionIdLoadPtr:389 case IrInstructionIdLoadPtr:
383 ir_print_load_ptr(irp, (IrInstructionLoadPtr *)instruction);390 ir_print_load_ptr(irp, (IrInstructionLoadPtr *)instruction);
384 break;391 break;
385 case IrInstructionIdSwitchBr:
386 case IrInstructionIdStorePtr:392 case IrInstructionIdStorePtr:
393 ir_print_store_ptr(irp, (IrInstructionStorePtr *)instruction);
394 break;
395 case IrInstructionIdSwitchBr:
387 case IrInstructionIdFieldPtr:396 case IrInstructionIdFieldPtr:
388 zig_panic("TODO print more IR instructions");397 zig_panic("TODO print more IR instructions");
389 }398 }