mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-17 11:22:22 -07:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
@@ -102,7 +102,7 @@ make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, alloc
|
||||
|
||||
total_size := 0
|
||||
for i in 0..<field_count {
|
||||
type := si.types[i].variant.(Type_Info_Pointer).elem
|
||||
type := si.types[i].variant.(Type_Info_Multi_Pointer).elem
|
||||
total_size += type.size * length
|
||||
total_size = align_forward_int(total_size, max_align)
|
||||
}
|
||||
@@ -126,7 +126,7 @@ make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, alloc
|
||||
data := uintptr(&array)
|
||||
offset := 0
|
||||
for i in 0..<field_count {
|
||||
type := si.types[i].variant.(Type_Info_Pointer).elem
|
||||
type := si.types[i].variant.(Type_Info_Multi_Pointer).elem
|
||||
|
||||
offset = align_forward_int(offset, max_align)
|
||||
|
||||
@@ -226,7 +226,7 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo
|
||||
|
||||
max_align :: align_of(E)
|
||||
for i in 0..<field_count {
|
||||
type := si.types[i].variant.(Type_Info_Pointer).elem
|
||||
type := si.types[i].variant.(Type_Info_Multi_Pointer).elem
|
||||
|
||||
old_size += type.size * old_cap
|
||||
new_size += type.size * capacity
|
||||
@@ -249,7 +249,7 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo
|
||||
old_offset := 0
|
||||
new_offset := 0
|
||||
for i in 0..<field_count {
|
||||
type := si.types[i].variant.(Type_Info_Pointer).elem
|
||||
type := si.types[i].variant.(Type_Info_Multi_Pointer).elem
|
||||
|
||||
old_offset = align_forward_int(old_offset, max_align)
|
||||
new_offset = align_forward_int(new_offset, max_align)
|
||||
@@ -307,7 +307,7 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_locat
|
||||
|
||||
max_align :: align_of(E)
|
||||
for i in 0..<field_count {
|
||||
type := si.types[i].variant.(Type_Info_Pointer).elem
|
||||
type := si.types[i].variant.(Type_Info_Multi_Pointer).elem
|
||||
|
||||
soa_offset = align_forward_int(soa_offset, max_align)
|
||||
item_offset = align_forward_int(item_offset, type.align)
|
||||
@@ -358,7 +358,7 @@ append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_l
|
||||
|
||||
max_align :: align_of(E)
|
||||
for i in 0..<field_count {
|
||||
type := si.types[i].variant.(Type_Info_Pointer).elem
|
||||
type := si.types[i].variant.(Type_Info_Multi_Pointer).elem
|
||||
|
||||
soa_offset = align_forward_int(soa_offset, max_align)
|
||||
item_offset = align_forward_int(item_offset, type.align)
|
||||
@@ -476,7 +476,7 @@ unordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, index: int, loc := #cal
|
||||
|
||||
data := uintptr(array)
|
||||
for i in 0..<field_count {
|
||||
type := si.types[i].variant.(Type_Info_Pointer).elem
|
||||
type := si.types[i].variant.(Type_Info_Multi_Pointer).elem
|
||||
|
||||
offset := rawptr((^uintptr)(data)^ + uintptr(index*type.size))
|
||||
final := rawptr((^uintptr)(data)^ + uintptr((len(array)-1)*type.size))
|
||||
@@ -509,7 +509,7 @@ ordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, index: int, loc := #calle
|
||||
|
||||
data := uintptr(array)
|
||||
for i in 0..<field_count {
|
||||
type := si.types[i].variant.(Type_Info_Pointer).elem
|
||||
type := si.types[i].variant.(Type_Info_Multi_Pointer).elem
|
||||
|
||||
offset := (^uintptr)(data)^ + uintptr(index*type.size)
|
||||
length := type.size*(len(array) - index - 1)
|
||||
|
||||
+1
-1
@@ -1960,7 +1960,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St
|
||||
fmt_arg(fi, any{data, t.id}, verb)
|
||||
}
|
||||
} else {
|
||||
t := info.types[i].variant.(runtime.Type_Info_Pointer).elem
|
||||
t := info.types[i].variant.(runtime.Type_Info_Multi_Pointer).elem
|
||||
t_size := uintptr(t.size)
|
||||
if reflect.is_any(t) {
|
||||
io.write_string(fi.writer, "any{}", &fi.n)
|
||||
|
||||
@@ -91,8 +91,8 @@ Inputs:
|
||||
Returns:
|
||||
- res: A string created from the null-terminated byte pointer and length
|
||||
*/
|
||||
string_from_null_terminated_ptr :: proc(ptr: ^byte, len: int) -> (res: string) {
|
||||
s := transmute(string)mem.Raw_String{ptr, len}
|
||||
string_from_null_terminated_ptr :: proc(ptr: [^]byte, len: int) -> (res: string) {
|
||||
s := string(ptr[:len])
|
||||
s = truncate_to_byte(s, 0)
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -3442,8 +3442,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
auto types = slice_make<Type *>(permanent_allocator(), t->Struct.fields.count-1);
|
||||
for_array(i, types) {
|
||||
Entity *f = t->Struct.fields[i];
|
||||
GB_ASSERT(f->type->kind == Type_Pointer);
|
||||
types[i] = alloc_type_slice(f->type->Pointer.elem);
|
||||
GB_ASSERT(f->type->kind == Type_MultiPointer);
|
||||
types[i] = alloc_type_slice(f->type->MultiPointer.elem);
|
||||
}
|
||||
|
||||
operand->type = alloc_type_tuple_from_field_types(types.data, types.count, false, false);
|
||||
|
||||
+2
-2
@@ -7808,8 +7808,8 @@ gb_internal bool check_set_index_data(Operand *o, Type *t, bool indirection, i64
|
||||
|
||||
if (is_type_pointer(original_type) && indirection) {
|
||||
Type *ptr = base_type(original_type);
|
||||
if (ptr->kind == Type_Pointer && o->mode == Addressing_SoaVariable) {
|
||||
o->type = ptr->Pointer.elem;
|
||||
if (ptr->kind == Type_MultiPointer && o->mode == Addressing_SoaVariable) {
|
||||
o->type = ptr->MultiPointer.elem;
|
||||
o->mode = Addressing_Value;
|
||||
return true;
|
||||
}
|
||||
|
||||
+12
-3
@@ -2827,12 +2827,15 @@ gb_internal bool complete_soa_type(Checker *checker, Type *t, bool wait_to_finis
|
||||
GB_ASSERT(soa_count >= 0);
|
||||
field_type = alloc_type_array(old_field->type, soa_count);
|
||||
} else {
|
||||
field_type = alloc_type_pointer(old_field->type);
|
||||
field_type = alloc_type_multi_pointer(old_field->type);
|
||||
}
|
||||
Entity *new_field = alloc_entity_field(scope, old_field->token, field_type, false, old_field->Variable.field_index);
|
||||
t->Struct.fields[i] = new_field;
|
||||
add_entity(scope, new_field);
|
||||
new_field->flags |= EntityFlag_Used;
|
||||
if (t->Struct.soa_kind != StructSoa_Fixed) {
|
||||
new_field->flags |= EntityFlag_SoaPtrField;
|
||||
}
|
||||
} else {
|
||||
t->Struct.fields[i] = old_field;
|
||||
}
|
||||
@@ -2948,7 +2951,7 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e
|
||||
GB_ASSERT(count >= 0);
|
||||
field_type = alloc_type_array(old_array->Array.elem, count);
|
||||
} else {
|
||||
field_type = alloc_type_pointer(old_array->Array.elem);
|
||||
field_type = alloc_type_multi_pointer(old_array->Array.elem);
|
||||
}
|
||||
Token token = {};
|
||||
token.string = params_xyzw[i];
|
||||
@@ -2957,6 +2960,9 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e
|
||||
soa_struct->Struct.fields[i] = new_field;
|
||||
add_entity(ctx, scope, nullptr, new_field);
|
||||
add_entity_use(ctx, nullptr, new_field);
|
||||
if (soa_kind != StructSoa_Fixed) {
|
||||
new_field->flags |= EntityFlag_SoaPtrField;
|
||||
}
|
||||
}
|
||||
|
||||
is_complete = true;
|
||||
@@ -2980,12 +2986,15 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e
|
||||
GB_ASSERT(count >= 0);
|
||||
field_type = alloc_type_array(old_field->type, count);
|
||||
} else {
|
||||
field_type = alloc_type_pointer(old_field->type);
|
||||
field_type = alloc_type_multi_pointer(old_field->type);
|
||||
}
|
||||
Entity *new_field = alloc_entity_field(scope, old_field->token, field_type, false, old_field->Variable.field_index);
|
||||
soa_struct->Struct.fields[i] = new_field;
|
||||
add_entity(ctx, scope, nullptr, new_field);
|
||||
add_entity_use(ctx, nullptr, new_field);
|
||||
if (soa_kind != StructSoa_Fixed) {
|
||||
new_field->flags |= EntityFlag_SoaPtrField;
|
||||
}
|
||||
} else {
|
||||
soa_struct->Struct.fields[i] = old_field;
|
||||
}
|
||||
|
||||
@@ -539,7 +539,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
|
||||
LLVMValueRef ptr = LLVMBuildInBoundsGEP2(p->builder, llvm_type, array_data, indices, 2, "");
|
||||
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true);
|
||||
|
||||
lbAddr slice = lb_add_local_generated(p, type, false);
|
||||
lbAddr slice = lb_add_local_generated(p, original_type, false);
|
||||
map_set(&m->exact_value_compound_literal_addr_map, value.value_compound, slice);
|
||||
|
||||
lb_fill_slice(p, slice, {ptr, alloc_type_pointer(elem)}, {len, t_int});
|
||||
|
||||
+37
-14
@@ -3851,27 +3851,39 @@ gb_internal lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) {
|
||||
|
||||
if (ie->expr->tav.mode == Addressing_SoaVariable) {
|
||||
// SOA Structures for slices/dynamic arrays
|
||||
GB_ASSERT(is_type_pointer(type_of_expr(ie->expr)));
|
||||
GB_ASSERT_MSG(is_type_multi_pointer(type_of_expr(ie->expr)), "%s", type_to_string(type_of_expr(ie->expr)));
|
||||
|
||||
lbValue field = lb_build_expr(p, ie->expr);
|
||||
lbValue index = lb_build_expr(p, ie->index);
|
||||
|
||||
|
||||
if (!build_context.no_bounds_check) {
|
||||
// TODO HACK(bill): Clean up this hack to get the length for bounds checking
|
||||
// GB_ASSERT(LLVMIsALoadInst(field.value));
|
||||
Ast *se_expr = unparen_expr(ie->expr);
|
||||
if (se_expr->kind == Ast_SelectorExpr) {
|
||||
ast_node(se, SelectorExpr, se_expr);
|
||||
lbValue len = {};
|
||||
|
||||
// lbValue a = {};
|
||||
// a.value = LLVMGetOperand(field.value, 0);
|
||||
// a.type = alloc_type_pointer(field.type);
|
||||
Type *type = base_type(type_deref(type_of_expr(se->expr)));
|
||||
GB_ASSERT_MSG(is_type_soa_struct(type), "%s", type_to_string(type));
|
||||
if (type->Struct.soa_kind == StructSoa_Fixed) {
|
||||
len = lb_const_int(p->module, t_int, type->Struct.soa_count);
|
||||
} else {
|
||||
lbAddr *found = map_get(&p->selector_addr, se_expr);
|
||||
if (found) {
|
||||
lbAddr addr = *found;
|
||||
lbValue parent = lb_addr_get_ptr(p, addr);
|
||||
if (is_type_pointer(type_deref(parent.type))) {
|
||||
parent = lb_emit_load(p, parent);
|
||||
}
|
||||
len = lb_soa_struct_len(p, parent);
|
||||
}
|
||||
}
|
||||
|
||||
// irInstr *b = &a->Instr;
|
||||
// GB_ASSERT(b->kind == irInstr_StructElementPtr);
|
||||
// lbValue base_struct = b->StructElementPtr.address;
|
||||
|
||||
// GB_ASSERT(is_type_soa_struct(type_deref(ir_type(base_struct))));
|
||||
// lbValue len = ir_soa_struct_len(p, base_struct);
|
||||
// lb_emit_bounds_check(p, ast_token(ie->index), index, len);
|
||||
if (len.value) {
|
||||
lb_emit_bounds_check(p, ast_token(ie->index), index, len);
|
||||
}
|
||||
} else {
|
||||
// TODO(bill): how do you even do bounds checking here?
|
||||
}
|
||||
}
|
||||
lbValue val = lb_emit_ptr_offset(p, field, index);
|
||||
return lb_addr(val);
|
||||
@@ -4218,6 +4230,7 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
|
||||
lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i);
|
||||
lbValue field_src = lb_emit_struct_ep(p, lb_addr_get_ptr(p, addr), i);
|
||||
field_src = lb_emit_array_ep(p, field_src, low);
|
||||
field_src = lb_emit_conv(p, field_src, type_deref(field_dst.type));
|
||||
lb_emit_store(p, field_dst, field_src);
|
||||
}
|
||||
|
||||
@@ -4233,6 +4246,7 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
|
||||
lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i);
|
||||
lbValue field_src = lb_emit_struct_ev(p, base, i);
|
||||
field_src = lb_emit_ptr_offset(p, field_src, low);
|
||||
field_src = lb_emit_conv(p, field_src, type_deref(field_dst.type));
|
||||
lb_emit_store(p, field_dst, field_src);
|
||||
}
|
||||
|
||||
@@ -4247,6 +4261,7 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
|
||||
lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i);
|
||||
lbValue field_src = lb_emit_struct_ev(p, base, i);
|
||||
field_src = lb_emit_ptr_offset(p, field_src, low);
|
||||
field_src = lb_emit_conv(p, field_src, type_deref(field_dst.type));
|
||||
lb_emit_store(p, field_dst, field_src);
|
||||
}
|
||||
|
||||
@@ -4978,6 +4993,9 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
|
||||
if (sub_sel.index.count > 0) {
|
||||
item = lb_emit_deep_field_gep(p, item, sub_sel);
|
||||
}
|
||||
// make sure it's ^T and not [^]T
|
||||
item.type = alloc_type_multi_pointer_to_pointer(item.type);
|
||||
|
||||
return lb_addr(item);
|
||||
} else if (addr.kind == lbAddr_Swizzle) {
|
||||
GB_ASSERT(sel.index.count > 0);
|
||||
@@ -4989,6 +5007,11 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
|
||||
sel.index[0] = addr.swizzle.indices[sel.index[0]];
|
||||
}
|
||||
|
||||
Type *atype = type_deref(lb_addr_type(addr));
|
||||
if (is_type_soa_struct(atype)) {
|
||||
map_set(&p->selector_addr, expr, addr);
|
||||
}
|
||||
|
||||
lbValue a = lb_addr_get_ptr(p, addr);
|
||||
a = lb_emit_deep_field_gep(p, a, sel);
|
||||
return lb_addr(a);
|
||||
|
||||
@@ -1324,7 +1324,7 @@ gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) {
|
||||
for (isize i = 0; i < field_count; i++) {
|
||||
Entity *field = t->Struct.fields[i];
|
||||
Type *base_type = field->type;
|
||||
GB_ASSERT(base_type->kind == Type_Pointer);
|
||||
GB_ASSERT(base_type->kind == Type_MultiPointer);
|
||||
|
||||
lbValue dst = lb_emit_struct_ep(p, res.addr, cast(i32)i);
|
||||
lbValue src_ptr = lb_emit_struct_ep(p, addr.addr, cast(i32)i);
|
||||
|
||||
@@ -328,6 +328,7 @@ gb_internal lbValue lb_soa_zip(lbProcedure *p, AstCallExpr *ce, TypeAndValue con
|
||||
lbAddr res = lb_add_local_generated(p, tv.type, true);
|
||||
for_array(i, slices) {
|
||||
lbValue src = lb_slice_elem(p, slices[i]);
|
||||
src = lb_emit_conv(p, src, alloc_type_pointer_to_multi_pointer(src.type));
|
||||
lbValue dst = lb_emit_struct_ep(p, res.addr, cast(i32)i);
|
||||
lb_emit_store(p, dst, src);
|
||||
}
|
||||
@@ -1559,19 +1560,26 @@ gb_internal lbValue lb_emit_matrix_ev(lbProcedure *p, lbValue s, isize row, isiz
|
||||
return lb_emit_load(p, ptr);
|
||||
}
|
||||
|
||||
|
||||
gb_internal void lb_fill_slice(lbProcedure *p, lbAddr const &slice, lbValue base_elem, lbValue len) {
|
||||
Type *t = lb_addr_type(slice);
|
||||
GB_ASSERT(is_type_slice(t));
|
||||
lbValue ptr = lb_addr_get_ptr(p, slice);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, ptr, 0), base_elem);
|
||||
lbValue data = lb_emit_struct_ep(p, ptr, 0);
|
||||
if (are_types_identical(type_deref(base_elem.type, true), type_deref(type_deref(data.type), true))) {
|
||||
base_elem = lb_emit_conv(p, base_elem, type_deref(data.type));
|
||||
}
|
||||
lb_emit_store(p, data, base_elem);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, ptr, 1), len);
|
||||
}
|
||||
gb_internal void lb_fill_string(lbProcedure *p, lbAddr const &string, lbValue base_elem, lbValue len) {
|
||||
Type *t = lb_addr_type(string);
|
||||
GB_ASSERT(is_type_string(t));
|
||||
lbValue ptr = lb_addr_get_ptr(p, string);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, ptr, 0), base_elem);
|
||||
lbValue data = lb_emit_struct_ep(p, ptr, 0);
|
||||
if (are_types_identical(type_deref(base_elem.type, true), type_deref(type_deref(data.type), true))) {
|
||||
base_elem = lb_emit_conv(p, base_elem, type_deref(data.type));
|
||||
}
|
||||
lb_emit_store(p, data, base_elem);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, ptr, 1), len);
|
||||
}
|
||||
|
||||
|
||||
@@ -988,6 +988,27 @@ gb_internal Type *alloc_type_soa_pointer(Type *elem) {
|
||||
return t;
|
||||
}
|
||||
|
||||
gb_internal Type *alloc_type_pointer_to_multi_pointer(Type *ptr) {
|
||||
Type *original_type = ptr;
|
||||
ptr = base_type(ptr);
|
||||
if (ptr->kind == Type_Pointer) {
|
||||
return alloc_type_multi_pointer(ptr->Pointer.elem);
|
||||
} else if (ptr->kind != Type_MultiPointer) {
|
||||
GB_PANIC("Invalid type: %s", type_to_string(original_type));
|
||||
}
|
||||
return original_type;
|
||||
}
|
||||
|
||||
gb_internal Type *alloc_type_multi_pointer_to_pointer(Type *ptr) {
|
||||
Type *original_type = ptr;
|
||||
ptr = base_type(ptr);
|
||||
if (ptr->kind == Type_MultiPointer) {
|
||||
return alloc_type_pointer(ptr->MultiPointer.elem);
|
||||
} else if (ptr->kind != Type_Pointer) {
|
||||
GB_PANIC("Invalid type: %s", type_to_string(original_type));
|
||||
}
|
||||
return original_type;
|
||||
}
|
||||
|
||||
gb_internal Type *alloc_type_array(Type *elem, i64 count, Type *generic_count = nullptr) {
|
||||
if (generic_count != nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user