diff options
| author | Veikka Tuominen <git@vexu.eu> | 2023-01-16 19:46:41 +0200 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2023-01-16 19:46:41 +0200 |
| commit | 342bae02d86d9bd9f2db6ae9489021bab28595ae (patch) | |
| tree | 8b50d7cffff029c135a17295c4c324603d2358b1 /src/Sema.zig | |
| parent | 31a2b8c3642f1240a70d78203d568051d4dbcd3f (diff) | |
| download | zig-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.zig | 36 |
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 } |
