From ed026b5dffd116d36aa51508e3eefa8c36838c07 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 25 Feb 2024 16:04:59 +0100 Subject: [PATCH] llvm: free llvm data before running llvm optimizations This reduces the max memory usage. --- src/codegen/llvm.zig | 10 ++++---- src/codegen/llvm/Builder.zig | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 140b7eeba0..1e7687b96c 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1183,6 +1183,10 @@ pub const Object = struct { } } + const target_triple_sentinel = + try self.gpa.dupeZ(u8, self.builder.target_triple.slice(&self.builder).?); + defer self.gpa.free(target_triple_sentinel); + const emit_asm_msg = options.asm_path orelse "(none)"; const emit_bin_msg = options.bin_path orelse "(none)"; const post_llvm_ir_msg = options.post_ir_path orelse "(none)"; @@ -1202,6 +1206,7 @@ pub const Object = struct { const bitcode = try self.builder.toBitcode(self.gpa); defer self.gpa.free(bitcode); + self.builder.clearAndFree(); if (options.pre_bc_path) |path| { var file = try std.fs.cwd().createFile(path, .{}); @@ -1249,16 +1254,13 @@ pub const Object = struct { }; defer context.dispose(); - const target_triple_sentinel = - try self.gpa.dupeZ(u8, self.builder.target_triple.slice(&self.builder).?); - defer self.gpa.free(target_triple_sentinel); var target: *llvm.Target = undefined; var error_message: [*:0]const u8 = undefined; if (llvm.Target.getFromTriple(target_triple_sentinel, &target, &error_message).toBool()) { defer llvm.disposeMessage(error_message); log.err("LLVM failed to parse '{s}': {s}", .{ - self.builder.target_triple.slice(&self.builder).?, + target_triple_sentinel, error_message, }); @panic("Invalid LLVM triple"); diff --git a/src/codegen/llvm/Builder.zig b/src/codegen/llvm/Builder.zig index aaddddf0c1..70a85093e8 100644 --- a/src/codegen/llvm/Builder.zig +++ b/src/codegen/llvm/Builder.zig @@ -8396,6 +8396,50 @@ pub fn init(options: Options) Allocator.Error!Builder { return self; } +pub fn clearAndFree(self: *Builder) void { + self.module_asm.clearAndFree(self.gpa); + + self.string_map.clearAndFree(self.gpa); + self.string_indices.clearAndFree(self.gpa); + self.string_bytes.clearAndFree(self.gpa); + + self.types.clearAndFree(self.gpa); + self.next_unique_type_id.clearAndFree(self.gpa); + self.type_map.clearAndFree(self.gpa); + self.type_items.clearAndFree(self.gpa); + self.type_extra.clearAndFree(self.gpa); + + self.attributes.clearAndFree(self.gpa); + self.attributes_map.clearAndFree(self.gpa); + self.attributes_indices.clearAndFree(self.gpa); + self.attributes_extra.clearAndFree(self.gpa); + + self.function_attributes_set.clearAndFree(self.gpa); + + self.globals.clearAndFree(self.gpa); + self.next_unique_global_id.clearAndFree(self.gpa); + self.aliases.clearAndFree(self.gpa); + self.variables.clearAndFree(self.gpa); + for (self.functions.items) |*function| function.deinit(self.gpa); + self.functions.clearAndFree(self.gpa); + + self.constant_map.clearAndFree(self.gpa); + self.constant_items.shrinkAndFree(self.gpa, 0); + self.constant_extra.clearAndFree(self.gpa); + self.constant_limbs.clearAndFree(self.gpa); + + self.metadata_map.clearAndFree(self.gpa); + self.metadata_items.shrinkAndFree(self.gpa, 0); + self.metadata_extra.clearAndFree(self.gpa); + self.metadata_limbs.clearAndFree(self.gpa); + self.metadata_forward_references.clearAndFree(self.gpa); + self.metadata_named.clearAndFree(self.gpa); + + self.metadata_string_map.clearAndFree(self.gpa); + self.metadata_string_indices.clearAndFree(self.gpa); + self.metadata_string_bytes.clearAndFree(self.gpa); +} + pub fn deinit(self: *Builder) void { self.module_asm.deinit(self.gpa);