Browse Source

Separate ssa_struct_gep and ssa_array_gep procedures

Ginger Bill 8 years ago
parent
commit
bd5d095de4

+ 1 - 1
code/demo.odin

@@ -1,7 +1,7 @@
 #import "fmt.odin"
 #import "fmt.odin"
 
 
 main :: proc() {
 main :: proc() {
-
+	fmt.println("Hellope!")
 }
 }
 
 
 
 

+ 1 - 1
src/array.cpp

@@ -18,7 +18,7 @@ struct Array {
 	}
 	}
 };
 };
 
 
-template <typename T> void     array_init        (Array<T> *array, gbAllocator a, isize init_capacity = 8);
+template <typename T> void     array_init        (Array<T> *array, gbAllocator a, isize init_capacity = ARRAY_GROW_FORMULA(0));
 template <typename T> Array<T> array_make        (T *data, isize count, isize capacity);
 template <typename T> Array<T> array_make        (T *data, isize count, isize capacity);
 template <typename T> void     array_free        (Array<T> *array);
 template <typename T> void     array_free        (Array<T> *array);
 template <typename T> void     array_add         (Array<T> *array, T const &t);
 template <typename T> void     array_add         (Array<T> *array, T const &t);

+ 19 - 15
src/checker/checker.cpp

@@ -246,7 +246,7 @@ CycleChecker *cycle_checker_add(CycleChecker *cc, Entity *e) {
 		return NULL;
 		return NULL;
 	}
 	}
 	if (cc->path.data == NULL) {
 	if (cc->path.data == NULL) {
-		array_init(&cc->path, gb_heap_allocator());
+		array_init(&cc->path, heap_allocator());
 	}
 	}
 	GB_ASSERT(e != NULL && e->kind == Entity_TypeName);
 	GB_ASSERT(e != NULL && e->kind == Entity_TypeName);
 	array_add(&cc->path, e);
 	array_add(&cc->path, e);
@@ -262,7 +262,7 @@ void cycle_checker_destroy(CycleChecker *cc) {
 
 
 void init_declaration_info(DeclInfo *d, Scope *scope) {
 void init_declaration_info(DeclInfo *d, Scope *scope) {
 	d->scope = scope;
 	d->scope = scope;
-	map_init(&d->deps, gb_heap_allocator());
+	map_init(&d->deps, heap_allocator());
 }
 }
 
 
 DeclInfo *make_declaration_info(gbAllocator a, Scope *scope) {
 DeclInfo *make_declaration_info(gbAllocator a, Scope *scope) {
@@ -296,10 +296,10 @@ b32 decl_info_has_init(DeclInfo *d) {
 Scope *make_scope(Scope *parent, gbAllocator allocator) {
 Scope *make_scope(Scope *parent, gbAllocator allocator) {
 	Scope *s = gb_alloc_item(allocator, Scope);
 	Scope *s = gb_alloc_item(allocator, Scope);
 	s->parent = parent;
 	s->parent = parent;
-	map_init(&s->elements,   gb_heap_allocator());
-	map_init(&s->implicit,   gb_heap_allocator());
-	array_init(&s->shared,   gb_heap_allocator());
-	array_init(&s->imported, gb_heap_allocator());
+	map_init(&s->elements,   heap_allocator());
+	map_init(&s->implicit,   heap_allocator());
+	array_init(&s->shared,   heap_allocator());
+	array_init(&s->imported, heap_allocator());
 
 
 	if (parent != NULL && parent != universal_scope) {
 	if (parent != NULL && parent != universal_scope) {
 		DLIST_APPEND(parent->first_child, parent->last_child, s);
 		DLIST_APPEND(parent->first_child, parent->last_child, s);
@@ -506,7 +506,7 @@ void add_global_constant(gbAllocator a, String name, Type *type, ExactValue valu
 
 
 void init_universal_scope(void) {
 void init_universal_scope(void) {
 	// NOTE(bill): No need to free these
 	// NOTE(bill): No need to free these
-	gbAllocator a = gb_heap_allocator();
+	gbAllocator a = heap_allocator();
 	universal_scope = make_scope(NULL, a);
 	universal_scope = make_scope(NULL, a);
 
 
 // Types
 // Types
@@ -536,7 +536,7 @@ void init_universal_scope(void) {
 
 
 
 
 void init_checker_info(CheckerInfo *i) {
 void init_checker_info(CheckerInfo *i) {
-	gbAllocator a = gb_heap_allocator();
+	gbAllocator a = heap_allocator();
 	map_init(&i->types,           a);
 	map_init(&i->types,           a);
 	map_init(&i->definitions,     a);
 	map_init(&i->definitions,     a);
 	map_init(&i->uses,            a);
 	map_init(&i->uses,            a);
@@ -566,7 +566,7 @@ void destroy_checker_info(CheckerInfo *i) {
 void init_checker(Checker *c, Parser *parser, BaseTypeSizes sizes) {
 void init_checker(Checker *c, Parser *parser, BaseTypeSizes sizes) {
 	PROF_PROC();
 	PROF_PROC();
 
 
-	gbAllocator a = gb_heap_allocator();
+	gbAllocator a = heap_allocator();
 
 
 	c->parser = parser;
 	c->parser = parser;
 	init_checker_info(&c->info);
 	init_checker_info(&c->info);
@@ -576,7 +576,7 @@ void init_checker(Checker *c, Parser *parser, BaseTypeSizes sizes) {
 	array_init(&c->procs, a);
 	array_init(&c->procs, a);
 
 
 	// NOTE(bill): Is this big enough or too small?
 	// NOTE(bill): Is this big enough or too small?
-	isize item_size = gb_max(gb_max(gb_size_of(Entity), gb_size_of(Type)), gb_size_of(Scope));
+	isize item_size = gb_max3(gb_size_of(Entity), gb_size_of(Type), gb_size_of(Scope));
 	isize total_token_count = 0;
 	isize total_token_count = 0;
 	for_array(i, c->parser->files) {
 	for_array(i, c->parser->files) {
 		AstFile *f = &c->parser->files[i];
 		AstFile *f = &c->parser->files[i];
@@ -888,7 +888,7 @@ void add_dependency_to_map(Map<Entity *> *map, CheckerInfo *info, Entity *node)
 
 
 Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
 Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
 	Map<Entity *> map = {}; // Key: Entity *
 	Map<Entity *> map = {}; // Key: Entity *
-	map_init(&map, gb_heap_allocator());
+	map_init(&map, heap_allocator());
 
 
 	for_array(i, info->entities.entries) {
 	for_array(i, info->entities.entries) {
 		auto *entry = &info->entities.entries[i];
 		auto *entry = &info->entities.entries[i];
@@ -913,6 +913,10 @@ Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start)
 void init_preload_types(Checker *c) {
 void init_preload_types(Checker *c) {
 	PROF_PROC();
 	PROF_PROC();
 
 
+	if (t_u8_ptr == NULL) {
+		t_u8_ptr = make_type_pointer(c->allocator, t_u8);
+	}
+
 	if (t_type_info == NULL) {
 	if (t_type_info == NULL) {
 		Entity *e = current_scope_lookup_entity(c->global_scope, make_string("Type_Info"));
 		Entity *e = current_scope_lookup_entity(c->global_scope, make_string("Type_Info"));
 		if (e == NULL) {
 		if (e == NULL) {
@@ -983,11 +987,11 @@ void add_implicit_value(Checker *c, ImplicitValueId id, String name, String back
 
 
 void check_parsed_files(Checker *c) {
 void check_parsed_files(Checker *c) {
 	Array<AstNode *> import_decls;
 	Array<AstNode *> import_decls;
-	array_init(&import_decls, gb_heap_allocator());
+	array_init(&import_decls, heap_allocator());
 	defer (array_free(&import_decls));
 	defer (array_free(&import_decls));
 
 
 	Map<Scope *> file_scopes; // Key: String (fullpath)
 	Map<Scope *> file_scopes; // Key: String (fullpath)
-	map_init(&file_scopes, gb_heap_allocator());
+	map_init(&file_scopes, heap_allocator());
 	defer (map_destroy(&file_scopes));
 	defer (map_destroy(&file_scopes));
 
 
 	// Map full filepaths to Scopes
 	// Map full filepaths to Scopes
@@ -1069,7 +1073,7 @@ void check_parsed_files(Checker *c) {
 				Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
 				Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
 				DeclInfo *di = NULL;
 				DeclInfo *di = NULL;
 				if (vd->values.count > 0) {
 				if (vd->values.count > 0) {
-					di = make_declaration_info(gb_heap_allocator(), file_scope);
+					di = make_declaration_info(heap_allocator(), file_scope);
 					di->entities = entities;
 					di->entities = entities;
 					di->entity_count = entity_count;
 					di->entity_count = entity_count;
 					di->type_expr = vd->type;
 					di->type_expr = vd->type;
@@ -1089,7 +1093,7 @@ void check_parsed_files(Checker *c) {
 					DeclInfo *d = di;
 					DeclInfo *d = di;
 					if (d == NULL) {
 					if (d == NULL) {
 						AstNode *init_expr = value;
 						AstNode *init_expr = value;
-						d = make_declaration_info(gb_heap_allocator(), file_scope);
+						d = make_declaration_info(heap_allocator(), file_scope);
 						d->type_expr = vd->type;
 						d->type_expr = vd->type;
 						d->init_expr = init_expr;
 						d->init_expr = init_expr;
 						d->var_decl_tags = vd->tags;
 						d->var_decl_tags = vd->tags;

+ 3 - 3
src/checker/expr.cpp

@@ -249,7 +249,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
 	PROF_PROC();
 	PROF_PROC();
 
 
 	Map<Entity *> entity_map = {};
 	Map<Entity *> entity_map = {};
-	map_init(&entity_map, gb_heap_allocator());
+	map_init(&entity_map, heap_allocator());
 	defer (map_destroy(&entity_map));
 	defer (map_destroy(&entity_map));
 
 
 	isize other_field_index = 0;
 	isize other_field_index = 0;
@@ -662,7 +662,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
 	ast_node(et, EnumType, node);
 	ast_node(et, EnumType, node);
 
 
 	Map<Entity *> entity_map = {};
 	Map<Entity *> entity_map = {};
-	map_init(&entity_map, gb_heap_allocator());
+	map_init(&entity_map, heap_allocator());
 	defer (map_destroy(&entity_map));
 	defer (map_destroy(&entity_map));
 
 
 	Type *base_type = t_int;
 	Type *base_type = t_int;
@@ -4458,5 +4458,5 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 }
 }
 
 
 gbString expr_to_string(AstNode *expression) {
 gbString expr_to_string(AstNode *expression) {
-	return write_expr_to_string(gb_string_make(gb_heap_allocator(), ""), expression);
+	return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression);
 }
 }

+ 2 - 2
src/checker/stmt.cpp

@@ -1180,7 +1180,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
 		};
 		};
 
 
 		Map<TypeAndToken> seen = {}; // Multimap
 		Map<TypeAndToken> seen = {}; // Multimap
-		map_init(&seen, gb_heap_allocator());
+		map_init(&seen, heap_allocator());
 		defer (map_destroy(&seen));
 		defer (map_destroy(&seen));
 		for_array(i, bs->stmts) {
 		for_array(i, bs->stmts) {
 			AstNode *stmt = bs->stmts[i];
 			AstNode *stmt = bs->stmts[i];
@@ -1319,7 +1319,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
 
 
 
 
 		Map<b32> seen = {};
 		Map<b32> seen = {};
-		map_init(&seen, gb_heap_allocator());
+		map_init(&seen, heap_allocator());
 		defer (map_destroy(&seen));
 		defer (map_destroy(&seen));
 
 
 
 

+ 4 - 2
src/checker/type.cpp

@@ -159,7 +159,7 @@ struct Type {
 	};
 	};
 };
 };
 
 
-gbString type_to_string(Type *type, gbAllocator a = gb_heap_allocator());
+gbString type_to_string(Type *type, gbAllocator a = heap_allocator());
 
 
 Type *base_type(Type *t) {
 Type *base_type(Type *t) {
 	for (;;) {
 	for (;;) {
@@ -359,6 +359,8 @@ gb_global Type *t_byte            = &basic_type_aliases[0];
 gb_global Type *t_rune            = &basic_type_aliases[1];
 gb_global Type *t_rune            = &basic_type_aliases[1];
 
 
 
 
+gb_global Type *t_u8_ptr = NULL;
+
 gb_global Type *t_type_info            = NULL;
 gb_global Type *t_type_info            = NULL;
 gb_global Type *t_type_info_ptr        = NULL;
 gb_global Type *t_type_info_ptr        = NULL;
 gb_global Type *t_type_info_member     = NULL;
 gb_global Type *t_type_info_member     = NULL;
@@ -791,7 +793,7 @@ void selection_add_index(Selection *s, isize index) {
 	// IMPORTANT NOTE(bill): this requires a stretchy buffer/dynamic array so it requires some form
 	// IMPORTANT NOTE(bill): this requires a stretchy buffer/dynamic array so it requires some form
 	// of heap allocation
 	// of heap allocation
 	if (s->index.data == NULL) {
 	if (s->index.data == NULL) {
-		array_init(&s->index, gb_heap_allocator());
+		array_init(&s->index, heap_allocator());
 	}
 	}
 	array_add(&s->index, index);
 	array_add(&s->index, index);
 }
 }

+ 62 - 63
src/codegen/codegen.cpp

@@ -301,15 +301,14 @@ void ssa_gen_tree(ssaGen *s) {
 			Type *t_string_slice_ptr     = make_type_pointer(a, make_type_slice(a, t_string));
 			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 * {
 			auto get_type_info_ptr = [](ssaProcedure *proc, ssaValue *type_info_data, Type *type) -> ssaValue * {
-				return ssa_emit_struct_gep(proc, type_info_data,
-				                           ssa_type_info_index(proc->module->info, type),
-				                           t_type_info_ptr);
+				return ssa_emit_array_gep(proc, type_info_data,
+				                          ssa_type_info_index(proc->module->info, type));
 			};
 			};
 
 
 			isize type_info_member_index = 0;
 			isize type_info_member_index = 0;
 
 
 			auto type_info_member_offset = [](ssaProcedure *proc, ssaValue *data, isize count, isize *index) -> ssaValue * {
 			auto type_info_member_offset = [](ssaProcedure *proc, ssaValue *data, isize count, isize *index) -> ssaValue * {
-				ssaValue *offset = ssa_emit_struct_gep(proc, data, *index, t_type_info_member_ptr);
+				ssaValue *offset = ssa_emit_array_gep(proc, data, *index);
 				*index += count;
 				*index += count;
 				return offset;
 				return offset;
 			};
 			};
@@ -337,8 +336,8 @@ void ssa_gen_tree(ssaGen *s) {
 
 
 					ssaValue *gep  = get_type_info_ptr(proc, type_info_data, t->Named.base);
 					ssaValue *gep  = get_type_info_ptr(proc, type_info_data, t->Named.base);
 
 
-					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero,  t_string_ptr), name);
-					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_one32, t_type_info_ptr), gep);
+					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 0), name);
+					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 1), gep);
 				} break;
 				} break;
 
 
 				case Type_Basic:
 				case Type_Basic:
@@ -360,15 +359,15 @@ void ssa_gen_tree(ssaGen *s) {
 						b32 is_unsigned = (t->Basic.flags & BasicFlag_Unsigned) != 0;
 						b32 is_unsigned = (t->Basic.flags & BasicFlag_Unsigned) != 0;
 						ssaValue *bits = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
 						ssaValue *bits = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
 						ssaValue *is_signed = ssa_make_const_bool(a, !is_unsigned);
 						ssaValue *is_signed = ssa_make_const_bool(a, !is_unsigned);
-						ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_int_ptr),  bits);
-						ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_one32,  t_bool_ptr), is_signed);
+						ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 0), bits);
+						ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 1), is_signed);
 					} break;
 					} break;
 
 
 					case Basic_f32:
 					case Basic_f32:
 					case Basic_f64: {
 					case Basic_f64: {
 						tag = ssa_add_local_generated(proc, t_type_info_float);
 						tag = ssa_add_local_generated(proc, t_type_info_float);
 						ssaValue *bits = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
 						ssaValue *bits = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
-						ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_int_ptr), bits);
+						ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 0), bits);
 					} break;
 					} break;
 
 
 					case Basic_rawptr:
 					case Basic_rawptr:
@@ -388,46 +387,46 @@ void ssa_gen_tree(ssaGen *s) {
 				case Type_Pointer: {
 				case Type_Pointer: {
 					tag = ssa_add_local_generated(proc, t_type_info_pointer);
 					tag = ssa_add_local_generated(proc, t_type_info_pointer);
 					ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Pointer.elem);
 					ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Pointer.elem);
-					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr), gep);
+					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 0), gep);
 				} break;
 				} break;
 				case Type_Maybe: {
 				case Type_Maybe: {
 					tag = ssa_add_local_generated(proc, t_type_info_maybe);
 					tag = ssa_add_local_generated(proc, t_type_info_maybe);
 					ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Maybe.elem);
 					ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Maybe.elem);
-					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr), gep);
+					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 0), gep);
 				} break;
 				} break;
 				case Type_Array: {
 				case Type_Array: {
 					tag = ssa_add_local_generated(proc, t_type_info_array);
 					tag = ssa_add_local_generated(proc, t_type_info_array);
 					ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Array.elem);
 					ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Array.elem);
-					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr), gep);
+					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 0), gep);
 
 
 					isize ez = type_size_of(m->sizes, a, t->Array.elem);
 					isize ez = type_size_of(m->sizes, a, t->Array.elem);
-					ssaValue *elem_size = ssa_emit_struct_gep(proc, tag, v_one32, t_int_ptr);
+					ssaValue *elem_size = ssa_emit_struct_gep(proc, tag, 1);
 					ssa_emit_store(proc, elem_size, ssa_make_const_int(a, ez));
 					ssa_emit_store(proc, elem_size, ssa_make_const_int(a, ez));
 
 
-					ssaValue *count = ssa_emit_struct_gep(proc, tag, v_two32, t_int_ptr);
+					ssaValue *count = ssa_emit_struct_gep(proc, tag, 2);
 					ssa_emit_store(proc, count, ssa_make_const_int(a, t->Array.count));
 					ssa_emit_store(proc, count, ssa_make_const_int(a, t->Array.count));
 
 
 				} break;
 				} break;
 				case Type_Slice: {
 				case Type_Slice: {
 					tag = ssa_add_local_generated(proc, t_type_info_slice);
 					tag = ssa_add_local_generated(proc, t_type_info_slice);
 					ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Slice.elem);
 					ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Slice.elem);
-					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr), gep);
+					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 0), gep);
 
 
 					isize ez = type_size_of(m->sizes, a, t->Slice.elem);
 					isize ez = type_size_of(m->sizes, a, t->Slice.elem);
-					ssaValue *elem_size = ssa_emit_struct_gep(proc, tag, v_one32, t_int_ptr);
+					ssaValue *elem_size = ssa_emit_struct_gep(proc, tag, 1);
 					ssa_emit_store(proc, elem_size, ssa_make_const_int(a, ez));
 					ssa_emit_store(proc, elem_size, ssa_make_const_int(a, ez));
 
 
 				} break;
 				} break;
 				case Type_Vector: {
 				case Type_Vector: {
 					tag = ssa_add_local_generated(proc, t_type_info_vector);
 					tag = ssa_add_local_generated(proc, t_type_info_vector);
 					ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Vector.elem);
 					ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Vector.elem);
-					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr), gep);
+					ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 0), gep);
 
 
 					isize ez = type_size_of(m->sizes, a, t->Vector.elem);
 					isize ez = type_size_of(m->sizes, a, t->Vector.elem);
-					ssaValue *elem_size = ssa_emit_struct_gep(proc, tag, v_one32, t_int_ptr);
+					ssaValue *elem_size = ssa_emit_struct_gep(proc, tag, 1);
 					ssa_emit_store(proc, elem_size, ssa_make_const_int(a, ez));
 					ssa_emit_store(proc, elem_size, ssa_make_const_int(a, ez));
 
 
-					ssaValue *count = ssa_emit_struct_gep(proc, tag, v_two32, t_int_ptr);
+					ssaValue *count = ssa_emit_struct_gep(proc, tag, 2);
 					ssa_emit_store(proc, count, ssa_make_const_int(a, t->Vector.count));
 					ssa_emit_store(proc, count, ssa_make_const_int(a, t->Vector.count));
 
 
 				} break;
 				} break;
@@ -441,10 +440,10 @@ void ssa_gen_tree(ssaGen *s) {
 							ssaValue *ordered = ssa_make_const_bool(a, t->Record.struct_is_ordered);
 							ssaValue *ordered = ssa_make_const_bool(a, t->Record.struct_is_ordered);
 							ssaValue *size    = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
 							ssaValue *size    = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
 							ssaValue *align   = ssa_make_const_int(a, type_align_of(m->sizes, a, t));
 							ssaValue *align   = ssa_make_const_int(a, type_align_of(m->sizes, a, t));
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 1, t_int_ptr),  size);
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 2, t_int_ptr),  align);
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 3, t_bool_ptr), packed);
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 4, t_bool_ptr), ordered);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 1), size);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 2), align);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 3), packed);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 4), ordered);
 						}
 						}
 
 
 						ssaValue *memory = type_info_member_offset(proc, type_info_member_data, t->Record.field_count, &type_info_member_index);
 						ssaValue *memory = type_info_member_offset(proc, type_info_member_data, t->Record.field_count, &type_info_member_index);
@@ -458,9 +457,9 @@ void ssa_gen_tree(ssaGen *s) {
 							GB_ASSERT(f->kind == Entity_Variable && f->Variable.field);
 							GB_ASSERT(f->kind == Entity_Variable && f->Variable.field);
 
 
 							ssaValue *field     = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, source_index));
 							ssaValue *field     = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, source_index));
-							ssaValue *name      = ssa_emit_struct_gep(proc, field, v_zero32, t_string_ptr);
-							ssaValue *type_info = ssa_emit_struct_gep(proc, field, v_one32, t_type_info_ptr_ptr);
-							ssaValue *offset    = ssa_emit_struct_gep(proc, field, v_two32, t_int_ptr);
+							ssaValue *name      = ssa_emit_struct_gep(proc, field, 0);
+							ssaValue *type_info = ssa_emit_struct_gep(proc, field, 1);
+							ssaValue *offset    = ssa_emit_struct_gep(proc, field, 2);
 
 
 							if (f->token.string.len > 0) {
 							if (f->token.string.len > 0) {
 								ssa_emit_store(proc, name, ssa_emit_global_string(proc, f->token.string));
 								ssa_emit_store(proc, name, ssa_emit_global_string(proc, f->token.string));
@@ -471,12 +470,12 @@ void ssa_gen_tree(ssaGen *s) {
 
 
 						Type *slice_type = make_type_slice(a, t_type_info_member);
 						Type *slice_type = make_type_slice(a, t_type_info_member);
 						Type *slice_type_ptr = make_type_pointer(a, slice_type);
 						Type *slice_type_ptr = make_type_pointer(a, slice_type);
-						ssaValue *slice = ssa_emit_struct_gep(proc, tag, v_zero32, slice_type_ptr);
+						ssaValue *slice = ssa_emit_struct_gep(proc, tag, 0);
 						ssaValue *field_count = ssa_make_const_int(a, t->Record.field_count);
 						ssaValue *field_count = ssa_make_const_int(a, t->Record.field_count);
 
 
-						ssaValue *elem = ssa_emit_struct_gep(proc, slice, v_zero32, make_type_pointer(a, t_type_info_member_ptr));
-						ssaValue *len  = ssa_emit_struct_gep(proc, slice, v_one32,  make_type_pointer(a, t_int_ptr));
-						ssaValue *cap  = ssa_emit_struct_gep(proc, slice, v_two32,  make_type_pointer(a, t_int_ptr));
+						ssaValue *elem = ssa_emit_struct_gep(proc, slice, 0);
+						ssaValue *len  = ssa_emit_struct_gep(proc, slice, 1);
+						ssaValue *cap  = ssa_emit_struct_gep(proc, slice, 2);
 
 
 						ssa_emit_store(proc, elem, memory);
 						ssa_emit_store(proc, elem, memory);
 						ssa_emit_store(proc, len, field_count);
 						ssa_emit_store(proc, len, field_count);
@@ -487,8 +486,8 @@ void ssa_gen_tree(ssaGen *s) {
 						{
 						{
 							ssaValue *size    = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
 							ssaValue *size    = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
 							ssaValue *align   = ssa_make_const_int(a, type_align_of(m->sizes, a, t));
 							ssaValue *align   = ssa_make_const_int(a, type_align_of(m->sizes, a, t));
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 1, t_int_ptr),  size);
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 2, t_int_ptr),  align);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 1),  size);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 2),  align);
 						}
 						}
 						break;
 						break;
 					case TypeRecord_RawUnion: {
 					case TypeRecord_RawUnion: {
@@ -496,17 +495,17 @@ void ssa_gen_tree(ssaGen *s) {
 						{
 						{
 							ssaValue *size    = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
 							ssaValue *size    = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
 							ssaValue *align   = ssa_make_const_int(a, type_align_of(m->sizes, a, t));
 							ssaValue *align   = ssa_make_const_int(a, type_align_of(m->sizes, a, t));
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 1, t_int_ptr),  size);
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 2, t_int_ptr),  align);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 1),  size);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 2),  align);
 						}
 						}
 
 
 						ssaValue *memory = type_info_member_offset(proc, type_info_member_data, t->Record.field_count, &type_info_member_index);
 						ssaValue *memory = type_info_member_offset(proc, type_info_member_data, t->Record.field_count, &type_info_member_index);
 
 
 						for (isize i = 0; i < t->Record.field_count; i++) {
 						for (isize i = 0; i < t->Record.field_count; i++) {
 							ssaValue *field     = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, i));
 							ssaValue *field     = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, i));
-							ssaValue *name      = ssa_emit_struct_gep(proc, field, v_zero32, t_string_ptr);
-							ssaValue *type_info = ssa_emit_struct_gep(proc, field, v_one32, t_type_info_ptr_ptr);
-							ssaValue *offset    = ssa_emit_struct_gep(proc, field, v_two32, t_int_ptr);
+							ssaValue *name      = ssa_emit_struct_gep(proc, field, 0);
+							ssaValue *type_info = ssa_emit_struct_gep(proc, field, 1);
+							ssaValue *offset    = ssa_emit_struct_gep(proc, field, 2);
 
 
 							Entity *f = t->Record.fields[i];
 							Entity *f = t->Record.fields[i];
 							ssaValue *tip = get_type_info_ptr(proc, type_info_data, f->type);
 							ssaValue *tip = get_type_info_ptr(proc, type_info_data, f->type);
@@ -520,12 +519,12 @@ void ssa_gen_tree(ssaGen *s) {
 
 
 						Type *slice_type = make_type_slice(a, t_type_info_member);
 						Type *slice_type = make_type_slice(a, t_type_info_member);
 						Type *slice_type_ptr = make_type_pointer(a, slice_type);
 						Type *slice_type_ptr = make_type_pointer(a, slice_type);
-						ssaValue *slice = ssa_emit_struct_gep(proc, tag, v_zero32, slice_type_ptr);
+						ssaValue *slice = ssa_emit_struct_gep(proc, tag, 0);
 						ssaValue *field_count = ssa_make_const_int(a, t->Record.field_count);
 						ssaValue *field_count = ssa_make_const_int(a, t->Record.field_count);
 
 
-						ssaValue *elem = ssa_emit_struct_gep(proc, slice, v_zero32, make_type_pointer(a, t_type_info_member_ptr));
-						ssaValue *len  = ssa_emit_struct_gep(proc, slice, v_one32,  make_type_pointer(a, t_int_ptr));
-						ssaValue *cap  = ssa_emit_struct_gep(proc, slice, v_two32,  make_type_pointer(a, t_int_ptr));
+						ssaValue *elem = ssa_emit_struct_gep(proc, slice, 0);
+						ssaValue *len  = ssa_emit_struct_gep(proc, slice, 1);
+						ssaValue *cap  = ssa_emit_struct_gep(proc, slice, 2);
 
 
 						ssa_emit_store(proc, elem, memory);
 						ssa_emit_store(proc, elem, memory);
 						ssa_emit_store(proc, len, field_count);
 						ssa_emit_store(proc, len, field_count);
@@ -537,7 +536,7 @@ void ssa_gen_tree(ssaGen *s) {
 						if (enum_base == NULL) {
 						if (enum_base == NULL) {
 							enum_base = t_int;
 							enum_base = t_int;
 						}
 						}
-						ssaValue *base = ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr);
+						ssaValue *base = ssa_emit_struct_gep(proc, tag, 0);
 						ssa_emit_store(proc, base, get_type_info_ptr(proc, type_info_data, enum_base));
 						ssa_emit_store(proc, base, get_type_info_ptr(proc, type_info_data, enum_base));
 
 
 						if (t->Record.other_field_count > 0) {
 						if (t->Record.other_field_count > 0) {
@@ -577,8 +576,8 @@ void ssa_gen_tree(ssaGen *s) {
 							}
 							}
 
 
 							for (isize i = 0; i < count; i++) {
 							for (isize i = 0; i < count; i++) {
-								ssaValue *value_gep = ssa_emit_struct_gep(proc, value_array, i, t_i64_ptr);
-								ssaValue *name_gep  = ssa_emit_struct_gep(proc, name_array, i, t_string_ptr);
+								ssaValue *value_gep = ssa_emit_struct_gep(proc, value_array, i);
+								ssaValue *name_gep  = ssa_emit_struct_gep(proc, name_array, i);
 
 
 								ssa_emit_store(proc, value_gep, ssa_make_const_i64(a, fields[i]->Constant.value.value_integer));
 								ssa_emit_store(proc, value_gep, ssa_make_const_i64(a, fields[i]->Constant.value.value_integer));
 								ssa_emit_store(proc, name_gep,  ssa_emit_global_string(proc, fields[i]->token.string));
 								ssa_emit_store(proc, name_gep,  ssa_emit_global_string(proc, fields[i]->token.string));
@@ -587,18 +586,18 @@ void ssa_gen_tree(ssaGen *s) {
 							ssaValue *v_count = ssa_make_const_int(a, count);
 							ssaValue *v_count = ssa_make_const_int(a, count);
 
 
 
 
-							ssaValue *values = ssa_emit_struct_gep(proc, tag, v_one32, t_i64_slice_ptr);
-							ssaValue *names  = ssa_emit_struct_gep(proc, tag, v_two32, t_string_slice_ptr);
+							ssaValue *values = ssa_emit_struct_gep(proc, tag, 1);
+							ssaValue *names  = ssa_emit_struct_gep(proc, tag, 2);
 							ssaValue *value_slice = ssa_add_local_generated(proc, type_deref(t_i64_slice_ptr));
 							ssaValue *value_slice = ssa_add_local_generated(proc, type_deref(t_i64_slice_ptr));
 							ssaValue *name_slice  = ssa_add_local_generated(proc, type_deref(t_string_slice_ptr));
 							ssaValue *name_slice  = ssa_add_local_generated(proc, type_deref(t_string_slice_ptr));
 
 
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, v_zero32, t_i64_ptr), ssa_array_elem(proc, value_array));
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, v_one32, t_int_ptr), v_count);
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, v_two32, t_int_ptr), v_count);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, 0), ssa_array_elem(proc, value_array));
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, 1), v_count);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, 2), v_count);
 
 
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, v_zero32, t_string_ptr), ssa_array_elem(proc, name_array));
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, v_one32, t_int_ptr), v_count);
-							ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, v_two32, t_int_ptr), v_count);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, 0), ssa_array_elem(proc, name_array));
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, 1), v_count);
+							ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, 2), v_count);
 
 
 							ssa_emit_store(proc, values, ssa_emit_load(proc, value_slice));
 							ssa_emit_store(proc, values, ssa_emit_load(proc, value_slice));
 							ssa_emit_store(proc, names,  ssa_emit_load(proc, name_slice));
 							ssa_emit_store(proc, names,  ssa_emit_load(proc, name_slice));
@@ -612,15 +611,15 @@ void ssa_gen_tree(ssaGen *s) {
 
 
 					{
 					{
 						ssaValue *align = ssa_make_const_int(a, type_align_of(m->sizes, a, t));
 						ssaValue *align = ssa_make_const_int(a, type_align_of(m->sizes, a, t));
-						ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 2, t_int_ptr), align);
+						ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, 2), align);
 					}
 					}
 
 
 					ssaValue *memory = type_info_member_offset(proc, type_info_member_data, t->Tuple.variable_count, &type_info_member_index);
 					ssaValue *memory = type_info_member_offset(proc, type_info_member_data, t->Tuple.variable_count, &type_info_member_index);
 
 
 					for (isize i = 0; i < t->Tuple.variable_count; i++) {
 					for (isize i = 0; i < t->Tuple.variable_count; i++) {
 						ssaValue *field     = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, i));
 						ssaValue *field     = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, i));
-						ssaValue *name      = ssa_emit_struct_gep(proc, field, v_zero32, t_string_ptr);
-						ssaValue *type_info = ssa_emit_struct_gep(proc, field, v_one32, t_type_info_ptr_ptr);
+						ssaValue *name      = ssa_emit_struct_gep(proc, field, 0);
+						ssaValue *type_info = ssa_emit_struct_gep(proc, field, 1);
 						// NOTE(bill): offset is not used for tuples
 						// NOTE(bill): offset is not used for tuples
 
 
 						Entity *f = t->Tuple.variables[i];
 						Entity *f = t->Tuple.variables[i];
@@ -634,12 +633,12 @@ void ssa_gen_tree(ssaGen *s) {
 
 
 					Type *slice_type = make_type_slice(a, t_type_info_member);
 					Type *slice_type = make_type_slice(a, t_type_info_member);
 					Type *slice_type_ptr = make_type_pointer(a, slice_type);
 					Type *slice_type_ptr = make_type_pointer(a, slice_type);
-					ssaValue *slice = ssa_emit_struct_gep(proc, tag, v_zero32, slice_type_ptr);
+					ssaValue *slice = ssa_emit_struct_gep(proc, tag, 0);
 					ssaValue *variable_count = ssa_make_const_int(a, t->Tuple.variable_count);
 					ssaValue *variable_count = ssa_make_const_int(a, t->Tuple.variable_count);
 
 
-					ssaValue *elem = ssa_emit_struct_gep(proc, slice, v_zero32, make_type_pointer(a, t_type_info_member_ptr));
-					ssaValue *len  = ssa_emit_struct_gep(proc, slice, v_one32,  make_type_pointer(a, t_int_ptr));
-					ssaValue *cap  = ssa_emit_struct_gep(proc, slice, v_two32,  make_type_pointer(a, t_int_ptr));
+					ssaValue *elem = ssa_emit_struct_gep(proc, slice, 0);
+					ssaValue *len  = ssa_emit_struct_gep(proc, slice, 1);
+					ssaValue *cap  = ssa_emit_struct_gep(proc, slice, 2);
 
 
 					ssa_emit_store(proc, elem, memory);
 					ssa_emit_store(proc, elem, memory);
 					ssa_emit_store(proc, len, variable_count);
 					ssa_emit_store(proc, len, variable_count);
@@ -649,9 +648,9 @@ void ssa_gen_tree(ssaGen *s) {
 				case Type_Proc: {
 				case Type_Proc: {
 					tag = ssa_add_local_generated(proc, t_type_info_procedure);
 					tag = ssa_add_local_generated(proc, t_type_info_procedure);
 
 
-					ssaValue *params   = ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr);
-					ssaValue *results  = ssa_emit_struct_gep(proc, tag, v_one32,  t_type_info_ptr_ptr);
-					ssaValue *variadic = ssa_emit_struct_gep(proc, tag, v_two32,  t_bool_ptr);
+					ssaValue *params   = ssa_emit_struct_gep(proc, tag, 0);
+					ssaValue *results  = ssa_emit_struct_gep(proc, tag, 1);
+					ssaValue *variadic = ssa_emit_struct_gep(proc, tag, 2);
 
 
 					if (t->Proc.params) {
 					if (t->Proc.params) {
 						ssa_emit_store(proc, params, get_type_info_ptr(proc, type_info_data, t->Proc.params));
 						ssa_emit_store(proc, params, get_type_info_ptr(proc, type_info_data, t->Proc.params));
@@ -666,7 +665,7 @@ void ssa_gen_tree(ssaGen *s) {
 				}
 				}
 
 
 				if (tag != NULL) {
 				if (tag != NULL) {
-					ssaValue *gep = ssa_emit_struct_gep(proc, type_info_data, entry_index, t_type_info_ptr);
+					ssaValue *gep = ssa_emit_array_gep(proc, type_info_data, entry_index);
 					ssaValue *val = ssa_emit_conv(proc, ssa_emit_load(proc, tag), t_type_info);
 					ssaValue *val = ssa_emit_conv(proc, ssa_emit_load(proc, tag), t_type_info);
 					ssa_emit_store(proc, gep, val);
 					ssa_emit_store(proc, gep, val);
 				}
 				}

+ 2 - 2
src/codegen/print_llvm.cpp

@@ -208,11 +208,11 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) {
 			}
 			}
 			break;
 			break;
 		case TypeRecord_Union: {
 		case TypeRecord_Union: {
-			i64 size_of_union = type_size_of(s, gb_heap_allocator(), t) - s.word_size;
+			i64 size_of_union = type_size_of(s, heap_allocator(), t) - s.word_size;
 			ssa_fprintf(f, "{[%lld x i8], i%lld}", size_of_union, word_bits);
 			ssa_fprintf(f, "{[%lld x i8], i%lld}", size_of_union, word_bits);
 		} break;
 		} break;
 		case TypeRecord_RawUnion:
 		case TypeRecord_RawUnion:
-			ssa_fprintf(f, "[%lld x i8]", type_size_of(s, gb_heap_allocator(), t));
+			ssa_fprintf(f, "[%lld x i8]", type_size_of(s, heap_allocator(), t));
 			break;
 			break;
 		case TypeRecord_Enum:
 		case TypeRecord_Enum:
 			ssa_print_type(f, m, t->Record.enum_base);
 			ssa_print_type(f, m, t->Record.enum_base);

+ 152 - 97
src/codegen/ssa.cpp

@@ -431,18 +431,18 @@ void ssa_init_module(ssaModule *m, Checker *c) {
 	// TODO(bill): Determine a decent size for the arena
 	// TODO(bill): Determine a decent size for the arena
 	isize token_count = c->parser->total_token_count;
 	isize token_count = c->parser->total_token_count;
 	isize arena_size = 4 * token_count * gb_size_of(ssaValue);
 	isize arena_size = 4 * token_count * gb_size_of(ssaValue);
-	gb_arena_init_from_allocator(&m->arena, gb_heap_allocator(), arena_size);
-	gb_arena_init_from_allocator(&m->tmp_arena, gb_heap_allocator(), arena_size);
+	gb_arena_init_from_allocator(&m->arena, heap_allocator(), arena_size);
+	gb_arena_init_from_allocator(&m->tmp_arena, heap_allocator(), arena_size);
 	m->allocator     = gb_arena_allocator(&m->arena);
 	m->allocator     = gb_arena_allocator(&m->arena);
 	m->tmp_allocator = gb_arena_allocator(&m->tmp_arena);
 	m->tmp_allocator = gb_arena_allocator(&m->tmp_arena);
 	m->info = &c->info;
 	m->info = &c->info;
 	m->sizes = c->sizes;
 	m->sizes = c->sizes;
 
 
-	map_init(&m->values,     gb_heap_allocator());
-	map_init(&m->members,    gb_heap_allocator());
-	map_init(&m->debug_info, gb_heap_allocator());
-	map_init(&m->type_names, gb_heap_allocator());
-	array_init(&m->procs,  gb_heap_allocator());
+	map_init(&m->values,     heap_allocator());
+	map_init(&m->members,    heap_allocator());
+	map_init(&m->debug_info, heap_allocator());
+	map_init(&m->type_names, heap_allocator());
+	array_init(&m->procs,  heap_allocator());
 
 
 	// Default states
 	// Default states
 	m->stmt_state_flags = 0;
 	m->stmt_state_flags = 0;
@@ -776,7 +776,7 @@ ssaValue *ssa_make_value_global(gbAllocator a, Entity *e, ssaValue *value) {
 	v->Global.entity = e;
 	v->Global.entity = e;
 	v->Global.type = make_type_pointer(a, e->type);
 	v->Global.type = make_type_pointer(a, e->type);
 	v->Global.value = value;
 	v->Global.value = value;
-	array_init(&v->Global.referrers, gb_heap_allocator()); // TODO(bill): Replace heap allocator here
+	array_init(&v->Global.referrers, heap_allocator()); // TODO(bill): Replace heap allocator here
 	return v;
 	return v;
 }
 }
 ssaValue *ssa_make_value_param(gbAllocator a, ssaProcedure *parent, Entity *e) {
 ssaValue *ssa_make_value_param(gbAllocator a, ssaProcedure *parent, Entity *e) {
@@ -784,7 +784,7 @@ ssaValue *ssa_make_value_param(gbAllocator a, ssaProcedure *parent, Entity *e) {
 	v->Param.parent = parent;
 	v->Param.parent = parent;
 	v->Param.entity = e;
 	v->Param.entity = e;
 	v->Param.type   = e->type;
 	v->Param.type   = e->type;
-	array_init(&v->Param.referrers, gb_heap_allocator()); // TODO(bill): Replace heap allocator here
+	array_init(&v->Param.referrers, heap_allocator()); // TODO(bill): Replace heap allocator here
 	return v;
 	return v;
 }
 }
 ssaValue *ssa_make_value_nil(gbAllocator a, Type *type) {
 ssaValue *ssa_make_value_nil(gbAllocator a, Type *type) {
@@ -801,7 +801,7 @@ ssaValue *ssa_make_instr_local(ssaProcedure *p, Entity *e, b32 zero_initialized)
 	i->Local.entity = e;
 	i->Local.entity = e;
 	i->Local.type = make_type_pointer(p->module->allocator, e->type);
 	i->Local.type = make_type_pointer(p->module->allocator, e->type);
 	i->Local.zero_initialized = zero_initialized;
 	i->Local.zero_initialized = zero_initialized;
-	array_init(&i->Local.referrers, gb_heap_allocator()); // TODO(bill): Replace heap allocator here
+	array_init(&i->Local.referrers, heap_allocator()); // TODO(bill): Replace heap allocator here
 	ssa_module_add_value(p->module, e, v);
 	ssa_module_add_value(p->module, e, v);
 	return v;
 	return v;
 }
 }
@@ -1044,7 +1044,7 @@ ssaValue *ssa_make_value_procedure(gbAllocator a, ssaModule *m, Entity *entity,
 	v->Proc.type_expr = type_expr;
 	v->Proc.type_expr = type_expr;
 	v->Proc.body   = body;
 	v->Proc.body   = body;
 	v->Proc.name   = name;
 	v->Proc.name   = name;
-	array_init(&v->Proc.referrers, gb_heap_allocator(), 0); // TODO(bill): replace heap allocator
+	array_init(&v->Proc.referrers, heap_allocator(), 0); // TODO(bill): replace heap allocator
 	return v;
 	return v;
 }
 }
 
 
@@ -1055,11 +1055,11 @@ ssaValue *ssa_make_value_block(ssaProcedure *proc, AstNode *node, Scope *scope,
 	v->Block.scope  = scope;
 	v->Block.scope  = scope;
 	v->Block.parent = proc;
 	v->Block.parent = proc;
 
 
-	array_init(&v->Block.instrs, gb_heap_allocator());
-	array_init(&v->Block.locals, gb_heap_allocator());
+	array_init(&v->Block.instrs, heap_allocator());
+	array_init(&v->Block.locals, heap_allocator());
 
 
-	array_init(&v->Block.preds,  gb_heap_allocator());
-	array_init(&v->Block.succs,  gb_heap_allocator());
+	array_init(&v->Block.preds,  heap_allocator());
+	array_init(&v->Block.succs,  heap_allocator());
 
 
 	return v;
 	return v;
 }
 }
@@ -1387,9 +1387,9 @@ ssaValue *ssa_lvalue_load(ssaProcedure *proc, ssaAddr lval) {
 
 
 
 
 void ssa_begin_procedure_body(ssaProcedure *proc) {
 void ssa_begin_procedure_body(ssaProcedure *proc) {
-	array_init(&proc->blocks,      gb_heap_allocator());
-	array_init(&proc->defer_stmts, gb_heap_allocator());
-	array_init(&proc->children,    gb_heap_allocator());
+	array_init(&proc->blocks,      heap_allocator());
+	array_init(&proc->defer_stmts, heap_allocator());
+	array_init(&proc->children,    heap_allocator());
 
 
 	proc->decl_block  = ssa_add_block(proc, proc->type_expr, "decls");
 	proc->decl_block  = ssa_add_block(proc, proc->type_expr, "decls");
 	proc->entry_block = ssa_add_block(proc, proc->type_expr, "entry");
 	proc->entry_block = ssa_add_block(proc, proc->type_expr, "entry");
@@ -1554,8 +1554,6 @@ 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));
 	return ssa_emit(proc, ssa_make_instr_binary_op(proc, op_kind, left, right, result));
 }
 }
 
 
-
-
 ssaValue *ssa_emit_zero_gep(ssaProcedure *proc, ssaValue *s) {
 ssaValue *ssa_emit_zero_gep(ssaProcedure *proc, ssaValue *s) {
 	ssaValue *gep = NULL;
 	ssaValue *gep = NULL;
 	// NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
 	// NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
@@ -1564,8 +1562,13 @@ ssaValue *ssa_emit_zero_gep(ssaProcedure *proc, ssaValue *s) {
 	return ssa_emit(proc, gep);
 	return ssa_emit(proc, gep);
 }
 }
 
 
-ssaValue *ssa_emit_struct_gep(ssaProcedure *proc, ssaValue *s, ssaValue *index, Type *result_type) {
+ssaValue *ssa_emit_array_gep(ssaProcedure *proc, ssaValue *s, ssaValue *index) {
 	ssaValue *gep = NULL;
 	ssaValue *gep = NULL;
+	Type *st = base_type(type_deref(ssa_type(s)));
+	GB_ASSERT(is_type_array(st));
+
+	Type *result_type = make_type_pointer(proc->module->allocator, st->Array.elem);
+
 	// NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
 	// NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
 	index = ssa_emit_conv(proc, index, t_i32);
 	index = ssa_emit_conv(proc, index, t_i32);
 	gep = ssa_make_instr_get_element_ptr(proc, s, v_zero, index, 2, true);
 	gep = ssa_make_instr_get_element_ptr(proc, s, v_zero, index, 2, true);
@@ -1574,9 +1577,72 @@ ssaValue *ssa_emit_struct_gep(ssaProcedure *proc, ssaValue *s, ssaValue *index,
 	return ssa_emit(proc, gep);
 	return ssa_emit(proc, gep);
 }
 }
 
 
-ssaValue *ssa_emit_struct_gep(ssaProcedure *proc, ssaValue *s, i32 index, Type *result_type) {
-	ssaValue *i = ssa_make_const_i32(proc->module->allocator, index);
-	return ssa_emit_struct_gep(proc, s, i, result_type);
+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_struct_gep(ssaProcedure *proc, ssaValue *s, i32 index) {
+	gbAllocator a = proc->module->allocator;
+	Type *t = base_type(type_deref(ssa_type(s)));
+	Type *result_type = NULL;
+	ssaValue *gep = NULL;
+	ssaValue *i = NULL;
+	switch (index) {
+	case 0:  i = v_zero32;                     break;
+	case 1:  i = v_one32;                      break;
+	case 2:  i = v_two32;                      break;
+	default: i = ssa_make_const_i32(a, index); break;
+	}
+
+	if (is_type_struct(t)) {
+		GB_ASSERT(t->Record.field_count > 0);
+		GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
+		result_type = make_type_pointer(a, t->Record.fields[index]->type);
+	} else if (is_type_tuple(t)) {
+		GB_ASSERT(t->Tuple.variable_count > 0);
+		GB_ASSERT(gb_is_between(index, 0, t->Tuple.variable_count-1));
+		result_type = make_type_pointer(a, t->Tuple.variables[index]->type);
+	} else if (is_type_slice(t)) {
+		switch (index) {
+		case 0: result_type = make_type_pointer(a, make_type_pointer(a, t->Slice.elem)); break;
+		case 1: result_type = make_type_pointer(a, t_int); break;
+		case 2: result_type = make_type_pointer(a, t_int); break;
+		}
+	} else if (is_type_string(t)) {
+		switch (index) {
+		case 0: result_type = make_type_pointer(a, t_u8_ptr); break;
+		case 1: result_type = make_type_pointer(a, t_int);    break;
+		}
+	} else if (is_type_any(t)) {
+		switch (index) {
+		case 0: result_type = make_type_pointer(a, t_type_info_ptr); break;
+		case 1: result_type = make_type_pointer(a, t_rawptr);        break;
+		}
+	} else if (is_type_maybe(t)) {
+		switch (index) {
+		case 0: result_type = make_type_pointer(a, t->Maybe.elem); break;
+		case 1: result_type = make_type_pointer(a, t_bool);        break;
+		}
+	} else if (is_type_union(t)) {
+		switch (index) {
+		case 1: result_type = make_type_pointer(a, t_int); break;
+
+		case 0:
+		default:
+			GB_PANIC("TODO(bill): struct_gep 0 for unions");
+			break;
+		}
+	} else {
+		GB_PANIC("TODO(bill): struct_gep type: %s, %d", type_to_string(ssa_type(s)), index);
+	}
+
+	GB_ASSERT(result_type != NULL);
+
+	gep = ssa_make_instr_get_element_ptr(proc, s, v_zero, i, 2, true);
+	gep->Instr.GetElementPtr.result_type = result_type;
+
+	return ssa_emit(proc, gep);
 }
 }
 
 
 
 
@@ -1590,11 +1656,11 @@ ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, S
 	GB_ASSERT(sel.index.count > 0);
 	GB_ASSERT(sel.index.count > 0);
 
 
 	for_array(i, sel.index) {
 	for_array(i, sel.index) {
-		isize index = sel.index[i];
+		i32 index = cast(i32)sel.index[i];
 		if (is_type_pointer(type)) {
 		if (is_type_pointer(type)) {
 			type = type_deref(type);
 			type = type_deref(type);
 			e = ssa_emit_load(proc, e);
 			e = ssa_emit_load(proc, e);
-			e = ssa_emit_ptr_offset(proc, e, v_zero);
+			e = ssa_emit_ptr_offset(proc, e, v_zero); // TODO(bill): Do I need these copies?
 		}
 		}
 		type = base_type(type);
 		type = base_type(type);
 
 
@@ -1604,7 +1670,7 @@ ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, S
 			e = ssa_emit_conv(proc, e, make_type_pointer(proc->module->allocator, type));
 			e = ssa_emit_conv(proc, e, make_type_pointer(proc->module->allocator, type));
 		} else if (type->kind == Type_Record) {
 		} else if (type->kind == Type_Record) {
 			type = type->Record.fields[index]->type;
 			type = type->Record.fields[index]->type;
-			e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, type));
+			e = ssa_emit_struct_gep(proc, e, index);
 		} else if (type->kind == Type_Basic) {
 		} else if (type->kind == Type_Basic) {
 			switch (type->Basic.kind) {
 			switch (type->Basic.kind) {
 			case Basic_any: {
 			case Basic_any: {
@@ -1613,11 +1679,11 @@ ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, S
 				} else if (index == 1) {
 				} else if (index == 1) {
 					type = t_rawptr;
 					type = t_rawptr;
 				}
 				}
-				e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, type));
+				e = ssa_emit_struct_gep(proc, e, index);
 			} break;
 			} break;
 
 
 			case Basic_string:
 			case Basic_string:
-				e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, sel.entity->type));
+				e = ssa_emit_struct_gep(proc, e, index);
 				break;
 				break;
 
 
 			default:
 			default:
@@ -1625,7 +1691,7 @@ ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, S
 				break;
 				break;
 			}
 			}
 		} else if (type->kind == Type_Slice) {
 		} else if (type->kind == Type_Slice) {
-			e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, sel.entity->type));
+			e = ssa_emit_struct_gep(proc, e, index);
 		} else {
 		} else {
 			GB_PANIC("un-gep-able type");
 			GB_PANIC("un-gep-able type");
 		}
 		}
@@ -1643,7 +1709,7 @@ ssaValue *ssa_emit_deep_field_ev(ssaProcedure *proc, Type *type, ssaValue *e, Se
 		if (is_type_pointer(type)) {
 		if (is_type_pointer(type)) {
 			type = type_deref(type);
 			type = type_deref(type);
 			e = ssa_emit_load(proc, e);
 			e = ssa_emit_load(proc, e);
-			e = ssa_emit_ptr_offset(proc, e, v_zero);
+			e = ssa_emit_ptr_offset(proc, e, v_zero); // TODO(bill): Do I need these copies?
 		}
 		}
 		type = base_type(type);
 		type = base_type(type);
 
 
@@ -1674,7 +1740,7 @@ ssaValue *ssa_emit_deep_field_ev(ssaProcedure *proc, Type *type, ssaValue *e, Se
 				break;
 				break;
 			}
 			}
 		} else if (type->kind == Type_Slice) {
 		} else if (type->kind == Type_Slice) {
-			e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, sel.entity->type));
+			e = ssa_emit_struct_gep(proc, e, index);
 		} else {
 		} else {
 			GB_PANIC("un-ev-able type");
 			GB_PANIC("un-ev-able type");
 		}
 		}
@@ -1720,8 +1786,8 @@ ssaValue *ssa_type_info(ssaProcedure *proc, Type *type) {
 	ssaValue *type_info_data = *found;
 	ssaValue *type_info_data = *found;
 
 
 	CheckerInfo *info = proc->module->info;
 	CheckerInfo *info = proc->module->info;
-	isize entry_index = ssa_type_info_index(info, type);
-	return ssa_emit_struct_gep(proc, type_info_data, entry_index, t_type_info_ptr);
+	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);
 }
 }
 
 
 
 
@@ -1731,10 +1797,7 @@ ssaValue *ssa_type_info(ssaProcedure *proc, Type *type) {
 
 
 
 
 ssaValue *ssa_array_elem(ssaProcedure *proc, ssaValue *array) {
 ssaValue *ssa_array_elem(ssaProcedure *proc, ssaValue *array) {
-	Type *t = type_deref(ssa_type(array));
-	GB_ASSERT(t->kind == Type_Array);
-	Type *result_type = make_type_pointer(proc->module->allocator, t->Array.elem);
-	return ssa_emit_struct_gep(proc, array, v_zero32, result_type);
+	return ssa_emit_array_gep(proc, array, v_zero32);
 }
 }
 ssaValue *ssa_array_len(ssaProcedure *proc, ssaValue *array) {
 ssaValue *ssa_array_len(ssaProcedure *proc, ssaValue *array) {
 	Type *t = ssa_type(array);
 	Type *t = ssa_type(array);
@@ -1817,13 +1880,13 @@ ssaValue *ssa_add_local_slice(ssaProcedure *proc, Type *slice_type, ssaValue *ba
 	ssaValue *slice = ssa_add_local_generated(proc, slice_type);
 	ssaValue *slice = ssa_add_local_generated(proc, slice_type);
 
 
 	ssaValue *gep = NULL;
 	ssaValue *gep = NULL;
-	gep = ssa_emit_struct_gep(proc, slice, v_zero32, ssa_type(elem));
+	gep = ssa_emit_struct_gep(proc, slice, 0);
 	ssa_emit_store(proc, gep, elem);
 	ssa_emit_store(proc, gep, elem);
 
 
-	gep = ssa_emit_struct_gep(proc, slice, v_one32, t_int);
+	gep = ssa_emit_struct_gep(proc, slice, 1);
 	ssa_emit_store(proc, gep, len);
 	ssa_emit_store(proc, gep, len);
 
 
-	gep = ssa_emit_struct_gep(proc, slice, v_two32, t_int);
+	gep = ssa_emit_struct_gep(proc, slice, 2);
 	ssa_emit_store(proc, gep, cap);
 	ssa_emit_store(proc, gep, cap);
 
 
 	return slice;
 	return slice;
@@ -1855,14 +1918,9 @@ ssaValue *ssa_add_global_string_array(ssaModule *m, String string) {
 }
 }
 
 
 ssaValue *ssa_emit_string(ssaProcedure *proc, ssaValue *elem, ssaValue *len) {
 ssaValue *ssa_emit_string(ssaProcedure *proc, ssaValue *elem, ssaValue *len) {
-	Type *t_u8_ptr = ssa_type(elem);
-	GB_ASSERT(t_u8_ptr->kind == Type_Pointer);
-
-	GB_ASSERT(is_type_u8(t_u8_ptr->Pointer.elem));
-
 	ssaValue *str = ssa_add_local_generated(proc, t_string);
 	ssaValue *str = ssa_add_local_generated(proc, t_string);
-	ssaValue *str_elem = ssa_emit_struct_gep(proc, str, v_zero32, t_u8_ptr);
-	ssaValue *str_len = ssa_emit_struct_gep(proc, str, v_one32, t_int);
+	ssaValue *str_elem = ssa_emit_struct_gep(proc, str, 0);
+	ssaValue *str_len = ssa_emit_struct_gep(proc, str, 1);
 	ssa_emit_store(proc, str_elem, elem);
 	ssa_emit_store(proc, str_elem, elem);
 	ssa_emit_store(proc, str_len, len);
 	ssa_emit_store(proc, str_len, len);
 	return ssa_emit_load(proc, str);
 	return ssa_emit_load(proc, str);
@@ -1952,8 +2010,8 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
 		gbAllocator a = proc->module->allocator;
 		gbAllocator a = proc->module->allocator;
 		Type *elem = base_type(dst)->Maybe.elem;
 		Type *elem = base_type(dst)->Maybe.elem;
 		ssaValue *maybe = ssa_add_local_generated(proc, dst);
 		ssaValue *maybe = ssa_add_local_generated(proc, dst);
-		ssaValue *val = ssa_emit_struct_gep(proc, maybe, v_zero32, make_type_pointer(a, elem));
-		ssaValue *set = ssa_emit_struct_gep(proc, maybe, v_one32,  make_type_pointer(a, t_bool));
+		ssaValue *val = ssa_emit_struct_gep(proc, maybe, 0);
+		ssaValue *set = ssa_emit_struct_gep(proc, maybe, 1);
 		ssa_emit_store(proc, val, value);
 		ssa_emit_store(proc, val, value);
 		ssa_emit_store(proc, set, v_true);
 		ssa_emit_store(proc, set, v_true);
 		return ssa_emit_load(proc, maybe);
 		return ssa_emit_load(proc, maybe);
@@ -2031,7 +2089,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
 				gbAllocator allocator = proc->module->allocator;
 				gbAllocator allocator = proc->module->allocator;
 				ssaValue *parent = ssa_add_local_generated(proc, t);
 				ssaValue *parent = ssa_add_local_generated(proc, t);
 				ssaValue *tag = ssa_make_const_int(allocator, i);
 				ssaValue *tag = ssa_make_const_int(allocator, i);
-				ssa_emit_store(proc, ssa_emit_struct_gep(proc, parent, v_one32, t_int), tag);
+				ssa_emit_store(proc, ssa_emit_struct_gep(proc, parent, 1), tag);
 
 
 				ssaValue *data = ssa_emit_conv(proc, parent, t_rawptr);
 				ssaValue *data = ssa_emit_conv(proc, parent, t_rawptr);
 
 
@@ -2149,8 +2207,8 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
 
 
 		ssaValue *ti = ssa_type_info(proc, src_type);
 		ssaValue *ti = ssa_type_info(proc, src_type);
 
 
-		ssaValue *gep0 = ssa_emit_struct_gep(proc, result, v_zero32, make_type_pointer(proc->module->allocator, t_type_info_ptr));
-		ssaValue *gep1 = ssa_emit_struct_gep(proc, result, v_one32,  make_type_pointer(proc->module->allocator, t_rawptr));
+		ssaValue *gep0 = ssa_emit_struct_gep(proc, result, 0);
+		ssaValue *gep1 = ssa_emit_struct_gep(proc, result, 1);
 		ssa_emit_store(proc, gep0, ti);
 		ssa_emit_store(proc, gep0, ti);
 		ssa_emit_store(proc, gep1, data);
 		ssa_emit_store(proc, gep1, data);
 
 
@@ -2162,6 +2220,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
 	}
 	}
 
 
 
 
+	gb_printf_err("ssa_emit_conv: src -> dst\n");
 	gb_printf_err("Not Identical %s != %s\n", type_to_string(src_type), type_to_string(t));
 	gb_printf_err("Not Identical %s != %s\n", type_to_string(src_type), type_to_string(t));
 	gb_printf_err("Not Identical %s != %s\n", type_to_string(src), type_to_string(dst));
 	gb_printf_err("Not Identical %s != %s\n", type_to_string(src), type_to_string(dst));
 
 
@@ -2220,9 +2279,6 @@ ssaValue *ssa_emit_union_cast(ssaProcedure *proc, ssaValue *value, Type *tuple)
 	Type *src_type = ssa_type(value);
 	Type *src_type = ssa_type(value);
 	b32 is_ptr = is_type_pointer(src_type);
 	b32 is_ptr = is_type_pointer(src_type);
 
 
-	Type *t_bool_ptr = make_type_pointer(a, t_bool);
-	Type *t_int_ptr  = make_type_pointer(a, t_int);
-
 	ssaValue *v = ssa_add_local_generated(proc, tuple);
 	ssaValue *v = ssa_add_local_generated(proc, tuple);
 
 
 	if (is_ptr) {
 	if (is_ptr) {
@@ -2232,7 +2288,7 @@ ssaValue *ssa_emit_union_cast(ssaProcedure *proc, ssaValue *value, Type *tuple)
 		Type *dst_ptr = tuple->Tuple.variables[0]->type;
 		Type *dst_ptr = tuple->Tuple.variables[0]->type;
 		Type *dst = type_deref(dst_ptr);
 		Type *dst = type_deref(dst_ptr);
 
 
-		ssaValue *tag = ssa_emit_load(proc, ssa_emit_struct_gep(proc, value, v_one32, t_int_ptr));
+		ssaValue *tag = ssa_emit_load(proc, ssa_emit_struct_gep(proc, value, 1));
 		ssaValue *dst_tag = NULL;
 		ssaValue *dst_tag = NULL;
 		for (isize i = 1; i < src->Record.field_count; i++) {
 		for (isize i = 1; i < src->Record.field_count; i++) {
 			Entity *f = src->Record.fields[i];
 			Entity *f = src->Record.fields[i];
@@ -2249,8 +2305,8 @@ ssaValue *ssa_emit_union_cast(ssaProcedure *proc, ssaValue *value, Type *tuple)
 		ssa_emit_if(proc, cond, ok_block, end_block);
 		ssa_emit_if(proc, cond, ok_block, end_block);
 		proc->curr_block = ok_block;
 		proc->curr_block = ok_block;
 
 
-		ssaValue *gep0 = ssa_emit_struct_gep(proc, v, v_zero32, make_type_pointer(a, dst_ptr));
-		ssaValue *gep1 = ssa_emit_struct_gep(proc, v, v_one32,  t_bool_ptr);
+		ssaValue *gep0 = ssa_emit_struct_gep(proc, v, 0);
+		ssaValue *gep1 = ssa_emit_struct_gep(proc, v, 1);
 
 
 		ssaValue *data = ssa_emit_conv(proc, value, dst_ptr);
 		ssaValue *data = ssa_emit_conv(proc, value, dst_ptr);
 		ssa_emit_store(proc, gep0, data);
 		ssa_emit_store(proc, gep0, data);
@@ -2286,8 +2342,8 @@ ssaValue *ssa_emit_union_cast(ssaProcedure *proc, ssaValue *value, Type *tuple)
 		ssa_emit_if(proc, cond, ok_block, end_block);
 		ssa_emit_if(proc, cond, ok_block, end_block);
 		proc->curr_block = ok_block;
 		proc->curr_block = ok_block;
 
 
-		ssaValue *gep0 = ssa_emit_struct_gep(proc, v, v_zero32, dst_ptr);
-		ssaValue *gep1 = ssa_emit_struct_gep(proc, v, v_one32, t_bool_ptr);
+		ssaValue *gep0 = ssa_emit_struct_gep(proc, v, 0);
+		ssaValue *gep1 = ssa_emit_struct_gep(proc, v, 1);
 
 
 		ssaValue *data = ssa_emit_load(proc, ssa_emit_conv(proc, union_copy, dst_ptr));
 		ssaValue *data = ssa_emit_load(proc, ssa_emit_conv(proc, union_copy, dst_ptr));
 		ssa_emit_store(proc, gep0, data);
 		ssa_emit_store(proc, gep0, data);
@@ -2666,7 +2722,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 
 
 					Type *ft = field->type;
 					Type *ft = field->type;
 					ssaValue *fv = ssa_emit_conv(proc, field_expr, ft);
 					ssaValue *fv = ssa_emit_conv(proc, field_expr, ft);
-					ssaValue *gep = ssa_emit_struct_gep(proc, v, index, ft);
+					ssaValue *gep = ssa_emit_struct_gep(proc, v, index);
 					ssa_emit_store(proc, gep, fv);
 					ssa_emit_store(proc, gep, fv);
 				}
 				}
 			}
 			}
@@ -2683,7 +2739,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 					Type *t = ssa_type(field_expr);
 					Type *t = ssa_type(field_expr);
 					GB_ASSERT(t->kind != Type_Tuple);
 					GB_ASSERT(t->kind != Type_Tuple);
 					ssaValue *ev = ssa_emit_conv(proc, field_expr, et);
 					ssaValue *ev = ssa_emit_conv(proc, field_expr, et);
-					ssaValue *gep = ssa_emit_struct_gep(proc, v, i, et);
+					ssaValue *gep = ssa_emit_array_gep(proc, v, i);
 					ssa_emit_store(proc, gep, ev);
 					ssa_emit_store(proc, gep, ev);
 				}
 				}
 			}
 			}
@@ -2697,7 +2753,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));
 				ssaValue *slice = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr));
 				GB_ASSERT(slice->kind == ssaValue_ConstantSlice);
 				GB_ASSERT(slice->kind == ssaValue_ConstantSlice);
 
 
-				ssaValue *data = ssa_emit_struct_gep(proc, slice->ConstantSlice.backing_array, v_zero32, elem_ptr_type);
+				ssaValue *data = ssa_emit_array_gep(proc, slice->ConstantSlice.backing_array, v_zero32);
 
 
 				for_array(i, cl->elems) {
 				for_array(i, cl->elems) {
 					AstNode *elem = cl->elems[i];
 					AstNode *elem = cl->elems[i];
@@ -2713,9 +2769,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 					ssa_emit_store(proc, offset, ev);
 					ssa_emit_store(proc, offset, ev);
 				}
 				}
 
 
-				ssaValue *gep0 = ssa_emit_struct_gep(proc, v, v_zero32, elem_ptr_ptr_type);
-				ssaValue *gep1 = ssa_emit_struct_gep(proc, v, v_one32, t_int_ptr);
-				ssaValue *gep2 = ssa_emit_struct_gep(proc, v, v_two32, t_int_ptr);
+				ssaValue *gep0 = ssa_emit_struct_gep(proc, v, 0);
+				ssaValue *gep1 = ssa_emit_struct_gep(proc, v, 1);
+				ssaValue *gep2 = ssa_emit_struct_gep(proc, v, 1);
 
 
 				ssa_emit_store(proc, gep0, data);
 				ssa_emit_store(proc, gep0, data);
 				ssa_emit_store(proc, gep1, ssa_make_const_int(proc->module->allocator, slice->ConstantSlice.count));
 				ssa_emit_store(proc, gep1, ssa_make_const_int(proc->module->allocator, slice->ConstantSlice.count));
@@ -2796,9 +2852,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 					ssaValue *ptr = ssa_emit_conv(proc, call, ptr_type, true);
 					ssaValue *ptr = ssa_emit_conv(proc, call, ptr_type, true);
 					ssaValue *slice = ssa_add_local_generated(proc, slice_type);
 					ssaValue *slice = ssa_add_local_generated(proc, slice_type);
 
 
-					ssaValue *gep0 = ssa_emit_struct_gep(proc, slice, v_zero32, ptr_type);
-					ssaValue *gep1 = ssa_emit_struct_gep(proc, slice, v_one32, t_int);
-					ssaValue *gep2 = ssa_emit_struct_gep(proc, slice, v_two32, t_int);
+					ssaValue *gep0 = ssa_emit_struct_gep(proc, slice, 0);
+					ssaValue *gep1 = ssa_emit_struct_gep(proc, slice, 1);
+					ssaValue *gep2 = ssa_emit_struct_gep(proc, slice, 2);
 					ssa_emit_store(proc, gep0, ptr);
 					ssa_emit_store(proc, gep0, ptr);
 					ssa_emit_store(proc, gep1, len);
 					ssa_emit_store(proc, gep1, len);
 					ssa_emit_store(proc, gep2, cap);
 					ssa_emit_store(proc, gep2, cap);
@@ -2941,7 +2997,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 
 
 					// Increment slice length
 					// Increment slice length
 					ssaValue *new_len = ssa_emit_arith(proc, Token_Add, len, v_one, t_int);
 					ssaValue *new_len = ssa_emit_arith(proc, Token_Add, len, v_one, t_int);
-					ssaValue *gep = ssa_emit_struct_gep(proc, slice_ptr, v_one32, t_int);
+					ssaValue *gep = ssa_emit_struct_gep(proc, slice_ptr, 1);
 					ssa_emit_store(proc, gep, new_len);
 					ssa_emit_store(proc, gep, new_len);
 
 
 					ssa_emit_jump(proc, done);
 					ssa_emit_jump(proc, done);
@@ -3014,9 +3070,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 
 
 					Type *slice_type = make_type_slice(proc->module->allocator, type_deref(ssa_type(ptr)));
 					Type *slice_type = make_type_slice(proc->module->allocator, type_deref(ssa_type(ptr)));
 					ssaValue *slice = ssa_add_local_generated(proc, slice_type);
 					ssaValue *slice = ssa_add_local_generated(proc, slice_type);
-					ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_zero32, ssa_type(ptr)), ptr);
-					ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_one32,  t_int),         len);
-					ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_two32,  t_int),         cap);
+					ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, 0), ptr);
+					ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, 1), len);
+					ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, 2), cap);
 					return ssa_emit_load(proc, slice);
 					return ssa_emit_load(proc, slice);
 				} break;
 				} break;
 
 
@@ -3136,16 +3192,16 @@ 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));
 				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++) {
 				for (isize i = type->param_count-1, j = 0; i < arg_count; i++, j++) {
-					ssaValue *addr = ssa_emit_struct_gep(proc, base_array, j, elem_type);
+					ssaValue *addr = ssa_emit_array_gep(proc, base_array, j);
 					ssa_emit_store(proc, addr, args[i]);
 					ssa_emit_store(proc, addr, args[i]);
 				}
 				}
 
 
-				ssaValue *base_elem  = ssa_emit_struct_gep(proc, base_array, v_zero32, elem_ptr_type);
-				ssaValue *slice_elem = ssa_emit_struct_gep(proc, slice,      v_zero32, elem_ptr_type);
+				ssaValue *base_elem  = ssa_emit_array_gep(proc, base_array, 0);
+				ssaValue *slice_elem = ssa_emit_struct_gep(proc, slice,      0);
 				ssa_emit_store(proc, slice_elem, base_elem);
 				ssa_emit_store(proc, slice_elem, base_elem);
 				ssaValue *len = ssa_make_const_int(allocator, slice_len);
 				ssaValue *len = ssa_make_const_int(allocator, slice_len);
-				ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_one32, t_int), len);
-				ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_two32, t_int), len);
+				ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, 1), len);
+				ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, 2), len);
 			}
 			}
 
 
 			if (args[0]->kind == ssaValue_Constant) {
 			if (args[0]->kind == ssaValue_Constant) {
@@ -3246,8 +3302,8 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
 				ssaValue *elem = ssa_array_elem(proc, global_array);
 				ssaValue *elem = ssa_array_elem(proc, global_array);
 				ssaValue *len =  ssa_make_const_int(proc->module->allocator, str.len);
 				ssaValue *len =  ssa_make_const_int(proc->module->allocator, str.len);
 				ssaValue *v = ssa_add_local_generated(proc, e->type);
 				ssaValue *v = ssa_add_local_generated(proc, e->type);
-				ssaValue *str_elem = ssa_emit_struct_gep(proc, v, v_zero32, ssa_type(elem));
-				ssaValue *str_len = ssa_emit_struct_gep(proc, v, v_one32, t_int);
+				ssaValue *str_elem = ssa_emit_struct_gep(proc, v, 0);
+				ssaValue *str_len = ssa_emit_struct_gep(proc, v, 1);
 				ssa_emit_store(proc, str_elem, elem);
 				ssa_emit_store(proc, str_elem, elem);
 				ssa_emit_store(proc, str_len, len);
 				ssa_emit_store(proc, str_len, len);
 				return ssa_make_addr(v, expr);
 				return ssa_make_addr(v, expr);
@@ -3382,9 +3438,8 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
 					array = ssa_emit_load(proc, array);
 					array = ssa_emit_load(proc, array);
 				}
 				}
 			}
 			}
-			Type *et = make_type_pointer(proc->module->allocator, t->Array.elem);
 			ssaValue *index = ssa_emit_conv(proc, ssa_build_expr(proc, ie->index), t_int);
 			ssaValue *index = ssa_emit_conv(proc, ssa_build_expr(proc, ie->index), t_int);
-			ssaValue *elem = ssa_emit_struct_gep(proc, array, index, et);
+			ssaValue *elem = ssa_emit_array_gep(proc, array, index);
 			ssaValue *len = ssa_make_const_int(a, t->Vector.count);
 			ssaValue *len = ssa_make_const_int(a, t->Vector.count);
 			ssa_array_bounds_check(proc, ast_node_token(ie->index), index, len);
 			ssa_array_bounds_check(proc, ast_node_token(ie->index), index, len);
 			return ssa_make_addr(elem, expr);
 			return ssa_make_addr(elem, expr);
@@ -3477,9 +3532,9 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
 			ssaValue *cap  = ssa_emit_arith(proc, Token_Sub, max,  low, t_int);
 			ssaValue *cap  = ssa_emit_arith(proc, Token_Sub, max,  low, t_int);
 			ssaValue *slice = ssa_add_local_generated(proc, slice_type);
 			ssaValue *slice = ssa_add_local_generated(proc, slice_type);
 
 
-			ssaValue *gep0 = ssa_emit_struct_gep(proc, slice, v_zero32, ssa_type(elem));
-			ssaValue *gep1 = ssa_emit_struct_gep(proc, slice, v_one32, t_int);
-			ssaValue *gep2 = ssa_emit_struct_gep(proc, slice, v_two32, t_int);
+			ssaValue *gep0 = ssa_emit_struct_gep(proc, slice, 0);
+			ssaValue *gep1 = ssa_emit_struct_gep(proc, slice, 1);
+			ssaValue *gep2 = ssa_emit_struct_gep(proc, slice, 2);
 			ssa_emit_store(proc, gep0, elem);
 			ssa_emit_store(proc, gep0, elem);
 			ssa_emit_store(proc, gep1, len);
 			ssa_emit_store(proc, gep1, len);
 			ssa_emit_store(proc, gep2, cap);
 			ssa_emit_store(proc, gep2, cap);
@@ -3501,9 +3556,9 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
 			ssaValue *cap  = ssa_emit_arith(proc, Token_Sub, max,  low, t_int);
 			ssaValue *cap  = ssa_emit_arith(proc, Token_Sub, max,  low, t_int);
 			ssaValue *slice = ssa_add_local_generated(proc, slice_type);
 			ssaValue *slice = ssa_add_local_generated(proc, slice_type);
 
 
-			ssaValue *gep0 = ssa_emit_struct_gep(proc, slice, v_zero32, ssa_type(elem));
-			ssaValue *gep1 = ssa_emit_struct_gep(proc, slice, v_one32, t_int);
-			ssaValue *gep2 = ssa_emit_struct_gep(proc, slice, v_two32, t_int);
+			ssaValue *gep0 = ssa_emit_struct_gep(proc, slice, 0);
+			ssaValue *gep1 = ssa_emit_struct_gep(proc, slice, 1);
+			ssaValue *gep2 = ssa_emit_struct_gep(proc, slice, 2);
 			ssa_emit_store(proc, gep0, elem);
 			ssa_emit_store(proc, gep0, elem);
 			ssa_emit_store(proc, gep1, len);
 			ssa_emit_store(proc, gep1, len);
 			ssa_emit_store(proc, gep2, cap);
 			ssa_emit_store(proc, gep2, cap);
@@ -3526,8 +3581,8 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
 			elem = ssa_emit_ptr_offset(proc, elem, low);
 			elem = ssa_emit_ptr_offset(proc, elem, low);
 
 
 			ssaValue *str = ssa_add_local_generated(proc, t_string);
 			ssaValue *str = ssa_add_local_generated(proc, t_string);
-			ssaValue *gep0 = ssa_emit_struct_gep(proc, str, v_zero32, ssa_type(elem));
-			ssaValue *gep1 = ssa_emit_struct_gep(proc, str, v_one32, t_int);
+			ssaValue *gep0 = ssa_emit_struct_gep(proc, str, 0);
+			ssaValue *gep1 = ssa_emit_struct_gep(proc, str, 1);
 			ssa_emit_store(proc, gep0, elem);
 			ssa_emit_store(proc, gep0, elem);
 			ssa_emit_store(proc, gep1, len);
 			ssa_emit_store(proc, gep1, len);
 
 
@@ -3556,8 +3611,8 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
 		elem = base_type(elem)->Maybe.elem;
 		elem = base_type(elem)->Maybe.elem;
 
 
 		ssaValue *result = ssa_add_local_generated(proc, t);
 		ssaValue *result = ssa_add_local_generated(proc, t);
-		ssaValue *gep0 = ssa_emit_struct_gep(proc, result, v_zero32, make_type_pointer(proc->module->allocator, elem));
-		ssaValue *gep1 = ssa_emit_struct_gep(proc, result, v_one32,  make_type_pointer(proc->module->allocator, t_bool));
+		ssaValue *gep0 = ssa_emit_struct_gep(proc, result, 0);
+		ssaValue *gep1 = ssa_emit_struct_gep(proc, result, 1);
 		ssa_emit_store(proc, gep0, ssa_emit_struct_ev(proc, maybe, 0, elem));
 		ssa_emit_store(proc, gep0, ssa_emit_struct_ev(proc, maybe, 0, elem));
 		ssa_emit_store(proc, gep1, ssa_emit_struct_ev(proc, maybe, 1, t_bool));
 		ssa_emit_store(proc, gep1, ssa_emit_struct_ev(proc, maybe, 1, t_bool));
 
 
@@ -4000,7 +4055,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 			for_array(i, results) {
 			for_array(i, results) {
 				Entity *e = return_type_tuple->variables[i];
 				Entity *e = return_type_tuple->variables[i];
 				ssaValue *res = ssa_emit_conv(proc, results[i], e->type);
 				ssaValue *res = ssa_emit_conv(proc, results[i], e->type);
-				ssaValue *field = ssa_emit_struct_gep(proc, v, i, make_type_pointer(proc->module->allocator, e->type));
+				ssaValue *field = ssa_emit_struct_gep(proc, v, i);
 				ssa_emit_store(proc, field, res);
 				ssa_emit_store(proc, field, res);
 			}
 			}
 
 
@@ -4193,7 +4248,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 		GB_ASSERT(is_type_union(union_type));
 		GB_ASSERT(is_type_union(union_type));
 
 
 		ssa_emit_comment(proc, make_string("get union's tag"));
 		ssa_emit_comment(proc, make_string("get union's tag"));
-		ssaValue *tag_index = ssa_emit_struct_gep(proc, parent, v_one32, make_type_pointer(allocator, t_int));
+		ssaValue *tag_index = ssa_emit_struct_gep(proc, parent, 1);
 		tag_index = ssa_emit_load(proc, tag_index);
 		tag_index = ssa_emit_load(proc, tag_index);
 
 
 		ssaValue *data = ssa_emit_conv(proc, parent, t_rawptr);
 		ssaValue *data = ssa_emit_conv(proc, parent, t_rawptr);
@@ -4325,7 +4380,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 
 		ssa_add_defer_instr(proc, proc->scope_index, ssa_make_instr_store(proc, context_ptr, ssa_emit_load(proc, prev_context)));
 		ssa_add_defer_instr(proc, proc->scope_index, ssa_make_instr_store(proc, context_ptr, ssa_emit_load(proc, prev_context)));
 
 
-		ssaValue *gep = ssa_emit_struct_gep(proc, context_ptr, 1, t_allocator_ptr);
+		ssaValue *gep = ssa_emit_struct_gep(proc, context_ptr, 1);
 		ssa_emit_store(proc, gep, ssa_build_expr(proc, pa->expr));
 		ssa_emit_store(proc, gep, ssa_build_expr(proc, pa->expr));
 
 
 		ssa_build_stmt(proc, pa->body);
 		ssa_build_stmt(proc, pa->body);
@@ -4748,7 +4803,7 @@ void ssa_build_dom_tree(ssaProcedure *proc) {
 			auto *children = &w->dom.idom->dom.children;
 			auto *children = &w->dom.idom->dom.children;
 			if (children->data == NULL) {
 			if (children->data == NULL) {
 				// TODO(bill): Is this good enough for memory allocations?
 				// TODO(bill): Is this good enough for memory allocations?
-				array_init(children, gb_heap_allocator());
+				array_init(children, heap_allocator());
 			}
 			}
 			array_add(children, w);
 			array_add(children, w);
 		}
 		}

+ 6 - 2
src/common.cpp

@@ -1,6 +1,10 @@
 #define GB_IMPLEMENTATION
 #define GB_IMPLEMENTATION
 #include "gb/gb.h"
 #include "gb/gb.h"
 
 
+gbAllocator heap_allocator(void) {
+	return gb_heap_allocator();
+}
+
 
 
 #include "string.cpp"
 #include "string.cpp"
 #include "array.cpp"
 #include "array.cpp"
@@ -14,7 +18,7 @@ String get_module_dir() {
 	}
 	}
 
 
 	Array<wchar_t> path_buf;
 	Array<wchar_t> path_buf;
-	array_init(&path_buf, gb_heap_allocator(), 300);
+	array_init(&path_buf, heap_allocator(), 300);
 	defer (array_free(&path_buf));
 	defer (array_free(&path_buf));
 	array_resize(&path_buf, 300);
 	array_resize(&path_buf, 300);
 
 
@@ -36,7 +40,7 @@ String get_module_dir() {
 	wchar_t *text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
 	wchar_t *text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
 
 
 	GetModuleFileNameW(NULL, text, len);
 	GetModuleFileNameW(NULL, text, len);
-	String path = string16_to_string(gb_heap_allocator(), make_string16(text, len));
+	String path = string16_to_string(heap_allocator(), make_string16(text, len));
 	for (isize i = path.len-1; i >= 0; i--) {
 	for (isize i = path.len-1; i >= 0; i--) {
 		u8 c = path.text[i];
 		u8 c = path.text[i];
 		if (c == '/' || c == '\\') {
 		if (c == '/' || c == '\\') {

+ 3 - 2
src/main.cpp

@@ -176,7 +176,7 @@ int main(int argc, char **argv) {
 	isize base_name_len = gb_path_extension(output_name)-1 - output_name;
 	isize base_name_len = gb_path_extension(output_name)-1 - output_name;
 	String output = make_string(cast(u8 *)output_name, base_name_len);
 	String output = make_string(cast(u8 *)output_name, base_name_len);
 
 
-	int optimization_level = 0;
+	i32 optimization_level = 0;
 	optimization_level = gb_clamp(optimization_level, 0, 3);
 	optimization_level = gb_clamp(optimization_level, 0, 3);
 
 
 	i32 exit_code = 0;
 	i32 exit_code = 0;
@@ -212,7 +212,7 @@ int main(int argc, char **argv) {
 	}
 	}
 
 
 
 
-	gbString lib_str = gb_string_make(gb_heap_allocator(), "Kernel32.lib");
+	gbString lib_str = gb_string_make(heap_allocator(), "Kernel32.lib");
 	// defer (gb_string_free(lib_str));
 	// defer (gb_string_free(lib_str));
 	char lib_str_buf[1024] = {};
 	char lib_str_buf[1024] = {};
 	for_array(i, parser.system_libraries) {
 	for_array(i, parser.system_libraries) {
@@ -221,6 +221,7 @@ int main(int argc, char **argv) {
 		                        " %.*s.lib", LIT(lib));
 		                        " %.*s.lib", LIT(lib));
 		lib_str = gb_string_appendc(lib_str, lib_str_buf);
 		lib_str = gb_string_appendc(lib_str, lib_str_buf);
 	}
 	}
+
 	exit_code = win32_exec_command_line_app("msvc-link",
 	exit_code = win32_exec_command_line_app("msvc-link",
 		"link %.*s.obj -OUT:%.*s.exe %s "
 		"link %.*s.obj -OUT:%.*s.exe %s "
 		"/defaultlib:libcmt "
 		"/defaultlib:libcmt "

+ 14 - 14
src/parser.cpp

@@ -2863,7 +2863,7 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) {
 	}
 	}
 	TokenizerInitError err = init_tokenizer(&f->tokenizer, fullpath);
 	TokenizerInitError err = init_tokenizer(&f->tokenizer, fullpath);
 	if (err == TokenizerInit_None) {
 	if (err == TokenizerInit_None) {
-		array_init(&f->tokens, gb_heap_allocator());
+		array_init(&f->tokens, heap_allocator());
 		{
 		{
 			PROF_SCOPED("Tokenize file");
 			PROF_SCOPED("Tokenize file");
 			for (;;) {
 			for (;;) {
@@ -2886,7 +2886,7 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) {
 		// NOTE(bill): Is this big enough or too small?
 		// NOTE(bill): Is this big enough or too small?
 		isize arena_size = gb_size_of(AstNode);
 		isize arena_size = gb_size_of(AstNode);
 		arena_size *= 2*f->tokens.count;
 		arena_size *= 2*f->tokens.count;
-		gb_arena_init_from_allocator(&f->arena, gb_heap_allocator(), arena_size);
+		gb_arena_init_from_allocator(&f->arena, heap_allocator(), arena_size);
 
 
 		f->curr_proc = NULL;
 		f->curr_proc = NULL;
 
 
@@ -2908,14 +2908,14 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) {
 void destroy_ast_file(AstFile *f) {
 void destroy_ast_file(AstFile *f) {
 	gb_arena_free(&f->arena);
 	gb_arena_free(&f->arena);
 	array_free(&f->tokens);
 	array_free(&f->tokens);
-	gb_free(gb_heap_allocator(), f->tokenizer.fullpath.text);
+	gb_free(heap_allocator(), f->tokenizer.fullpath.text);
 	destroy_tokenizer(&f->tokenizer);
 	destroy_tokenizer(&f->tokenizer);
 }
 }
 
 
 b32 init_parser(Parser *p) {
 b32 init_parser(Parser *p) {
-	array_init(&p->files, gb_heap_allocator());
-	array_init(&p->imports, gb_heap_allocator());
-	array_init(&p->system_libraries, gb_heap_allocator());
+	array_init(&p->files, heap_allocator());
+	array_init(&p->imports, heap_allocator());
+	array_init(&p->system_libraries, heap_allocator());
 	gb_mutex_init(&p->mutex);
 	gb_mutex_init(&p->mutex);
 	return true;
 	return true;
 }
 }
@@ -2927,7 +2927,7 @@ void destroy_parser(Parser *p) {
 	}
 	}
 #if 1
 #if 1
 	for_array(i, p->imports) {
 	for_array(i, p->imports) {
-		// gb_free(gb_heap_allocator(), p->imports[i].text);
+		// gb_free(heap_allocator(), p->imports[i].text);
 	}
 	}
 #endif
 #endif
 	array_free(&p->files);
 	array_free(&p->files);
@@ -2959,8 +2959,8 @@ b32 try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) {
 String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
 String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
 	isize str_len = base_dir.len+path.len;
 	isize str_len = base_dir.len+path.len;
 
 
-	u8 *str = gb_alloc_array(gb_heap_allocator(), u8, str_len+1);
-	defer (gb_free(gb_heap_allocator(), str));
+	u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
+	defer (gb_free(heap_allocator(), str));
 
 
 	isize i = 0;
 	isize i = 0;
 	gb_memmove(str+i, base_dir.text, base_dir.len); i += base_dir.len;
 	gb_memmove(str+i, base_dir.text, base_dir.len); i += base_dir.len;
@@ -2976,8 +2976,8 @@ String get_fullpath_core(gbAllocator a, String path) {
 	isize core_len = gb_size_of(core)-1;
 	isize core_len = gb_size_of(core)-1;
 
 
 	isize str_len = module_dir.len + core_len + path.len;
 	isize str_len = module_dir.len + core_len + path.len;
-	u8 *str = gb_alloc_array(gb_heap_allocator(), u8, str_len+1);
-	defer (gb_free(gb_heap_allocator(), str));
+	u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
+	defer (gb_free(heap_allocator(), str));
 
 
 	gb_memmove(str, module_dir.text, module_dir.len);
 	gb_memmove(str, module_dir.text, module_dir.len);
 	gb_memmove(str+module_dir.len, core, core_len);
 	gb_memmove(str+module_dir.len, core, core_len);
@@ -3101,7 +3101,7 @@ void parse_file(Parser *p, AstFile *f) {
 					continue;
 					continue;
 				}
 				}
 
 
-				gbAllocator allocator = gb_heap_allocator(); // TODO(bill): Change this allocator
+				gbAllocator allocator = heap_allocator(); // TODO(bill): Change this allocator
 
 
 				String rel_path = get_fullpath_relative(allocator, base_dir, file_str);
 				String rel_path = get_fullpath_relative(allocator, base_dir, file_str);
 				String import_file = rel_path;
 				String import_file = rel_path;
@@ -3135,7 +3135,7 @@ void parse_file(Parser *p, AstFile *f) {
 
 
 
 
 ParseFileError parse_files(Parser *p, char *init_filename) {
 ParseFileError parse_files(Parser *p, char *init_filename) {
-	char *fullpath_str = gb_path_get_full_name(gb_heap_allocator(), init_filename);
+	char *fullpath_str = gb_path_get_full_name(heap_allocator(), init_filename);
 	String init_fullpath = make_string(fullpath_str);
 	String init_fullpath = make_string(fullpath_str);
 	TokenPos init_pos = {};
 	TokenPos init_pos = {};
 	ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos};
 	ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos};
@@ -3143,7 +3143,7 @@ ParseFileError parse_files(Parser *p, char *init_filename) {
 	p->init_fullpath = init_fullpath;
 	p->init_fullpath = init_fullpath;
 
 
 	{
 	{
-		String s = get_fullpath_core(gb_heap_allocator(), make_string("_preload.odin"));
+		String s = get_fullpath_core(heap_allocator(), make_string("_preload.odin"));
 		ImportedFile runtime_file = {s, s, init_pos};
 		ImportedFile runtime_file = {s, s, init_pos};
 		array_add(&p->imports, runtime_file);
 		array_add(&p->imports, runtime_file);
 	}
 	}

+ 3 - 3
src/profiler.cpp

@@ -23,7 +23,7 @@ i64 prof_get_timestamp(void) {
 
 
 void prof_init(void) {
 void prof_init(void) {
 #if defined(PROF_TIMINGS)
 #if defined(PROF_TIMINGS)
-	map_init(&global_profiler.info, gb_heap_allocator());
+	map_init(&global_profiler.info, heap_allocator());
 	global_profiler.start_time = prof_get_timestamp();
 	global_profiler.start_time = prof_get_timestamp();
 #endif
 #endif
 }
 }
@@ -88,8 +88,8 @@ void prof_print_all(void) {
 	isize pad_len = gb_size_of(spaces)-1;
 	isize pad_len = gb_size_of(spaces)-1;
 
 
 	isize info_count = global_profiler.info.entries.count;
 	isize info_count = global_profiler.info.entries.count;
-	ProfInfo *info_data = gb_alloc_array(gb_heap_allocator(), ProfInfo, info_count);
-	defer (gb_free(gb_heap_allocator(), info_data));
+	ProfInfo *info_data = gb_alloc_array(heap_allocator(), ProfInfo, info_count);
+	defer (gb_free(heap_allocator(), info_data));
 	for (isize i = 0; i < info_count; i++) {
 	for (isize i = 0; i < info_count; i++) {
 		info_data[i] = global_profiler.info.entries[i].value;
 		info_data[i] = global_profiler.info.entries[i].value;
 	}
 	}

+ 1 - 1
src/string.cpp

@@ -3,7 +3,7 @@ gb_global gbAllocator string_buffer_allocator = {};
 
 
 void init_string_buffer_memory(void) {
 void init_string_buffer_memory(void) {
 	// NOTE(bill): This should be enough memory for file systems
 	// NOTE(bill): This should be enough memory for file systems
-	gb_arena_init_from_allocator(&string_buffer_arena, gb_heap_allocator(), gb_megabytes(1));
+	gb_arena_init_from_allocator(&string_buffer_arena, heap_allocator(), gb_megabytes(1));
 	string_buffer_allocator = gb_arena_allocator(&string_buffer_arena);
 	string_buffer_allocator = gb_arena_allocator(&string_buffer_arena);
 }
 }
 
 

+ 7 - 7
src/tokenizer.cpp

@@ -348,15 +348,15 @@ void advance_to_next_rune(Tokenizer *t) {
 TokenizerInitError init_tokenizer(Tokenizer *t, String fullpath) {
 TokenizerInitError init_tokenizer(Tokenizer *t, String fullpath) {
 	PROF_PROC();
 	PROF_PROC();
 
 
-	char *c_str = gb_alloc_array(gb_heap_allocator(), char, fullpath.len+1);
+	char *c_str = gb_alloc_array(heap_allocator(), char, fullpath.len+1);
 	memcpy(c_str, fullpath.text, fullpath.len);
 	memcpy(c_str, fullpath.text, fullpath.len);
 	c_str[fullpath.len] = '\0';
 	c_str[fullpath.len] = '\0';
 
 
-	defer (gb_free(gb_heap_allocator(), c_str));
+	defer (gb_free(heap_allocator(), c_str));
 
 
 
 
 	// TODO(bill): Memory map rather than copy contents
 	// TODO(bill): Memory map rather than copy contents
-	gbFileContents fc = gb_file_read_contents(gb_heap_allocator(), true, c_str);
+	gbFileContents fc = gb_file_read_contents(heap_allocator(), true, c_str);
 	gb_zero_item(t);
 	gb_zero_item(t);
 	if (fc.data != NULL) {
 	if (fc.data != NULL) {
 		t->start = cast(u8 *)fc.data;
 		t->start = cast(u8 *)fc.data;
@@ -372,7 +372,7 @@ TokenizerInitError init_tokenizer(Tokenizer *t, String fullpath) {
 			advance_to_next_rune(t); // Ignore BOM at file beginning
 			advance_to_next_rune(t); // Ignore BOM at file beginning
 		}
 		}
 
 
-		array_init(&t->allocated_strings, gb_heap_allocator());
+		array_init(&t->allocated_strings, heap_allocator());
 
 
 		return TokenizerInit_None;
 		return TokenizerInit_None;
 	}
 	}
@@ -399,10 +399,10 @@ TokenizerInitError init_tokenizer(Tokenizer *t, String fullpath) {
 
 
 gb_inline void destroy_tokenizer(Tokenizer *t) {
 gb_inline void destroy_tokenizer(Tokenizer *t) {
 	if (t->start != NULL) {
 	if (t->start != NULL) {
-		gb_free(gb_heap_allocator(), t->start);
+		gb_free(heap_allocator(), t->start);
 	}
 	}
 	for_array(i, t->allocated_strings) {
 	for_array(i, t->allocated_strings) {
-		gb_free(gb_heap_allocator(), t->allocated_strings[i].text);
+		gb_free(heap_allocator(), t->allocated_strings[i].text);
 	}
 	}
 	array_free(&t->allocated_strings);
 	array_free(&t->allocated_strings);
 }
 }
@@ -699,7 +699,7 @@ Token tokenizer_get_token(Tokenizer *t) {
 				}
 				}
 			}
 			}
 			token.string.len = t->curr - token.string.text;
 			token.string.len = t->curr - token.string.text;
-			i32 success = unquote_string(gb_heap_allocator(), &token.string);
+			i32 success = unquote_string(heap_allocator(), &token.string);
 			if (success > 0) {
 			if (success > 0) {
 				if (success == 2) {
 				if (success == 2) {
 					array_add(&t->allocated_strings, token.string);
 					array_add(&t->allocated_strings, token.string);