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 {
17341734 LValPurposeNone,
17351735 LValPurposeAssign,
17361736 LValPurposeAddressOf,
1737 LValPurposeConstAddressOf,
17381737};
17391738
17401739static 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
11651165
11661166 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
11671167 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 }
11691174 }
11701175
11711176 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
11791184
11801185 AstNode *decl_node = find_decl(node->block_context, variable_name);
11811186 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;
11831192 }
11841193
11851194 if (node->owner->any_imports_failed) {
......@@ -1196,7 +1205,8 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, AstNode *node, LValPur
11961205 assert(node->type == NodeTypeArrayAccessExpr);
11971206
11981207 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);
12001210 if (array_ref_instruction == irb->codegen->invalid_instruction)
12011211 return array_ref_instruction;
12021212
......@@ -1396,6 +1406,10 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, Ir
13961406 if (value == irb->codegen->invalid_instruction)
13971407 return value;
13981408
1409 if (lval == LValPurposeAddressOf && (op_id == IrUnOpAddressOf || op_id == IrUnOpConstAddressOf)) {
1410 return value;
1411 }
1412
13991413 return ir_build_un_op(irb, node, op_id, value);
14001414}
14011415
......@@ -1422,7 +1436,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, AstNode *node, LValP
14221436 case PrefixOpAddressOf:
14231437 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpAddressOf, LValPurposeAddressOf);
14241438 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);
14261440 case PrefixOpDereference:
14271441 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpDereference, lval);
14281442 case PrefixOpMaybe:
......@@ -2972,11 +2986,14 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi
29722986}
29732987
29742988static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) {
2989 VariableTableEntry *var = decl_var_instruction->var;
2990
29752991 IrInstruction *init_value = decl_var_instruction->init_value->other;
2976 if (init_value->type_entry->id == TypeTableEntryIdInvalid)
2977 return init_value->type_entry;
2992 if (init_value->type_entry->id == TypeTableEntryIdInvalid) {
2993 var->type = ira->codegen->builtin_types.entry_invalid;
2994 return var->type;
2995 }
29782996
2979 VariableTableEntry *var = decl_var_instruction->var;
29802997 AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration;
29812998 bool is_export = (variable_declaration->top_level_decl.visib_mod == VisibModExport);
29822999 bool is_extern = variable_declaration->is_extern;
......@@ -3522,6 +3539,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
35223539
35233540static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {
35243541 VariableTableEntry *var = var_ptr_instruction->var;
3542 assert(var->type);
35253543 if (var->type->id == TypeTableEntryIdInvalid)
35263544 return var->type;
35273545
......@@ -3561,7 +3579,12 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
35613579 if (elem_index->type_entry->id == TypeTableEntryIdInvalid)
35623580 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);
35653588 TypeTableEntry *return_type;
35663589
35673590 if (array_type->id == TypeTableEntryIdInvalid) {
......@@ -3600,12 +3623,12 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
36003623 }
36013624 }
36023625
3603 if (array_ptr->static_value.special != ConstValSpecialRuntime) {
3604 bool depends_on_compile_var = array_ptr->static_value.depends_on_compile_var ||
3626 if (array_ptr_val->special != ConstValSpecialRuntime) {
3627 bool depends_on_compile_var = array_ptr_val->depends_on_compile_var ||
36053628 casted_elem_index->static_value.depends_on_compile_var;
36063629 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base, depends_on_compile_var);
36073630 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;
36093632 size_t new_index;
36103633 size_t mem_size;
36113634 size_t old_size;
......@@ -3615,7 +3638,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
36153638 old_size = 1;
36163639 } else {
36173640 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;
36193642 old_size = mem_size - offset;
36203643 }
36213644 if (new_index >= mem_size) {
......@@ -3623,11 +3646,11 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
36233646 buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64, index, old_size));
36243647 return ira->codegen->builtin_types.entry_invalid;
36253648 }
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;
36273650 out_val->data.x_ptr.index = new_index;
36283651 } else if (is_slice(array_type)) {
3629 ConstExprValue *ptr_field = &array_ptr->static_value.data.x_struct.fields[slice_ptr_index];
3630 ConstExprValue *len_field = &array_ptr->static_value.data.x_struct.fields[slice_len_index];
3652 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];
3653 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index];
36313654 uint64_t slice_len = len_field->data.x_bignum.data.x_uint;
36323655 if (index >= slice_len) {
36333656 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
36453668 out_val->data.x_ptr.index = new_index;
36463669 }
36473670 } 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;
36493672 out_val->data.x_ptr.index = index;
36503673 } else {
36513674 zig_unreachable();