struct field reordering (minimizing padding)
This commit is contained in:
+38
-5
@@ -1117,6 +1117,15 @@ emit_instruction_stream :: proc(
|
||||
} else if item.kind == .Range && arg_index == 2 {
|
||||
element_type = types.BOOL
|
||||
}
|
||||
aggregate_index := arg_index
|
||||
if item.kind == .Struct {
|
||||
aggregate_index = types.physical_field_index(
|
||||
&emitter.module.types,
|
||||
instruction.type,
|
||||
arg_index,
|
||||
emitter.module.target,
|
||||
)
|
||||
}
|
||||
final := arg_index == total-1
|
||||
if final {
|
||||
fmt.sbprintf(&emitter.builder, " %%v%d = insertvalue %s ", instruction_index, type_name)
|
||||
@@ -1134,7 +1143,7 @@ emit_instruction_stream :: proc(
|
||||
} else {
|
||||
write_constant(&emitter.builder, i64(item.sentinel), element_type, &emitter.module.types)
|
||||
}
|
||||
fmt.sbprintf(&emitter.builder, ", %d\n", arg_index)
|
||||
fmt.sbprintf(&emitter.builder, ", %d\n", aggregate_index)
|
||||
}
|
||||
case .Null:
|
||||
item, ok := types.node(&emitter.module.types, instruction.type)
|
||||
@@ -1334,13 +1343,19 @@ emit_instruction_stream :: proc(
|
||||
emit_recovery_value(emitter, instruction_index, instruction, "invalid field reference")
|
||||
continue
|
||||
}
|
||||
physical_index := types.physical_field_index(
|
||||
&emitter.module.types,
|
||||
base_type,
|
||||
field_index,
|
||||
emitter.module.target,
|
||||
)
|
||||
if types.is_union(base_type, &emitter.module.types) {
|
||||
fmt.sbprintf(&emitter.builder, " %%v%d = getelementptr i8, ptr %%v%d, i64 %d\n", instruction_index, instruction.a, types.union_payload_offset(base_type, &emitter.module.types, emitter.module.target))
|
||||
} else {
|
||||
fmt.sbprintf(
|
||||
&emitter.builder,
|
||||
" %%v%d = getelementptr %s, ptr %%v%d, i32 0, i32 %d\n",
|
||||
instruction_index, llvm_type(base_type, &emitter.module.types), instruction.a, field_index,
|
||||
instruction_index, llvm_type(base_type, &emitter.module.types), instruction.a, physical_index,
|
||||
)
|
||||
}
|
||||
case .Load:
|
||||
@@ -2593,12 +2608,30 @@ emit_types :: proc(emitter: ^Emitter) {
|
||||
strings.write_string(&emitter.builder, " }\n")
|
||||
continue
|
||||
}
|
||||
fields := types.fields_for(&emitter.module.types, id)
|
||||
strings.write_string(&emitter.builder, "{ ")
|
||||
for field, field_index in types.fields_for(&emitter.module.types, id) {
|
||||
if field_index > 0 {
|
||||
previous_index := -1
|
||||
for physical_index in 0..<len(fields) {
|
||||
logical_index := -1
|
||||
for _, candidate_index in fields {
|
||||
if previous_index >= 0 &&
|
||||
!types.field_layout_precedes(
|
||||
&emitter.module.types, id, previous_index, candidate_index, emitter.module.target,
|
||||
) {
|
||||
continue
|
||||
}
|
||||
if logical_index < 0 ||
|
||||
types.field_layout_precedes(
|
||||
&emitter.module.types, id, candidate_index, logical_index, emitter.module.target,
|
||||
) {
|
||||
logical_index = candidate_index
|
||||
}
|
||||
}
|
||||
if physical_index > 0 {
|
||||
strings.write_string(&emitter.builder, ", ")
|
||||
}
|
||||
strings.write_string(&emitter.builder, llvm_type(field.type, &emitter.module.types))
|
||||
strings.write_string(&emitter.builder, llvm_type(fields[logical_index].type, &emitter.module.types))
|
||||
previous_index = logical_index
|
||||
}
|
||||
strings.write_string(&emitter.builder, " }\n")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user