authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-19 10:48:32+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-19 10:48:32+02:00
log6cd402f1b44247c2e990aab7c7a1ce32f0f8d53a
treea460221ee66dfd2336af361703cd52cdb93f081c
parent809deb6ec0bf9ea5649d3ba4ca80485e2148a538
signature Commit is signed but in an unrecognized format.

translate-c-2 increments worst-case


2 files changed, 160 insertions(+), 69 deletions(-)

src-self-hosted/translate_c.zig+72-25
...@@ -2261,9 +2261,37 @@ fn transCreatePreCrement(...@@ -2261,9 +2261,37 @@ fn transCreatePreCrement(
2261 // c: ++expr2261 // c: ++expr
2262 // zig: (blk: {2262 // zig: (blk: {
2263 // zig: const _ref = &expr;2263 // zig: const _ref = &expr;
2264 // zig: *_ref += 1;2264 // zig: _ref.* += 1;
2265 // zig: break :blk *_ref2265 // zig: break :blk _ref.*
2266 // zig: })2266 // zig: })
2267 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
2268 block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
2269 const ref = try std.fmt.allocPrint(rp.c.a(), "_ref_{}", .{rp.c.getMangle()});
2270
2271 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
2272 node.eq_token = try appendToken(rp.c, .Equal, "=");
2273 const rhs_node = try transCreateNodePrefixOp(rp.c, .AddressOf, .Ampersand, "&");
2274 rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value);
2275 node.init_node = &rhs_node.base;
2276 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
2277 try block_scope.block_node.statements.push(&node.base);
2278
2279 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
2280 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
2281 _ = try appendToken(rp.c, .Semicolon, ";");
2282 const token = try appendToken(rp.c, op_tok_id, bytes);
2283 const one = try transCreateNodeInt(rp.c, 1);
2284 _ = try appendToken(rp.c, .Semicolon, ";");
2285 const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false);
2286 try block_scope.block_node.statements.push(assign);
2287
2288 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
2289 break_node.rhs = ref_node;
2290 try block_scope.block_node.statements.push(&break_node.base);
2291 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
2292 // semicolon must immediately follow rbrace because it is the last token in a block
2293 _ = try appendToken(rp.c, .Semicolon, ";");
2294 return &block_scope.block_node.base;
2267}2295}
22682296
2269fn transCreatePostCrement(2297fn transCreatePostCrement(
...@@ -2291,10 +2319,45 @@ fn transCreatePostCrement(...@@ -2291,10 +2319,45 @@ fn transCreatePostCrement(
2291 // c: expr++2319 // c: expr++
2292 // zig: (blk: {2320 // zig: (blk: {
2293 // zig: const _ref = &expr;2321 // zig: const _ref = &expr;
2294 // zig: const _tmp = *_ref;2322 // zig: const _tmp = _ref.*;
2295 // zig: *_ref += 1;2323 // zig: _ref.* += 1;
2296 // zig: break :blk _tmp2324 // zig: break :blk _tmp
2297 // zig: })2325 // zig: })
2326 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
2327 block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
2328 const ref = try std.fmt.allocPrint(rp.c.a(), "_ref_{}", .{rp.c.getMangle()});
2329
2330 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
2331 node.eq_token = try appendToken(rp.c, .Equal, "=");
2332 const rhs_node = try transCreateNodePrefixOp(rp.c, .AddressOf, .Ampersand, "&");
2333 rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value);
2334 node.init_node = &rhs_node.base;
2335 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
2336 try block_scope.block_node.statements.push(&node.base);
2337
2338 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
2339 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
2340 _ = try appendToken(rp.c, .Semicolon, ";");
2341
2342 const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()});
2343 const tmp_node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
2344 tmp_node.eq_token = try appendToken(rp.c, .Equal, "=");
2345 tmp_node.init_node = ref_node;
2346 tmp_node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
2347 try block_scope.block_node.statements.push(&tmp_node.base);
2348
2349 const token = try appendToken(rp.c, op_tok_id, bytes);
2350 const one = try transCreateNodeInt(rp.c, 1);
2351 _ = try appendToken(rp.c, .Semicolon, ";");
2352 const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false);
2353 try block_scope.block_node.statements.push(assign);
2354
2355 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
2356 break_node.rhs = try transCreateNodeIdentifier(rp.c,tmp);
2357 try block_scope.block_node.statements.push(&break_node.base);
2358 _ = try appendToken(rp.c, .Semicolon, ";");
2359 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
2360 return &block_scope.block_node.base;
2298}2361}
22992362
2300fn transCPtrCast(2363fn transCPtrCast(
...@@ -2694,25 +2757,16 @@ fn transCreateNodeAssign(...@@ -2694,25 +2757,16 @@ fn transCreateNodeAssign(
2694 }2757 }
2695 if (scope.id != .Condition)2758 if (scope.id != .Condition)
2696 _ = try appendToken(rp.c, .Semicolon, ";");2759 _ = try appendToken(rp.c, .Semicolon, ";");
26972760 return transCreateNodeInfixOp(rp, scope, lhs_node, .Assign, eq_token, rhs_node, .used, false);
2698 const node = try rp.c.a().create(ast.Node.InfixOp);
2699 node.* = .{
2700 .op_token = eq_token,
2701 .lhs = lhs_node,
2702 .op = .Assign,
2703 .rhs = rhs_node,
2704 };
2705 return &node.base;
2706 }2761 }
27072762
2708 // worst case2763 // worst case
2709 // c: lhs = rhs2764 // c: lhs = rhs
2710 // zig: (x: {2765 // zig: (blk: {
2711 // zig: const _tmp = rhs;2766 // zig: const _tmp = rhs;
2712 // zig: lhs = _tmp;2767 // zig: lhs = _tmp;
2713 // zig: break :x _tmp2768 // zig: break :blk _tmp
2714 // zig: })2769 // zig: })
2715 _ = try appendToken(rp.c, .LParen, "(");
2716 const block_scope = try Scope.Block.init(rp.c, scope, "blk");2770 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
2717 block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);2771 block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
2718 const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()});2772 const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()});
...@@ -2735,14 +2789,8 @@ fn transCreateNodeAssign(...@@ -2735,14 +2789,8 @@ fn transCreateNodeAssign(
2735 const ident = try transCreateNodeIdentifier(rp.c, tmp);2789 const ident = try transCreateNodeIdentifier(rp.c, tmp);
2736 _ = try appendToken(rp.c, .Semicolon, ";");2790 _ = try appendToken(rp.c, .Semicolon, ";");
27372791
2738 const assign = try rp.c.a().create(ast.Node.InfixOp);2792 const assign = try transCreateNodeInfixOp(rp, scope, lhs_node, .Assign, eq_token, ident, .used, false);
2739 assign.* = .{2793 try block_scope.block_node.statements.push(assign);
2740 .op_token = eq_token,
2741 .lhs = lhs_node,
2742 .op = .Assign,
2743 .rhs = ident,
2744 };
2745 try block_scope.block_node.statements.push(&assign.base);
27462794
2747 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);2795 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
2748 break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);2796 break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);
...@@ -2751,7 +2799,6 @@ fn transCreateNodeAssign(...@@ -2751,7 +2799,6 @@ fn transCreateNodeAssign(
2751 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");2799 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
2752 // semicolon must immediately follow rbrace because it is the last token in a block2800 // semicolon must immediately follow rbrace because it is the last token in a block
2753 _ = try appendToken(rp.c, .Semicolon, ";");2801 _ = try appendToken(rp.c, .Semicolon, ";");
2754 _ = try appendToken(rp.c, .RParen, ")");
2755 return &block_scope.block_node.base;2802 return &block_scope.block_node.base;
2756}2803}
27572804
test/translate_c.zig+88-44
...@@ -1786,6 +1786,50 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1786,6 +1786,50 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1786 \\}1786 \\}
1787 });1787 });
17881788
1789 cases.add_2("pre increment/decrement",
1790 \\void foo(void) {
1791 \\ int i = 0;
1792 \\ unsigned u = 0;
1793 \\ ++i;
1794 \\ --i;
1795 \\ ++u;
1796 \\ --u;
1797 \\ i = ++i;
1798 \\ i = --i;
1799 \\ u = ++u;
1800 \\ u = --u;
1801 \\}
1802 , &[_][]const u8{
1803 \\pub export fn foo() void {
1804 \\ var i: c_int = 0;
1805 \\ var u: c_uint = @as(c_uint, 0);
1806 \\ i += 1;
1807 \\ i -= 1;
1808 \\ u +%= 1;
1809 \\ u -%= 1;
1810 \\ i = blk: {
1811 \\ const _ref_1 = &i;
1812 \\ _ref_1.* += 1;
1813 \\ break :blk _ref_1.*;
1814 \\ };
1815 \\ i = blk: {
1816 \\ const _ref_2 = &i;
1817 \\ _ref_2.* -= 1;
1818 \\ break :blk _ref_2.*;
1819 \\ };
1820 \\ u = blk: {
1821 \\ const _ref_3 = &u;
1822 \\ _ref_3.* +%= 1;
1823 \\ break :blk _ref_3.*;
1824 \\ };
1825 \\ u = blk: {
1826 \\ const _ref_4 = &u;
1827 \\ _ref_4.* -%= 1;
1828 \\ break :blk _ref_4.*;
1829 \\ };
1830 \\}
1831 });
1832
1789 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////1833 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
17901834
1791 cases.add("macro defines string literal with hex",1835 cases.add("macro defines string literal with hex",
...@@ -2025,50 +2069,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2025,50 +2069,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2025 \\}2069 \\}
2026 });2070 });
20272071
2028 cases.addC("pre increment/decrement",
2029 \\void foo(void) {
2030 \\ int i = 0;
2031 \\ unsigned u = 0;
2032 \\ ++i;
2033 \\ --i;
2034 \\ ++u;
2035 \\ --u;
2036 \\ i = ++i;
2037 \\ i = --i;
2038 \\ u = ++u;
2039 \\ u = --u;
2040 \\}
2041 , &[_][]const u8{
2042 \\pub export fn foo() void {
2043 \\ var i: c_int = 0;
2044 \\ var u: c_uint = @as(c_uint, 0);
2045 \\ i += 1;
2046 \\ i -= 1;
2047 \\ u +%= 1;
2048 \\ u -%= 1;
2049 \\ i = (x: {
2050 \\ const _ref = &i;
2051 \\ _ref.* += 1;
2052 \\ break :x _ref.*;
2053 \\ });
2054 \\ i = (x: {
2055 \\ const _ref = &i;
2056 \\ _ref.* -= 1;
2057 \\ break :x _ref.*;
2058 \\ });
2059 \\ u = (x: {
2060 \\ const _ref = &u;
2061 \\ _ref.* +%= 1;
2062 \\ break :x _ref.*;
2063 \\ });
2064 \\ u = (x: {
2065 \\ const _ref = &u;
2066 \\ _ref.* -%= 1;
2067 \\ break :x _ref.*;
2068 \\ });
2069 \\}
2070 });
2071
2072 cases.addC("implicit casts",2072 cases.addC("implicit casts",
2073 \\#include <stdbool.h>2073 \\#include <stdbool.h>
2074 \\2074 \\
...@@ -2745,4 +2745,48 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2745,4 +2745,48 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2745 \\ _ = baz();2745 \\ _ = baz();
2746 \\}2746 \\}
2747 });2747 });
2748
2749 cases.addC("pre increment/decrement",
2750 \\void foo(void) {
2751 \\ int i = 0;
2752 \\ unsigned u = 0;
2753 \\ ++i;
2754 \\ --i;
2755 \\ ++u;
2756 \\ --u;
2757 \\ i = ++i;
2758 \\ i = --i;
2759 \\ u = ++u;
2760 \\ u = --u;
2761 \\}
2762 , &[_][]const u8{
2763 \\pub export fn foo() void {
2764 \\ var i: c_int = 0;
2765 \\ var u: c_uint = @as(c_uint, 0);
2766 \\ i += 1;
2767 \\ i -= 1;
2768 \\ u +%= 1;
2769 \\ u -%= 1;
2770 \\ i = (x: {
2771 \\ const _ref = &i;
2772 \\ _ref.* += 1;
2773 \\ break :x _ref.*;
2774 \\ });
2775 \\ i = (x: {
2776 \\ const _ref = &i;
2777 \\ _ref.* -= 1;
2778 \\ break :x _ref.*;
2779 \\ });
2780 \\ u = (x: {
2781 \\ const _ref = &u;
2782 \\ _ref.* +%= 1;
2783 \\ break :x _ref.*;
2784 \\ });
2785 \\ u = (x: {
2786 \\ const _ref = &u;
2787 \\ _ref.* -%= 1;
2788 \\ break :x _ref.*;
2789 \\ });
2790 \\}
2791 });
2748}2792}