struct field reordering (minimizing padding)

This commit is contained in:
2026-08-09 14:12:25 +02:00
parent 729488e702
commit 6688822de2
4 changed files with 111 additions and 15 deletions
+49 -5
View File
@@ -636,6 +636,43 @@ fields_for :: proc(store: ^Store, value: Type) -> []Field {
return store.fields[start:end]
}
field_layout_precedes :: proc(
store: ^Store,
value: Type,
left, right: int,
selected := target.DEFAULT,
) -> bool {
fields := fields_for(store, value)
item, ok := node(store, value)
if !ok || item.kind != .Struct || item.c_layout ||
left < 0 || left >= len(fields) || right < 0 || right >= len(fields) {
return left < right
}
left_alignment := alignment_of(fields[left].type, store, selected)
right_alignment := alignment_of(fields[right].type, store, selected)
return left_alignment > right_alignment ||
(left_alignment == right_alignment && left < right)
}
physical_field_index :: proc(
store: ^Store,
value: Type,
logical_index: int,
selected := target.DEFAULT,
) -> int {
fields := fields_for(store, value)
if logical_index < 0 || logical_index >= len(fields) {
return logical_index
}
result := 0
for _, other_index in fields {
if field_layout_precedes(store, value, other_index, logical_index, selected) {
result += 1
}
}
return result
}
params_for :: proc(store: ^Store, value: Type) -> []Field {
item, ok := node(store, value)
if !ok || item.kind != .Function {
@@ -1709,11 +1746,18 @@ size :: proc(value: Type, store: ^Store, selected := target.DEFAULT) -> u64 {
}
offset: u64
max_align: u64 = 1
for field in fields_for(store, value) {
field_align := u64(alignment_of(field.type, store, selected))
offset = (offset+field_align-1)/field_align*field_align
offset += size(field.type, store, selected)
max_align = max(max_align, field_align)
if !item.c_layout {
for field in fields_for(store, value) {
offset += size(field.type, store, selected)
max_align = max(max_align, u64(alignment_of(field.type, store, selected)))
}
} else {
for field in fields_for(store, value) {
field_align := u64(alignment_of(field.type, store, selected))
offset = (offset+field_align-1)/field_align*field_align
offset += size(field.type, store, selected)
max_align = max(max_align, field_align)
}
}
return (offset+max_align-1)/max_align*max_align
case .Union: