authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-29 19:38:45-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-01 06:47:20-04:00
log1d202008d8008681988effdf25be2c6a753cf067
tree74c0432a2a1fa077f507a31ea25d089636a10a2a
parent751903ba8fba467411942317c8da0e6bc22a0ff6

add ZIR transform test case


2 files changed, 133 insertions(+), 8 deletions(-)

src-self-hosted/test.zig+88-8
...@@ -16,6 +16,7 @@ test "self-hosted" {...@@ -16,6 +16,7 @@ test "self-hosted" {
1616
17pub const TestContext = struct {17pub const TestContext = struct {
18 zir_cmp_output_cases: std.ArrayList(ZIRCompareOutputCase),18 zir_cmp_output_cases: std.ArrayList(ZIRCompareOutputCase),
19 zir_transform_cases: std.ArrayList(ZIRTransformCase),
1920
20 pub const ZIRCompareOutputCase = struct {21 pub const ZIRCompareOutputCase = struct {
21 name: []const u8,22 name: []const u8,
...@@ -23,6 +24,12 @@ pub const TestContext = struct {...@@ -23,6 +24,12 @@ pub const TestContext = struct {
23 expected_stdout: []const u8,24 expected_stdout: []const u8,
24 };25 };
2526
27 pub const ZIRTransformCase = struct {
28 name: []const u8,
29 src: [:0]const u8,
30 expected_zir: []const u8,
31 };
32
26 pub fn addZIRCompareOutput(33 pub fn addZIRCompareOutput(
27 ctx: *TestContext,34 ctx: *TestContext,
28 name: []const u8,35 name: []const u8,
...@@ -36,20 +43,36 @@ pub const TestContext = struct {...@@ -36,20 +43,36 @@ pub const TestContext = struct {
36 }) catch unreachable;43 }) catch unreachable;
37 }44 }
3845
46 pub fn addZIRTransform(
47 ctx: *TestContext,
48 name: []const u8,
49 src: [:0]const u8,
50 expected_zir: []const u8,
51 ) void {
52 ctx.zir_transform_cases.append(.{
53 .name = name,
54 .src = src,
55 .expected_zir = expected_zir,
56 }) catch unreachable;
57 }
58
39 fn init(self: *TestContext) !void {59 fn init(self: *TestContext) !void {
40 self.* = .{60 self.* = .{
41 .zir_cmp_output_cases = std.ArrayList(ZIRCompareOutputCase).init(std.heap.page_allocator),61 .zir_cmp_output_cases = std.ArrayList(ZIRCompareOutputCase).init(std.heap.page_allocator),
62 .zir_transform_cases = std.ArrayList(ZIRTransformCase).init(std.heap.page_allocator),
42 };63 };
43 }64 }
4465
45 fn deinit(self: *TestContext) void {66 fn deinit(self: *TestContext) void {
46 self.zir_cmp_output_cases.deinit();67 self.zir_cmp_output_cases.deinit();
68 self.zir_transform_cases.deinit();
47 self.* = undefined;69 self.* = undefined;
48 }70 }
4971
50 fn run(self: *TestContext) !void {72 fn run(self: *TestContext) !void {
51 var progress = std.Progress{};73 var progress = std.Progress{};
52 const root_node = try progress.start("zir", self.zir_cmp_output_cases.items.len);74 const root_node = try progress.start("zir", self.zir_cmp_output_cases.items.len +
75 self.zir_transform_cases.items.len);
53 defer root_node.end();76 defer root_node.end();
5477
55 const native_info = try std.zig.system.NativeTargetInfo.detect(std.heap.page_allocator, .{});78 const native_info = try std.zig.system.NativeTargetInfo.detect(std.heap.page_allocator, .{});
...@@ -59,6 +82,11 @@ pub const TestContext = struct {...@@ -59,6 +82,11 @@ pub const TestContext = struct {
59 try self.runOneZIRCmpOutputCase(std.testing.allocator, root_node, case, native_info.target);82 try self.runOneZIRCmpOutputCase(std.testing.allocator, root_node, case, native_info.target);
60 try std.testing.allocator_instance.validate();83 try std.testing.allocator_instance.validate();
61 }84 }
85 for (self.zir_transform_cases.items) |case| {
86 std.testing.base_allocator_instance.reset();
87 try self.runOneZIRTransformCase(std.testing.allocator, root_node, case, native_info.target);
88 try std.testing.allocator_instance.validate();
89 }
62 }90 }
6391
64 fn runOneZIRCmpOutputCase(92 fn runOneZIRCmpOutputCase(
...@@ -93,7 +121,12 @@ pub const TestContext = struct {...@@ -93,7 +121,12 @@ pub const TestContext = struct {
93 analyze_node.activate();121 analyze_node.activate();
94 defer analyze_node.end();122 defer analyze_node.end();
95123
96 break :x try ir.analyze(allocator, zir_module, target);124 break :x try ir.analyze(allocator, zir_module, .{
125 .target = target,
126 .output_mode = .Exe,
127 .link_mode = .Static,
128 .optimize_mode = .Debug,
129 });
97 };130 };
98 defer analyzed_module.deinit(allocator);131 defer analyzed_module.deinit(allocator);
99 if (analyzed_module.errors.len != 0) {132 if (analyzed_module.errors.len != 0) {
...@@ -106,12 +139,7 @@ pub const TestContext = struct {...@@ -106,12 +139,7 @@ pub const TestContext = struct {
106 link_node.activate();139 link_node.activate();
107 defer link_node.end();140 defer link_node.end();
108141
109 break :x try link.updateExecutableFilePath(142 break :x try link.updateFilePath(allocator, analyzed_module, tmp.dir, "a.out");
110 allocator,
111 analyzed_module,
112 tmp.dir,
113 "a.out",
114 );
115 };143 };
116 defer link_result.deinit(allocator);144 defer link_result.deinit(allocator);
117 if (link_result.errors.len != 0) {145 if (link_result.errors.len != 0) {
...@@ -143,6 +171,58 @@ pub const TestContext = struct {...@@ -143,6 +171,58 @@ pub const TestContext = struct {
143 }171 }
144 std.testing.expectEqualSlices(u8, case.expected_stdout, exec_result.stdout);172 std.testing.expectEqualSlices(u8, case.expected_stdout, exec_result.stdout);
145 }173 }
174
175 fn runOneZIRTransformCase(
176 self: *TestContext,
177 allocator: *Allocator,
178 root_node: *std.Progress.Node,
179 case: ZIRTransformCase,
180 target: std.Target,
181 ) !void {
182 var prg_node = root_node.start(case.name, 4);
183 prg_node.activate();
184 defer prg_node.end();
185
186 var parse_node = prg_node.start("parse", null);
187 parse_node.activate();
188 var zir_module = try ir.text.parse(allocator, case.src);
189 defer zir_module.deinit(allocator);
190 if (zir_module.errors.len != 0) {
191 debugPrintErrors(case.src, zir_module.errors);
192 return error.ParseFailure;
193 }
194 parse_node.end();
195
196 var analyze_node = prg_node.start("analyze", null);
197 analyze_node.activate();
198 var analyzed_module = try ir.analyze(allocator, zir_module, .{
199 .target = target,
200 .output_mode = .Obj,
201 .link_mode = .Static,
202 .optimize_mode = .Debug,
203 });
204 defer analyzed_module.deinit(allocator);
205 if (analyzed_module.errors.len != 0) {
206 debugPrintErrors(case.src, analyzed_module.errors);
207 return error.ParseFailure;
208 }
209 analyze_node.end();
210
211 var emit_node = prg_node.start("emit", null);
212 emit_node.activate();
213 var new_zir_module = try ir.text.emit_zir(allocator, analyzed_module);
214 defer new_zir_module.deinit(allocator);
215 emit_node.end();
216
217 var write_node = prg_node.start("write", null);
218 write_node.activate();
219 var out_zir = std.ArrayList(u8).init(allocator);
220 defer out_zir.deinit();
221 try new_zir_module.writeToStream(allocator, out_zir.outStream());
222 write_node.end();
223
224 std.testing.expectEqualSlices(u8, case.expected_zir, out_zir.items);
225 }
146};226};
147227
148fn debugPrintErrors(src: []const u8, errors: var) void {228fn debugPrintErrors(src: []const u8, errors: var) void {
test/stage2/zir.zig+45
...@@ -1,6 +1,51 @@...@@ -1,6 +1,51 @@
1const TestContext = @import("../../src-self-hosted/test.zig").TestContext;1const TestContext = @import("../../src-self-hosted/test.zig").TestContext;
22
3pub fn addCases(ctx: *TestContext) void {3pub fn addCases(ctx: *TestContext) void {
4 ctx.addZIRTransform("elemptr, add, cmp, condbr, return, breakpoint",
5 \\@void = primitive(void)
6 \\@usize = primitive(usize)
7 \\@fnty = fntype([], @void, cc=C)
8 \\@0 = int(0)
9 \\@1 = int(1)
10 \\@2 = int(2)
11 \\@3 = int(3)
12 \\
13 \\@entry = fn(@fnty, {
14 \\ %a = str("\x32\x08\x01\x0a")
15 \\ %eptr0 = elemptr(%a, @0)
16 \\ %eptr1 = elemptr(%a, @1)
17 \\ %eptr2 = elemptr(%a, @2)
18 \\ %eptr3 = elemptr(%a, @3)
19 \\ %v0 = deref(%eptr0)
20 \\ %v1 = deref(%eptr1)
21 \\ %v2 = deref(%eptr2)
22 \\ %v3 = deref(%eptr3)
23 \\ %x0 = add(%v0, %v1)
24 \\ %x1 = add(%v2, %v3)
25 \\ %result = add(%x0, %x1)
26 \\
27 \\ %expected = int(69)
28 \\ %ok = cmp(%result, eq, %expected)
29 \\ %10 = condbr(%ok, {
30 \\ %11 = return()
31 \\ }, {
32 \\ %12 = breakpoint()
33 \\ })
34 \\})
35 \\
36 \\@9 = str("entry")
37 \\@10 = export(@9, @entry)
38 ,
39 \\@0 = primitive(void)
40 \\@1 = fntype([], @0, cc=C)
41 \\@2 = fn(@1, {
42 \\ %0 = return()
43 \\})
44 \\@3 = str("entry")
45 \\@4 = export(@3, @2)
46 \\
47 );
48
4 if (@import("std").Target.current.os.tag != .linux or49 if (@import("std").Target.current.os.tag != .linux or
5 @import("std").Target.current.cpu.arch != .x86_64)50 @import("std").Target.current.cpu.arch != .x86_64)
6 {51 {