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(
22612261 // c: ++expr
22622262 // zig: (blk: {
22632263 // zig: const _ref = &expr;
2264 // zig: *_ref += 1;
2265 // zig: break :blk *_ref
2264 // zig: _ref.* += 1;
2265 // zig: break :blk _ref.*
22662266 // 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;
22672295}
22682296
22692297fn transCreatePostCrement(
......@@ -2291,10 +2319,45 @@ fn transCreatePostCrement(
22912319 // c: expr++
22922320 // zig: (blk: {
22932321 // zig: const _ref = &expr;
2294 // zig: const _tmp = *_ref;
2295 // zig: *_ref += 1;
2322 // zig: const _tmp = _ref.*;
2323 // zig: _ref.* += 1;
22962324 // zig: break :blk _tmp
22972325 // 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;
22982361}
22992362
23002363fn transCPtrCast(
......@@ -2694,25 +2757,16 @@ fn transCreateNodeAssign(
26942757 }
26952758 if (scope.id != .Condition)
26962759 _ = try appendToken(rp.c, .Semicolon, ";");
2697
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;
2760 return transCreateNodeInfixOp(rp, scope, lhs_node, .Assign, eq_token, rhs_node, .used, false);
27062761 }
27072762
27082763 // worst case
27092764 // c: lhs = rhs
2710 // zig: (x: {
2765 // zig: (blk: {
27112766 // zig: const _tmp = rhs;
27122767 // zig: lhs = _tmp;
2713 // zig: break :x _tmp
2768 // zig: break :blk _tmp
27142769 // zig: })
2715 _ = try appendToken(rp.c, .LParen, "(");
27162770 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
27172771 block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
27182772 const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()});
......@@ -2735,14 +2789,8 @@ fn transCreateNodeAssign(
27352789 const ident = try transCreateNodeIdentifier(rp.c, tmp);
27362790 _ = try appendToken(rp.c, .Semicolon, ";");
27372791
2738 const assign = try rp.c.a().create(ast.Node.InfixOp);
2739 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);
2792 const assign = try transCreateNodeInfixOp(rp, scope, lhs_node, .Assign, eq_token, ident, .used, false);
2793 try block_scope.block_node.statements.push(assign);
27462794
27472795 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
27482796 break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);
......@@ -2751,7 +2799,6 @@ fn transCreateNodeAssign(
27512799 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
27522800 // semicolon must immediately follow rbrace because it is the last token in a block
27532801 _ = try appendToken(rp.c, .Semicolon, ";");
2754 _ = try appendToken(rp.c, .RParen, ")");
27552802 return &block_scope.block_node.base;
27562803}
27572804
test/translate_c.zig+88-44
......@@ -1786,6 +1786,50 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17861786 \\}
17871787 });
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
17891833 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
17901834
17911835 cases.add("macro defines string literal with hex",
......@@ -2025,50 +2069,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
20252069 \\}
20262070 });
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
20722072 cases.addC("implicit casts",
20732073 \\#include <stdbool.h>
20742074 \\
......@@ -2745,4 +2745,48 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
27452745 \\ _ = baz();
27462746 \\}
27472747 });
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 });
27482792}