authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-17 21:07:29-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-17 21:07:29-05:00
log7a2a0672b4370d0dfe7a64541c4fb90a89132113
tree03a279bb3e612f270a80c42eba4f829a1cb32d54
parent62d0d88b56b909cf9f9f7a78a8222acd0f37b6cb

IR: pointers to constants use correct addresses


2 files changed, 39 insertions(+), 17 deletions(-)

src/all_types.hpp-1
...@@ -1734,7 +1734,6 @@ enum LValPurpose {...@@ -1734,7 +1734,6 @@ enum LValPurpose {
1734 LValPurposeNone,1734 LValPurposeNone,
1735 LValPurposeAssign,1735 LValPurposeAssign,
1736 LValPurposeAddressOf,1736 LValPurposeAddressOf,
1737 LValPurposeConstAddressOf,
1738};1737};
17391738
1740static const size_t slice_ptr_index = 0;1739static const size_t slice_ptr_index = 0;
src/ir.cpp+39-16
...@@ -1165,7 +1165,12 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l...@@ -1165,7 +1165,12 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l
11651165
1166 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);1166 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
1167 if (primitive_table_entry) {1167 if (primitive_table_entry) {
1168 return ir_build_const_type(irb, node, primitive_table_entry->value);1168 IrInstruction *value = ir_build_const_type(irb, node, primitive_table_entry->value);
1169 if (lval == LValPurposeAddressOf) {
1170 return ir_build_un_op(irb, node, IrUnOpAddressOf, value);
1171 } else {
1172 return value;
1173 }
1169 }1174 }
11701175
1171 VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name);1176 VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name);
...@@ -1179,7 +1184,11 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l...@@ -1179,7 +1184,11 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l
11791184
1180 AstNode *decl_node = find_decl(node->block_context, variable_name);1185 AstNode *decl_node = find_decl(node->block_context, variable_name);
1181 if (decl_node) {1186 if (decl_node) {
1182 return ir_gen_decl_ref(irb, node, decl_node, lval, node->block_context);1187 IrInstruction *value = ir_gen_decl_ref(irb, node, decl_node, lval, node->block_context);
1188 if (lval == LValPurposeAddressOf)
1189 return ir_build_un_op(irb, node, IrUnOpAddressOf, value);
1190 else
1191 return value;
1183 }1192 }
11841193
1185 if (node->owner->any_imports_failed) {1194 if (node->owner->any_imports_failed) {
...@@ -1196,7 +1205,8 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, AstNode *node, LValPur...@@ -1196,7 +1205,8 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, AstNode *node, LValPur
1196 assert(node->type == NodeTypeArrayAccessExpr);1205 assert(node->type == NodeTypeArrayAccessExpr);
11971206
1198 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;1207 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
1199 IrInstruction *array_ref_instruction = ir_gen_node(irb, array_ref_node, node->block_context);1208 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, node->block_context,
1209 LValPurposeAddressOf);
1200 if (array_ref_instruction == irb->codegen->invalid_instruction)1210 if (array_ref_instruction == irb->codegen->invalid_instruction)
1201 return array_ref_instruction;1211 return array_ref_instruction;
12021212
...@@ -1396,6 +1406,10 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, Ir...@@ -1396,6 +1406,10 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, Ir
1396 if (value == irb->codegen->invalid_instruction)1406 if (value == irb->codegen->invalid_instruction)
1397 return value;1407 return value;
13981408
1409 if (lval == LValPurposeAddressOf && (op_id == IrUnOpAddressOf || op_id == IrUnOpConstAddressOf)) {
1410 return value;
1411 }
1412
1399 return ir_build_un_op(irb, node, op_id, value);1413 return ir_build_un_op(irb, node, op_id, value);
1400}1414}
14011415
...@@ -1422,7 +1436,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, AstNode *node, LValP...@@ -1422,7 +1436,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, AstNode *node, LValP
1422 case PrefixOpAddressOf:1436 case PrefixOpAddressOf:
1423 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpAddressOf, LValPurposeAddressOf);1437 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpAddressOf, LValPurposeAddressOf);
1424 case PrefixOpConstAddressOf:1438 case PrefixOpConstAddressOf:
1425 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpConstAddressOf, LValPurposeConstAddressOf);1439 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpConstAddressOf, LValPurposeAddressOf);
1426 case PrefixOpDereference:1440 case PrefixOpDereference:
1427 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpDereference, lval);1441 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpDereference, lval);
1428 case PrefixOpMaybe:1442 case PrefixOpMaybe:
...@@ -2972,11 +2986,14 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi...@@ -2972,11 +2986,14 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi
2972}2986}
29732987
2974static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) {2988static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) {
2989 VariableTableEntry *var = decl_var_instruction->var;
2990
2975 IrInstruction *init_value = decl_var_instruction->init_value->other;2991 IrInstruction *init_value = decl_var_instruction->init_value->other;
2976 if (init_value->type_entry->id == TypeTableEntryIdInvalid)2992 if (init_value->type_entry->id == TypeTableEntryIdInvalid) {
2977 return init_value->type_entry;2993 var->type = ira->codegen->builtin_types.entry_invalid;
2994 return var->type;
2995 }
29782996
2979 VariableTableEntry *var = decl_var_instruction->var;
2980 AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration;2997 AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration;
2981 bool is_export = (variable_declaration->top_level_decl.visib_mod == VisibModExport);2998 bool is_export = (variable_declaration->top_level_decl.visib_mod == VisibModExport);
2982 bool is_extern = variable_declaration->is_extern;2999 bool is_extern = variable_declaration->is_extern;
...@@ -3522,6 +3539,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP...@@ -3522,6 +3539,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
35223539
3523static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {3540static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {
3524 VariableTableEntry *var = var_ptr_instruction->var;3541 VariableTableEntry *var = var_ptr_instruction->var;
3542 assert(var->type);
3525 if (var->type->id == TypeTableEntryIdInvalid)3543 if (var->type->id == TypeTableEntryIdInvalid)
3526 return var->type;3544 return var->type;
35273545
...@@ -3561,7 +3579,12 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -3561,7 +3579,12 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
3561 if (elem_index->type_entry->id == TypeTableEntryIdInvalid)3579 if (elem_index->type_entry->id == TypeTableEntryIdInvalid)
3562 return ira->codegen->builtin_types.entry_invalid;3580 return ira->codegen->builtin_types.entry_invalid;
35633581
3564 TypeTableEntry *array_type = array_ptr->type_entry;3582 // This will be a pointer type because elem ptr IR instruction operates on a pointer to a thing.
3583 TypeTableEntry *ptr_type = array_ptr->type_entry;
3584 assert(ptr_type->id == TypeTableEntryIdPointer);
3585
3586 TypeTableEntry *array_type = ptr_type->data.pointer.child_type;
3587 ConstExprValue *array_ptr_val = const_ptr_pointee(&array_ptr->static_value);
3565 TypeTableEntry *return_type;3588 TypeTableEntry *return_type;
35663589
3567 if (array_type->id == TypeTableEntryIdInvalid) {3590 if (array_type->id == TypeTableEntryIdInvalid) {
...@@ -3600,12 +3623,12 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -3600,12 +3623,12 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
3600 }3623 }
3601 }3624 }
36023625
3603 if (array_ptr->static_value.special != ConstValSpecialRuntime) {3626 if (array_ptr_val->special != ConstValSpecialRuntime) {
3604 bool depends_on_compile_var = array_ptr->static_value.depends_on_compile_var ||3627 bool depends_on_compile_var = array_ptr_val->depends_on_compile_var ||
3605 casted_elem_index->static_value.depends_on_compile_var;3628 casted_elem_index->static_value.depends_on_compile_var;
3606 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base, depends_on_compile_var);3629 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base, depends_on_compile_var);
3607 if (array_type->id == TypeTableEntryIdPointer) {3630 if (array_type->id == TypeTableEntryIdPointer) {
3608 size_t offset = array_ptr->static_value.data.x_ptr.index;3631 size_t offset = array_ptr_val->data.x_ptr.index;
3609 size_t new_index;3632 size_t new_index;
3610 size_t mem_size;3633 size_t mem_size;
3611 size_t old_size;3634 size_t old_size;
...@@ -3615,7 +3638,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -3615,7 +3638,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
3615 old_size = 1;3638 old_size = 1;
3616 } else {3639 } else {
3617 new_index = offset + index;3640 new_index = offset + index;
3618 mem_size = array_ptr->static_value.data.x_ptr.base_ptr->data.x_array.size;3641 mem_size = array_ptr_val->data.x_ptr.base_ptr->data.x_array.size;
3619 old_size = mem_size - offset;3642 old_size = mem_size - offset;
3620 }3643 }
3621 if (new_index >= mem_size) {3644 if (new_index >= mem_size) {
...@@ -3623,11 +3646,11 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -3623,11 +3646,11 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
3623 buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64, index, old_size));3646 buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64, index, old_size));
3624 return ira->codegen->builtin_types.entry_invalid;3647 return ira->codegen->builtin_types.entry_invalid;
3625 }3648 }
3626 out_val->data.x_ptr.base_ptr = array_ptr->static_value.data.x_ptr.base_ptr;3649 out_val->data.x_ptr.base_ptr = array_ptr_val->data.x_ptr.base_ptr;
3627 out_val->data.x_ptr.index = new_index;3650 out_val->data.x_ptr.index = new_index;
3628 } else if (is_slice(array_type)) {3651 } else if (is_slice(array_type)) {
3629 ConstExprValue *ptr_field = &array_ptr->static_value.data.x_struct.fields[slice_ptr_index];3652 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];
3630 ConstExprValue *len_field = &array_ptr->static_value.data.x_struct.fields[slice_len_index];3653 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index];
3631 uint64_t slice_len = len_field->data.x_bignum.data.x_uint;3654 uint64_t slice_len = len_field->data.x_bignum.data.x_uint;
3632 if (index >= slice_len) {3655 if (index >= slice_len) {
3633 add_node_error(ira->codegen, elem_ptr_instruction->base.source_node,3656 add_node_error(ira->codegen, elem_ptr_instruction->base.source_node,
...@@ -3645,7 +3668,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -3645,7 +3668,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
3645 out_val->data.x_ptr.index = new_index;3668 out_val->data.x_ptr.index = new_index;
3646 }3669 }
3647 } else if (array_type->id == TypeTableEntryIdArray) {3670 } else if (array_type->id == TypeTableEntryIdArray) {
3648 out_val->data.x_ptr.base_ptr = &array_ptr->static_value;3671 out_val->data.x_ptr.base_ptr = array_ptr_val;
3649 out_val->data.x_ptr.index = index;3672 out_val->data.x_ptr.index = index;
3650 } else {3673 } else {
3651 zig_unreachable();3674 zig_unreachable();