if (TM.Options.EmitAddrsig) {
// Emit address-significance attributes for all globals.
OutStreamer->emitAddrsig();
- for (const GlobalValue &GV : M.global_values())
- if (!GV.use_empty() && !GV.isThreadLocal() &&
- !GV.hasDLLImportStorageClass() && !GV.getName().startswith("llvm.") &&
- !GV.hasAtLeastLocalUnnamedAddr())
+ for (const GlobalValue &GV : M.global_values()) {
+ if (!GV.use_empty() && !GV.isTransitiveUsedByMetadataOnly() &&
+ !GV.isThreadLocal() && !GV.hasDLLImportStorageClass() &&
+ !GV.getName().startswith("llvm.") && !GV.hasAtLeastLocalUnnamedAddr())
OutStreamer->emitAddrsigSym(getSymbol(&GV));
+ }
}
// Emit symbol partition specifications (ELF only).
return Alloca->isSwiftError();
}
+bool Value::isTransitiveUsedByMetadataOnly() const {
+ if (use_empty())
+ return false;
+ llvm::SmallVector<const User *, 32> WorkList;
+ llvm::SmallPtrSet<const User *, 32> Visited;
+ WorkList.insert(WorkList.begin(), user_begin(), user_end());
+ while (!WorkList.empty()) {
+ const User *U = WorkList.back();
+ WorkList.pop_back();
+ Visited.insert(U);
+ // If it is transitively used by a global value or a non-constant value,
+ // it's obviously not only used by metadata.
+ if (!isa<Constant>(U) || isa<GlobalValue>(U))
+ return false;
+ for (const User *UU : U->users())
+ if (!Visited.count(UU))
+ WorkList.push_back(UU);
+ }
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// ValueHandleBase Class
//===----------------------------------------------------------------------===//
%a2 = bitcast i32* @a2 to i8*
%i1 = bitcast void()* @i1 to i8*
%i2 = bitcast void()* @i2 to i8*
+ call void @llvm.dbg.value(metadata i8* bitcast (void()* @metadata_f1 to i8*), metadata !5, metadata !DIExpression()), !dbg !7
+ call void @llvm.dbg.value(metadata i8* bitcast (void()* @metadata_f2 to i8*), metadata !5, metadata !DIExpression()), !dbg !7
+ call void @f4(i8* bitcast (void()* @metadata_f2 to i8*))
unreachable
}
+declare void @f4(i8*) unnamed_addr
+
+; CHECK-NOT: .addrsig_sym metadata_f1
+declare void @metadata_f1()
+
+; CHECK: .addrsig_sym metadata_f2
+declare void @metadata_f2()
+
; CHECK-NOT: .addrsig_sym f2
define internal void @f2() local_unnamed_addr {
unreachable
@i1 = ifunc void(), void()* @f1
; CHECK-NOT: .addrsig_sym i2
@i2 = internal local_unnamed_addr ifunc void(), void()* @f2
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug)
+!1 = !DIFile(filename: "a", directory: "")
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!3 = distinct !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false, unit: !0)
+!4 = !DILocation(line: 0, scope: !3)
+!5 = !DILocalVariable(scope: !6)
+!6 = distinct !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false, unit: !0)
+!7 = !DILocation(line: 0, scope: !6, inlinedAt: !4)