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 {
822822 /// This is denormalized data.
823823 struct_field_map: std.AutoHashMapUnmanaged(ZigStructField, c_uint),
824824
825 /// Values for `@llvm.compiler.used`.
826 compiler_used: std.ArrayListUnmanaged(Builder.Constant),
827
825828 const ZigStructField = struct {
826829 struct_ty: InternPool.Index,
827830 field_index: u32,
......@@ -975,6 +978,7 @@ pub const Object = struct {
975978 .error_name_table = .none,
976979 .null_opt_usize = .no_init,
977980 .struct_field_map = .{},
981 .compiler_used = .{},
978982 };
979983 return obj;
980984 }
......@@ -1097,44 +1101,57 @@ pub const Object = struct {
10971101 lto: bool,
10981102 };
10991103
1100 pub fn emit(self: *Object, options: EmitOptions) !void {
1101 const zcu = self.pt.zcu;
1104 pub fn emit(o: *Object, options: EmitOptions) !void {
1105 const zcu = o.pt.zcu;
11021106 const comp = zcu.comp;
11031107
11041108 {
1105 try self.genErrorNameTable();
1106 try self.genCmpLtErrorsLenFunction();
1107 try self.genModuleLevelAssembly();
1109 try o.genErrorNameTable();
1110 try o.genCmpLtErrorsLenFunction();
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) {
11101127 {
11111128 var i: usize = 0;
1112 while (i < self.debug_unresolved_namespace_scopes.count()) : (i += 1) {
1113 const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i];
1114 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];
1129 while (i < o.debug_unresolved_namespace_scopes.count()) : (i += 1) {
1130 const namespace_index = o.debug_unresolved_namespace_scopes.keys()[i];
1131 const fwd_ref = o.debug_unresolved_namespace_scopes.values()[i];
11151132
11161133 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);
11201137 }
11211138 }
11221139
1123 self.builder.debugForwardReferenceSetType(
1124 self.debug_enums_fwd_ref,
1125 try self.builder.metadataTuple(self.debug_enums.items),
1140 o.builder.debugForwardReferenceSetType(
1141 o.debug_enums_fwd_ref,
1142 try o.builder.metadataTuple(o.debug_enums.items),
11261143 );
11271144
1128 self.builder.debugForwardReferenceSetType(
1129 self.debug_globals_fwd_ref,
1130 try self.builder.metadataTuple(self.debug_globals.items),
1145 o.builder.debugForwardReferenceSetType(
1146 o.debug_globals_fwd_ref,
1147 try o.builder.metadataTuple(o.debug_globals.items),
11311148 );
11321149 }
11331150 }
11341151
11351152 const target_triple_sentinel =
1136 try self.gpa.dupeZ(u8, self.builder.target_triple.slice(&self.builder).?);
1137 defer self.gpa.free(target_triple_sentinel);
1153 try o.gpa.dupeZ(u8, o.builder.target_triple.slice(&o.builder).?);
1154 defer o.gpa.free(target_triple_sentinel);
11381155
11391156 const emit_asm_msg = options.asm_path orelse "(none)";
11401157 const emit_bin_msg = options.bin_path orelse "(none)";
......@@ -1147,15 +1164,15 @@ pub const Object = struct {
11471164 const context, const module = emit: {
11481165 if (options.pre_ir_path) |path| {
11491166 if (std.mem.eql(u8, path, "-")) {
1150 self.builder.dump();
1167 o.builder.dump();
11511168 } else {
1152 _ = try self.builder.printToFile(path);
1169 _ = try o.builder.printToFile(path);
11531170 }
11541171 }
11551172
1156 const bitcode = try self.builder.toBitcode(self.gpa);
1157 defer self.gpa.free(bitcode);
1158 self.builder.clearAndFree();
1173 const bitcode = try o.builder.toBitcode(o.gpa);
1174 defer o.gpa.free(bitcode);
1175 o.builder.clearAndFree();
11591176
11601177 if (options.pre_bc_path) |path| {
11611178 var file = try std.fs.cwd().createFile(path, .{});
......@@ -1707,7 +1724,7 @@ pub const Object = struct {
17071724
17081725 fg.genBody(air.getMainBody(), .poi) catch |err| switch (err) {
17091726 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.?);
17111728 ng.err_msg = null;
17121729 return;
17131730 },
......@@ -1730,6 +1747,11 @@ pub const Object = struct {
17301747 pcs_variable.setAlignment(Type.usize.abiAlignment(zcu).toLlvm(), &o.builder);
17311748 pcs_variable.setSection(try o.builder.string("__sancov_pcs1"), &o.builder);
17321749 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 });
17331755 }
17341756
17351757 try fg.wip.finish();