authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-06 16:47:09-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-06 16:47:09-07:00
logefe94a9a1289db274be326d6d66a19caeee86d33
tree95dd2f96a79284df771dad7746790daa4bc810be
parent91e3431d4a55aa46884b267be5aa586f3ed94f74

stage2: C backend: support unused Decls


3 files changed, 46 insertions(+), 22 deletions(-)

src/Compilation.zig+4
...@@ -527,6 +527,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -527,6 +527,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
527 if (options.root_pkg == null)527 if (options.root_pkg == null)
528 break :blk false;528 break :blk false;
529529
530 // If we are outputting .c code we must use Zig backend.
531 if (ofmt == .c)
532 break :blk false;
533
530 // If we are the stage1 compiler, we depend on the stage1 c++ llvm backend534 // If we are the stage1 compiler, we depend on the stage1 c++ llvm backend
531 // to compile zig code.535 // to compile zig code.
532 if (build_options.is_stage1)536 if (build_options.is_stage1)
src/link/C.zig+32-22
...@@ -151,36 +151,46 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {...@@ -151,36 +151,46 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
151 var fn_count: usize = 0;151 var fn_count: usize = 0;
152152
153 // Forward decls and non-functions first.153 // Forward decls and non-functions first.
154 // TODO: performance investigation: would keeping a list of Decls that we should
155 // generate, rather than querying here, be faster?
154 for (module.decl_table.items()) |kv| {156 for (module.decl_table.items()) |kv| {
155 const decl = kv.value;157 const decl = kv.value;
156 const decl_tv = decl.typed_value.most_recent.typed_value;158 switch (decl.typed_value) {
157 const buf = buf: {159 .most_recent => |tvm| {
158 if (decl_tv.val.castTag(.function)) |_| {160 const buf = buf: {
159 fn_count += 1;161 if (tvm.typed_value.val.castTag(.function)) |_| {
160 break :buf decl.fn_link.c.fwd_decl.items;162 fn_count += 1;
161 } else {163 break :buf decl.fn_link.c.fwd_decl.items;
162 break :buf decl.link.c.code.items;164 } else {
163 }165 break :buf decl.link.c.code.items;
164 };166 }
165 all_buffers.appendAssumeCapacity(.{167 };
166 .iov_base = buf.ptr,168 all_buffers.appendAssumeCapacity(.{
167 .iov_len = buf.len,169 .iov_base = buf.ptr,
168 });170 .iov_len = buf.len,
169 file_size += buf.len;171 });
172 file_size += buf.len;
173 },
174 .never_succeeded => continue,
175 }
170 }176 }
171177
172 // Now the function bodies.178 // Now the function bodies.
173 try all_buffers.ensureCapacity(all_buffers.items.len + fn_count);179 try all_buffers.ensureCapacity(all_buffers.items.len + fn_count);
174 for (module.decl_table.items()) |kv| {180 for (module.decl_table.items()) |kv| {
175 const decl = kv.value;181 const decl = kv.value;
176 const decl_tv = decl.typed_value.most_recent.typed_value;182 switch (decl.typed_value) {
177 if (decl_tv.val.castTag(.function)) |_| {183 .most_recent => |tvm| {
178 const buf = decl.link.c.code.items;184 if (tvm.typed_value.val.castTag(.function)) |_| {
179 all_buffers.appendAssumeCapacity(.{185 const buf = decl.link.c.code.items;
180 .iov_base = buf.ptr,186 all_buffers.appendAssumeCapacity(.{
181 .iov_len = buf.len,187 .iov_base = buf.ptr,
182 });188 .iov_len = buf.len,
183 file_size += buf.len;189 });
190 file_size += buf.len;
191 }
192 },
193 .never_succeeded => continue,
184 }194 }
185 }195 }
186196
test/stage2/cbe.zig+10
...@@ -29,6 +29,16 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -29,6 +29,16 @@ pub fn addCases(ctx: *TestContext) !void {
29 \\ return 0;29 \\ return 0;
30 \\}30 \\}
31 , "yo" ++ std.cstr.line_sep);31 , "yo" ++ std.cstr.line_sep);
32
33 // Add an unused Decl
34 case.addCompareOutput(
35 \\extern fn puts(s: [*:0]const u8) c_int;
36 \\export fn main() c_int {
37 \\ _ = puts("yo!");
38 \\ return 0;
39 \\}
40 \\fn unused() void {}
41 , "yo!" ++ std.cstr.line_sep);
32 }42 }
3343
34 {44 {