[CodeGen] don't emit addrsig symbol if it's used only by metadata
Value only used by metadata can be removed from .addrsig table. This solves the undefined symbol error when enabling addrsig table on COFF LTO. Differential Revision: https://reviews.llvm.org/D101512
This commit is contained in:
parent
be01b091af
commit
cab48e2f0e
@ -565,6 +565,9 @@ public:
|
||||
/// Return true if there is metadata referencing this value.
|
||||
bool isUsedByMetadata() const { return IsUsedByMD; }
|
||||
|
||||
// Return true if this value is only transitively referenced by metadata.
|
||||
bool isTransitiveUsedByMetadataOnly() const;
|
||||
|
||||
protected:
|
||||
/// Get the current metadata attachments for the given kind, if any.
|
||||
///
|
||||
|
||||
@ -1847,11 +1847,12 @@ bool AsmPrinter::doFinalization(Module &M) {
|
||||
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).
|
||||
|
||||
@ -980,6 +980,27 @@ bool Value::isSwiftError() const {
|
||||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -19,9 +19,20 @@ define void @f1() {
|
||||
%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
|
||||
@ -55,3 +66,17 @@ declare void @f3() unnamed_addr
|
||||
@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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user