authorgravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2021-01-03 16:09:32+01:00
committergravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2021-01-03 17:39:43+01:00
log3c05c60accb534e857e4ad2c1a957d439af184e4
treebe30787aba2c0c87e066e84c9f10dddc289d2ee6
parent0008bef1e643c190a12e13d99a21d5af7ebdaa1b

stage2: Output the LLVM object files in the cache directory

Also make sure to properly free everything.

3 files changed, 30 insertions(+), 11 deletions(-)

src/link/Coff.zig+5-2
...@@ -811,8 +811,11 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {...@@ -811,8 +811,11 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
811 // If there is no Zig code to compile, then we should skip flushing the output file because it811 // If there is no Zig code to compile, then we should skip flushing the output file because it
812 // will not be part of the linker line anyway.812 // will not be part of the linker line anyway.
813 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {813 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {
814 const use_stage1 = build_options.is_stage1 and self.base.options.use_llvm;814 // Both stage1 and stage2 LLVM backend put the object file in the cache directory.
815 if (use_stage1) {815 if (self.base.options.use_llvm) {
816 // Stage2 has to call flushModule since that outputs the LLVM object file.
817 if (!build_options.is_stage1) try self.flushModule(comp);
818
816 const obj_basename = try std.zig.binNameAlloc(arena, .{819 const obj_basename = try std.zig.binNameAlloc(arena, .{
817 .root_name = self.base.options.root_name,820 .root_name = self.base.options.root_name,
818 .target = self.base.options.target,821 .target = self.base.options.target,
src/link/Elf.zig+5-2
...@@ -1251,8 +1251,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1251,8 +1251,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1251 // If there is no Zig code to compile, then we should skip flushing the output file because it1251 // If there is no Zig code to compile, then we should skip flushing the output file because it
1252 // will not be part of the linker line anyway.1252 // will not be part of the linker line anyway.
1253 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {1253 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {
1254 const use_stage1 = build_options.is_stage1 and self.base.options.use_llvm;1254 // Both stage1 and stage2 LLVM backend put the object file in the cache directory.
1255 if (use_stage1) {1255 if (self.base.options.use_llvm) {
1256 // Stage2 has to call flushModule since that outputs the LLVM object file.
1257 if (!build_options.is_stage1) try self.flushModule(comp);
1258
1256 const obj_basename = try std.zig.binNameAlloc(arena, .{1259 const obj_basename = try std.zig.binNameAlloc(arena, .{
1257 .root_name = self.base.options.root_name,1260 .root_name = self.base.options.root_name,
1258 .target = self.base.options.target,1261 .target = self.base.options.target,
src/llvm_backend.zig+20-7
...@@ -142,7 +142,7 @@ pub const LLVMIRModule = struct {...@@ -142,7 +142,7 @@ pub const LLVMIRModule = struct {
142 target_machine: *const llvm.TargetMachineRef,142 target_machine: *const llvm.TargetMachineRef,
143 builder: *const llvm.BuilderRef,143 builder: *const llvm.BuilderRef,
144144
145 output_path: []const u8,145 object_path: []const u8,
146146
147 gpa: *Allocator,147 gpa: *Allocator,
148 err_msg: ?*Compilation.ErrorMsg = null,148 err_msg: ?*Compilation.ErrorMsg = null,
...@@ -161,6 +161,17 @@ pub const LLVMIRModule = struct {...@@ -161,6 +161,17 @@ pub const LLVMIRModule = struct {
161161
162 const gpa = options.module.?.gpa;162 const gpa = options.module.?.gpa;
163163
164 const obj_basename = try std.zig.binNameAlloc(gpa, .{
165 .root_name = options.root_name,
166 .target = options.target,
167 .output_mode = .Obj,
168 });
169 defer gpa.free(obj_basename);
170
171 const o_directory = options.module.?.zig_cache_artifact_directory;
172 const object_path = try o_directory.join(gpa, &[_][]const u8{obj_basename});
173 errdefer gpa.free(object_path);
174
164 initializeLLVMTargets();175 initializeLLVMTargets();
165176
166 const root_nameZ = try gpa.dupeZ(u8, options.root_name);177 const root_nameZ = try gpa.dupeZ(u8, options.root_name);
...@@ -212,7 +223,7 @@ pub const LLVMIRModule = struct {...@@ -212,7 +223,7 @@ pub const LLVMIRModule = struct {
212 .llvm_module = llvm_module,223 .llvm_module = llvm_module,
213 .target_machine = target_machine,224 .target_machine = target_machine,
214 .builder = builder,225 .builder = builder,
215 .output_path = sub_path,226 .object_path = object_path,
216 .gpa = gpa,227 .gpa = gpa,
217 };228 };
218 return self;229 return self;
...@@ -222,6 +233,10 @@ pub const LLVMIRModule = struct {...@@ -222,6 +233,10 @@ pub const LLVMIRModule = struct {
222 self.builder.disposeBuilder();233 self.builder.disposeBuilder();
223 self.target_machine.disposeTargetMachine();234 self.target_machine.disposeTargetMachine();
224 self.llvm_module.disposeModule();235 self.llvm_module.disposeModule();
236
237 self.func_inst_table.deinit(self.gpa);
238 self.gpa.free(self.object_path);
239
225 allocator.destroy(self);240 allocator.destroy(self);
226 }241 }
227242
...@@ -254,15 +269,13 @@ pub const LLVMIRModule = struct {...@@ -254,15 +269,13 @@ pub const LLVMIRModule = struct {
254 }269 }
255 }270 }
256271
257 const output_pathZ = try self.gpa.dupeZ(u8, self.output_path);272 const object_pathZ = try self.gpa.dupeZ(u8, self.object_path);
258 defer self.gpa.free(output_pathZ);273 defer self.gpa.free(object_pathZ);
259274
260 var error_message: [*:0]const u8 = undefined;275 var error_message: [*:0]const u8 = undefined;
261 // TODO: where to put the output object, zig-cache something?
262 // TODO: caching?
263 if (self.target_machine.emitToFile(276 if (self.target_machine.emitToFile(
264 self.llvm_module,277 self.llvm_module,
265 output_pathZ.ptr,278 object_pathZ.ptr,
266 .ObjectFile,279 .ObjectFile,
267 &error_message,280 &error_message,
268 )) {281 )) {