Commit 4b5cc80f66

Andrew Kelley <superjoe30@gmail.com>
2017-02-16 19:58:42
move volatile pointers to central type table
1 parent 4a957b9
src/all_types.hpp
@@ -1038,7 +1038,7 @@ struct TypeTableEntry {
     } data;
 
     // use these fields to make sure we don't duplicate type table entries for the same type
-    TypeTableEntry *pointer_parent[2][2]; // [0 - mut, 1 - const][0 - normal, 1 - volatile]
+    TypeTableEntry *pointer_parent[2]; // [0 - mut, 1 - const]
     TypeTableEntry *slice_parent[2]; // [0 - mut, 1 - const]
     TypeTableEntry *maybe_parent;
     TypeTableEntry *error_parent;
src/analyze.cpp
@@ -286,11 +286,28 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
     return get_int_type(g, false, bits_needed_for_unsigned(x));
 }
 
-TypeTableEntry *get_pointer_to_type_volatile(CodeGen *g, TypeTableEntry *child_type, bool is_const, bool is_volatile) {
+TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const,
+        uint8_t bit_offset, bool is_volatile)
+{
     assert(child_type->id != TypeTableEntryIdInvalid);
-    TypeTableEntry **parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)][(is_volatile ? 1 : 0)];
-    if (*parent_pointer)
-        return *parent_pointer;
+
+    TypeId type_id = {};
+    TypeTableEntry **parent_pointer = nullptr;
+    if (bit_offset != 0 || is_volatile) {
+        type_id.id = TypeTableEntryIdPointer;
+        type_id.data.pointer.child_type = child_type;
+        type_id.data.pointer.is_const = is_const;
+        type_id.data.pointer.is_volatile = is_volatile;
+        type_id.data.pointer.bit_offset = bit_offset;
+
+        auto existing_entry = g->type_table.maybe_get(type_id);
+        if (existing_entry)
+            return existing_entry->value;
+    } else {
+        parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];
+        if (*parent_pointer)
+            return *parent_pointer;
+    }
 
     type_ensure_zero_bits_known(g, child_type);
 
@@ -322,12 +339,16 @@ TypeTableEntry *get_pointer_to_type_volatile(CodeGen *g, TypeTableEntry *child_t
     entry->data.pointer.is_const = is_const;
     entry->data.pointer.is_volatile = is_volatile;
 
-    *parent_pointer = entry;
+    if (parent_pointer) {
+        *parent_pointer = entry;
+    } else {
+        g->type_table.put(type_id, entry);
+    }
     return entry;
 }
 
 TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {
-    return get_pointer_to_type_volatile(g, child_type, is_const, false);
+    return get_pointer_to_type_extra(g, child_type, is_const, 0, false);
 }
 
 TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
@@ -488,7 +509,7 @@ TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
 }
 
 TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size) {
-    TypeId type_id;
+    TypeId type_id = {};
     type_id.id = TypeTableEntryIdArray;
     type_id.data.array.child_type = child_type;
     type_id.data.array.size = array_size;
@@ -2825,7 +2846,7 @@ TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, uint8_t size_in_bits) {
     if (common_entry)
         return *common_entry;
 
-    TypeId type_id;
+    TypeId type_id = {};
     type_id.id = TypeTableEntryIdInt;
     type_id.data.integer.is_signed = is_signed;
     type_id.data.integer.bit_count = size_in_bits;
src/analyze.hpp
@@ -15,7 +15,8 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg);
 ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg);
 TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
 TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
-TypeTableEntry *get_pointer_to_type_volatile(CodeGen *g, TypeTableEntry *child_type, bool is_const, bool is_volatile);
+TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const,
+        uint8_t bit_offset, bool is_volatile);
 bool is_node_void_expr(AstNode *node);
 uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
 TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint8_t size_in_bits);
src/ir.cpp
@@ -6226,12 +6226,12 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio
         ConstExprValue *const_val = &const_instr->value;
         const_val->type = pointee_type;
         type_ensure_zero_bits_known(ira->codegen, type_entry);
-        const_val->data.x_type = get_pointer_to_type_volatile(ira->codegen, type_entry,
-                ptr_is_const, ptr_is_volatile);
+        const_val->data.x_type = get_pointer_to_type_extra(ira->codegen, type_entry,
+                ptr_is_const, 0, ptr_is_volatile);
         return const_instr;
     } else {
-        TypeTableEntry *ptr_type = get_pointer_to_type_volatile(ira->codegen, pointee_type,
-                ptr_is_const, ptr_is_volatile);
+        TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type,
+                ptr_is_const, 0, ptr_is_volatile);
         IrInstruction *const_instr = ir_get_const(ira, instruction);
         ConstExprValue *const_val = &const_instr->value;
         const_val->type = ptr_type;
@@ -6547,7 +6547,7 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
                 ConstPtrMutComptimeConst, is_const, is_volatile);
     }
 
-    TypeTableEntry *ptr_type = get_pointer_to_type_volatile(ira->codegen, value->value.type, is_const, is_volatile);
+    TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, is_const, 0, is_volatile);
     FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
     assert(fn_entry);
     IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,
@@ -8838,8 +8838,8 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
                     buf_sprintf("index 0 outside array of size 0"));
         }
         TypeTableEntry *child_type = array_type->data.array.child_type;
-        return_type = get_pointer_to_type_volatile(ira->codegen, child_type,
-                ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile);
+        return_type = get_pointer_to_type_extra(ira->codegen, child_type,
+                ptr_type->data.pointer.is_const, 0, ptr_type->data.pointer.is_volatile);
     } else if (array_type->id == TypeTableEntryIdPointer) {
         return_type = array_type;
     } else if (is_slice(array_type)) {
@@ -9056,8 +9056,8 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
                 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
                     ConstExprValue *struct_val = const_ptr_pointee(ptr_val);
                     ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];
-                    TypeTableEntry *ptr_type = get_pointer_to_type_volatile(ira->codegen, field_val->type,
-                            is_const, is_volatile);
+                    TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,
+                            is_const, 0, is_volatile);
                     ConstExprValue *const_val = ir_build_const_from(ira, &field_ptr_instruction->base);
                     const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;
                     const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut;
@@ -9067,7 +9067,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
                 }
             }
             ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
-            return get_pointer_to_type_volatile(ira->codegen, field->type_entry, is_const, is_volatile);
+            return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, 0, is_volatile);
         } else {
             return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
                 field_ptr_instruction, container_ptr, container_type);
@@ -9079,7 +9079,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
         TypeEnumField *field = find_enum_type_field(bare_type, field_name);
         if (field) {
             ir_build_enum_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
-            return get_pointer_to_type_volatile(ira->codegen, field->type_entry, is_const, is_volatile);
+            return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, 0, is_volatile);
         } else {
             return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
                 field_ptr_instruction, container_ptr, container_type);
@@ -10014,8 +10014,8 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira,
         return ira->codegen->builtin_types.entry_invalid;
     }
     TypeTableEntry *child_type = type_entry->data.maybe.child_type;
-    TypeTableEntry *result_type = get_pointer_to_type_volatile(ira->codegen, child_type,
-            ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile);
+    TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, child_type,
+            ptr_type->data.pointer.is_const, 0, ptr_type->data.pointer.is_volatile);
 
     if (instr_is_comptime(value)) {
         ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
@@ -11321,7 +11321,7 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi
 
     TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
     TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;
-    TypeTableEntry *u8_ptr = get_pointer_to_type_volatile(ira->codegen, u8, false, dest_is_volatile);
+    TypeTableEntry *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, 0, dest_is_volatile);
 
     IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr);
     if (casted_dest_ptr->value.type->id == TypeTableEntryIdInvalid)
@@ -11409,8 +11409,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
 
     TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
     TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;
-    TypeTableEntry *u8_ptr_mut = get_pointer_to_type_volatile(ira->codegen, u8, false, dest_is_volatile);
-    TypeTableEntry *u8_ptr_const = get_pointer_to_type_volatile(ira->codegen, u8, true, src_is_volatile);
+    TypeTableEntry *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, 0, dest_is_volatile);
+    TypeTableEntry *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, 0, src_is_volatile);
 
     IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut);
     if (casted_dest_ptr->value.type->id == TypeTableEntryIdInvalid)
@@ -11927,8 +11927,8 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
         return ira->codegen->builtin_types.entry_invalid;
     } else if (canon_type->id == TypeTableEntryIdErrorUnion) {
         TypeTableEntry *child_type = canon_type->data.error.child_type;
-        TypeTableEntry *result_type = get_pointer_to_type_volatile(ira->codegen, child_type,
-                ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile);
+        TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, child_type,
+                ptr_type->data.pointer.is_const, 0, ptr_type->data.pointer.is_volatile);
         if (instr_is_comptime(value)) {
             ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
             if (!ptr_val)