authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-28 15:18:42-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-28 18:07:13-07:00
log9e11c4f60ea56af50bed7bb27984307762d5f167
tree2436a6f651a480fbc0f8b63f8947e05393cdaee1
parent1bec824cadba7870d6e2b52588d782f32be44866

LLVM: put sancov globals into llvm.compiler.used

This matches what LLVM's sancov pass does and is required so that optimization passes do not delete the instrumentation. However, this is currently triggering an error: "members of llvm.compiler.used must be named" so the next commit will add names to those globals.

1 files changed, 47 insertions(+), 25 deletions(-)

src/codegen/llvm.zig+47-25
...@@ -822,6 +822,9 @@ pub const Object = struct {...@@ -822,6 +822,9 @@ pub const Object = struct {
822 /// This is denormalized data.822 /// This is denormalized data.
823 struct_field_map: std.AutoHashMapUnmanaged(ZigStructField, c_uint),823 struct_field_map: std.AutoHashMapUnmanaged(ZigStructField, c_uint),
824824
825 /// Values for `@llvm.compiler.used`.
826 compiler_used: std.ArrayListUnmanaged(Builder.Constant),
827
825 const ZigStructField = struct {828 const ZigStructField = struct {
826 struct_ty: InternPool.Index,829 struct_ty: InternPool.Index,
827 field_index: u32,830 field_index: u32,
...@@ -975,6 +978,7 @@ pub const Object = struct {...@@ -975,6 +978,7 @@ pub const Object = struct {
975 .error_name_table = .none,978 .error_name_table = .none,
976 .null_opt_usize = .no_init,979 .null_opt_usize = .no_init,
977 .struct_field_map = .{},980 .struct_field_map = .{},
981 .compiler_used = .{},
978 };982 };
979 return obj;983 return obj;
980 }984 }
...@@ -1097,44 +1101,57 @@ pub const Object = struct {...@@ -1097,44 +1101,57 @@ pub const Object = struct {
1097 lto: bool,1101 lto: bool,
1098 };1102 };
10991103
1100 pub fn emit(self: *Object, options: EmitOptions) !void {1104 pub fn emit(o: *Object, options: EmitOptions) !void {
1101 const zcu = self.pt.zcu;1105 const zcu = o.pt.zcu;
1102 const comp = zcu.comp;1106 const comp = zcu.comp;
11031107
1104 {1108 {
1105 try self.genErrorNameTable();1109 try o.genErrorNameTable();
1106 try self.genCmpLtErrorsLenFunction();1110 try o.genCmpLtErrorsLenFunction();
1107 try self.genModuleLevelAssembly();1111 try o.genModuleLevelAssembly();
1112
1113 if (o.compiler_used.items.len > 0) {
1114 const array_llvm_ty = try o.builder.arrayType(o.compiler_used.items.len, .ptr);
1115 const init_val = try o.builder.arrayConst(array_llvm_ty, o.compiler_used.items);
1116 const compiler_used_variable = try o.builder.addVariable(
1117 try o.builder.strtabString("llvm.compiler.used"),
1118 array_llvm_ty,
1119 .default,
1120 );
1121 compiler_used_variable.setLinkage(.appending, &o.builder);
1122 compiler_used_variable.setSection(try o.builder.string("llvm.metadata"), &o.builder);
1123 try compiler_used_variable.setInitializer(init_val, &o.builder);
1124 }
11081125
1109 if (!self.builder.strip) {1126 if (!o.builder.strip) {
1110 {1127 {
1111 var i: usize = 0;1128 var i: usize = 0;
1112 while (i < self.debug_unresolved_namespace_scopes.count()) : (i += 1) {1129 while (i < o.debug_unresolved_namespace_scopes.count()) : (i += 1) {
1113 const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i];1130 const namespace_index = o.debug_unresolved_namespace_scopes.keys()[i];
1114 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];1131 const fwd_ref = o.debug_unresolved_namespace_scopes.values()[i];
11151132
1116 const namespace = zcu.namespacePtr(namespace_index);1133 const namespace = zcu.namespacePtr(namespace_index);
1117 const debug_type = try self.lowerDebugType(Type.fromInterned(namespace.owner_type));1134 const debug_type = try o.lowerDebugType(Type.fromInterned(namespace.owner_type));
11181135
1119 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);1136 o.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
1120 }1137 }
1121 }1138 }
11221139
1123 self.builder.debugForwardReferenceSetType(1140 o.builder.debugForwardReferenceSetType(
1124 self.debug_enums_fwd_ref,1141 o.debug_enums_fwd_ref,
1125 try self.builder.metadataTuple(self.debug_enums.items),1142 try o.builder.metadataTuple(o.debug_enums.items),
1126 );1143 );
11271144
1128 self.builder.debugForwardReferenceSetType(1145 o.builder.debugForwardReferenceSetType(
1129 self.debug_globals_fwd_ref,1146 o.debug_globals_fwd_ref,
1130 try self.builder.metadataTuple(self.debug_globals.items),1147 try o.builder.metadataTuple(o.debug_globals.items),
1131 );1148 );
1132 }1149 }
1133 }1150 }
11341151
1135 const target_triple_sentinel =1152 const target_triple_sentinel =
1136 try self.gpa.dupeZ(u8, self.builder.target_triple.slice(&self.builder).?);1153 try o.gpa.dupeZ(u8, o.builder.target_triple.slice(&o.builder).?);
1137 defer self.gpa.free(target_triple_sentinel);1154 defer o.gpa.free(target_triple_sentinel);
11381155
1139 const emit_asm_msg = options.asm_path orelse "(none)";1156 const emit_asm_msg = options.asm_path orelse "(none)";
1140 const emit_bin_msg = options.bin_path orelse "(none)";1157 const emit_bin_msg = options.bin_path orelse "(none)";
...@@ -1147,15 +1164,15 @@ pub const Object = struct {...@@ -1147,15 +1164,15 @@ pub const Object = struct {
1147 const context, const module = emit: {1164 const context, const module = emit: {
1148 if (options.pre_ir_path) |path| {1165 if (options.pre_ir_path) |path| {
1149 if (std.mem.eql(u8, path, "-")) {1166 if (std.mem.eql(u8, path, "-")) {
1150 self.builder.dump();1167 o.builder.dump();
1151 } else {1168 } else {
1152 _ = try self.builder.printToFile(path);1169 _ = try o.builder.printToFile(path);
1153 }1170 }
1154 }1171 }
11551172
1156 const bitcode = try self.builder.toBitcode(self.gpa);1173 const bitcode = try o.builder.toBitcode(o.gpa);
1157 defer self.gpa.free(bitcode);1174 defer o.gpa.free(bitcode);
1158 self.builder.clearAndFree();1175 o.builder.clearAndFree();
11591176
1160 if (options.pre_bc_path) |path| {1177 if (options.pre_bc_path) |path| {
1161 var file = try std.fs.cwd().createFile(path, .{});1178 var file = try std.fs.cwd().createFile(path, .{});
...@@ -1707,7 +1724,7 @@ pub const Object = struct {...@@ -1707,7 +1724,7 @@ pub const Object = struct {
17071724
1708 fg.genBody(air.getMainBody(), .poi) catch |err| switch (err) {1725 fg.genBody(air.getMainBody(), .poi) catch |err| switch (err) {
1709 error.CodegenFail => {1726 error.CodegenFail => {
1710 try zcu.failed_codegen.put(zcu.gpa, func.owner_nav, ng.err_msg.?);1727 try zcu.failed_codegen.put(gpa, func.owner_nav, ng.err_msg.?);
1711 ng.err_msg = null;1728 ng.err_msg = null;
1712 return;1729 return;
1713 },1730 },
...@@ -1730,6 +1747,11 @@ pub const Object = struct {...@@ -1730,6 +1747,11 @@ pub const Object = struct {
1730 pcs_variable.setAlignment(Type.usize.abiAlignment(zcu).toLlvm(), &o.builder);1747 pcs_variable.setAlignment(Type.usize.abiAlignment(zcu).toLlvm(), &o.builder);
1731 pcs_variable.setSection(try o.builder.string("__sancov_pcs1"), &o.builder);1748 pcs_variable.setSection(try o.builder.string("__sancov_pcs1"), &o.builder);
1732 try pcs_variable.setInitializer(init_val, &o.builder);1749 try pcs_variable.setInitializer(init_val, &o.builder);
1750
1751 try o.compiler_used.appendSlice(gpa, &.{
1752 f.counters_variable.toConst(&o.builder),
1753 pcs_variable.toConst(&o.builder),
1754 });
1733 }1755 }
17341756
1735 try fg.wip.finish();1757 try fg.wip.finish();