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" {
1616
1717pub const TestContext = struct {
1818 zir_cmp_output_cases: std.ArrayList(ZIRCompareOutputCase),
19 zir_transform_cases: std.ArrayList(ZIRTransformCase),
1920
2021 pub const ZIRCompareOutputCase = struct {
2122 name: []const u8,
......@@ -23,6 +24,12 @@ pub const TestContext = struct {
2324 expected_stdout: []const u8,
2425 };
2526
27 pub const ZIRTransformCase = struct {
28 name: []const u8,
29 src: [:0]const u8,
30 expected_zir: []const u8,
31 };
32
2633 pub fn addZIRCompareOutput(
2734 ctx: *TestContext,
2835 name: []const u8,
......@@ -36,20 +43,36 @@ pub const TestContext = struct {
3643 }) catch unreachable;
3744 }
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
3959 fn init(self: *TestContext) !void {
4060 self.* = .{
4161 .zir_cmp_output_cases = std.ArrayList(ZIRCompareOutputCase).init(std.heap.page_allocator),
62 .zir_transform_cases = std.ArrayList(ZIRTransformCase).init(std.heap.page_allocator),
4263 };
4364 }
4465
4566 fn deinit(self: *TestContext) void {
4667 self.zir_cmp_output_cases.deinit();
68 self.zir_transform_cases.deinit();
4769 self.* = undefined;
4870 }
4971
5072 fn run(self: *TestContext) !void {
5173 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);
5376 defer root_node.end();
5477
5578 const native_info = try std.zig.system.NativeTargetInfo.detect(std.heap.page_allocator, .{});
......@@ -59,6 +82,11 @@ pub const TestContext = struct {
5982 try self.runOneZIRCmpOutputCase(std.testing.allocator, root_node, case, native_info.target);
6083 try std.testing.allocator_instance.validate();
6184 }
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 }
6290 }
6391
6492 fn runOneZIRCmpOutputCase(
......@@ -93,7 +121,12 @@ pub const TestContext = struct {
93121 analyze_node.activate();
94122 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 });
97130 };
98131 defer analyzed_module.deinit(allocator);
99132 if (analyzed_module.errors.len != 0) {
......@@ -106,12 +139,7 @@ pub const TestContext = struct {
106139 link_node.activate();
107140 defer link_node.end();
108141
109 break :x try link.updateExecutableFilePath(
110 allocator,
111 analyzed_module,
112 tmp.dir,
113 "a.out",
114 );
142 break :x try link.updateFilePath(allocator, analyzed_module, tmp.dir, "a.out");
115143 };
116144 defer link_result.deinit(allocator);
117145 if (link_result.errors.len != 0) {
......@@ -143,6 +171,58 @@ pub const TestContext = struct {
143171 }
144172 std.testing.expectEqualSlices(u8, case.expected_stdout, exec_result.stdout);
145173 }
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 }
146226};
147227
148228fn debugPrintErrors(src: []const u8, errors: var) void {
test/stage2/zir.zig+45
......@@ -1,6 +1,51 @@
11const TestContext = @import("../../src-self-hosted/test.zig").TestContext;
22
33pub 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
449 if (@import("std").Target.current.os.tag != .linux or
550 @import("std").Target.current.cpu.arch != .x86_64)
651 {