authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-02-24 23:33:03+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-25 03:58:06-08:00
logf6af773578e20dbae3bf2a350c036558fea84803
treef1a2bab3cbac4f6667853417e1eea3ef4595c46d
parent55f437b92bb394f7df558bb3209f057f9f46274f

llvm: remork memory management in emit


3 files changed, 63 insertions(+), 68 deletions(-)

src/codegen/llvm.zig+60-65
......@@ -1149,61 +1149,38 @@ pub const Object = struct {
11491149 };
11501150
11511151 pub fn emit(self: *Object, options: EmitOptions) !void {
1152 try self.resolveExportExternCollisions();
1153 try self.genErrorNameTable();
1154 try self.genCmpLtErrorsLenFunction();
1155 try self.genModuleLevelAssembly();
1152 {
1153 try self.resolveExportExternCollisions();
1154 try self.genErrorNameTable();
1155 try self.genCmpLtErrorsLenFunction();
1156 try self.genModuleLevelAssembly();
11561157
1157 if (!self.builder.strip) {
1158 {
1159 var i: usize = 0;
1160 while (i < self.debug_unresolved_namespace_scopes.count()) : (i += 1) {
1161 const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i];
1162 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];
1158 if (!self.builder.strip) {
1159 {
1160 var i: usize = 0;
1161 while (i < self.debug_unresolved_namespace_scopes.count()) : (i += 1) {
1162 const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i];
1163 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];
11631164
1164 const namespace = self.module.namespacePtr(namespace_index);
1165 const debug_type = try self.lowerDebugType(namespace.ty);
1165 const namespace = self.module.namespacePtr(namespace_index);
1166 const debug_type = try self.lowerDebugType(namespace.ty);
11661167
1167 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
1168 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
1169 }
11681170 }
1169 }
11701171
1171 self.builder.debugForwardReferenceSetType(
1172 self.debug_enums_fwd_ref,
1173 try self.builder.debugTuple(self.debug_enums.items),
1174 );
1175
1176 self.builder.debugForwardReferenceSetType(
1177 self.debug_globals_fwd_ref,
1178 try self.builder.debugTuple(self.debug_globals.items),
1179 );
1180 }
1172 self.builder.debugForwardReferenceSetType(
1173 self.debug_enums_fwd_ref,
1174 try self.builder.debugTuple(self.debug_enums.items),
1175 );
11811176
1182 if (options.pre_ir_path) |path| {
1183 if (std.mem.eql(u8, path, "-")) {
1184 self.builder.dump();
1185 } else {
1186 _ = try self.builder.printToFile(path);
1177 self.builder.debugForwardReferenceSetType(
1178 self.debug_globals_fwd_ref,
1179 try self.builder.debugTuple(self.debug_globals.items),
1180 );
11871181 }
11881182 }
11891183
1190 var bitcode_arena_allocator = std.heap.ArenaAllocator.init(
1191 std.heap.page_allocator,
1192 );
1193 errdefer bitcode_arena_allocator.deinit();
1194
1195 const bitcode = try self.builder.toBitcode(
1196 bitcode_arena_allocator.allocator(),
1197 );
1198
1199 if (options.pre_bc_path) |path| {
1200 var file = try std.fs.cwd().createFile(path, .{});
1201 defer file.close();
1202
1203 const ptr: [*]const u8 = @ptrCast(bitcode.ptr);
1204 try file.writeAll(ptr[0..(bitcode.len * 4)]);
1205 }
1206
12071184 const emit_asm_msg = options.asm_path orelse "(none)";
12081185 const emit_bin_msg = options.bin_path orelse "(none)";
12091186 const post_llvm_ir_msg = options.post_ir_path orelse "(none)";
......@@ -1212,28 +1189,47 @@ pub const Object = struct {
12121189 emit_asm_msg, emit_bin_msg, post_llvm_ir_msg, post_llvm_bc_msg,
12131190 });
12141191
1215 if (options.asm_path == null and options.bin_path == null and
1216 options.post_ir_path == null and options.post_bc_path == null) return;
1192 const context, const module = emit: {
1193 if (options.pre_ir_path) |path| {
1194 if (std.mem.eql(u8, path, "-")) {
1195 self.builder.dump();
1196 } else {
1197 _ = try self.builder.printToFile(path);
1198 }
1199 }
12171200
1218 if (options.post_bc_path) |path| {
1219 var file = try std.fs.cwd().createFileZ(path, .{});
1220 defer file.close();
1201 const bitcode = try self.builder.toBitcode(self.gpa);
1202 defer self.gpa.free(bitcode);
12211203
1222 const ptr: [*]const u8 = @ptrCast(bitcode.ptr);
1223 try file.writeAll(ptr[0..(bitcode.len * 4)]);
1224 }
1204 if (options.pre_bc_path) |path| {
1205 var file = try std.fs.cwd().createFile(path, .{});
1206 defer file.close();
12251207
1226 if (!build_options.have_llvm or !self.module.comp.config.use_lib_llvm) {
1227 log.err("emitting without libllvm not implemented", .{});
1228 return error.FailedToEmit;
1229 }
1208 const ptr: [*]const u8 = @ptrCast(bitcode.ptr);
1209 try file.writeAll(ptr[0..(bitcode.len * 4)]);
1210 }
12301211
1231 initializeLLVMTarget(self.module.comp.root_mod.resolved_target.result.cpu.arch);
1212 if (options.asm_path == null and options.bin_path == null and
1213 options.post_ir_path == null and options.post_bc_path == null) return;
12321214
1233 const context: *llvm.Context = llvm.Context.create();
1234 defer context.dispose();
1215 if (options.post_bc_path) |path| {
1216 var file = try std.fs.cwd().createFileZ(path, .{});
1217 defer file.close();
1218
1219 const ptr: [*]const u8 = @ptrCast(bitcode.ptr);
1220 try file.writeAll(ptr[0..(bitcode.len * 4)]);
1221 }
1222
1223 if (!build_options.have_llvm or !self.module.comp.config.use_lib_llvm) {
1224 log.err("emitting without libllvm not implemented", .{});
1225 return error.FailedToEmit;
1226 }
1227
1228 initializeLLVMTarget(self.module.comp.root_mod.resolved_target.result.cpu.arch);
1229
1230 const context: *llvm.Context = llvm.Context.create();
1231 errdefer context.dispose();
12351232
1236 const module = blk: {
12371233 const bitcode_memory_buffer = llvm.MemoryBuffer.createMemoryBufferWithMemoryRange(
12381234 @ptrCast(bitcode.ptr),
12391235 bitcode.len * 4,
......@@ -1247,10 +1243,9 @@ pub const Object = struct {
12471243 std.debug.print("Failed to parse bitcode\n", .{});
12481244 return error.FailedToEmit;
12491245 }
1250
1251 break :blk module;
1246 break :emit .{ context, module };
12521247 };
1253 bitcode_arena_allocator.deinit();
1248 defer context.dispose();
12541249
12551250 const target_triple_sentinel =
12561251 try self.gpa.dupeZ(u8, self.builder.target_triple.slice(&self.builder).?);
src/codegen/llvm/Builder.zig+1-1
......@@ -14945,7 +14945,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1494514945 try strtab_block.end();
1494614946 }
1494714947
14948 return bitcode.toSlice();
14948 return bitcode.toOwnedSlice();
1494914949}
1495014950
1495114951const Allocator = std.mem.Allocator;
src/codegen/llvm/bitcode_writer.zig+2-2
......@@ -40,9 +40,9 @@ pub fn BitcodeWriter(comptime types: []const type) type {
4040 self.buffer.deinit();
4141 }
4242
43 pub fn toSlice(self: BcWriter) []const u32 {
43 pub fn toOwnedSlice(self: *BcWriter) Error![]const u32 {
4444 std.debug.assert(self.bit_count == 0);
45 return self.buffer.items;
45 return self.buffer.toOwnedSlice();
4646 }
4747
4848 pub fn length(self: BcWriter) usize {