struct field reordering (minimizing padding)
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user