mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Improve rules for zeroing types with the ir.cpp backend with ir_type_requires_mem_zero
This commit is contained in:
+64
-2
@@ -3162,14 +3162,76 @@ void ir_value_set_debug_location(irProcedure *proc, irValue *v) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ir_type_requires_mem_zero(Type *t) {
|
||||||
|
t = core_type(t);
|
||||||
|
isize sz = type_size_of(t);
|
||||||
|
if (t->kind == Type_SimdVector) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(gb_is_power_of_two(sz) && sz <= build_context.max_align)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum : i64 {LARGE_SIZE = 64};
|
||||||
|
if (sz > LARGE_SIZE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (t->kind) {
|
||||||
|
case Type_Union:
|
||||||
|
return true;
|
||||||
|
case Type_Struct:
|
||||||
|
if (t->Struct.is_raw_union) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (t->Struct.is_packed) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
i64 packed_sized = 0;
|
||||||
|
for_array(i, t->Struct.fields) {
|
||||||
|
Type *f = t->Struct.fields[i];
|
||||||
|
if (f->kind == Entity_Variable) {
|
||||||
|
packed_sized += type_size_of(f->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sz != packed_sized;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type_Tuple:
|
||||||
|
if (t->Tuple.is_packed) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
i64 packed_sized = 0;
|
||||||
|
for_array(i, t->Tuple.variables) {
|
||||||
|
Entity *f = t->Tuple.variables[i];
|
||||||
|
if (f->kind == Entity_Variable) {
|
||||||
|
packed_sized += type_size_of(f->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sz != packed_sized;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type_DynamicArray:
|
||||||
|
case Type_Map:
|
||||||
|
case Type_BitField:
|
||||||
|
return true;
|
||||||
|
case Type_Array:
|
||||||
|
return ir_type_requires_mem_zero(t->Array.elem);
|
||||||
|
case Type_EnumeratedArray:
|
||||||
|
return ir_type_requires_mem_zero(t->EnumeratedArray.elem);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ir_emit_zero_init(irProcedure *p, irValue *address, Ast *expr) {
|
void ir_emit_zero_init(irProcedure *p, irValue *address, Ast *expr) {
|
||||||
gbAllocator a = ir_allocator();
|
gbAllocator a = ir_allocator();
|
||||||
Type *t = type_deref(ir_type(address));
|
Type *t = type_deref(ir_type(address));
|
||||||
isize sz = type_size_of(t);
|
|
||||||
|
|
||||||
if (address) address->uses += 1;
|
if (address) address->uses += 1;
|
||||||
|
|
||||||
if (!(gb_is_power_of_two(sz) && sz <= build_context.max_align)) {
|
if (ir_type_requires_mem_zero(t)) {
|
||||||
// TODO(bill): Is this a good idea?
|
// TODO(bill): Is this a good idea?
|
||||||
auto args = array_make<irValue *>(a, 2);
|
auto args = array_make<irValue *>(a, 2);
|
||||||
args[0] = ir_emit_conv(p, address, t_rawptr);
|
args[0] = ir_emit_conv(p, address, t_rawptr);
|
||||||
|
|||||||
Reference in New Issue
Block a user