mirror of
https://github.com/ziglang/zig.git
synced 2024-11-17 01:23:54 +00:00
Sema: storePtr optimization for tuples
To generate better code for tuples, we detect a tuple operand in storePtr, and analyze field loads and stores directly. This avoids an extra allocation + memcpy which would occur if we used `coerce`.
This commit is contained in:
parent
4fccc95b01
commit
1417698c11
24
src/Sema.zig
24
src/Sema.zig
@ -14012,7 +14012,7 @@ fn coerce(
|
||||
if (inst == .empty_struct) {
|
||||
return arrayInitEmpty(sema, dest_ty);
|
||||
}
|
||||
if (inst_ty.tag() == .tuple) {
|
||||
if (inst_ty.isTuple()) {
|
||||
return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src);
|
||||
}
|
||||
},
|
||||
@ -14384,12 +14384,30 @@ fn storePtr2(
|
||||
uncasted_operand: Air.Inst.Ref,
|
||||
operand_src: LazySrcLoc,
|
||||
air_tag: Air.Inst.Tag,
|
||||
) !void {
|
||||
) CompileError!void {
|
||||
const ptr_ty = sema.typeOf(ptr);
|
||||
if (ptr_ty.isConstPtr())
|
||||
return sema.fail(block, src, "cannot assign to constant", .{});
|
||||
return sema.fail(block, ptr_src, "cannot assign to constant", .{});
|
||||
|
||||
const elem_ty = ptr_ty.childType();
|
||||
|
||||
// To generate better code for tuples, we detect a tuple operand here, and
|
||||
// analyze field loads and stores directly. This avoids an extra allocation + memcpy
|
||||
// which would occur if we used `coerce`.
|
||||
const operand_ty = sema.typeOf(uncasted_operand);
|
||||
if (operand_ty.castTag(.tuple)) |payload| {
|
||||
const tuple_fields_len = payload.data.types.len;
|
||||
var i: u32 = 0;
|
||||
while (i < tuple_fields_len) : (i += 1) {
|
||||
const elem_src = operand_src; // TODO better source location
|
||||
const elem = try tupleField(sema, block, uncasted_operand, i, operand_src, elem_src);
|
||||
const elem_index = try sema.addIntUnsigned(Type.usize, i);
|
||||
const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src);
|
||||
try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const operand = try sema.coerce(block, elem_ty, uncasted_operand, operand_src);
|
||||
if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null)
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user