authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-20 15:40:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-20 16:17:16-07:00
log1417698c111e7f75d1c6959c7af8cd1a4d5231f6
treef66c94d9c97d231dc5a32fb815f57f420912ad7a
parent4fccc95b0152aefeb40912768ec045b57a2fdc2b

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`.

1 files changed, 21 insertions(+), 3 deletions(-)

src/Sema.zig+21-3
......@@ -14012,7 +14012,7 @@ fn coerce(
1401214012 if (inst == .empty_struct) {
1401314013 return arrayInitEmpty(sema, dest_ty);
1401414014 }
14015 if (inst_ty.tag() == .tuple) {
14015 if (inst_ty.isTuple()) {
1401614016 return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src);
1401714017 }
1401814018 },
......@@ -14384,12 +14384,30 @@ fn storePtr2(
1438414384 uncasted_operand: Air.Inst.Ref,
1438514385 operand_src: LazySrcLoc,
1438614386 air_tag: Air.Inst.Tag,
14387) !void {
14387) CompileError!void {
1438814388 const ptr_ty = sema.typeOf(ptr);
1438914389 if (ptr_ty.isConstPtr())
14390 return sema.fail(block, src, "cannot assign to constant", .{});
14390 return sema.fail(block, ptr_src, "cannot assign to constant", .{});
1439114391
1439214392 const elem_ty = ptr_ty.childType();
14393
14394 // To generate better code for tuples, we detect a tuple operand here, and
14395 // analyze field loads and stores directly. This avoids an extra allocation + memcpy
14396 // which would occur if we used `coerce`.
14397 const operand_ty = sema.typeOf(uncasted_operand);
14398 if (operand_ty.castTag(.tuple)) |payload| {
14399 const tuple_fields_len = payload.data.types.len;
14400 var i: u32 = 0;
14401 while (i < tuple_fields_len) : (i += 1) {
14402 const elem_src = operand_src; // TODO better source location
14403 const elem = try tupleField(sema, block, uncasted_operand, i, operand_src, elem_src);
14404 const elem_index = try sema.addIntUnsigned(Type.usize, i);
14405 const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src);
14406 try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store);
14407 }
14408 return;
14409 }
14410
1439314411 const operand = try sema.coerce(block, elem_ty, uncasted_operand, operand_src);
1439414412 if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null)
1439514413 return;