diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 4 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 68 | ||||
| -rw-r--r-- | src/codegen/llvm/Builder.zig | 103 |
3 files changed, 119 insertions, 56 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index bfc9aa3adc..741c4e2fba 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -6407,8 +6407,6 @@ fn zirDbgVar( inst: Zir.Inst.Index, air_tag: Air.Inst.Tag, ) CompileError!void { - if (block.is_comptime or block.ownerModule().strip) return; - const str_op = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_op; const operand = try sema.resolveInst(str_op.operand); const name = str_op.getStr(sema.code); @@ -6422,6 +6420,8 @@ fn addDbgVar( air_tag: Air.Inst.Tag, name: []const u8, ) CompileError!void { + if (block.is_comptime or block.ownerModule().strip) return; + const mod = sema.mod; const operand_ty = sema.typeOf(operand); const val_ty = switch (air_tag) { diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 6608ea90eb..bd0c337169 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -837,11 +837,10 @@ pub const Object = struct { const gpa = comp.gpa; const target = comp.root_mod.resolved_target.result; const llvm_target_triple = try targetTriple(arena, target); - const strip = comp.root_mod.strip; var builder = try Builder.init(.{ .allocator = gpa, - .strip = strip, + .strip = comp.config.debug_format == .strip, .name = comp.root_name, .target = target, .triple = llvm_target_triple, @@ -1052,7 +1051,10 @@ pub const Object = struct { const mod = o.module; const errors_len = mod.global_error_set.count(); - var wip = try Builder.WipFunction.init(&o.builder, llvm_fn.ptrConst(&o.builder).kind.function); + var wip = try Builder.WipFunction.init(&o.builder, .{ + .function = llvm_fn.ptrConst(&o.builder).kind.function, + .strip = true, + }); defer wip.deinit(); wip.cursor = .{ .block = try wip.block(0, "Entry") }; @@ -1181,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)"; @@ -1200,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, .{}); @@ -1247,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"); @@ -1372,6 +1376,7 @@ pub const Object = struct { air: Air, liveness: Liveness, ) !void { + const comp = zcu.comp; const func = zcu.funcInfo(func_index); const decl_index = func.owner_decl; const decl = zcu.declPtr(decl_index); @@ -1440,7 +1445,10 @@ pub const Object = struct { function_index.setSection(try o.builder.string(section), &o.builder); var deinit_wip = true; - var wip = try Builder.WipFunction.init(&o.builder, function_index); + var wip = try Builder.WipFunction.init(&o.builder, .{ + .function = function_index, + .strip = owner_mod.strip, + }); defer if (deinit_wip) wip.deinit(); wip.cursor = .{ .block = try wip.block(0, "Entry") }; @@ -1459,8 +1467,6 @@ pub const Object = struct { .unsigned => try attributes.addRetAttr(.zeroext, &o.builder), }; - const comp = zcu.comp; - const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(zcu) and comp.config.any_error_tracing; @@ -1645,7 +1651,7 @@ pub const Object = struct { function_index.setAttributes(try attributes.finish(&o.builder), &o.builder); - const file, const subprogram = if (!o.builder.strip) debug_info: { + const file, const subprogram = if (!wip.strip) debug_info: { const file = try o.getDebugFile(namespace.file_scope); const line_number = decl.src_line + 1; @@ -4614,7 +4620,10 @@ pub const Object = struct { function_index.setAttributes(try attributes.finish(&o.builder), &o.builder); gop.value_ptr.* = function_index.ptrConst(&o.builder).global; - var wip = try Builder.WipFunction.init(&o.builder, function_index); + var wip = try Builder.WipFunction.init(&o.builder, .{ + .function = function_index, + .strip = true, + }); defer wip.deinit(); wip.cursor = .{ .block = try wip.block(0, "Entry") }; @@ -4684,23 +4693,23 @@ pub const DeclGen = struct { fn genDecl(dg: *DeclGen) !void { const o = dg.object; - const mod = o.module; + const zcu = o.module; const decl = dg.decl; const decl_index = dg.decl_index; assert(decl.has_tv); - if (decl.val.getExternFunc(mod)) |extern_func| { + if (decl.val.getExternFunc(zcu)) |extern_func| { _ = try o.resolveLlvmFunction(extern_func.decl); } else { const variable_index = try o.resolveGlobalDecl(decl_index); variable_index.setAlignment( - decl.getAlignment(mod).toLlvm(), + decl.getAlignment(zcu).toLlvm(), &o.builder, ); - if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |section| + if (zcu.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |section| variable_index.setSection(try o.builder.string(section), &o.builder); assert(decl.has_tv); - const init_val = if (decl.val.getVariable(mod)) |decl_var| decl_var.init else init_val: { + const init_val = if (decl.val.getVariable(zcu)) |decl_var| decl_var.init else init_val: { variable_index.setMutability(.constant, &o.builder); break :init_val decl.val.toIntern(); }; @@ -4712,12 +4721,15 @@ pub const DeclGen = struct { const line_number = decl.src_line + 1; const is_internal_linkage = !o.module.decl_exports.contains(decl_index); - if (dg.object.builder.strip) return; + const namespace = zcu.namespacePtr(decl.src_namespace); + const owner_mod = namespace.file_scope.mod; - const debug_file = try o.getDebugFile(mod.namespacePtr(decl.src_namespace).file_scope); + if (owner_mod.strip) return; + + const debug_file = try o.getDebugFile(namespace.file_scope); const debug_global_var = try o.builder.debugGlobalVar( - try o.builder.metadataString(mod.intern_pool.stringToSlice(decl.name)), // Name + try o.builder.metadataString(zcu.intern_pool.stringToSlice(decl.name)), // Name try o.builder.metadataStringFromString(variable_index.name(&o.builder)), // Linkage name debug_file, // File debug_file, // Scope @@ -4733,7 +4745,7 @@ pub const DeclGen = struct { debug_global_var, debug_expression, ); - if (!is_internal_linkage or decl.isExtern(mod)) + if (!is_internal_linkage or decl.isExtern(zcu)) variable_index.setGlobalVariableExpression(debug_global_var_expression, &o.builder); try o.debug_globals.append(o.gpa, debug_global_var_expression); } @@ -6568,7 +6580,6 @@ pub const FuncGen = struct { } fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { - if (self.wip.builder.strip) return .none; const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1); self.prev_dbg_column = @intCast(dbg_stmt.column + 1); @@ -6591,7 +6602,6 @@ pub const FuncGen = struct { } fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { - if (self.wip.builder.strip) return .none; const o = self.dg.object; const zcu = o.module; @@ -6658,7 +6668,6 @@ pub const FuncGen = struct { } fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { - if (self.wip.builder.strip) return .none; const o = self.dg.object; const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; @@ -6675,7 +6684,6 @@ pub const FuncGen = struct { } fn airDbgBlockBegin(self: *FuncGen) Allocator.Error!Builder.Value { - if (self.wip.builder.strip) return .none; const o = self.dg.object; try self.scope_stack.append(self.gpa, self.scope); @@ -6691,13 +6699,11 @@ pub const FuncGen = struct { } fn airDbgBlockEnd(self: *FuncGen) !Builder.Value { - if (self.wip.builder.strip) return .none; self.scope = self.scope_stack.pop(); return .none; } fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { - if (self.wip.builder.strip) return .none; const o = self.dg.object; const mod = o.module; const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; @@ -6730,7 +6736,6 @@ pub const FuncGen = struct { } fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { - if (self.wip.builder.strip) return .none; const o = self.dg.object; const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; const operand = try self.resolveInst(pl_op.operand); @@ -8817,7 +8822,7 @@ pub const FuncGen = struct { const arg_val = self.args[self.arg_index]; self.arg_index += 1; - if (self.wip.builder.strip) return arg_val; + if (self.wip.strip) return arg_val; const inst_ty = self.typeOfIndex(inst); if (needDbgVarWorkaround(o)) return arg_val; @@ -9664,7 +9669,10 @@ pub const FuncGen = struct { function_index.setAttributes(try attributes.finish(&o.builder), &o.builder); gop.value_ptr.* = function_index; - var wip = try Builder.WipFunction.init(&o.builder, function_index); + var wip = try Builder.WipFunction.init(&o.builder, .{ + .function = function_index, + .strip = true, + }); defer wip.deinit(); wip.cursor = .{ .block = try wip.block(0, "Entry") }; diff --git a/src/codegen/llvm/Builder.zig b/src/codegen/llvm/Builder.zig index 7eb2098322..70a85093e8 100644 --- a/src/codegen/llvm/Builder.zig +++ b/src/codegen/llvm/Builder.zig @@ -3797,6 +3797,7 @@ pub const Function = struct { instructions: std.MultiArrayList(Instruction) = .{}, names: [*]const String = &[0]String{}, value_indices: [*]const u32 = &[0]u32{}, + strip: bool, debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, DebugLocation) = .{}, debug_values: []const Instruction.Index = &.{}, extra: []const u32 = &.{}, @@ -4890,6 +4891,7 @@ pub const WipFunction = struct { blocks: std.ArrayListUnmanaged(Block), instructions: std.MultiArrayList(Instruction), names: std.ArrayListUnmanaged(String), + strip: bool, debug_locations: std.AutoArrayHashMapUnmanaged(Instruction.Index, DebugLocation), debug_values: std.AutoArrayHashMapUnmanaged(Instruction.Index, void), extra: std.ArrayListUnmanaged(u32), @@ -4922,31 +4924,35 @@ pub const WipFunction = struct { pub const Instruction = Function.Instruction; - pub fn init(builder: *Builder, function: Function.Index) Allocator.Error!WipFunction { + pub fn init(builder: *Builder, options: struct { + function: Function.Index, + strip: bool, + }) Allocator.Error!WipFunction { var self: WipFunction = .{ .builder = builder, - .function = function, + .function = options.function, .prev_debug_location = .no_location, .debug_location = .no_location, .cursor = undefined, .blocks = .{}, .instructions = .{}, .names = .{}, + .strip = options.strip, .debug_locations = .{}, .debug_values = .{}, .extra = .{}, }; errdefer self.deinit(); - const params_len = function.typeOf(self.builder).functionParameters(self.builder).len; + const params_len = options.function.typeOf(self.builder).functionParameters(self.builder).len; try self.ensureUnusedExtraCapacity(params_len, NoExtra, 0); try self.instructions.ensureUnusedCapacity(self.builder.gpa, params_len); - if (!self.builder.strip) { + if (!self.strip) { try self.names.ensureUnusedCapacity(self.builder.gpa, params_len); } for (0..params_len) |param_index| { self.instructions.appendAssumeCapacity(.{ .tag = .arg, .data = @intCast(param_index) }); - if (!self.builder.strip) { + if (!self.strip) { self.names.appendAssumeCapacity(.empty); // TODO: param names } } @@ -4967,7 +4973,7 @@ pub const WipFunction = struct { try self.blocks.ensureUnusedCapacity(self.builder.gpa, 1); const index: Block.Index = @enumFromInt(self.blocks.items.len); - const final_name = if (self.builder.strip) .empty else try self.builder.string(name); + const final_name = if (self.strip) .empty else try self.builder.string(name); self.blocks.appendAssumeCapacity(.{ .name = final_name, .incoming = incoming, @@ -5828,7 +5834,7 @@ pub const WipFunction = struct { } pub fn debugValue(self: *WipFunction, value: Value) Allocator.Error!Metadata { - if (self.builder.strip) return .none; + if (self.strip) return .none; return switch (value.unwrap()) { .instruction => |instr_index| blk: { const gop = try self.debug_values.getOrPut(self.builder.gpa, instr_index); @@ -6015,7 +6021,7 @@ pub const WipFunction = struct { value_index += 1; function.instructions.appendAssumeCapacity(argument); names[@intFromEnum(new_argument_index)] = try wip_name.map( - if (self.builder.strip) .empty else self.names.items[@intFromEnum(old_argument_index)], + if (self.strip) .empty else self.names.items[@intFromEnum(old_argument_index)], ".", ); if (self.debug_locations.get(old_argument_index)) |location| { @@ -6333,7 +6339,7 @@ pub const WipFunction = struct { }, } function.instructions.appendAssumeCapacity(instruction); - names[@intFromEnum(new_instruction_index)] = try wip_name.map(if (self.builder.strip) + names[@intFromEnum(new_instruction_index)] = try wip_name.map(if (self.strip) if (old_instruction_index.hasResultWip(self)) .empty else .none else self.names.items[@intFromEnum(old_instruction_index)], "."); @@ -6356,6 +6362,7 @@ pub const WipFunction = struct { function.blocks = blocks; function.names = names.ptr; function.value_indices = value_indices.ptr; + function.strip = self.strip; function.debug_locations = debug_locations; function.debug_values = debug_values; } @@ -6503,19 +6510,19 @@ pub const WipFunction = struct { ) Allocator.Error!Instruction.Index { const block_instructions = &self.cursor.block.ptr(self).instructions; try self.instructions.ensureUnusedCapacity(self.builder.gpa, 1); - if (!self.builder.strip) { + if (!self.strip) { try self.names.ensureUnusedCapacity(self.builder.gpa, 1); try self.debug_locations.ensureUnusedCapacity(self.builder.gpa, 1); } try block_instructions.ensureUnusedCapacity(self.builder.gpa, 1); const final_name = if (name) |n| - if (self.builder.strip) .empty else try self.builder.string(n) + if (self.strip) .empty else try self.builder.string(n) else .none; const index: Instruction.Index = @enumFromInt(self.instructions.len); self.instructions.appendAssumeCapacity(instruction); - if (!self.builder.strip) { + if (!self.strip) { self.names.appendAssumeCapacity(final_name); if (block_instructions.items.len == 0 or !std.meta.eql(self.debug_location, self.prev_debug_location)) @@ -8389,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); @@ -8723,11 +8774,14 @@ pub fn addFunctionAssumeCapacity( ) Function.Index { assert(ty.isFunction(self)); const function_index: Function.Index = @enumFromInt(self.functions.items.len); - self.functions.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{ - .addr_space = addr_space, - .type = ty, - .kind = .{ .function = function_index }, - }) }); + self.functions.appendAssumeCapacity(.{ + .global = self.addGlobalAssumeCapacity(name, .{ + .addr_space = addr_space, + .type = ty, + .kind = .{ .function = function_index }, + }), + .strip = undefined, + }); return function_index; } @@ -14396,16 +14450,17 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co return @intCast(switch (value.unwrap()) { .instruction => |instruction| instruction.valueIndex(adapter.func) + adapter.firstInstr(), .constant => |constant| adapter.constant_adapter.getConstantIndex(constant), - .metadata => |metadata| if (!adapter.metadata_adapter.builder.strip) blk: { + .metadata => |metadata| { + assert(!adapter.func.strip); const real_metadata = metadata.unwrap(adapter.metadata_adapter.builder); if (@intFromEnum(real_metadata) < Metadata.first_local_metadata) - break :blk adapter.metadata_adapter.getMetadataIndex(real_metadata) - 1; + return adapter.metadata_adapter.getMetadataIndex(real_metadata) - 1; return @intCast(@intFromEnum(metadata) - Metadata.first_local_metadata + adapter.metadata_adapter.builder.metadata_string_map.count() - 1 + adapter.metadata_adapter.builder.metadata_map.count() - 1); - } else unreachable, + }, }); } @@ -14452,7 +14507,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co var adapter = FunctionAdapter.init(constant_adapter, metadata_adapter, &func); // Emit function level metadata block - if (!self.strip and func.debug_values.len != 0) { + if (!func.strip and func.debug_values.len > 0) { const MetadataBlock = ir.FunctionMetadataBlock; var metadata_block = try function_block.enterSubBlock(MetadataBlock); @@ -14913,7 +14968,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }, } - if (!self.strip) { + if (!func.strip) { if (func.debug_locations.get(@enumFromInt(instr_index))) |debug_location| { switch (debug_location) { .no_location => has_location = false, @@ -14937,7 +14992,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co } // VALUE_SYMTAB - if (!self.strip) { + if (!func.strip) { const ValueSymbolTable = ir.FunctionValueSymbolTable; var value_symtab_block = try function_block.enterSubBlock(ValueSymbolTable); @@ -14959,7 +15014,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co } // METADATA_ATTACHMENT_BLOCK - if (!self.strip) blk: { + if (!func.strip) blk: { const dbg = func.global.ptrConst(self).dbg; if (dbg == .none) break :blk; |
