[llvm] cab48e2 - [CodeGen] don't emit addrsig symbol if it's used only by metadata

Zequan Wu via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 29 15:39:51 PDT 2021


Author: Zequan Wu
Date: 2021-04-29T15:39:30-07:00
New Revision: cab48e2f0e00648ef0494ce114f4e00a3ded330f

URL: https://github.com/llvm/llvm-project/commit/cab48e2f0e00648ef0494ce114f4e00a3ded330f
DIFF: https://github.com/llvm/llvm-project/commit/cab48e2f0e00648ef0494ce114f4e00a3ded330f.diff

LOG: [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

Added: 
    

Modified: 
    llvm/include/llvm/IR/Value.h
    llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/lib/IR/Value.cpp
    llvm/test/CodeGen/X86/addrsig.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h
index 6bc406c8de837..f6fd621b0d4aa 100644
--- a/llvm/include/llvm/IR/Value.h
+++ b/llvm/include/llvm/IR/Value.h
@@ -565,6 +565,9 @@ class Value {
   /// 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.
   ///

diff  --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 581b877ed587b..e491fe7f9f198 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -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).

diff  --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index 47a5be4e5d709..8d6918c59d52a 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -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
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/test/CodeGen/X86/addrsig.ll b/llvm/test/CodeGen/X86/addrsig.ll
index 0ff8e99b287d4..957de7ec2a64c 100644
--- a/llvm/test/CodeGen/X86/addrsig.ll
+++ b/llvm/test/CodeGen/X86/addrsig.ll
@@ -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)


        


More information about the llvm-commits mailing list