[llvm] 80dc066 - [LTO] Perform DSOLocal propagation in combined index

Wei Wang via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 12 23:10:41 PST 2021


Author: Wei Wang
Date: 2021-02-12T22:58:26-08:00
New Revision: 80dc0661bd8bba92fb0843cac3bdc061c093039f

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

LOG: [LTO] Perform DSOLocal propagation in combined index

Perform DSOLocal propagation within summary list of every GV. This
avoids the repeated query of this information during function
importing.

Differential Revision: https://reviews.llvm.org/D96398

Added: 
    

Modified: 
    llvm/include/llvm/IR/ModuleSummaryIndex.h
    llvm/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/lib/IR/ModuleSummaryIndex.cpp
    llvm/lib/LTO/LTO.cpp
    llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
    llvm/test/Assembler/summary-flags.ll
    llvm/test/Bitcode/thinlto-deadstrip-flag.ll
    llvm/test/Bitcode/thinlto-synthetic-count-flag.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h
index 3e30cb166db2..b588c0a5a778 100644
--- a/llvm/include/llvm/IR/ModuleSummaryIndex.h
+++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -228,7 +228,9 @@ struct ValueInfo {
   /// protected and hidden.
   GlobalValue::VisibilityTypes getELFVisibility() const;
 
-  bool isDSOLocal() const;
+  /// Checks if all summaries are DSO local (have the flag set). When DSOLocal
+  /// propagation has been done, set the parameter to enable fast check.
+  bool isDSOLocal(bool WithDSOLocalPropagation = false) const;
 
   /// Checks if all copies are eligible for auto-hiding (have flag set).
   bool canAutoHide() const;
@@ -1055,6 +1057,10 @@ class ModuleSummaryIndex {
   /// read/write only.
   bool WithAttributePropagation = false;
 
+  /// Indicates that summary-based DSOLocal propagation has run and the flag in
+  /// every summary of a GV is synchronized.
+  bool WithDSOLocalPropagation = false;
+
   /// Indicates that summary-based synthetic entry count propagation has run
   bool HasSyntheticEntryCounts = false;
 
@@ -1210,6 +1216,9 @@ class ModuleSummaryIndex {
     WithAttributePropagation = true;
   }
 
+  bool withDSOLocalPropagation() const { return WithDSOLocalPropagation; }
+  void setWithDSOLocalPropagation() { WithDSOLocalPropagation = true; }
+
   bool isReadOnly(const GlobalVarSummary *GVS) const {
     return WithAttributePropagation && GVS->maybeReadOnly();
   }
@@ -1513,7 +1522,7 @@ class ModuleSummaryIndex {
   /// Print out strongly connected components for debugging.
   void dumpSCCs(raw_ostream &OS);
 
-  /// Analyze index and detect unmodified globals
+  /// Do the access attribute and DSOLocal propagation in combined index.
   void propagateAttributes(const DenseSet<GlobalValue::GUID> &PreservedSymbols);
 
   /// Checks if we can import global variable from another module.

diff  --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 2911eb57033c..f88c371b99be 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -6845,7 +6845,7 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream,
     case bitc::FS_FLAGS: { // [flags]
       uint64_t Flags = Record[0];
       // Scan flags.
-      assert(Flags <= 0x3f && "Unexpected bits in flag");
+      assert(Flags <= 0x7f && "Unexpected bits in flag");
 
       return Flags & 0x8;
     }

diff  --git a/llvm/lib/IR/ModuleSummaryIndex.cpp b/llvm/lib/IR/ModuleSummaryIndex.cpp
index df3e801a714d..c2ded87c4947 100644
--- a/llvm/lib/IR/ModuleSummaryIndex.cpp
+++ b/llvm/lib/IR/ModuleSummaryIndex.cpp
@@ -52,13 +52,17 @@ GlobalValue::VisibilityTypes ValueInfo::getELFVisibility() const {
                       : GlobalValue::DefaultVisibility;
 }
 
-bool ValueInfo::isDSOLocal() const {
-  // Need to check all summaries are local in case of hash collisions.
-  return getSummaryList().size() &&
-         llvm::all_of(getSummaryList(),
-                      [](const std::unique_ptr<GlobalValueSummary> &Summary) {
-                        return Summary->isDSOLocal();
-                      });
+bool ValueInfo::isDSOLocal(bool WithDSOLocalPropagation) const {
+  // With DSOLocal propagation done, the flag in evey summary is the same.
+  // Check the first one is enough.
+  return WithDSOLocalPropagation
+             ? getSummaryList().size() && getSummaryList()[0]->isDSOLocal()
+             : getSummaryList().size() &&
+                   llvm::all_of(
+                       getSummaryList(),
+                       [](const std::unique_ptr<GlobalValueSummary> &Summary) {
+                         return Summary->isDSOLocal();
+                       });
 }
 
 bool ValueInfo::canAutoHide() const {
@@ -100,11 +104,13 @@ uint64_t ModuleSummaryIndex::getFlags() const {
     Flags |= 0x10;
   if (withAttributePropagation())
     Flags |= 0x20;
+  if (withDSOLocalPropagation())
+    Flags |= 0x40;
   return Flags;
 }
 
 void ModuleSummaryIndex::setFlags(uint64_t Flags) {
-  assert(Flags <= 0x3f && "Unexpected bits in flag");
+  assert(Flags <= 0x7f && "Unexpected bits in flag");
   // 1 bit: WithGlobalValueDeadStripping flag.
   // Set on combined index only.
   if (Flags & 0x1)
@@ -130,6 +136,10 @@ void ModuleSummaryIndex::setFlags(uint64_t Flags) {
   // Set on combined index only.
   if (Flags & 0x20)
     setWithAttributePropagation();
+  // 1 bit: WithDSOLocalPropagation flag.
+  // Set on combined index only.
+  if (Flags & 0x40)
+    setWithDSOLocalPropagation();
 }
 
 // Collect for the given module the list of function it defines
@@ -205,7 +215,7 @@ propagateAttributesToRefs(GlobalValueSummary *S,
   }
 }
 
-// Do the access attribute propagation in combined index.
+// Do the access attribute and DSOLocal propagation in combined index.
 // The goal of attribute propagation is internalization of readonly (RO)
 // or writeonly (WO) variables. To determine which variables are RO or WO
 // and which are not we take following steps:
@@ -216,7 +226,7 @@ propagateAttributesToRefs(GlobalValueSummary *S,
 //   or doesn't read it (writeonly).
 //
 // - After computing dead symbols in combined index we do the attribute
-//   propagation. During this step we:
+//   and DSOLocal propagation. During this step we:
 //   a. clear RO and WO attributes from variables which are preserved or
 //      can't be imported
 //   b. clear RO and WO attributes from variables referenced by any global
@@ -225,6 +235,7 @@ propagateAttributesToRefs(GlobalValueSummary *S,
 //      reference is not readonly
 //   d. clear WO attribute from variable referenced by a function when
 //      reference is not writeonly
+//   e. clear IsDSOLocal flag in every summary if any of them is false.
 //
 //   Because of (c, d) we don't internalize variables read by function A
 //   and modified by function B.
@@ -236,7 +247,8 @@ void ModuleSummaryIndex::propagateAttributes(
   if (!PropagateAttrs)
     return;
   DenseSet<ValueInfo> MarkedNonReadWriteOnly;
-  for (auto &P : *this)
+  for (auto &P : *this) {
+    bool IsDSOLocal = true;
     for (auto &S : P.second.SummaryList) {
       if (!isGlobalValueLive(S.get())) {
         // computeDeadSymbols should have marked all copies live. Note that
@@ -273,8 +285,20 @@ void ModuleSummaryIndex::propagateAttributes(
           GVS->setWriteOnly(false);
         }
       propagateAttributesToRefs(S.get(), MarkedNonReadWriteOnly);
+
+      // If the flag from any summary is false, the GV is not DSOLocal.
+      IsDSOLocal &= S->isDSOLocal();
     }
+    if (!IsDSOLocal)
+      // Mark the flag in all summaries false so that we can do quick check
+      // without going through the whole list.
+      llvm::for_each(P.second.SummaryList,
+                     [](const std::unique_ptr<GlobalValueSummary> &Summary) {
+                       return Summary->setDSOLocal(false);
+                     });
+  }
   setWithAttributePropagation();
+  setWithDSOLocalPropagation();
   if (llvm::AreStatisticsEnabled())
     for (auto &P : *this)
       if (P.second.SummaryList.size())

diff  --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 375d205235a8..ea576269ec84 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -207,7 +207,7 @@ void llvm::computeLTOCacheKey(
     AddUnsigned(GS->isLive());
     AddUnsigned(GS->canAutoHide());
     for (const ValueInfo &VI : GS->refs()) {
-      AddUnsigned(VI.isDSOLocal());
+      AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));
       AddUsedCfiGlobal(VI.getGUID());
     }
     if (auto *GVS = dyn_cast<GlobalVarSummary>(GS)) {
@@ -226,7 +226,7 @@ void llvm::computeLTOCacheKey(
       for (auto &TT : FS->type_checked_load_const_vcalls())
         UsedTypeIds.insert(TT.VFunc.GUID);
       for (auto &ET : FS->calls()) {
-        AddUnsigned(ET.first.isDSOLocal());
+        AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));
         AddUsedCfiGlobal(ET.first.getGUID());
       }
     }

diff  --git a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
index 8df7ae9563d8..94c97bb1264f 100644
--- a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
+++ b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
@@ -279,7 +279,7 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
   if (ClearDSOLocalOnDeclarations && GV.isDeclarationForLinker() &&
       !GV.isImplicitDSOLocal()) {
     GV.setDSOLocal(false);
-  } else if (VI && VI.isDSOLocal()) {
+  } else if (VI && VI.isDSOLocal(ImportIndex.withDSOLocalPropagation())) {
     // If all summaries are dso_local, symbol gets resolved to a known local
     // definition.
     GV.setDSOLocal(true);

diff  --git a/llvm/test/Assembler/summary-flags.ll b/llvm/test/Assembler/summary-flags.ll
index 619647bd451a..384ba19d6f85 100644
--- a/llvm/test/Assembler/summary-flags.ll
+++ b/llvm/test/Assembler/summary-flags.ll
@@ -5,8 +5,8 @@ source_filename = "tmp.bc"
 ; RUN: llvm-as %s -o - | llvm-dis -o - | FileCheck %s
 ; CHECK:       ^0 = module
 ; CHECK-NEXT:  ^1 = gv
-; CHECK-NEXT:  ^2 = flags: 33
+; CHECK-NEXT:  ^2 = flags: 97
 
 ^0 = module: (path: "main.bc", hash: (3499594384, 1671013073, 3271036935, 1830411232, 59290952))
 ^1 = gv: (guid: 15822663052811949562, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 1, dsoLocal: 1, canAutoHide: 0), insts: 2)))
-^2 = flags: 33
+^2 = flags: 97

diff  --git a/llvm/test/Bitcode/thinlto-deadstrip-flag.ll b/llvm/test/Bitcode/thinlto-deadstrip-flag.ll
index acde6e943d42..00c01314a51c 100644
--- a/llvm/test/Bitcode/thinlto-deadstrip-flag.ll
+++ b/llvm/test/Bitcode/thinlto-deadstrip-flag.ll
@@ -5,14 +5,14 @@
 ; RUN: llvm-lto2 run %t.o -o %t.out -thinlto-distributed-indexes \
 ; RUN:		-r %t.o,glob,plx
 ; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=WITHDEAD
-; WITHDEAD: <FLAGS op0=33/>
+; WITHDEAD: <FLAGS op0=97/>
 
 ; Ensure dead stripping performed flag is not set on distributed index
 ; when option used to disable dead stripping computation.
 ; RUN: llvm-lto2 run %t.o -o %t.out -thinlto-distributed-indexes \
 ; RUN:		-r %t.o,glob,plx -compute-dead=false
 ; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=NODEAD
-; NODEAD: <FLAGS op0=32/>
+; NODEAD: <FLAGS op0=96/>
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"

diff  --git a/llvm/test/Bitcode/thinlto-synthetic-count-flag.ll b/llvm/test/Bitcode/thinlto-synthetic-count-flag.ll
index 2174335f7bcb..1b92a15145ca 100644
--- a/llvm/test/Bitcode/thinlto-synthetic-count-flag.ll
+++ b/llvm/test/Bitcode/thinlto-synthetic-count-flag.ll
@@ -5,7 +5,7 @@
 ; RUN: llvm-lto2 run %t.o -o %t.out -thinlto-distributed-indexes \
 ; RUN:		-r %t.o,glob,plx -compute-dead=false
 ; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=NOSYNTHETIC
-; NOSYNTHETIC: <FLAGS op0=32/>
+; NOSYNTHETIC: <FLAGS op0=96/>
 
 ; Ensure synthetic entry count flag is set on distributed index
 ; when option used to enable synthetic count propagation
@@ -13,7 +13,7 @@
 ; RUN:		-r %t.o,glob,plx -thinlto-synthesize-entry-counts \
 ; RUN:          -compute-dead=false
 ; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=HASSYNTHETIC
-; HASSYNTHETIC: <FLAGS op0=36/>
+; HASSYNTHETIC: <FLAGS op0=100/>
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"


        


More information about the llvm-commits mailing list