| ... | @@ -54,8 +54,6 @@ pub const CValue = union(enum) { | ... | @@ -54,8 +54,6 @@ pub const CValue = union(enum) { |
| 54 | /// Render these bytes literally. | 54 | /// Render these bytes literally. |
| 55 | /// TODO make this a [*:0]const u8 to save memory | 55 | /// TODO make this a [*:0]const u8 to save memory |
| 56 | bytes: []const u8, | 56 | bytes: []const u8, |
| 57 | /// A deferred call_always_tail | | |
| 58 | call_always_tail: void, | | |
| 59 | }; | 57 | }; |
| 60 | | 58 | |
| 61 | const BlockData = struct { | 59 | const BlockData = struct { |
| ... | @@ -1751,7 +1749,6 @@ pub const DeclGen = struct { | ... | @@ -1751,7 +1749,6 @@ pub const DeclGen = struct { |
| 1751 | fmtIdent(ident), | 1749 | fmtIdent(ident), |
| 1752 | }), | 1750 | }), |
| 1753 | .bytes => |bytes| return w.writeAll(bytes), | 1751 | .bytes => |bytes| return w.writeAll(bytes), |
| 1754 | .call_always_tail => return dg.fail("CBE: the result of @call(.always_tail, ...) must be returned directly", .{}), | | |
| 1755 | } | 1752 | } |
| 1756 | } | 1753 | } |
| 1757 | | 1754 | |
| ... | @@ -1785,7 +1782,6 @@ pub const DeclGen = struct { | ... | @@ -1785,7 +1782,6 @@ pub const DeclGen = struct { |
| 1785 | try w.writeAll(bytes); | 1782 | try w.writeAll(bytes); |
| 1786 | return w.writeByte(')'); | 1783 | return w.writeByte(')'); |
| 1787 | }, | 1784 | }, |
| 1788 | .call_always_tail => return dg.writeCValue(w, c_value), | | |
| 1789 | } | 1785 | } |
| 1790 | } | 1786 | } |
| 1791 | | 1787 | |
| ... | @@ -1798,16 +1794,7 @@ pub const DeclGen = struct { | ... | @@ -1798,16 +1794,7 @@ pub const DeclGen = struct { |
| 1798 | fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void { | 1794 | fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void { |
| 1799 | switch (c_value) { | 1795 | switch (c_value) { |
| 1800 | .none, .constant, .field, .undef => unreachable, | 1796 | .none, .constant, .field, .undef => unreachable, |
| 1801 | .new_local, | 1797 | .new_local, .local, .arg, .arg_array, .decl, .identifier, .payload_identifier, .bytes => { |
| 1802 | .local, | | |
| 1803 | .arg, | | |
| 1804 | .arg_array, | | |
| 1805 | .decl, | | |
| 1806 | .identifier, | | |
| 1807 | .payload_identifier, | | |
| 1808 | .bytes, | | |
| 1809 | .call_always_tail, | | |
| 1810 | => { | | |
| 1811 | try dg.writeCValue(writer, c_value); | 1798 | try dg.writeCValue(writer, c_value); |
| 1812 | try writer.writeAll("->"); | 1799 | try writer.writeAll("->"); |
| 1813 | }, | 1800 | }, |
| ... | @@ -2910,7 +2897,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, | ... | @@ -2910,7 +2897,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 2910 | => .none, | 2897 | => .none, |
| 2911 | | 2898 | |
| 2912 | .call => try airCall(f, inst, .auto), | 2899 | .call => try airCall(f, inst, .auto), |
| 2913 | .call_always_tail => .call_always_tail, | 2900 | .call_always_tail => .none, |
| 2914 | .call_never_tail => try airCall(f, inst, .never_tail), | 2901 | .call_never_tail => try airCall(f, inst, .never_tail), |
| 2915 | .call_never_inline => try airCall(f, inst, .never_inline), | 2902 | .call_never_inline => try airCall(f, inst, .never_inline), |
| 2916 | | 2903 | |
| ... | @@ -3365,20 +3352,15 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { | ... | @@ -3365,20 +3352,15 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 3365 | const un_op = f.air.instructions.items(.data)[inst].un_op; | 3352 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 3366 | const writer = f.object.writer(); | 3353 | const writer = f.object.writer(); |
| 3367 | const target = f.object.dg.module.getTarget(); | 3354 | const target = f.object.dg.module.getTarget(); |
| | 3355 | const op_inst = Air.refToIndex(un_op); |
| 3368 | const op_ty = f.air.typeOf(un_op); | 3356 | const op_ty = f.air.typeOf(un_op); |
| 3369 | const ret_ty = if (is_ptr) op_ty.childType() else op_ty; | 3357 | const ret_ty = if (is_ptr) op_ty.childType() else op_ty; |
| 3370 | var lowered_ret_buf: LowerFnRetTyBuffer = undefined; | 3358 | var lowered_ret_buf: LowerFnRetTyBuffer = undefined; |
| 3371 | const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, target); | 3359 | const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, target); |
| 3372 | | 3360 | |
| 3373 | const is_naked = if (f.object.dg.decl) |decl| decl.ty.fnCallingConvention() == .Naked else false; | 3361 | if (op_inst != null and f.air.instructions.items(.tag)[op_inst.?] == .call_always_tail) { |
| 3374 | const peek_operand = f.value_map.get(un_op); | | |
| 3375 | if (if (peek_operand) |operand| operand == .call_always_tail else false) { | | |
| 3376 | try reap(f, inst, &.{un_op}); | 3362 | try reap(f, inst, &.{un_op}); |
| 3377 | if (is_naked) { | 3363 | _ = try airCall(f, op_inst.?, .always_tail); |
| 3378 | try f.writeCValue(writer, peek_operand.?, .Other); | | |
| 3379 | unreachable; | | |
| 3380 | } | | |
| 3381 | _ = try airCall(f, Air.refToIndex(un_op).?, .always_tail); | | |
| 3382 | } else if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime()) { | 3364 | } else if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime()) { |
| 3383 | const operand = try f.resolveInst(un_op); | 3365 | const operand = try f.resolveInst(un_op); |
| 3384 | try reap(f, inst, &.{un_op}); | 3366 | try reap(f, inst, &.{un_op}); |
| ... | @@ -3412,7 +3394,8 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { | ... | @@ -3412,7 +3394,8 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 3412 | } else { | 3394 | } else { |
| 3413 | try reap(f, inst, &.{un_op}); | 3395 | try reap(f, inst, &.{un_op}); |
| 3414 | // Not even allowed to return void in a naked function. | 3396 | // 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"); |
| 3416 | } | 3399 | } |
| 3417 | return .none; | 3400 | return .none; |
| 3418 | } | 3401 | } |