aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2023-01-16 19:46:41 +0200
committerVeikka Tuominen <git@vexu.eu>2023-01-16 19:46:41 +0200
commit342bae02d86d9bd9f2db6ae9489021bab28595ae (patch)
tree8b50d7cffff029c135a17295c4c324603d2358b1 /src/Sema.zig
parent31a2b8c3642f1240a70d78203d568051d4dbcd3f (diff)
downloadzig-342bae02d86d9bd9f2db6ae9489021bab28595ae.tar.gz
zig-342bae02d86d9bd9f2db6ae9489021bab28595ae.zip
Sema: automatically optimize order of struct fields
This is a simple starting version of the optimization described in #168 where the fields are just sorted by order of descending alignment.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 3db5eb5ba1..fcf25ab9bf 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -29919,6 +29919,42 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
);
return sema.failWithOwnedErrorMsg(msg);
}
+
+ if (struct_obj.layout == .Auto and sema.mod.backendSupportsFeature(.field_reordering)) {
+ const optimized_order = blk: {
+ const decl = sema.mod.declPtr(struct_obj.owner_decl);
+ var decl_arena = decl.value_arena.?.promote(sema.mod.gpa);
+ defer decl.value_arena.?.* = decl_arena.state;
+ const decl_arena_allocator = decl_arena.allocator();
+
+ break :blk try decl_arena_allocator.alloc(u32, struct_obj.fields.count());
+ };
+
+ for (struct_obj.fields.values()) |field, i| {
+ optimized_order[i] = if (field.ty.hasRuntimeBits())
+ @intCast(u32, i)
+ else
+ Module.Struct.omitted_field;
+ }
+
+ const AlignSortContext = struct {
+ struct_obj: *Module.Struct,
+ sema: *Sema,
+
+ fn lessThan(ctx: @This(), a: u32, b: u32) bool {
+ if (a == Module.Struct.omitted_field) return false;
+ if (b == Module.Struct.omitted_field) return true;
+ const target = ctx.sema.mod.getTarget();
+ return ctx.struct_obj.fields.values()[a].ty.abiAlignment(target) >
+ ctx.struct_obj.fields.values()[b].ty.abiAlignment(target);
+ }
+ };
+ std.sort.sort(u32, optimized_order, AlignSortContext{
+ .struct_obj = struct_obj,
+ .sema = sema,
+ }, AlignSortContext.lessThan);
+ struct_obj.optimized_order = optimized_order.ptr;
+ }
}
// otherwise it's a tuple; no need to resolve anything
}