authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-02-23 20:12:02-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-02-23 20:30:59-05:00
logc0671a92c7f200a3c32d03db7b7e342c3efdd1fe
tree4a431a548e4eb6fa567fc5c8191f23e5a627ed5e
parent3a1cb62317073b8e599e604b74edf9d10f16d4a2

CBE: simplify always_tail call logic

It should be Sema's job to check this anyway.

1 files changed, 7 insertions(+), 24 deletions(-)

src/codegen/c.zig+7-24
......@@ -54,8 +54,6 @@ pub const CValue = union(enum) {
5454 /// Render these bytes literally.
5555 /// TODO make this a [*:0]const u8 to save memory
5656 bytes: []const u8,
57 /// A deferred call_always_tail
58 call_always_tail: void,
5957};
6058
6159const BlockData = struct {
......@@ -1751,7 +1749,6 @@ pub const DeclGen = struct {
17511749 fmtIdent(ident),
17521750 }),
17531751 .bytes => |bytes| return w.writeAll(bytes),
1754 .call_always_tail => return dg.fail("CBE: the result of @call(.always_tail, ...) must be returned directly", .{}),
17551752 }
17561753 }
17571754
......@@ -1785,7 +1782,6 @@ pub const DeclGen = struct {
17851782 try w.writeAll(bytes);
17861783 return w.writeByte(')');
17871784 },
1788 .call_always_tail => return dg.writeCValue(w, c_value),
17891785 }
17901786 }
17911787
......@@ -1798,16 +1794,7 @@ pub const DeclGen = struct {
17981794 fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void {
17991795 switch (c_value) {
18001796 .none, .constant, .field, .undef => unreachable,
1801 .new_local,
1802 .local,
1803 .arg,
1804 .arg_array,
1805 .decl,
1806 .identifier,
1807 .payload_identifier,
1808 .bytes,
1809 .call_always_tail,
1810 => {
1797 .new_local, .local, .arg, .arg_array, .decl, .identifier, .payload_identifier, .bytes => {
18111798 try dg.writeCValue(writer, c_value);
18121799 try writer.writeAll("->");
18131800 },
......@@ -2910,7 +2897,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
29102897 => .none,
29112898
29122899 .call => try airCall(f, inst, .auto),
2913 .call_always_tail => .call_always_tail,
2900 .call_always_tail => .none,
29142901 .call_never_tail => try airCall(f, inst, .never_tail),
29152902 .call_never_inline => try airCall(f, inst, .never_inline),
29162903
......@@ -3365,20 +3352,15 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
33653352 const un_op = f.air.instructions.items(.data)[inst].un_op;
33663353 const writer = f.object.writer();
33673354 const target = f.object.dg.module.getTarget();
3355 const op_inst = Air.refToIndex(un_op);
33683356 const op_ty = f.air.typeOf(un_op);
33693357 const ret_ty = if (is_ptr) op_ty.childType() else op_ty;
33703358 var lowered_ret_buf: LowerFnRetTyBuffer = undefined;
33713359 const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, target);
33723360
3373 const is_naked = if (f.object.dg.decl) |decl| decl.ty.fnCallingConvention() == .Naked else false;
3374 const peek_operand = f.value_map.get(un_op);
3375 if (if (peek_operand) |operand| operand == .call_always_tail else false) {
3361 if (op_inst != null and f.air.instructions.items(.tag)[op_inst.?] == .call_always_tail) {
33763362 try reap(f, inst, &.{un_op});
3377 if (is_naked) {
3378 try f.writeCValue(writer, peek_operand.?, .Other);
3379 unreachable;
3380 }
3381 _ = try airCall(f, Air.refToIndex(un_op).?, .always_tail);
3363 _ = try airCall(f, op_inst.?, .always_tail);
33823364 } else if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime()) {
33833365 const operand = try f.resolveInst(un_op);
33843366 try reap(f, inst, &.{un_op});
......@@ -3412,7 +3394,8 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
34123394 } else {
34133395 try reap(f, inst, &.{un_op});
34143396 // Not even allowed to return void in a naked function.
3415 if (!is_naked) try writer.writeAll("return;\n");
3397 if (if (f.object.dg.decl) |decl| decl.ty.fnCallingConvention() != .Naked else true)
3398 try writer.writeAll("return;\n");
34163399 }
34173400 return .none;
34183401}