diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-01-30 22:31:34 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-01-30 22:31:34 +0000 |
| commit | 34150385d8db82ab8de7eeba06c51a43ba59ec6e (patch) | |
| tree | 5ebdcf9aff9a029009999d5ed72e92727ebbdd6e /src | |
| parent | 0ca1b4612c35c649d16476aa67462835249145e8 (diff) | |
Change vector memory layout and operations; `for in` vector.
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_stmt.c | 8 | ||||
| -rw-r--r-- | src/checker.c | 80 | ||||
| -rw-r--r-- | src/ir.c | 338 | ||||
| -rw-r--r-- | src/ir_opt.c | 24 | ||||
| -rw-r--r-- | src/ir_print.c | 151 | ||||
| -rw-r--r-- | src/types.c | 97 |
6 files changed, 404 insertions, 294 deletions
diff --git a/src/check_stmt.c b/src/check_stmt.c index 6fdef7cf1..8ff5c3b2e 100644 --- a/src/check_stmt.c +++ b/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; } } diff --git a/src/checker.c b/src/checker.c index ef28c6d20..7108eb4b7 100644 --- a/src/checker.c +++ b/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) { @@ -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); diff --git a/src/ir_opt.c b/src/ir_opt.c index b4c348b2d..44f100bf8 100644 --- a/src/ir_opt.c +++ b/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: diff --git a/src/ir_print.c b/src/ir_print.c index 37411a905..ee1983360 100644 --- a/src/ir_print.c +++ b/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; diff --git a/src/types.c b/src/types.c index 2612ee72c..099f0e05e 100644 --- a/src/types.c +++ b/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; |