[llvm] r267303 - Always traverse GlobalVariable initializer when computing the export list

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 23 16:29:24 PDT 2016


Author: mehdi_amini
Date: Sat Apr 23 18:29:24 2016
New Revision: 267303

URL: http://llvm.org/viewvc/llvm-project?rev=267303&view=rev
Log:
Always traverse GlobalVariable initializer when computing the export list

Summary:
We are always importing the initializer for a GlobalVariable.
So if a GlobalVariable is in the export-list, we pull in any
refs as well.

Reviewers: tejohnson

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D19102

From: Mehdi Amini <mehdi.amini at apple.com>

Added:
    llvm/trunk/test/ThinLTO/X86/Inputs/referenced_by_constant.ll
    llvm/trunk/test/ThinLTO/X86/referenced_by_constant.ll
Modified:
    llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp

Modified: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp?rev=267303&r1=267302&r2=267303&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp Sat Apr 23 18:29:24 2016
@@ -131,23 +131,54 @@ static const GlobalValueSummary *selectC
   return selectCallee(CalleeInfoList->second, Threshold);
 }
 
-/// Return true if the global \p GUID is exported by module \p ExportModulePath.
-static bool isGlobalExported(const ModuleSummaryIndex &Index,
-                             StringRef ExportModulePath,
-                             GlobalValue::GUID GUID) {
-  auto CalleeInfoList = Index.findGlobalValueInfoList(GUID);
-  if (CalleeInfoList == Index.end())
-    // This global does not have a summary, it is not part of the ThinLTO
-    // process
-    return false;
-  auto DefinedInCalleeModule = llvm::find_if(
-      CalleeInfoList->second,
-      [&](const std::unique_ptr<GlobalValueInfo> &GlobInfo) {
-        auto *Summary = GlobInfo->summary();
-        assert(Summary && "Unexpected GlobalValueInfo without summary");
-        return Summary->modulePath() == ExportModulePath;
-      });
-  return (DefinedInCalleeModule != CalleeInfoList->second.end());
+/// Mark the global \p GUID as export by module \p ExportModulePath if found in
+/// this module. If it is a GlobalVariable, we also mark any referenced global
+/// in the current module as exported.
+static void exportGlobalInModule(const ModuleSummaryIndex &Index,
+                                 StringRef ExportModulePath,
+                                 GlobalValue::GUID GUID,
+                                 FunctionImporter::ExportSetTy &ExportList) {
+  auto FindGlobalInfoInModule =
+      [&](GlobalValue::GUID GUID) -> GlobalValueInfo *{
+        auto InfoList = Index.findGlobalValueInfoList(GUID);
+        if (InfoList == Index.end())
+          // This global does not have a summary, it is not part of the ThinLTO
+          // process
+          return nullptr;
+        auto Info = llvm::find_if(
+            InfoList->second,
+            [&](const std::unique_ptr<GlobalValueInfo> &GlobInfo) {
+              auto *Summary = GlobInfo->summary();
+              assert(Summary && "Unexpected GlobalValueInfo without summary");
+              return Summary->modulePath() == ExportModulePath;
+            });
+        if (Info == InfoList->second.end())
+          return nullptr;
+        return Info->get();
+      };
+
+  auto *GVInfo = FindGlobalInfoInModule(GUID);
+  if (!GVInfo)
+    return;
+  // We found it in the current module, mark as exported
+  ExportList.insert(GUID);
+
+  auto *Summary = GVInfo->summary();
+  auto GVS = dyn_cast<GlobalVarSummary>(Summary);
+  if (!GVS)
+    return;
+  // FunctionImportGlobalProcessing::doPromoteLocalToGlobal() will always
+  // trigger importing  the initializer for `constant unnamed addr` globals that
+  // are referenced. We conservatively export all the referenced symbols for
+  // every global to workaround this, so that the ExportList is accurate.
+  // FIXME: with a "isConstant" flag in the summary we could be more targetted.
+  for (auto &Ref : GVS->refs()) {
+    auto GUID = Ref.getGUID();
+    auto *RefInfo = FindGlobalInfoInModule(GUID);
+    if (RefInfo)
+      // Found a ref in the current module, mark it as exported
+      ExportList.insert(GUID);
+  }
 }
 
 using EdgeInfo = std::pair<const FunctionSummary *, unsigned /* Threshold */>;
@@ -211,13 +242,11 @@ static void computeImportForFunction(
       // to the outside if they are defined in the same source module.
       for (auto &Edge : ResolvedCalleeSummary->calls()) {
         auto CalleeGUID = Edge.first.getGUID();
-        if (isGlobalExported(Index, ExportModulePath, CalleeGUID))
-          ExportList.insert(CalleeGUID);
+        exportGlobalInModule(Index, ExportModulePath, CalleeGUID, ExportList);
       }
       for (auto &Ref : ResolvedCalleeSummary->refs()) {
         auto GUID = Ref.getGUID();
-        if (isGlobalExported(Index, ExportModulePath, GUID))
-          ExportList.insert(GUID);
+        exportGlobalInModule(Index, ExportModulePath, GUID, ExportList);
       }
     }
 

Added: llvm/trunk/test/ThinLTO/X86/Inputs/referenced_by_constant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/referenced_by_constant.ll?rev=267303&view=auto
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/Inputs/referenced_by_constant.ll (added)
+++ llvm/trunk/test/ThinLTO/X86/Inputs/referenced_by_constant.ll Sat Apr 23 18:29:24 2016
@@ -0,0 +1,16 @@
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+define void @referencedbyglobal() {
+    ret void
+}
+
+ at someglobal = internal unnamed_addr constant i8* bitcast (void ()* @referencedbyglobal to i8*)
+ at ptr = global i8** null
+
+define  void @bar() #0 align 2 {
+  store i8** getelementptr inbounds (i8*, i8** @someglobal, i64 0) , i8*** @ptr, align 8
+  ret void
+}
+

Added: llvm/trunk/test/ThinLTO/X86/referenced_by_constant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/referenced_by_constant.ll?rev=267303&view=auto
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/referenced_by_constant.ll (added)
+++ llvm/trunk/test/ThinLTO/X86/referenced_by_constant.ll Sat Apr 23 18:29:24 2016
@@ -0,0 +1,21 @@
+; Do setup work for all below tests: generate bitcode and combined index
+; RUN: opt -module-summary %s -o %t.bc
+; RUN: opt -module-summary %p/Inputs/referenced_by_constant.ll -o %t2.bc
+; RUN: llvm-lto -thinlto-action=thinlink -o %t3.bc %t.bc %t2.bc
+
+; Check the import side: we import bar() and @someglobal, but not @referencedbyglobal()
+; RUN: llvm-lto -thinlto-action=import %t.bc -thinlto-index=%t3.bc -o - | llvm-dis -o -   | FileCheck %s --check-prefix=IMPORT
+; IMPORT: @someglobal.llvm.0 =
+; IMPORT: define available_externally void @bar()
+; IMPORT: declare void @referencedbyglobal()
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+declare void @bar()
+
+define void @foo() {
+    call void @bar()
+    ret void
+}
+




More information about the llvm-commits mailing list