Pārlūkot izejas kodu

Change vector memory layout and operations; `for in` vector.

Ginger Bill 8 gadi atpakaļ
vecāks
revīzija
34150385d8
9 mainītis faili ar 445 papildinājumiem un 308 dzēšanām
  1. 16 0
      code/demo.odin
  2. 4 0
      core/_preload.odin
  3. 21 14
      core/fmt.odin
  4. 5 3
      src/check_stmt.c
  5. 44 36
      src/checker.c
  6. 201 137
      src/ir.c
  7. 12 12
      src/ir_opt.c
  8. 84 67
      src/ir_print.c
  9. 58 39
      src/types.c

+ 16 - 0
code/demo.odin

@@ -10,4 +10,20 @@ main :: proc() {
 		fmt.print(p);
 	}
 	fmt.println();
+
+	{
+		Vec3 :: [vector 3]f32;
+
+		x := Vec3{1, 2, 3};
+		y := Vec3{4, 5, 6};
+		fmt.println(x < y);
+		fmt.println(x + y);
+		fmt.println(x - y);
+		fmt.println(x * y);
+		fmt.println(x / y);
+
+		for i in x {
+			fmt.println(i);
+		}
+	}
 }

+ 4 - 0
core/_preload.odin

@@ -70,6 +70,10 @@ Type_Info :: union {
 		elem_size: int,
 		count:     int,
 	},
+	Dynamic_Array: struct #ordered {
+		elem:      ^Type_Info,
+		elem_size: int,
+	},
 	Slice: struct #ordered {
 		elem:      ^Type_Info,
 		elem_size: int,

+ 21 - 14
core/fmt.odin

@@ -173,6 +173,10 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
 		fmt_int(^fi, cast(u64)info.count, false, 'd');
 		buffer_write_string(buf, "]");
 		buffer_write_type(buf, info.elem);
+	case Dynamic_Array:
+		buffer_write_string(buf, "[dynamic");
+		buffer_write_string(buf, "]");
+		buffer_write_type(buf, info.elem);
 	case Slice:
 		buffer_write_string(buf, "[");
 		buffer_write_string(buf, "]");
@@ -792,6 +796,23 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 			fmt_arg(fi, any{info.elem, cast(rawptr)data}, 'v');
 		}
 
+	case Dynamic_Array:
+		if verb != 'v' {
+			fmt_bad_verb(fi, verb);
+			return;
+		}
+
+		buffer_write_byte(fi.buf, '[');
+		defer buffer_write_byte(fi.buf, ']');
+		array := cast(^Raw_Dynamic_Array)v.data;
+		for i in 0..<array.count {
+			if i > 0 {
+				buffer_write_string(fi.buf, ", ");
+			}
+			data := cast(^byte)array.data + i*info.elem_size;
+			fmt_arg(fi, any{info.elem, cast(rawptr)data}, 'v');
+		}
+
 	case Slice:
 		if verb != 'v' {
 			fmt_bad_verb(fi, verb);
@@ -810,23 +831,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 		}
 
 	case Vector:
-		is_bool :: proc(type_info: ^Type_Info) -> bool {
-			match type info in type_info {
-			case Named:
-				return is_bool(info.base);
-			case Boolean:
-				return true;
-			}
-			return false;
-		}
-
 		buffer_write_byte(fi.buf, '<');
 		defer buffer_write_byte(fi.buf, '>');
 
-		if is_bool(info.elem) {
-			return;
-		}
-
 		for i in 0..<info.count {
 			if i > 0 {
 				buffer_write_string(fi.buf, ", ");

+ 5 - 3
src/check_stmt.c

@@ -693,22 +693,24 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 					}
 					break;
 				case Type_Array:
-					// val = make_type_pointer(c->allocator, t->Array.elem);
 					val = t->Array.elem;
 					idx = t_int;
 					break;
 
 				case Type_DynamicArray:
-					// val = make_type_pointer(c->allocator, t->DynamicArray.elem);
 					val = t->DynamicArray.elem;
 					idx = t_int;
 					break;
 
 				case Type_Slice:
-					// val = make_type_pointer(c->allocator, t->Slice.elem);
 					val = t->Slice.elem;
 					idx = t_int;
 					break;
+
+				case Type_Vector:
+					val = t->Vector.elem;
+					idx = t_int;
+					break;
 				}
 			}
 

+ 44 - 36
src/checker.c

@@ -932,6 +932,12 @@ void add_type_info_type(Checker *c, Type *t) {
 		add_type_info_type(c, make_type_pointer(c->allocator, bt->Array.elem));
 		add_type_info_type(c, t_int);
 		break;
+	case Type_DynamicArray:
+		add_type_info_type(c, bt->DynamicArray.elem);
+		add_type_info_type(c, make_type_pointer(c->allocator, bt->DynamicArray.elem));
+		add_type_info_type(c, t_int);
+		add_type_info_type(c, t_allocator);
+		break;
 	case Type_Slice:
 		add_type_info_type(c, bt->Slice.elem);
 		add_type_info_type(c, make_type_pointer(c->allocator, bt->Slice.elem));
@@ -1104,44 +1110,46 @@ void init_preload(Checker *c) {
 		t_type_info_enum_value_ptr = make_type_pointer(c->allocator, t_type_info_enum_value);
 
 
-		if (record->field_count != 18) {
+		if (record->field_count != 19) {
 			compiler_error("Invalid `Type_Info` layout");
 		}
-		t_type_info_named     = record->fields[ 1]->type;
-		t_type_info_integer   = record->fields[ 2]->type;
-		t_type_info_float     = record->fields[ 3]->type;
-		t_type_info_any       = record->fields[ 4]->type;
-		t_type_info_string    = record->fields[ 5]->type;
-		t_type_info_boolean   = record->fields[ 6]->type;
-		t_type_info_pointer   = record->fields[ 7]->type;
-		t_type_info_maybe     = record->fields[ 8]->type;
-		t_type_info_procedure = record->fields[ 9]->type;
-		t_type_info_array     = record->fields[10]->type;
-		t_type_info_slice     = record->fields[11]->type;
-		t_type_info_vector    = record->fields[12]->type;
-		t_type_info_tuple     = record->fields[13]->type;
-		t_type_info_struct    = record->fields[14]->type;
-		t_type_info_union     = record->fields[15]->type;
-		t_type_info_raw_union = record->fields[16]->type;
-		t_type_info_enum      = record->fields[17]->type;
-
-		t_type_info_named_ptr     = make_type_pointer(heap_allocator(), t_type_info_named);
-		t_type_info_integer_ptr   = make_type_pointer(heap_allocator(), t_type_info_integer);
-		t_type_info_float_ptr     = make_type_pointer(heap_allocator(), t_type_info_float);
-		t_type_info_any_ptr       = make_type_pointer(heap_allocator(), t_type_info_any);
-		t_type_info_string_ptr    = make_type_pointer(heap_allocator(), t_type_info_string);
-		t_type_info_boolean_ptr   = make_type_pointer(heap_allocator(), t_type_info_boolean);
-		t_type_info_pointer_ptr   = make_type_pointer(heap_allocator(), t_type_info_pointer);
-		t_type_info_maybe_ptr     = make_type_pointer(heap_allocator(), t_type_info_maybe);
-		t_type_info_procedure_ptr = make_type_pointer(heap_allocator(), t_type_info_procedure);
-		t_type_info_array_ptr     = make_type_pointer(heap_allocator(), t_type_info_array);
-		t_type_info_slice_ptr     = make_type_pointer(heap_allocator(), t_type_info_slice);
-		t_type_info_vector_ptr    = make_type_pointer(heap_allocator(), t_type_info_vector);
-		t_type_info_tuple_ptr     = make_type_pointer(heap_allocator(), t_type_info_tuple);
-		t_type_info_struct_ptr    = make_type_pointer(heap_allocator(), t_type_info_struct);
-		t_type_info_union_ptr     = make_type_pointer(heap_allocator(), t_type_info_union);
-		t_type_info_raw_union_ptr = make_type_pointer(heap_allocator(), t_type_info_raw_union);
-		t_type_info_enum_ptr      = make_type_pointer(heap_allocator(), t_type_info_enum);
+		t_type_info_named         = record->fields[ 1]->type;
+		t_type_info_integer       = record->fields[ 2]->type;
+		t_type_info_float         = record->fields[ 3]->type;
+		t_type_info_any           = record->fields[ 4]->type;
+		t_type_info_string        = record->fields[ 5]->type;
+		t_type_info_boolean       = record->fields[ 6]->type;
+		t_type_info_pointer       = record->fields[ 7]->type;
+		t_type_info_maybe         = record->fields[ 8]->type;
+		t_type_info_procedure     = record->fields[ 9]->type;
+		t_type_info_array         = record->fields[10]->type;
+		t_type_info_dynamic_array = record->fields[11]->type;
+		t_type_info_slice         = record->fields[12]->type;
+		t_type_info_vector        = record->fields[13]->type;
+		t_type_info_tuple         = record->fields[14]->type;
+		t_type_info_struct        = record->fields[15]->type;
+		t_type_info_union         = record->fields[16]->type;
+		t_type_info_raw_union     = record->fields[17]->type;
+		t_type_info_enum          = record->fields[18]->type;
+
+		t_type_info_named_ptr         = make_type_pointer(heap_allocator(), t_type_info_named);
+		t_type_info_integer_ptr       = make_type_pointer(heap_allocator(), t_type_info_integer);
+		t_type_info_float_ptr         = make_type_pointer(heap_allocator(), t_type_info_float);
+		t_type_info_any_ptr           = make_type_pointer(heap_allocator(), t_type_info_any);
+		t_type_info_string_ptr        = make_type_pointer(heap_allocator(), t_type_info_string);
+		t_type_info_boolean_ptr       = make_type_pointer(heap_allocator(), t_type_info_boolean);
+		t_type_info_pointer_ptr       = make_type_pointer(heap_allocator(), t_type_info_pointer);
+		t_type_info_maybe_ptr         = make_type_pointer(heap_allocator(), t_type_info_maybe);
+		t_type_info_procedure_ptr     = make_type_pointer(heap_allocator(), t_type_info_procedure);
+		t_type_info_array_ptr         = make_type_pointer(heap_allocator(), t_type_info_array);
+		t_type_info_dynamic_array_ptr = make_type_pointer(heap_allocator(), t_type_info_dynamic_array);
+		t_type_info_slice_ptr         = make_type_pointer(heap_allocator(), t_type_info_slice);
+		t_type_info_vector_ptr        = make_type_pointer(heap_allocator(), t_type_info_vector);
+		t_type_info_tuple_ptr         = make_type_pointer(heap_allocator(), t_type_info_tuple);
+		t_type_info_struct_ptr        = make_type_pointer(heap_allocator(), t_type_info_struct);
+		t_type_info_union_ptr         = make_type_pointer(heap_allocator(), t_type_info_union);
+		t_type_info_raw_union_ptr     = make_type_pointer(heap_allocator(), t_type_info_raw_union);
+		t_type_info_enum_ptr          = make_type_pointer(heap_allocator(), t_type_info_enum);
 	}
 
 	if (t_allocator == NULL) {

+ 201 - 137
src/ir.c

@@ -150,7 +150,7 @@ struct irProcedure {
 	}) \
 	IR_INSTR_KIND(ArrayElementPtr, struct { \
 		irValue *address; \
-		Type *    result_type; \
+		Type *   result_type; \
 		irValue *elem_index; \
 	}) \
 	IR_INSTR_KIND(StructElementPtr, struct {  \
@@ -206,7 +206,7 @@ struct irProcedure {
 		irValue **args; \
 		isize      arg_count; \
 	}) \
-	IR_INSTR_KIND(VectorExtractElement, struct { \
+	/* IR_INSTR_KIND(VectorExtractElement, struct { \
 		irValue *vector; \
 		irValue *index; \
 	}) \
@@ -220,7 +220,7 @@ struct irProcedure {
 		i32 *     indices; \
 		i32       index_count; \
 		Type *    type; \
-	}) \
+	})  */\
 	IR_INSTR_KIND(StartupRuntime, i32) \
 	IR_INSTR_KIND(BoundsCheck, struct { \
 		TokenPos  pos; \
@@ -375,28 +375,29 @@ gb_global irValue *v_true    = NULL;
 
 typedef enum irAddrKind {
 	irAddr_Default,
-	irAddr_Vector,
+	// irAddr_Vector,
 } irAddrKind;
 
 typedef struct irAddr {
 	irValue *  addr;
-	AstNode *    expr; // NOTE(bill): Just for testing - probably remove later
-	irAddrKind kind;
-	union {
-		struct { irValue *index; } Vector;
-	};
+	AstNode *  expr; // NOTE(bill): Just for testing - probably remove later
+	// irAddrKind kind;
+	// union {
+		// struct { irValue *index; } Vector;
+	// };
 } irAddr;
 
 irAddr ir_make_addr(irValue *addr, AstNode *expr) {
 	irAddr v = {addr, expr};
 	return v;
 }
-irAddr ir_make_addr_vector(irValue *addr, irValue *index, AstNode *expr) {
-	irAddr v = ir_make_addr(addr, expr);
-	v.kind = irAddr_Vector;
-	v.Vector.index = index;
-	return v;
-}
+
+// irAddr ir_make_addr_vector(irValue *addr, irValue *index, AstNode *expr) {
+// 	irAddr v = ir_make_addr(addr, expr);
+// 	v.kind = irAddr_Vector;
+// 	v.Vector.index = index;
+// 	return v;
+// }
 
 
 
@@ -571,7 +572,7 @@ Type *ir_instr_type(irInstr *instr) {
 		}
 		return NULL;
 	} break;
-	case irInstr_VectorExtractElement: {
+/* 	case irInstr_VectorExtractElement: {
 		Type *vt = ir_type(instr->VectorExtractElement.vector);
 		Type *bt = base_vector_type(vt);
 		GB_ASSERT(!is_type_vector(bt));
@@ -581,6 +582,7 @@ Type *ir_instr_type(irInstr *instr) {
 		return ir_type(instr->VectorInsertElement.vector);
 	case irInstr_VectorShuffle:
 		return instr->VectorShuffle.type;
+ */
 	}
 	return NULL;
 }
@@ -952,6 +954,7 @@ irValue *ir_make_instr_conv(irProcedure *p, irConvKind kind, irValue *value, Typ
 	return v;
 }
 
+/*
 irValue *ir_make_instr_extract_element(irProcedure *p, irValue *vector, irValue *index) {
 	irValue *v = ir_alloc_instr(p, irInstr_VectorExtractElement);
 	v->Instr.VectorExtractElement.vector = vector;
@@ -978,7 +981,7 @@ irValue *ir_make_instr_vector_shuffle(irProcedure *p, irValue *vector, i32 *indi
 
 	return v;
 }
-
+*/
 irValue *ir_make_instr_comment(irProcedure *p, String text) {
 	irValue *v = ir_alloc_instr(p, irInstr_Comment);
 	v->Instr.Comment.text = text;
@@ -1422,16 +1425,16 @@ irValue *ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
 		return NULL;
 	}
 
-	if (addr.kind == irAddr_Vector) {
-		irValue *v = ir_emit_load(proc, addr.addr);
-		Type *elem_type = base_type(ir_type(v))->Vector.elem;
-		irValue *elem = ir_emit_conv(proc, value, elem_type);
-		irValue *out = ir_emit(proc, ir_make_instr_insert_element(proc, v, elem, addr.Vector.index));
-		return ir_emit_store(proc, addr.addr, out);
-	} else {
+	// if (addr.kind == irAddr_Vector) {
+		// irValue *v = ir_emit_load(proc, addr.addr);
+		// Type *elem_type = base_type(ir_type(v))->Vector.elem;
+		// irValue *elem = ir_emit_conv(proc, value, elem_type);
+		// irValue *out = ir_emit(proc, ir_make_instr_insert_element(proc, v, elem, addr.Vector.index));
+		// return ir_emit_store(proc, addr.addr, out);
+	// } else {
 		irValue *v = ir_emit_conv(proc, value, ir_addr_type(addr));
 		return ir_emit_store(proc, addr.addr, v);
-	}
+	// }
 }
 irValue *ir_addr_load(irProcedure *proc, irAddr addr) {
 	if (addr.addr == NULL) {
@@ -1439,10 +1442,10 @@ irValue *ir_addr_load(irProcedure *proc, irAddr addr) {
 		return NULL;
 	}
 
-	if (addr.kind == irAddr_Vector) {
-		irValue *v = ir_emit_load(proc, addr.addr);
-		return ir_emit(proc, ir_make_instr_extract_element(proc, v, addr.Vector.index));
-	}
+	// if (addr.kind == irAddr_Vector) {
+		// irValue *v = ir_emit_load(proc, addr.addr);
+		// return ir_emit(proc, ir_make_instr_extract_element(proc, v, addr.Vector.index));
+	// }
 	Type *t = base_type(ir_type(addr.addr));
 	if (t->kind == Type_Proc) {
 		// NOTE(bill): Imported procedures don't require a load as they are pointers
@@ -1451,18 +1454,50 @@ irValue *ir_addr_load(irProcedure *proc, irAddr addr) {
 	return ir_emit_load(proc, addr.addr);
 }
 
-
-
+irValue *ir_emit_array_epi(irProcedure *proc, irValue *s, i32 index);
 
 irValue *ir_emit_ptr_offset(irProcedure *proc, irValue *ptr, irValue *offset) {
 	offset = ir_emit_conv(proc, offset, t_int);
 	return ir_emit(proc, ir_make_instr_ptr_offset(proc, ptr, offset));
 }
 
+// NOTE(bill): Returns NULL if not possible
+irValue *ir_address_from_load_or_generate_local(irProcedure *proc, irValue *val) {
+	if (val->kind == irValue_Instr) {
+		if (val->Instr.kind == irInstr_Load) {
+			return val->Instr.Load.address;
+		}
+	}
+	Type *type = ir_type(val);
+	irValue *local = ir_add_local_generated(proc, type);
+	ir_emit_store(proc, local, val);
+	return local;
+}
+
 irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *right, Type *type) {
 	Type *t_left = ir_type(left);
 	Type *t_right = ir_type(right);
 
+	if (is_type_vector(t_left)) {
+		// IMPORTANT TODO(bill): This is very wasteful with regards to stack memory
+		Type *tl = base_type(t_left);
+		irValue *lhs = ir_address_from_load_or_generate_local(proc, left);
+		irValue *rhs = ir_address_from_load_or_generate_local(proc, right);
+		GB_ASSERT(is_type_vector(type));
+		Type *elem_type = base_type(type)->Vector.elem;
+
+		irValue *res = ir_add_local_generated(proc, type);
+		for (i32 i = 0; i < tl->Vector.count; i++) {
+			irValue *x = ir_emit_load(proc, ir_emit_array_epi(proc, lhs, i));
+			irValue *y = ir_emit_load(proc, ir_emit_array_epi(proc, rhs, i));
+			irValue *z = ir_emit_arith(proc, op, x, y, elem_type);
+			ir_emit_store(proc, ir_emit_array_epi(proc, res, i), z);
+		}
+
+		return ir_emit_load(proc, res);
+	}
+
+
 	if (op == Token_Add) {
 		if (is_type_pointer(t_left)) {
 			irValue *ptr = ir_emit_conv(proc, left, type);
@@ -1550,6 +1585,28 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
 	if (is_type_vector(a)) {
 		result = make_type_vector(proc->module->allocator, t_bool, a->Vector.count);
 	}
+
+	if (is_type_vector(a)) {
+		// IMPORTANT TODO(bill): This is very wasteful with regards to stack memory
+		Type *tl = base_type(a);
+		irValue *lhs = ir_address_from_load_or_generate_local(proc, left);
+		irValue *rhs = ir_address_from_load_or_generate_local(proc, right);
+
+		GB_ASSERT(is_type_vector(result));
+		Type *elem_type = base_type(result)->Vector.elem;
+
+		irValue *res = ir_add_local_generated(proc, result);
+		for (i32 i = 0; i < tl->Vector.count; i++) {
+			irValue *x = ir_emit_load(proc, ir_emit_array_epi(proc, lhs, i));
+			irValue *y = ir_emit_load(proc, ir_emit_array_epi(proc, rhs, i));
+			irValue *z = ir_emit_comp(proc, op_kind, x, y);
+			ir_emit_store(proc, ir_emit_array_epi(proc, res, i), z);
+		}
+
+		return ir_emit_load(proc, res);
+	}
+
+
 	return ir_emit(proc, ir_make_instr_binary_op(proc, op_kind, left, right, result));
 }
 
@@ -1786,6 +1843,11 @@ irValue *ir_array_len(irProcedure *proc, irValue *array) {
 	return ir_make_const_int(proc->module->allocator, t->Array.count);
 }
 
+irValue *ir_vector_elem(irProcedure *proc, irValue *vector) {
+	return ir_emit_array_ep(proc, vector, v_one32);
+}
+
+
 irValue *ir_slice_elem(irProcedure *proc, irValue *slice) {
 	Type *t = base_type(ir_type(slice));
 	GB_ASSERT(t->kind == Type_Slice);
@@ -2125,17 +2187,13 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
 		Type *dst_elem = dst->Vector.elem;
 		value = ir_emit_conv(proc, value, dst_elem);
 		irValue *v = ir_add_local_generated(proc, t);
-		v = ir_emit_load(proc, v);
-		v = ir_emit(proc, ir_make_instr_insert_element(proc, v, value, v_zero32));
-		// NOTE(bill): Broadcast lowest value to all values
 		isize index_count = dst->Vector.count;
-		i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
-		for (isize i = 0; i < index_count; i++) {
-			indices[i] = 0;
-		}
 
-		v = ir_emit(proc, ir_make_instr_vector_shuffle(proc, v, indices, index_count));
-		return v;
+		for (i32 i = 0; i < index_count; i++) {
+			irValue *elem = ir_emit_array_epi(proc, v, i);
+			ir_emit_store(proc, elem, value);
+		}
+		return ir_emit_load(proc, v);
 	}
 
 	if (is_type_any(dst)) {
@@ -2230,9 +2288,7 @@ irValue *ir_emit_transmute(irProcedure *proc, irValue *value, Type *t) {
 	GB_ASSERT_MSG(sz == dz, "Invalid transmute conversion: `%s` to `%s`", type_to_string(src_type), type_to_string(t));
 
 	if (ir_is_type_aggregate(src) || ir_is_type_aggregate(dst)) {
-		irValue *s = ir_add_local_generated(proc, src);
-		ir_emit_store(proc, s, value);
-
+		irValue *s = ir_address_from_load_or_generate_local(proc, value);
 		irValue *d = ir_emit_bitcast(proc, s, make_type_pointer(m->allocator, dst));
 		return ir_emit_load(proc, d);
 	}
@@ -2318,8 +2374,7 @@ irValue *ir_emit_union_cast(irProcedure *proc, irValue *value, Type *tuple) {
 		GB_ASSERT(dst_tag != NULL);
 
 		// HACK(bill): This is probably not very efficient
-		irValue *union_copy = ir_add_local_generated(proc, src_type);
-		ir_emit_store(proc, union_copy, value);
+		irValue *union_ptr = ir_address_from_load_or_generate_local(proc, value);
 
 		irBlock *ok_block = ir_add_block(proc, NULL, "union_cast.ok");
 		irBlock *end_block = ir_add_block(proc, NULL, "union_cast.end");
@@ -2330,7 +2385,7 @@ irValue *ir_emit_union_cast(irProcedure *proc, irValue *value, Type *tuple) {
 		irValue *gep0 = ir_emit_struct_ep(proc, v, 0);
 		irValue *gep1 = ir_emit_struct_ep(proc, v, 1);
 
-		irValue *data = ir_emit_load(proc, ir_emit_conv(proc, union_copy, dst_ptr));
+		irValue *data = ir_emit_load(proc, ir_emit_conv(proc, union_ptr, dst_ptr));
 		ir_emit_store(proc, gep0, data);
 		ir_emit_store(proc, gep1, v_true);
 
@@ -3196,85 +3251,32 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
 
 					return len;
 				} break;
-				#if 0
-				case BuiltinProc_append: {
-					ir_emit_comment(proc, str_lit("append"));
-					// append :: proc(s: ^[]Type, item: Type) -> bool
-					AstNode *sptr_node = ce->args.e[0];
-					AstNode *item_node = ce->args.e[1];
-					irValue *slice_ptr = ir_build_expr(proc, sptr_node);
-					irValue *slice = ir_emit_load(proc, slice_ptr);
-
-					irValue *elem = ir_slice_elem(proc, slice);
-					irValue *len  = ir_slice_count(proc,  slice);
-					irValue *cap  = ir_slice_cap(proc,  slice);
-
-					Type *elem_type = type_deref(ir_type(elem));
-
-					irValue *item_value = ir_build_expr(proc, item_node);
-					item_value = ir_emit_conv(proc, item_value, elem_type);
-
-					irValue *item = ir_add_local_generated(proc, elem_type);
-					ir_emit_store(proc, item, item_value);
-
-
-					// NOTE(bill): Check if can append is possible
-					irValue *cond = ir_emit_comp(proc, Token_Lt, len, cap);
-					irBlock *able = ir_add_block(proc, NULL, "builtin.append.able");
-					irBlock *done = ir_add_block(proc, NULL, "builtin.append.done");
-
-					ir_emit_if(proc, cond, able, done);
-					proc->curr_block = able;
-
-					// Add new slice item
-					i64 item_size = type_size_of(proc->module->sizes, proc->module->allocator, elem_type);
-					irValue *byte_count = ir_make_const_int(proc->module->allocator, item_size);
-
-					irValue *offset = ir_emit_ptr_offset(proc, elem, len);
-					offset = ir_emit_conv(proc, offset, t_rawptr);
-
-					item = ir_emit_ptr_offset(proc, item, v_zero);
-					item = ir_emit_conv(proc, item, t_rawptr);
-
-					irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 3);
-					args[0] = offset;
-					args[1] = item;
-					args[2] = byte_count;
-
-					ir_emit_global_call(proc, "__mem_copy", args, 3);
-
-					// Increment slice length
-					irValue *new_len = ir_emit_arith(proc, Token_Add, len, v_one, t_int);
-					irValue *gep = ir_emit_struct_ep(proc, slice_ptr, 1);
-					ir_emit_store(proc, gep, new_len);
-
-					ir_emit_jump(proc, done);
-					proc->curr_block = done;
-
-					return ir_emit_conv(proc, cond, t_bool);
-				} break;
-				#endif
-
 				case BuiltinProc_swizzle: {
 					ir_emit_comment(proc, str_lit("swizzle"));
-					irValue *vector = ir_build_expr(proc, ce->args.e[0]);
+					irAddr vector_addr = ir_build_addr(proc, ce->args.e[0]);
 					isize index_count = ce->args.count-1;
 					if (index_count == 0) {
-						return vector;
+						return ir_addr_load(proc, vector_addr);
 					}
+					irValue *src = vector_addr.addr;
+					irValue *dst = ir_add_local_generated(proc, tv->type);
 
-					i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
-					isize index = 0;
-					for_array(i, ce->args) {
-						if (i == 0) continue;
+					for (i32 i = 1; i < ce->args.count; i++) {
 						TypeAndValue *tv = type_and_value_of_expression(proc->module->info, ce->args.e[i]);
 						GB_ASSERT(is_type_integer(tv->type));
 						GB_ASSERT(tv->value.kind == ExactValue_Integer);
-						indices[index++] = cast(i32)tv->value.value_integer;
-					}
 
-					return ir_emit(proc, ir_make_instr_vector_shuffle(proc, vector, indices, index_count));
+						i32 src_index = cast(i32)tv->value.value_integer;
+						i32 dst_index = i-1;
 
+						irValue *src_elem = ir_emit_array_epi(proc, src, src_index);
+						irValue *dst_elem = ir_emit_array_epi(proc, dst, dst_index);
+
+						ir_emit_store(proc, dst_elem, ir_emit_load(proc, src_elem));
+					}
+
+					return ir_emit_load(proc, dst);
+					// return ir_emit(proc, ir_make_instr_vector_shuffle(proc, vector, indices, index_count));
 				} break;
 
 				case BuiltinProc_slice_ptr: {
@@ -3656,6 +3658,20 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 
 		switch (t->kind) {
 		case Type_Vector: {
+			/* irValue *vector = NULL;
+			if (using_addr != NULL) {
+				vector = using_addr;
+			} else {
+				vector = ir_build_addr(proc, ie->expr).addr;
+				if (deref) {
+					vector = ir_emit_load(proc, vector);
+				}
+			}
+			irValue *index = ir_emit_conv(proc, ir_build_expr(proc, ie->index), t_int);
+			irValue *len = ir_make_const_int(a, t->Vector.count);
+			ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
+			return ir_make_addr_vector(vector, index, expr); */
+
 			irValue *vector = NULL;
 			if (using_addr != NULL) {
 				vector = using_addr;
@@ -3666,9 +3682,10 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 				}
 			}
 			irValue *index = ir_emit_conv(proc, ir_build_expr(proc, ie->index), t_int);
+			irValue *elem = ir_emit_array_ep(proc, vector, index);
 			irValue *len = ir_make_const_int(a, t->Vector.count);
 			ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
-			return ir_make_addr_vector(vector, index, expr);
+			return ir_make_addr(elem, expr);
 		} break;
 
 		case Type_Array: {
@@ -3895,31 +3912,55 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 		default: GB_PANIC("Unknown CompoundLit type: %s", type_to_string(type)); break;
 
 		case Type_Vector: {
-			irValue *result = ir_add_module_constant(proc->module, type, make_exact_value_compound(expr));
-			for_array(index, cl->elems) {
-				AstNode *elem = cl->elems.e[index];
-				if (ir_is_elem_const(proc->module, elem, et)) {
-					continue;
-				}
-				irValue *field_elem = ir_build_expr(proc, elem);
-				Type *t = ir_type(field_elem);
-				GB_ASSERT(t->kind != Type_Tuple);
-				irValue *ev = ir_emit_conv(proc, field_elem, et);
-				irValue *i = ir_make_const_int(proc->module->allocator, index);
-				result = ir_emit(proc, ir_make_instr_insert_element(proc, result, ev, i));
-			}
-
+			irValue *vector_elem = ir_vector_elem(proc, v);
 			if (cl->elems.count == 1 && bt->Vector.count > 1) {
 				isize index_count = bt->Vector.count;
-				i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
+				irValue *elem_val = ir_build_expr(proc, cl->elems.e[0]);
 				for (isize i = 0; i < index_count; i++) {
-					indices[i] = 0;
+					ir_emit_store(proc, ir_emit_array_epi(proc, vector_elem, i), elem_val);
+				}
+			} else if (cl->elems.count > 0) {
+				ir_emit_store(proc, vector_elem, ir_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
+				for_array(i, cl->elems) {
+					AstNode *elem = cl->elems.e[i];
+					if (ir_is_elem_const(proc->module, elem, et)) {
+						continue;
+					}
+					irValue *field_expr = ir_build_expr(proc, elem);
+					Type *t = ir_type(field_expr);
+					GB_ASSERT(t->kind != Type_Tuple);
+					irValue *ev = ir_emit_conv(proc, field_expr, et);
+					irValue *gep = ir_emit_array_epi(proc, vector_elem, i);
+					ir_emit_store(proc, gep, ev);
 				}
-				irValue *sv = ir_emit(proc, ir_make_instr_vector_shuffle(proc, result, indices, index_count));
-				ir_emit_store(proc, v, sv);
-				return ir_make_addr(v, expr);
 			}
-			ir_emit_store(proc, v, result);
+
+
+			// irValue *result = ir_add_module_constant(proc->module, type, make_exact_value_compound(expr));
+			// for_array(index, cl->elems) {
+			// 	AstNode *elem = cl->elems.e[index];
+			// 	if (ir_is_elem_const(proc->module, elem, et)) {
+			// 		continue;
+			// 	}
+			// 	irValue *field_elem = ir_build_expr(proc, elem);
+			// 	Type *t = ir_type(field_elem);
+			// 	GB_ASSERT(t->kind != Type_Tuple);
+			// 	irValue *ev = ir_emit_conv(proc, field_elem, et);
+			// 	irValue *i = ir_make_const_int(proc->module->allocator, index);
+			// 	result = ir_emit(proc, ir_make_instr_insert_element(proc, result, ev, i));
+			// }
+
+			// if (cl->elems.count == 1 && bt->Vector.count > 1) {
+			// 	isize index_count = bt->Vector.count;
+			// 	i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
+			// 	for (isize i = 0; i < index_count; i++) {
+			// 		indices[i] = 0;
+			// 	}
+			// 	irValue *sv = ir_emit(proc, ir_make_instr_vector_shuffle(proc, result, indices, index_count));
+			// 	ir_emit_store(proc, v, sv);
+			// 	return ir_make_addr(v, expr);
+			// }
+			// ir_emit_store(proc, v, result);
 		} break;
 
 		case Type_Record: {
@@ -4188,6 +4229,9 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
 	case Type_Array:
 		count = ir_make_const_int(proc->module->allocator, expr_type->Array.count);
 		break;
+	case Type_Vector:
+		count = ir_make_const_int(proc->module->allocator, expr_type->Vector.count);
+		break;
 	}
 
 	irValue *val = NULL;
@@ -4219,7 +4263,9 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
 	if (val_type != NULL) {
 		switch (expr_type->kind) {
 		case Type_Array: {
-			// val = ir_emit_array_ep(proc, expr, idx);
+			val = ir_emit_load(proc, ir_emit_array_ep(proc, expr, idx));
+		} break;
+		case Type_Vector: {
 			val = ir_emit_load(proc, ir_emit_array_ep(proc, expr, idx));
 		} break;
 		case Type_Slice: {
@@ -4795,6 +4841,16 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 				ir_emit_store(proc, count_ptr, ir_make_const_int(proc->module->allocator, et->Array.count));
 				ir_build_range_indexed(proc, array, val_type, count_ptr, &val, &index, &loop, &done);
 			} break;
+			case Type_Vector: {
+				irValue *count_ptr = NULL;
+				irValue *vector = ir_build_addr(proc, rs->expr).addr;
+				if (is_type_pointer(type_deref(ir_type(vector)))) {
+					vector = ir_emit_load(proc, vector);
+				}
+				count_ptr = ir_add_local_generated(proc, t_int);
+				ir_emit_store(proc, count_ptr, ir_make_const_int(proc->module->allocator, et->Vector.count));
+				ir_build_range_indexed(proc, vector, val_type, count_ptr, &val, &index, &loop, &done);
+			} break;
 			case Type_DynamicArray: {
 				irValue *count_ptr = NULL;
 				irValue *array = ir_build_addr(proc, rs->expr).addr;
@@ -5942,6 +5998,15 @@ void ir_gen_tree(irGen *s) {
 					ir_emit_store(proc, count, ir_make_const_int(a, t->Array.count));
 
 				} break;
+				case Type_DynamicArray: {
+					tag = ir_emit_conv(proc, ti_ptr, t_type_info_dynamic_array_ptr);
+					irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->DynamicArray.elem);
+					ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
+
+					isize ez = type_size_of(m->sizes, a, t->DynamicArray.elem);
+					irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
+					ir_emit_store(proc, elem_size, ir_make_const_int(a, ez));
+				} break;
 				case Type_Slice: {
 					tag = ir_emit_conv(proc, ti_ptr, t_type_info_slice_ptr);
 					irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Slice.elem);
@@ -5950,7 +6015,6 @@ void ir_gen_tree(irGen *s) {
 					isize ez = type_size_of(m->sizes, a, t->Slice.elem);
 					irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
 					ir_emit_store(proc, elem_size, ir_make_const_int(a, ez));
-
 				} break;
 				case Type_Vector: {
 					tag = ir_emit_conv(proc, ti_ptr, t_type_info_vector_ptr);

+ 12 - 12
src/ir_opt.c

@@ -66,18 +66,18 @@ void ir_opt_add_operands(irValueArray *ops, irInstr *i) {
 			array_add(ops, i->Call.args[j]);
 		}
 		break;
-	case irInstr_VectorExtractElement:
-		array_add(ops, i->VectorExtractElement.vector);
-		array_add(ops, i->VectorExtractElement.index);
-		break;
-	case irInstr_VectorInsertElement:
-		array_add(ops, i->VectorInsertElement.vector);
-		array_add(ops, i->VectorInsertElement.elem);
-		array_add(ops, i->VectorInsertElement.index);
-		break;
-	case irInstr_VectorShuffle:
-		array_add(ops, i->VectorShuffle.vector);
-		break;
+	// case irInstr_VectorExtractElement:
+		// array_add(ops, i->VectorExtractElement.vector);
+		// array_add(ops, i->VectorExtractElement.index);
+		// break;
+	// case irInstr_VectorInsertElement:
+		// array_add(ops, i->VectorInsertElement.vector);
+		// array_add(ops, i->VectorInsertElement.elem);
+		// array_add(ops, i->VectorInsertElement.index);
+		// break;
+	// case irInstr_VectorShuffle:
+		// array_add(ops, i->VectorShuffle.vector);
+		// break;
 	case irInstr_StartupRuntime:
 		break;
 	case irInstr_BoundsCheck:

+ 84 - 67
src/ir_print.c

@@ -184,11 +184,18 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 		ir_print_type(f, m, t->Array.elem);
 		ir_fprintf(f, "]");
 		return;
-	case Type_Vector:
-		ir_fprintf(f, "<%lld x ", t->Vector.count);
+	case Type_Vector: {
+		i64 align = type_align_of(s, heap_allocator(), t);
+		i64 count = t->Vector.count;
+		ir_fprintf(f, "{[0 x <%lld x i8>], [%lld x ", align, count);
 		ir_print_type(f, m, t->Vector.elem);
-		ir_fprintf(f, ">");
+		ir_fprintf(f, "]}");
 		return;
+	}
+/* 		ir_fprintf(f, "<%lld x ", t->Vector.count);
+		ir_print_type(f, m, t->Vector.elem);
+		ir_fprintf(f, ">");
+		return; */
 	case Type_Slice:
 		ir_fprintf(f, "{");
 		ir_print_type(f, m, t->Slice.elem);
@@ -458,9 +465,14 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
 				break;
 			}
 
-			ir_fprintf(f, "<");
+			i64 align = type_align_of(m->sizes, m->allocator, type);
+			i64 count = type->Vector.count;
 			Type *elem_type = type->Vector.elem;
 
+			ir_fprintf(f, "{[0 x <%lld x i8>] zeroinitializer, [%lld x ", align, count);
+			ir_print_type(f, m, elem_type);
+			ir_fprintf(f, "][");
+
 			if (elem_count == 1 && type->Vector.count > 1) {
 				TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[0]);
 				GB_ASSERT(tav != NULL);
@@ -482,7 +494,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
 				}
 			}
 
-			ir_fprintf(f, ">");
+			ir_fprintf(f, "]}");
 		} else if (is_type_struct(type)) {
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
 
@@ -727,6 +739,10 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
 		ir_fprintf(f, ", ");
 		ir_print_type(f, m, t_int);
 		ir_fprintf(f, " 0, ");
+		if (is_type_vector(type_deref(et))) {
+			ir_print_type(f, m, t_i32);
+			ir_fprintf(f, " 1, ");
+		}
 
 		irValue *index =instr->ArrayElementPtr.elem_index;
 		Type *t = ir_type(index);
@@ -936,6 +952,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
 		irInstrBinaryOp *bo = &value->Instr.BinaryOp;
 		Type *type = base_type(ir_type(bo->left));
 		Type *elem_type = type;
+		GB_ASSERT(!is_type_vector(elem_type));
 		while (elem_type->kind == Type_Vector) {
 			elem_type = base_type(elem_type->Vector.elem);
 		}
@@ -1102,68 +1119,68 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
 		ir_fprintf(f, "\n");
 	} break;
 
-	case irInstr_VectorExtractElement: {
-		Type *vt = ir_type(instr->VectorExtractElement.vector);
-		Type *it = ir_type(instr->VectorExtractElement.index);
-		ir_fprintf(f, "%%%d = extractelement ", value->index);
-
-		ir_print_type(f, m, vt);
-		ir_fprintf(f, " ");
-		ir_print_value(f, m, instr->VectorExtractElement.vector, vt);
-		ir_fprintf(f, ", ");
-		ir_print_type(f, m, it);
-		ir_fprintf(f, " ");
-		ir_print_value(f, m, instr->VectorExtractElement.index, it);
-		ir_fprintf(f, "\n");
-	} break;
-
-	case irInstr_VectorInsertElement: {
-		irInstrVectorInsertElement *ie = &instr->VectorInsertElement;
-		Type *vt = ir_type(ie->vector);
-		ir_fprintf(f, "%%%d = insertelement ", value->index);
-
-		ir_print_type(f, m, vt);
-		ir_fprintf(f, " ");
-		ir_print_value(f, m, ie->vector, vt);
-		ir_fprintf(f, ", ");
-
-		ir_print_type(f, m, ir_type(ie->elem));
-		ir_fprintf(f, " ");
-		ir_print_value(f, m, ie->elem, ir_type(ie->elem));
-		ir_fprintf(f, ", ");
-
-		ir_print_type(f, m, ir_type(ie->index));
-		ir_fprintf(f, " ");
-		ir_print_value(f, m, ie->index, ir_type(ie->index));
-
-		ir_fprintf(f, "\n");
-	} break;
-
-	case irInstr_VectorShuffle: {
-		irInstrVectorShuffle *sv = &instr->VectorShuffle;
-		Type *vt = ir_type(sv->vector);
-		ir_fprintf(f, "%%%d = shufflevector ", value->index);
-
-		ir_print_type(f, m, vt);
-		ir_fprintf(f, " ");
-		ir_print_value(f, m, sv->vector, vt);
-		ir_fprintf(f, ", ");
-
-		ir_print_type(f, m, vt);
-		ir_fprintf(f, " ");
-		ir_print_value(f, m, sv->vector, vt);
-		ir_fprintf(f, ", ");
-
-		ir_fprintf(f, "<%td x i32> <", sv->index_count);
-		for (isize i = 0; i < sv->index_count; i++) {
-			if (i > 0) {
-				ir_fprintf(f, ", ");
-			}
-			ir_fprintf(f, "i32 %d", sv->indices[i]);
-		}
-		ir_fprintf(f, ">");
-		ir_fprintf(f, "\n");
-	} break;
+	// case irInstr_VectorExtractElement: {
+		// Type *vt = ir_type(instr->VectorExtractElement.vector);
+		// Type *it = ir_type(instr->VectorExtractElement.index);
+		// ir_fprintf(f, "%%%d = extractelement ", value->index);
+
+		// ir_print_type(f, m, vt);
+		// ir_fprintf(f, " ");
+		// ir_print_value(f, m, instr->VectorExtractElement.vector, vt);
+		// ir_fprintf(f, ", ");
+		// ir_print_type(f, m, it);
+		// ir_fprintf(f, " ");
+		// ir_print_value(f, m, instr->VectorExtractElement.index, it);
+		// ir_fprintf(f, "\n");
+	// } break;
+
+	// case irInstr_VectorInsertElement: {
+	// 	irInstrVectorInsertElement *ie = &instr->VectorInsertElement;
+	// 	Type *vt = ir_type(ie->vector);
+	// 	ir_fprintf(f, "%%%d = insertelement ", value->index);
+
+	// 	ir_print_type(f, m, vt);
+	// 	ir_fprintf(f, " ");
+	// 	ir_print_value(f, m, ie->vector, vt);
+	// 	ir_fprintf(f, ", ");
+
+	// 	ir_print_type(f, m, ir_type(ie->elem));
+	// 	ir_fprintf(f, " ");
+	// 	ir_print_value(f, m, ie->elem, ir_type(ie->elem));
+	// 	ir_fprintf(f, ", ");
+
+	// 	ir_print_type(f, m, ir_type(ie->index));
+	// 	ir_fprintf(f, " ");
+	// 	ir_print_value(f, m, ie->index, ir_type(ie->index));
+
+	// 	ir_fprintf(f, "\n");
+	// } break;
+
+	// case irInstr_VectorShuffle: {
+	// 	irInstrVectorShuffle *sv = &instr->VectorShuffle;
+	// 	Type *vt = ir_type(sv->vector);
+	// 	ir_fprintf(f, "%%%d = shufflevector ", value->index);
+
+	// 	ir_print_type(f, m, vt);
+	// 	ir_fprintf(f, " ");
+	// 	ir_print_value(f, m, sv->vector, vt);
+	// 	ir_fprintf(f, ", ");
+
+	// 	ir_print_type(f, m, vt);
+	// 	ir_fprintf(f, " ");
+	// 	ir_print_value(f, m, sv->vector, vt);
+	// 	ir_fprintf(f, ", ");
+
+	// 	ir_fprintf(f, "<%td x i32> <", sv->index_count);
+	// 	for (isize i = 0; i < sv->index_count; i++) {
+	// 		if (i > 0) {
+	// 			ir_fprintf(f, ", ");
+	// 		}
+	// 		ir_fprintf(f, "i32 %d", sv->indices[i]);
+	// 	}
+	// 	ir_fprintf(f, ">");
+	// 	ir_fprintf(f, "\n");
+	// } break;
 
 	case irInstr_BoundsCheck: {
 		irInstrBoundsCheck *bc = &instr->BoundsCheck;

+ 58 - 39
src/types.c

@@ -270,42 +270,44 @@ gb_global Type *t_type_info_ptr            = NULL;
 gb_global Type *t_type_info_member_ptr     = NULL;
 gb_global Type *t_type_info_enum_value_ptr = NULL;
 
-gb_global Type *t_type_info_named      = NULL;
-gb_global Type *t_type_info_integer    = NULL;
-gb_global Type *t_type_info_float      = NULL;
-gb_global Type *t_type_info_any        = NULL;
-gb_global Type *t_type_info_string     = NULL;
-gb_global Type *t_type_info_boolean    = NULL;
-gb_global Type *t_type_info_pointer    = NULL;
-gb_global Type *t_type_info_maybe      = NULL;
-gb_global Type *t_type_info_procedure  = NULL;
-gb_global Type *t_type_info_array      = NULL;
-gb_global Type *t_type_info_slice      = NULL;
-gb_global Type *t_type_info_vector     = NULL;
-gb_global Type *t_type_info_tuple      = NULL;
-gb_global Type *t_type_info_struct     = NULL;
-gb_global Type *t_type_info_union      = NULL;
-gb_global Type *t_type_info_raw_union  = NULL;
-gb_global Type *t_type_info_enum       = NULL;
-
-
-gb_global Type *t_type_info_named_ptr      = NULL;
-gb_global Type *t_type_info_integer_ptr    = NULL;
-gb_global Type *t_type_info_float_ptr      = NULL;
-gb_global Type *t_type_info_any_ptr        = NULL;
-gb_global Type *t_type_info_string_ptr     = NULL;
-gb_global Type *t_type_info_boolean_ptr    = NULL;
-gb_global Type *t_type_info_pointer_ptr    = NULL;
-gb_global Type *t_type_info_maybe_ptr      = NULL;
-gb_global Type *t_type_info_procedure_ptr  = NULL;
-gb_global Type *t_type_info_array_ptr      = NULL;
-gb_global Type *t_type_info_slice_ptr      = NULL;
-gb_global Type *t_type_info_vector_ptr     = NULL;
-gb_global Type *t_type_info_tuple_ptr      = NULL;
-gb_global Type *t_type_info_struct_ptr     = NULL;
-gb_global Type *t_type_info_union_ptr      = NULL;
-gb_global Type *t_type_info_raw_union_ptr  = NULL;
-gb_global Type *t_type_info_enum_ptr       = NULL;
+gb_global Type *t_type_info_named         = NULL;
+gb_global Type *t_type_info_integer       = NULL;
+gb_global Type *t_type_info_float         = NULL;
+gb_global Type *t_type_info_any           = NULL;
+gb_global Type *t_type_info_string        = NULL;
+gb_global Type *t_type_info_boolean       = NULL;
+gb_global Type *t_type_info_pointer       = NULL;
+gb_global Type *t_type_info_maybe         = NULL;
+gb_global Type *t_type_info_procedure     = NULL;
+gb_global Type *t_type_info_array         = NULL;
+gb_global Type *t_type_info_dynamic_array = NULL;
+gb_global Type *t_type_info_slice         = NULL;
+gb_global Type *t_type_info_vector        = NULL;
+gb_global Type *t_type_info_tuple         = NULL;
+gb_global Type *t_type_info_struct        = NULL;
+gb_global Type *t_type_info_union         = NULL;
+gb_global Type *t_type_info_raw_union     = NULL;
+gb_global Type *t_type_info_enum          = NULL;
+
+
+gb_global Type *t_type_info_named_ptr         = NULL;
+gb_global Type *t_type_info_integer_ptr       = NULL;
+gb_global Type *t_type_info_float_ptr         = NULL;
+gb_global Type *t_type_info_any_ptr           = NULL;
+gb_global Type *t_type_info_string_ptr        = NULL;
+gb_global Type *t_type_info_boolean_ptr       = NULL;
+gb_global Type *t_type_info_pointer_ptr       = NULL;
+gb_global Type *t_type_info_maybe_ptr         = NULL;
+gb_global Type *t_type_info_procedure_ptr     = NULL;
+gb_global Type *t_type_info_array_ptr         = NULL;
+gb_global Type *t_type_info_dynamic_array_ptr = NULL;
+gb_global Type *t_type_info_slice_ptr         = NULL;
+gb_global Type *t_type_info_vector_ptr        = NULL;
+gb_global Type *t_type_info_tuple_ptr         = NULL;
+gb_global Type *t_type_info_struct_ptr        = NULL;
+gb_global Type *t_type_info_union_ptr         = NULL;
+gb_global Type *t_type_info_raw_union_ptr     = NULL;
+gb_global Type *t_type_info_enum_ptr          = NULL;
 
 
 
@@ -548,11 +550,13 @@ bool is_type_untyped(Type *t) {
 }
 bool is_type_ordered(Type *t) {
 	t = base_type(base_enum_type(t));
-	if (t->kind == Type_Basic) {
+	switch (t->kind) {
+	case Type_Basic:
 		return (t->Basic.flags & BasicFlag_Ordered) != 0;
-	}
-	if (t->kind == Type_Pointer) {
+	case Type_Pointer:
 		return true;
+	case Type_Vector:
+		return is_type_ordered(t->Vector.elem);
 	}
 	return false;
 }
@@ -1603,6 +1607,7 @@ i64 type_size_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, TypeP
 		return 3*s.word_size + type_size_of(s, allocator, t_allocator);
 
 	case Type_Vector: {
+#if 0
 		i64 count, bit_size, total_size_in_bits, total_size;
 		count = t->Vector.count;
 		if (count == 0) {
@@ -1621,6 +1626,20 @@ i64 type_size_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, TypeP
 		total_size_in_bits = bit_size * count;
 		total_size = (total_size_in_bits+7)/8;
 		return total_size;
+#else
+		i64 count, align, size, alignment;
+		count = t->Vector.count;
+		if (count == 0) {
+			return 0;
+		}
+		align = type_align_of_internal(s, allocator, t->Vector.elem, path);
+		if (path->failure) {
+			return FAILURE_SIZE;
+		}
+		size  = type_size_of_internal(s,  allocator, t->Vector.elem, path);
+		alignment = align_formula(size, align);
+		return alignment*(count-1) + size;
+#endif
 	} break;