2
0
Эх сурвалжийг харах

Fix Type_Info bug overwriting type_info data.

Ginger Bill 9 жил өмнө
parent
commit
a5c1e83ce4

+ 3 - 2
code/demo.odin

@@ -1,9 +1,10 @@
 #import "fmt.odin"
 
+a: [12]u8
 main :: proc() {
-	v: {4}f32
+	v: [4]f32
 	v[0] = 123
-	fmt.println("Hellope!", v, v[0])
+	fmt.println("Hellope!", v, v[0], a)
 }
 
 

+ 40 - 4
src/checker/checker.cpp

@@ -586,7 +586,8 @@ void init_checker(Checker *c, Parser *parser, BaseTypeSizes sizes) {
 	gb_arena_init_from_allocator(&c->arena, a, arena_size);
 	gb_arena_init_from_allocator(&c->tmp_arena, a, arena_size);
 
-	c->allocator = gb_arena_allocator(&c->arena);
+
+	c->allocator     = gb_arena_allocator(&c->arena);
 	c->tmp_allocator = gb_arena_allocator(&c->tmp_arena);
 
 	c->global_scope = make_scope(universal_scope, c->allocator);
@@ -742,7 +743,7 @@ void add_type_info_type(Checker *c, Type *t) {
 	isize ti_index = -1;
 	for_array(i, c->info.type_info_map.entries) {
 		auto *e = &c->info.type_info_map.entries[i];
-		Type *prev_type = cast(Type *)cast(uintptr)e->key.key;
+		Type *prev_type = cast(Type *)e->key.ptr;
 		if (are_types_identical(t, prev_type)) {
 			// Duplicate entry
 			ti_index = i;
@@ -769,14 +770,21 @@ void add_type_info_type(Checker *c, Type *t) {
 	Type *bt = base_type(t);
 	switch (bt->kind) {
 	case Type_Basic: {
-		if (bt->Basic.kind == Basic_string) {
-			add_type_info_type(c, make_type_pointer(c->allocator, t_u8));
+		switch (bt->Basic.kind) {
+		case Basic_string:
+			add_type_info_type(c, t_u8_ptr);
 			add_type_info_type(c, t_int);
+			break;
+		case Basic_any:
+			add_type_info_type(c, t_type_info_ptr);
+			add_type_info_type(c, t_rawptr);
+			break;
 		}
 	} break;
 
 	case Type_Maybe:
 		add_type_info_type(c, bt->Maybe.elem);
+		add_type_info_type(c, t_bool);
 		break;
 
 	case Type_Pointer:
@@ -803,6 +811,10 @@ void add_type_info_type(Checker *c, Type *t) {
 		case TypeRecord_Enum:
 			add_type_info_type(c, bt->Record.enum_base);
 			break;
+
+		case TypeRecord_Union:
+			add_type_info_type(c, t_int);
+			/* fallthrough */
 		default:
 			for (isize i = 0; i < bt->Record.field_count; i++) {
 				Entity *f = bt->Record.fields[i];
@@ -1320,6 +1332,30 @@ void check_parsed_files(Checker *c) {
 			add_type_and_value(&c->info, expr, info->mode, info->type, info->value);
 		}
 	}
+
+	// for_array(i, c->info.type_info_map.entries) {
+	// 	auto *e = &c->info.type_info_map.entries[i];
+	// 	Type *prev_type = cast(Type *)e->key.ptr;
+	// 	gb_printf("%td - %s\n", i, type_to_string(prev_type));
+	// }
+
+	// for_array(i, c->info.type_info_map.entries) {
+	// 	auto *p = &c->info.type_info_map.entries[i];
+	// 	for (isize j = 0; j < i-1; j++) {
+	// 		auto *q = &c->info.type_info_map.entries[j];
+	// 		Type *a = cast(Type *)p->key.ptr;
+	// 		Type *b = cast(Type *)q->key.ptr;
+	// 		p->value = i;
+	// 		// GB_ASSERT(!are_types_identical(a, b));
+	// 	}
+	// }
+
+	// for_array(i, c->info.type_info_map.entries) {
+	// 	auto *e = &c->info.type_info_map.entries[i];
+	// 	Type *prev_type = cast(Type *)e->key.ptr;
+	// 	gb_printf("%td - %s\n", e->value, type_to_string(prev_type));
+	// }
+
 }
 
 

+ 12 - 12
src/checker/entity.cpp

@@ -5,26 +5,26 @@ enum BuiltinProcId;
 enum ImplicitValueId;
 
 #define ENTITY_KINDS \
-	ENTITY_KIND(Invalid), \
-	ENTITY_KIND(Constant), \
-	ENTITY_KIND(Variable), \
-	ENTITY_KIND(TypeName), \
-	ENTITY_KIND(Procedure), \
-	ENTITY_KIND(Builtin), \
-	ENTITY_KIND(ImportName), \
-	ENTITY_KIND(Nil), \
-	ENTITY_KIND(ImplicitValue), \
-	ENTITY_KIND(Count),
+	ENTITY_KIND(Invalid) \
+	ENTITY_KIND(Constant) \
+	ENTITY_KIND(Variable) \
+	ENTITY_KIND(TypeName) \
+	ENTITY_KIND(Procedure) \
+	ENTITY_KIND(Builtin) \
+	ENTITY_KIND(ImportName) \
+	ENTITY_KIND(Nil) \
+	ENTITY_KIND(ImplicitValue) \
+	ENTITY_KIND(Count)
 
 
 enum EntityKind {
-#define ENTITY_KIND(k) GB_JOIN2(Entity_, k)
+#define ENTITY_KIND(k) GB_JOIN2(Entity_, k),
 	ENTITY_KINDS
 #undef ENTITY_KIND
 };
 
 String const entity_strings[] = {
-#define ENTITY_KIND(k) {cast(u8 *)#k, gb_size_of(#k)-1}
+#define ENTITY_KIND(k) {cast(u8 *)#k, gb_size_of(#k)-1},
 	ENTITY_KINDS
 #undef ENTITY_KIND
 };

+ 56 - 25
src/checker/type.cpp

@@ -97,7 +97,9 @@ struct Type {
 	u32 flags; // See parser.cpp `enum TypeFlag`
 	union {
 		BasicType Basic;
-		struct { Type *elem; } Pointer;
+		struct {
+			Type *elem;
+		} Pointer;
 		struct {
 			Type *elem;
 			i64 count;
@@ -121,19 +123,21 @@ struct Type {
 			isize    field_count; // == offset_count is struct
 			AstNode *node;
 
-			// enum only
-			Type *   enum_base; // Default is `int`
-			Entity * enum_count;
-			Entity * min_value;
-			Entity * max_value;
-
-			// struct only
-			i64 *    struct_offsets;
-			b32      struct_are_offsets_set;
-			b32      struct_is_packed;
-			b32      struct_is_ordered;
-			Entity **fields_in_src_order; // Entity_Variable
-
+			union { // NOTE(bill): Reduce size_of Type
+				struct { // enum only
+					Type *   enum_base; // Default is `int`
+					Entity * enum_count;
+					Entity * min_value;
+					Entity * max_value;
+				};
+				struct { // struct only
+					i64 *    struct_offsets;
+					b32      struct_are_offsets_set;
+					b32      struct_is_packed;
+					b32      struct_is_ordered;
+					Entity **fields_in_src_order; // Entity_Variable
+				};
+			};
 
 			// Entity_Constant or Entity_TypeName
 			Entity **other_fields;
@@ -645,23 +649,27 @@ b32 are_types_identical(Type *x, Type *y) {
 
 	switch (x->kind) {
 	case Type_Basic:
-		if (y->kind == Type_Basic)
+		if (y->kind == Type_Basic) {
 			return x->Basic.kind == y->Basic.kind;
+		}
 		break;
 
 	case Type_Array:
-		if (y->kind == Type_Array)
+		if (y->kind == Type_Array) {
 			return (x->Array.count == y->Array.count) && are_types_identical(x->Array.elem, y->Array.elem);
+		}
 		break;
 
 	case Type_Vector:
-		if (y->kind == Type_Vector)
+		if (y->kind == Type_Vector) {
 			return (x->Vector.count == y->Vector.count) && are_types_identical(x->Vector.elem, y->Vector.elem);
+		}
 		break;
 
 	case Type_Slice:
-		if (y->kind == Type_Slice)
+		if (y->kind == Type_Slice) {
 			return are_types_identical(x->Slice.elem, y->Slice.elem);
+		}
 		break;
 
 	case Type_Record:
@@ -678,6 +686,9 @@ b32 are_types_identical(Type *x, Type *y) {
 							if (!are_types_identical(x->Record.fields[i]->type, y->Record.fields[i]->type)) {
 								return false;
 							}
+							if (x->Record.fields[i]->token.string != y->Record.fields[i]->token.string) {
+								return false;
+							}
 						}
 						return true;
 					}
@@ -692,13 +703,15 @@ b32 are_types_identical(Type *x, Type *y) {
 		break;
 
 	case Type_Pointer:
-		if (y->kind == Type_Pointer)
+		if (y->kind == Type_Pointer) {
 			return are_types_identical(x->Pointer.elem, y->Pointer.elem);
+		}
 		break;
 
 	case Type_Maybe:
-		if (y->kind == Type_Maybe)
+		if (y->kind == Type_Maybe) {
 			return are_types_identical(x->Maybe.elem, y->Maybe.elem);
+		}
 		break;
 
 	case Type_Named:
@@ -711,8 +724,9 @@ b32 are_types_identical(Type *x, Type *y) {
 		if (y->kind == Type_Tuple) {
 			if (x->Tuple.variable_count == y->Tuple.variable_count) {
 				for (isize i = 0; i < x->Tuple.variable_count; i++) {
-					if (!are_types_identical(x->Tuple.variables[i]->type, y->Tuple.variables[i]->type))
+					if (!are_types_identical(x->Tuple.variables[i]->type, y->Tuple.variables[i]->type)) {
 						return false;
+					}
 				}
 				return true;
 			}
@@ -740,7 +754,6 @@ Type *default_type(Type *type) {
 		case Basic_UntypedFloat:   return t_f64;
 		case Basic_UntypedString:  return t_string;
 		case Basic_UntypedRune:    return t_rune;
-		// case Basic_UntypedPointer: return &basic_types[Basic_rawptr];
 		}
 	}
 	return type;
@@ -1031,6 +1044,17 @@ i64 type_align_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
 		switch (t->Record.kind) {
 		case TypeRecord_Struct:
 			if (t->Record.field_count > 0) {
+				if (!t->Record.struct_is_ordered) {
+					i64 max = s.word_size;
+					for (isize i = 1; i < t->Record.field_count; i++) {
+						// NOTE(bill): field zero is null
+						i64 align = type_align_of(s, allocator, t->Record.fields[i]->type);
+						if (max < align) {
+							max = align;
+						}
+					}
+					return max;
+				}
 				return type_align_of(s, allocator, t->Record.fields[0]->type);
 			}
 			break;
@@ -1297,7 +1321,14 @@ gbString write_type_to_string(gbString str, Type *type) {
 	case Type_Record: {
 		switch (type->Record.kind) {
 		case TypeRecord_Struct:
-			str = gb_string_appendc(str, "struct{");
+			str = gb_string_appendc(str, "struct");
+			if (type->Record.struct_is_packed) {
+				str = gb_string_appendc(str, " #packed");
+			}
+			if (type->Record.struct_is_ordered) {
+				str = gb_string_appendc(str, " #ordered");
+			}
+			str = gb_string_appendc(str, " {");
 			for (isize i = 0; i < type->Record.field_count; i++) {
 				Entity *f = type->Record.fields[i];
 				GB_ASSERT(f->kind == Entity_Variable);
@@ -1312,7 +1343,7 @@ gbString write_type_to_string(gbString str, Type *type) {
 
 		case TypeRecord_Union:
 			str = gb_string_appendc(str, "union{");
-			for (isize i = 0; i < type->Record.field_count; i++) {
+			for (isize i = 1; i < type->Record.field_count; i++) {
 				Entity *f = type->Record.fields[i];
 				GB_ASSERT(f->kind == Entity_TypeName);
 				if (i > 0) {
@@ -1320,7 +1351,7 @@ gbString write_type_to_string(gbString str, Type *type) {
 				}
 				str = gb_string_append_length(str, f->token.string.text, f->token.string.len);
 				str = gb_string_appendc(str, ": ");
-				str = write_type_to_string(str, f->type);
+				str = write_type_to_string(str, base_type(f->type));
 			}
 			str = gb_string_appendc(str, "}");
 			break;

+ 7 - 6
src/codegen/codegen.cpp

@@ -296,19 +296,19 @@ void ssa_gen_tree(ssaGen *s) {
 			Type *t_string_slice_ptr = make_type_pointer(a, make_type_slice(a, t_string));
 
 			auto get_type_info_ptr = [](ssaProcedure *proc, ssaValue *type_info_data, Type *type) -> ssaValue * {
-				return ssa_emit_array_gep(proc, type_info_data,
-				                          ssa_type_info_index(proc->module->info, type));
+				return ssa_emit_array_ep(proc, type_info_data, cast(i32)ssa_type_info_index(proc->module->info, type));
 			};
 
-			isize type_info_member_index = 0;
+			i32 type_info_member_index = 0;
 
-			auto type_info_member_offset = [](ssaProcedure *proc, ssaValue *data, isize count, isize *index) -> ssaValue * {
-				ssaValue *offset = ssa_emit_array_gep(proc, data, *index);
+			auto type_info_member_offset = [](ssaProcedure *proc, ssaValue *data, isize count, i32 *index) -> ssaValue * {
+				ssaValue *offset = ssa_emit_array_ep(proc, data, *index);
 				*index += count;
 				return offset;
 			};
 
 
+
 			for_array(type_info_map_index, info->type_info_map.entries) {
 				auto *entry = &info->type_info_map.entries[type_info_map_index];
 				Type *t = cast(Type *)cast(uintptr)entry->key.key;
@@ -659,7 +659,7 @@ void ssa_gen_tree(ssaGen *s) {
 				}
 
 				if (tag != NULL) {
-					ssaValue *gep = ssa_emit_array_gep(proc, type_info_data, entry_index);
+					ssaValue *gep = ssa_emit_array_ep(proc, type_info_data, entry_index);
 					ssaValue *val = ssa_emit_conv(proc, ssa_emit_load(proc, tag), t_type_info);
 					ssa_emit_store(proc, gep, val);
 				}
@@ -673,6 +673,7 @@ void ssa_gen_tree(ssaGen *s) {
 		ssa_build_proc(m->procs[i], m->procs[i]->Proc.parent);
 	}
 
+
 	// m->layout = make_string("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64");
 }
 

+ 19 - 9
src/codegen/print_llvm.cpp

@@ -715,14 +715,24 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
 		ssa_fprintf(f, "\n");
 	} break;
 
-	case ssaInstr_ExtractValue: {
-		Type *et = instr->ExtractValue.elem_type;
+	case ssaInstr_ArrayExtractValue: {
+		Type *et = ssa_type(instr->ArrayExtractValue.address);
 		ssa_fprintf(f, "%%%d = extractvalue ", value->index);
 
 		ssa_print_type(f, m, et);
 		ssa_fprintf(f, " ");
-		ssa_print_value(f, m, instr->ExtractValue.address, et);
-		ssa_fprintf(f, ", %d\n", instr->ExtractValue.index);
+		ssa_print_value(f, m, instr->ArrayExtractValue.address, et);
+		ssa_fprintf(f, ", %d\n", instr->ArrayExtractValue.index);
+	} break;
+
+	case ssaInstr_StructExtractValue: {
+		Type *et = ssa_type(instr->StructExtractValue.address);
+		ssa_fprintf(f, "%%%d = extractvalue ", value->index);
+
+		ssa_print_type(f, m, et);
+		ssa_fprintf(f, " ");
+		ssa_print_value(f, m, instr->StructExtractValue.address, et);
+		ssa_fprintf(f, ", %d\n", instr->StructExtractValue.index);
 	} break;
 
 	case ssaInstr_Jump: {;
@@ -731,14 +741,14 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
 		ssa_fprintf(f, "\n");
 	} break;
 
-	case ssaInstr_CondJump: {;
+	case ssaInstr_If: {;
 		ssa_fprintf(f, "br ");
 		ssa_print_type(f, m, t_bool);
 		ssa_fprintf(f, " ");
-		ssa_print_value(f, m, instr->CondJump.cond, t_bool);
-		ssa_fprintf(f, ", ", instr->CondJump.cond->index);
-		ssa_fprintf(f, "label %%");   ssa_print_block_name(f, instr->CondJump.true_block);
-		ssa_fprintf(f, ", label %%"); ssa_print_block_name(f, instr->CondJump.false_block);
+		ssa_print_value(f, m, instr->If.cond, t_bool);
+		ssa_fprintf(f, ", ", instr->If.cond->index);
+		ssa_fprintf(f, "label %%");   ssa_print_block_name(f, instr->If.true_block);
+		ssa_fprintf(f, ", label %%"); ssa_print_block_name(f, instr->If.false_block);
 		ssa_fprintf(f, "\n");
 	} break;
 

+ 62 - 50
src/codegen/ssa.cpp

@@ -154,14 +154,14 @@ struct ssaProcedure {
 	SSA_INSTR_KIND(ZeroInit), \
 	SSA_INSTR_KIND(Store), \
 	SSA_INSTR_KIND(Load), \
+	SSA_INSTR_KIND(PtrOffset), \
 	SSA_INSTR_KIND(ArrayElementPtr), \
 	SSA_INSTR_KIND(StructElementPtr), \
-	SSA_INSTR_KIND(PtrOffset), \
-	SSA_INSTR_KIND(ExtractValue), \
-	SSA_INSTR_KIND(InsertValue), \
+	SSA_INSTR_KIND(ArrayExtractValue), \
+	SSA_INSTR_KIND(StructExtractValue), \
 	SSA_INSTR_KIND(Conv), \
 	SSA_INSTR_KIND(Jump), \
-	SSA_INSTR_KIND(CondJump), \
+	SSA_INSTR_KIND(If), \
 	SSA_INSTR_KIND(Return), \
 	SSA_INSTR_KIND(Select), \
 	SSA_INSTR_KIND(Phi), \
@@ -255,9 +255,13 @@ struct ssaInstr {
 		struct {
 			ssaValue *address;
 			Type *    result_type;
-			Type *    elem_type;
 			i32       index;
-		} ExtractValue;
+		} ArrayExtractValue;
+		struct {
+			ssaValue *address;
+			Type *    result_type;
+			i32       index;
+		} StructExtractValue;
 		struct {
 			ssaValue *value;
 			ssaValue *elem;
@@ -275,7 +279,7 @@ struct ssaInstr {
 			ssaValue *cond;
 			ssaBlock *true_block;
 			ssaBlock *false_block;
-		} CondJump;
+		} If;
 		struct {
 			ssaValue *value;
 		} Return;
@@ -547,10 +551,10 @@ Type *ssa_instr_type(ssaInstr *instr) {
 		return ssa_type(instr->PtrOffset.address);
 	case ssaInstr_Phi:
 		return instr->Phi.type;
-	case ssaInstr_ExtractValue:
-		return instr->ExtractValue.result_type;
-	case ssaInstr_InsertValue:
-		return ssa_type(instr->InsertValue.value);
+	case ssaInstr_ArrayExtractValue:
+		return instr->ArrayExtractValue.result_type;
+	case ssaInstr_StructExtractValue:
+		return instr->StructExtractValue.result_type;
 	case ssaInstr_BinaryOp:
 		return instr->BinaryOp.type;
 	case ssaInstr_Conv:
@@ -661,19 +665,19 @@ void ssa_add_operands(Array<ssaValue *> *ops, ssaInstr *i) {
 		array_add(ops, i->PtrOffset.address);
 		array_add(ops, i->PtrOffset.offset);
 		break;
-	case ssaInstr_ExtractValue:
-		array_add(ops, i->ExtractValue.address);
+	case ssaInstr_ArrayExtractValue:
+		array_add(ops, i->ArrayExtractValue.address);
 		break;
-	case ssaInstr_InsertValue:
-		array_add(ops, i->InsertValue.value);
+	case ssaInstr_StructExtractValue:
+		array_add(ops, i->StructExtractValue.address);
 		break;
 	case ssaInstr_Conv:
 		array_add(ops, i->Conv.value);
 		break;
 	case ssaInstr_Jump:
 		break;
-	case ssaInstr_CondJump:
-		array_add(ops, i->CondJump.cond);
+	case ssaInstr_If:
+		array_add(ops, i->If.cond);
 		break;
 	case ssaInstr_Return:
 		if (i->Return.value != NULL) {
@@ -904,27 +908,26 @@ ssaValue *ssa_make_instr_ptr_offset(ssaProcedure *p, ssaValue *address, ssaValue
 
 
 
-ssaValue *ssa_make_instr_extract_value(ssaProcedure *p, ssaValue *address, i32 index, Type *result_type) {
-	ssaValue *v = ssa_alloc_instr(p, ssaInstr_ExtractValue);
+ssaValue *ssa_make_instr_array_extract_value(ssaProcedure *p, ssaValue *address, i32 index) {
+	ssaValue *v = ssa_alloc_instr(p, ssaInstr_ArrayExtractValue);
 	ssaInstr *i = &v->Instr;
-	i->ExtractValue.address = address;
-	i->ExtractValue.index = index;
-	i->ExtractValue.result_type = result_type;
-	Type *et = ssa_type(address);
-	i->ExtractValue.elem_type = et;
+	i->ArrayExtractValue.address = address;
+	i->ArrayExtractValue.index = index;
+	Type *t = base_type(ssa_type(address));
+	GB_ASSERT(is_type_array(t));
+	i->ArrayExtractValue.result_type = t->Array.elem;
 	return v;
 }
-ssaValue *ssa_make_instr_insert_value(ssaProcedure *p, ssaValue *value, ssaValue *elem, i32 index) {
-	Type *t = ssa_type(value);
-	GB_ASSERT(is_type_array(t) || is_type_struct(t));
-	ssaValue *v = ssa_alloc_instr(p, ssaInstr_InsertValue);
-	v->Instr.InsertValue.value = value;
-	v->Instr.InsertValue.elem   = elem;
-	v->Instr.InsertValue.index  = index;
+
+ssaValue *ssa_make_instr_struct_extract_value(ssaProcedure *p, ssaValue *address, i32 index, Type *result_type) {
+	ssaValue *v = ssa_alloc_instr(p, ssaInstr_StructExtractValue);
+	ssaInstr *i = &v->Instr;
+	i->StructExtractValue.address = address;
+	i->StructExtractValue.index = index;
+	i->StructExtractValue.result_type = result_type;
 	return v;
 }
 
-
 ssaValue *ssa_make_instr_binary_op(ssaProcedure *p, TokenKind op, ssaValue *left, ssaValue *right, Type *type) {
 	ssaValue *v = ssa_alloc_instr(p, ssaInstr_BinaryOp);
 	ssaInstr *i = &v->Instr;
@@ -941,12 +944,12 @@ ssaValue *ssa_make_instr_jump(ssaProcedure *p, ssaBlock *block) {
 	i->Jump.block = block;
 	return v;
 }
-ssaValue *ssa_make_instr_cond_jump(ssaProcedure *p, ssaValue *cond, ssaBlock *true_block, ssaBlock *false_block) {
-	ssaValue *v = ssa_alloc_instr(p, ssaInstr_CondJump);
+ssaValue *ssa_make_instr_if(ssaProcedure *p, ssaValue *cond, ssaBlock *true_block, ssaBlock *false_block) {
+	ssaValue *v = ssa_alloc_instr(p, ssaInstr_If);
 	ssaInstr *i = &v->Instr;
-	i->CondJump.cond = cond;
-	i->CondJump.true_block = true_block;
-	i->CondJump.false_block = false_block;
+	i->If.cond = cond;
+	i->If.true_block = true_block;
+	i->If.false_block = false_block;
 	return v;
 }
 
@@ -1398,7 +1401,7 @@ void ssa_emit_if(ssaProcedure *proc, ssaValue *cond, ssaBlock *true_block, ssaBl
 	if (b == NULL) {
 		return;
 	}
-	ssa_emit(proc, ssa_make_instr_cond_jump(proc, cond, true_block, false_block));
+	ssa_emit(proc, ssa_make_instr_if(proc, cond, true_block, false_block));
 	ssa_add_edge(b, true_block);
 	ssa_add_edge(b, false_block);
 	proc->curr_block = NULL;
@@ -1607,7 +1610,7 @@ ssaValue *ssa_emit_comp(ssaProcedure *proc, TokenKind op_kind, ssaValue *left, s
 	return ssa_emit(proc, ssa_make_instr_binary_op(proc, op_kind, left, right, result));
 }
 
-ssaValue *ssa_emit_array_gep(ssaProcedure *proc, ssaValue *s, ssaValue *index) {
+ssaValue *ssa_emit_array_ep(ssaProcedure *proc, ssaValue *s, ssaValue *index) {
 	ssaValue *gep = NULL;
 	Type *st = base_type(type_deref(ssa_type(s)));
 	GB_ASSERT(is_type_array(st));
@@ -1617,8 +1620,8 @@ ssaValue *ssa_emit_array_gep(ssaProcedure *proc, ssaValue *s, ssaValue *index) {
 	return ssa_emit(proc, ssa_make_instr_array_element_ptr(proc, s, index));
 }
 
-ssaValue *ssa_emit_array_gep(ssaProcedure *proc, ssaValue *s, i32 index) {
-	return ssa_emit_array_gep(proc, s, ssa_make_const_i32(proc->module->allocator, index));
+ssaValue *ssa_emit_array_ep(ssaProcedure *proc, ssaValue *s, i32 index) {
+	return ssa_emit_array_ep(proc, s, ssa_make_const_i32(proc->module->allocator, index));
 }
 
 
@@ -1677,6 +1680,14 @@ ssaValue *ssa_emit_struct_ep(ssaProcedure *proc, ssaValue *s, i32 index) {
 }
 
 
+
+ssaValue *ssa_emit_array_ev(ssaProcedure *proc, ssaValue *s, i32 index) {
+	ssaValue *gep = NULL;
+	Type *st = base_type(ssa_type(s));
+	GB_ASSERT(is_type_array(st));
+	return ssa_emit(proc, ssa_make_instr_array_extract_value(proc, s, index));
+}
+
 ssaValue *ssa_emit_struct_ev(ssaProcedure *proc, ssaValue *s, i32 index) {
 	// NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
 
@@ -1728,7 +1739,7 @@ ssaValue *ssa_emit_struct_ev(ssaProcedure *proc, ssaValue *s, i32 index) {
 
 	GB_ASSERT(result_type != NULL);
 
-	return ssa_emit(proc, ssa_make_instr_extract_value(proc, s, index, result_type));
+	return ssa_emit(proc, ssa_make_instr_struct_extract_value(proc, s, index, result_type));
 }
 
 
@@ -1821,7 +1832,7 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) {
 		// TODO(bill): This is O(n) and can be very slow
 		for_array(i, info->type_info_map.entries){
 			auto *e = &info->type_info_map.entries[i];
-			Type *prev_type = cast(Type *)cast(uintptr)e->key.key;
+			Type *prev_type = cast(Type *)e->key.ptr;
 			if (are_types_identical(prev_type, type)) {
 				entry_index = e->value;
 				// NOTE(bill): Add it to the search map
@@ -1830,6 +1841,7 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) {
 			}
 		}
 	}
+
 	if (entry_index < 0) {
 		compiler_error("Type_Info for `%s` could not be found", type_to_string(type));
 	}
@@ -1843,7 +1855,7 @@ ssaValue *ssa_type_info(ssaProcedure *proc, Type *type) {
 
 	CheckerInfo *info = proc->module->info;
 	ssaValue *entry_index = ssa_make_const_i32(proc->module->allocator, ssa_type_info_index(info, type));
-	return ssa_emit_array_gep(proc, type_info_data, entry_index);
+	return ssa_emit_array_ep(proc, type_info_data, entry_index);
 }
 
 
@@ -1853,7 +1865,7 @@ ssaValue *ssa_type_info(ssaProcedure *proc, Type *type) {
 
 
 ssaValue *ssa_array_elem(ssaProcedure *proc, ssaValue *array) {
-	return ssa_emit_array_gep(proc, array, v_zero32);
+	return ssa_emit_array_ep(proc, array, v_zero32);
 }
 ssaValue *ssa_array_len(ssaProcedure *proc, ssaValue *array) {
 	Type *t = ssa_type(array);
@@ -2792,7 +2804,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 					Type *t = ssa_type(field_expr);
 					GB_ASSERT(t->kind != Type_Tuple);
 					ssaValue *ev = ssa_emit_conv(proc, field_expr, et);
-					ssaValue *gep = ssa_emit_array_gep(proc, v, i);
+					ssaValue *gep = ssa_emit_array_ep(proc, v, i);
 					ssa_emit_store(proc, gep, ev);
 				}
 			}
@@ -2806,7 +2818,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 				ssaValue *slice = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr));
 				GB_ASSERT(slice->kind == ssaValue_ConstantSlice);
 
-				ssaValue *data = ssa_emit_array_gep(proc, slice->ConstantSlice.backing_array, v_zero32);
+				ssaValue *data = ssa_emit_array_ep(proc, slice->ConstantSlice.backing_array, v_zero32);
 
 				for_array(i, cl->elems) {
 					AstNode *elem = cl->elems[i];
@@ -3245,11 +3257,11 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 				ssaValue *base_array = ssa_add_local_generated(proc, make_type_array(allocator, elem_type, slice_len));
 
 				for (isize i = type->param_count-1, j = 0; i < arg_count; i++, j++) {
-					ssaValue *addr = ssa_emit_array_gep(proc, base_array, j);
+					ssaValue *addr = ssa_emit_array_ep(proc, base_array, j);
 					ssa_emit_store(proc, addr, args[i]);
 				}
 
-				ssaValue *base_elem  = ssa_emit_array_gep(proc, base_array, 0);
+				ssaValue *base_elem  = ssa_emit_array_ep(proc, base_array, 0);
 				ssaValue *slice_elem = ssa_emit_struct_ep(proc, slice,      0);
 				ssa_emit_store(proc, slice_elem, base_elem);
 				ssaValue *len = ssa_make_const_int(allocator, slice_len);
@@ -3492,7 +3504,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
 				}
 			}
 			ssaValue *index = ssa_emit_conv(proc, ssa_build_expr(proc, ie->index), t_int);
-			ssaValue *elem = ssa_emit_array_gep(proc, array, index);
+			ssaValue *elem = ssa_emit_array_ep(proc, array, index);
 			ssaValue *len = ssa_make_const_int(a, t->Vector.count);
 			ssa_array_bounds_check(proc, ast_node_token(ie->index), index, len);
 			return ssa_make_addr(elem, expr);

+ 5 - 1
src/common.cpp

@@ -5,13 +5,13 @@ gbAllocator heap_allocator(void) {
 	return gb_heap_allocator();
 }
 
-
 #include "string.cpp"
 #include "array.cpp"
 
 gb_global String global_module_path = {};
 gb_global b32 global_module_path_set = false;
 
+
 String get_module_dir() {
 	if (global_module_path_set) {
 		return global_module_path;
@@ -90,6 +90,7 @@ struct BlockTimer {
 enum HashKeyKind {
 	HashKey_Default,
 	HashKey_String,
+	HashKey_Pointer,
 };
 
 struct HashKey {
@@ -97,6 +98,7 @@ struct HashKey {
 	u64         key;
 	union {
 		String string; // if String, s.len > 0
+		void * ptr;
 	};
 };
 
@@ -118,6 +120,8 @@ gb_inline HashKey hash_string(String s) {
 gb_inline HashKey hash_pointer(void *ptr) {
 	HashKey h = {};
 	h.key = cast(u64)cast(uintptr)ptr;
+	h.ptr = ptr;
+	h.kind = HashKey_Default;
 	return h;
 }