[llvm] r266047 - Refactor the Internalize stage of libLTO in a separate file (NFC)

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 11 23:34:11 PDT 2016


Author: mehdi_amini
Date: Tue Apr 12 01:34:10 2016
New Revision: 266047

URL: http://llvm.org/viewvc/llvm-project?rev=266047&view=rev
Log:
Refactor the Internalize stage of libLTO in a separate file (NFC)

This is intended to be shared by the ThinLTOCodeGenerator.

Note that there is a change in the way the verifier is run, previously
it was ran as a Pass on the merged module during internalization.
While now the verifier is called explicitely on the merged module
outside of the internalize "pass pipeline".

What remains strange in the API is the fact that `DisableVerify` in
the API does not disable this initial verifier.

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

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

Added:
    llvm/trunk/lib/LTO/LTOInternalize.cpp
    llvm/trunk/lib/LTO/LTOInternalize.h
Modified:
    llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h
    llvm/trunk/lib/LTO/CMakeLists.txt
    llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
    llvm/trunk/test/LTO/X86/disable-verify.ll

Modified: llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h?rev=266047&r1=266046&r2=266047&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h (original)
+++ llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h Tue Apr 12 01:34:10 2016
@@ -174,10 +174,6 @@ private:
   bool compileOptimizedToFile(const char **Name);
   void restoreLinkageForExternals();
   void applyScopeRestrictions();
-  void applyRestriction(GlobalValue &GV, ArrayRef<StringRef> Libcalls,
-                        std::vector<const char *> &MustPreserveList,
-                        SmallPtrSetImpl<GlobalValue *> &AsmUsed,
-                        Mangler &Mangler);
   bool determineTarget();
 
   static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context);

Modified: llvm/trunk/lib/LTO/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/CMakeLists.txt?rev=266047&r1=266046&r2=266047&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/CMakeLists.txt (original)
+++ llvm/trunk/lib/LTO/CMakeLists.txt Tue Apr 12 01:34:10 2016
@@ -1,6 +1,7 @@
 add_llvm_library(LLVMLTO
   LTOModule.cpp
   LTOCodeGenerator.cpp
+  LTOInternalize.cpp
   ThinLTOCodeGenerator.cpp
 
   ADDITIONAL_HEADER_DIRS

Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=266047&r1=266046&r2=266047&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)
+++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Tue Apr 12 01:34:10 2016
@@ -13,6 +13,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/LTO/LTOCodeGenerator.h"
+
+#include "LTOInternalize.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Analysis/Passes.h"
@@ -331,145 +333,13 @@ bool LTOCodeGenerator::determineTarget()
   return true;
 }
 
-void LTOCodeGenerator::
-applyRestriction(GlobalValue &GV,
-                 ArrayRef<StringRef> Libcalls,
-                 std::vector<const char*> &MustPreserveList,
-                 SmallPtrSetImpl<GlobalValue*> &AsmUsed,
-                 Mangler &Mangler) {
-  // There are no restrictions to apply to declarations.
-  if (GV.isDeclaration())
-    return;
-
-  // There is nothing more restrictive than private linkage.
-  if (GV.hasPrivateLinkage())
-    return;
-
-  SmallString<64> Buffer;
-  TargetMach->getNameWithPrefix(Buffer, &GV, Mangler);
-
-  if (MustPreserveSymbols.count(Buffer))
-    MustPreserveList.push_back(GV.getName().data());
-  if (AsmUndefinedRefs.count(Buffer))
-    AsmUsed.insert(&GV);
-
-  // Conservatively append user-supplied runtime library functions to
-  // llvm.compiler.used.  These could be internalized and deleted by
-  // optimizations like -globalopt, causing problems when later optimizations
-  // add new library calls (e.g., llvm.memset => memset and printf => puts).
-  // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
-  if (isa<Function>(GV) &&
-      std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName()))
-    AsmUsed.insert(&GV);
-
-  // Record the linkage type of non-local symbols so they can be restored prior
-  // to module splitting.
-  if (ShouldRestoreGlobalsLinkage && !GV.hasAvailableExternallyLinkage() &&
-      !GV.hasLocalLinkage() && GV.hasName())
-    ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
-}
-
-static void findUsedValues(GlobalVariable *LLVMUsed,
-                           SmallPtrSetImpl<GlobalValue*> &UsedValues) {
-  if (!LLVMUsed) return;
-
-  ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
-  for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
-    if (GlobalValue *GV =
-        dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
-      UsedValues.insert(GV);
-}
-
-// Collect names of runtime library functions. User-defined functions with the
-// same names are added to llvm.compiler.used to prevent them from being
-// deleted by optimizations.
-static void accumulateAndSortLibcalls(std::vector<StringRef> &Libcalls,
-                                      const TargetLibraryInfo& TLI,
-                                      const Module &Mod,
-                                      const TargetMachine &TM) {
-  // TargetLibraryInfo has info on C runtime library calls on the current
-  // target.
-  for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
-       I != E; ++I) {
-    LibFunc::Func F = static_cast<LibFunc::Func>(I);
-    if (TLI.has(F))
-      Libcalls.push_back(TLI.getName(F));
-  }
-
-  SmallPtrSet<const TargetLowering *, 1> TLSet;
-
-  for (const Function &F : Mod) {
-    const TargetLowering *Lowering =
-        TM.getSubtargetImpl(F)->getTargetLowering();
-
-    if (Lowering && TLSet.insert(Lowering).second)
-      // TargetLowering has info on library calls that CodeGen expects to be
-      // available, both from the C runtime and compiler-rt.
-      for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
-           I != E; ++I)
-        if (const char *Name =
-                Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
-          Libcalls.push_back(Name);
-  }
-
-  array_pod_sort(Libcalls.begin(), Libcalls.end());
-  Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()),
-                 Libcalls.end());
-}
-
 void LTOCodeGenerator::applyScopeRestrictions() {
   if (ScopeRestrictionsDone || !ShouldInternalize)
     return;
 
-  // Start off with a verification pass.
-  legacy::PassManager passes;
-  passes.add(createVerifierPass());
-
-  // mark which symbols can not be internalized
-  Mangler Mangler;
-  std::vector<const char*> MustPreserveList;
-  SmallPtrSet<GlobalValue*, 8> AsmUsed;
-  std::vector<StringRef> Libcalls;
-  TargetLibraryInfoImpl TLII(Triple(TargetMach->getTargetTriple()));
-  TargetLibraryInfo TLI(TLII);
-
-  accumulateAndSortLibcalls(Libcalls, TLI, *MergedModule, *TargetMach);
-
-  for (Function &f : *MergedModule)
-    applyRestriction(f, Libcalls, MustPreserveList, AsmUsed, Mangler);
-  for (GlobalVariable &v : MergedModule->globals())
-    applyRestriction(v, Libcalls, MustPreserveList, AsmUsed, Mangler);
-  for (GlobalAlias &a : MergedModule->aliases())
-    applyRestriction(a, Libcalls, MustPreserveList, AsmUsed, Mangler);
-
-  GlobalVariable *LLVMCompilerUsed =
-    MergedModule->getGlobalVariable("llvm.compiler.used");
-  findUsedValues(LLVMCompilerUsed, AsmUsed);
-  if (LLVMCompilerUsed)
-    LLVMCompilerUsed->eraseFromParent();
-
-  if (!AsmUsed.empty()) {
-    llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context);
-    std::vector<Constant*> asmUsed2;
-    for (auto *GV : AsmUsed) {
-      Constant *c = ConstantExpr::getBitCast(GV, i8PTy);
-      asmUsed2.push_back(c);
-    }
-
-    llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
-    LLVMCompilerUsed =
-      new llvm::GlobalVariable(*MergedModule, ATy, false,
-                               llvm::GlobalValue::AppendingLinkage,
-                               llvm::ConstantArray::get(ATy, asmUsed2),
-                               "llvm.compiler.used");
-
-    LLVMCompilerUsed->setSection("llvm.metadata");
-  }
-
-  passes.add(createInternalizePass(MustPreserveList));
-
-  // apply scope restrictions
-  passes.run(*MergedModule);
+  LTOInternalize(*MergedModule, *TargetMach, MustPreserveSymbols,
+                 AsmUndefinedRefs,
+                 (ShouldRestoreGlobalsLinkage ? &ExternalSymbols : nullptr));
 
   ScopeRestrictionsDone = true;
 }
@@ -510,6 +380,11 @@ bool LTOCodeGenerator::optimize(bool Dis
   if (!this->determineTarget())
     return false;
 
+  // We always run the verifier once on the merged module, the `DisableVerify`
+  // parameter only applies to subsequent verify.
+  if (verifyModule(*MergedModule, &dbgs()))
+    report_fatal_error("Broken module found, compilation aborted!");
+
   // Mark which symbols can not be internalized
   this->applyScopeRestrictions();
 

Added: llvm/trunk/lib/LTO/LTOInternalize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOInternalize.cpp?rev=266047&view=auto
==============================================================================
--- llvm/trunk/lib/LTO/LTOInternalize.cpp (added)
+++ llvm/trunk/lib/LTO/LTOInternalize.cpp Tue Apr 12 01:34:10 2016
@@ -0,0 +1,189 @@
+//==-LTOInternalize.cpp - LLVM Link Time Optimizer Internalization Utility -==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a helper to run the internalization part of LTO.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LTOInternalize.h"
+
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
+#include "llvm/Transforms/IPO.h"
+
+using namespace llvm;
+
+namespace {
+
+class ComputePreserveList {
+public:
+  ComputePreserveList(const StringSet<> &MustPreserveSymbols,
+                      const StringSet<> &AsmUndefinedRefs,
+                      const TargetMachine &TM, const Module &TheModule,
+                      StringMap<GlobalValue::LinkageTypes> *ExternalSymbols,
+                      std::vector<const char *> &MustPreserveList,
+                      SmallPtrSetImpl<const GlobalValue *> &AsmUsed)
+      : MustPreserveSymbols(MustPreserveSymbols),
+        AsmUndefinedRefs(AsmUndefinedRefs), TM(TM),
+        ExternalSymbols(ExternalSymbols), MustPreserveList(MustPreserveList),
+        AsmUsed(AsmUsed) {
+    accumulateAndSortLibcalls(TheModule);
+    for (const Function &F : TheModule)
+      applyRestriction(F);
+    for (const GlobalVariable &GV : TheModule.globals())
+      applyRestriction(GV);
+    for (const GlobalAlias &GA : TheModule.aliases())
+      applyRestriction(GA);
+  }
+
+private:
+  // Inputs
+  const StringSet<> &MustPreserveSymbols;
+  const StringSet<> AsmUndefinedRefs;
+  const TargetMachine &TM;
+
+  // Temps
+  Mangler Mangler;
+  std::vector<StringRef> Libcalls;
+
+  // Output
+  StringMap<GlobalValue::LinkageTypes> *ExternalSymbols;
+  std::vector<const char *> &MustPreserveList;
+  SmallPtrSetImpl<const GlobalValue *> &AsmUsed;
+
+  // Collect names of runtime library functions. User-defined functions with the
+  // same names are added to llvm.compiler.used to prevent them from being
+  // deleted by optimizations.
+  void accumulateAndSortLibcalls(const Module &TheModule) {
+    TargetLibraryInfoImpl TLII(Triple(TM.getTargetTriple()));
+    TargetLibraryInfo TLI(TLII);
+
+    // TargetLibraryInfo has info on C runtime library calls on the current
+    // target.
+    for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
+         I != E; ++I) {
+      LibFunc::Func F = static_cast<LibFunc::Func>(I);
+      if (TLI.has(F))
+        Libcalls.push_back(TLI.getName(F));
+    }
+
+    SmallPtrSet<const TargetLowering *, 1> TLSet;
+
+    for (const Function &F : TheModule) {
+      const TargetLowering *Lowering =
+          TM.getSubtargetImpl(F)->getTargetLowering();
+
+      if (Lowering && TLSet.insert(Lowering).second)
+        // TargetLowering has info on library calls that CodeGen expects to be
+        // available, both from the C runtime and compiler-rt.
+        for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
+             I != E; ++I)
+          if (const char *Name =
+                  Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
+            Libcalls.push_back(Name);
+    }
+
+    array_pod_sort(Libcalls.begin(), Libcalls.end());
+    Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()),
+                   Libcalls.end());
+  }
+
+  void applyRestriction(const GlobalValue &GV) {
+    // There are no restrictions to apply to declarations.
+    if (GV.isDeclaration())
+      return;
+
+    // There is nothing more restrictive than private linkage.
+    if (GV.hasPrivateLinkage())
+      return;
+
+    SmallString<64> Buffer;
+    TM.getNameWithPrefix(Buffer, &GV, Mangler);
+
+    if (MustPreserveSymbols.count(Buffer))
+      MustPreserveList.push_back(GV.getName().data());
+    if (AsmUndefinedRefs.count(Buffer))
+      AsmUsed.insert(&GV);
+
+    // Conservatively append user-supplied runtime library functions to
+    // llvm.compiler.used.  These could be internalized and deleted by
+    // optimizations like -globalopt, causing problems when later optimizations
+    // add new library calls (e.g., llvm.memset => memset and printf => puts).
+    // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
+    if (isa<Function>(GV) &&
+        std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName()))
+      AsmUsed.insert(&GV);
+
+    // Record the linkage type of non-local symbols so they can be restored
+    // prior
+    // to module splitting.
+    if (ExternalSymbols && !GV.hasAvailableExternallyLinkage() &&
+        !GV.hasLocalLinkage() && GV.hasName())
+      ExternalSymbols->insert(std::make_pair(GV.getName(), GV.getLinkage()));
+  }
+};
+
+} // namespace anonymous
+
+static void findUsedValues(GlobalVariable *LLVMUsed,
+                           SmallPtrSetImpl<const GlobalValue *> &UsedValues) {
+  if (!LLVMUsed)
+    return;
+
+  ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
+  for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
+    if (GlobalValue *GV =
+            dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
+      UsedValues.insert(GV);
+}
+
+void llvm::LTOInternalize(
+    Module &TheModule, const TargetMachine &TM,
+    const StringSet<> &MustPreserveSymbols, const StringSet<> &AsmUndefinedRefs,
+    StringMap<GlobalValue::LinkageTypes> *ExternalSymbols) {
+  legacy::PassManager passes;
+  // mark which symbols can not be internalized
+  Mangler Mangler;
+  std::vector<const char *> MustPreserveList;
+  SmallPtrSet<const GlobalValue *, 8> AsmUsed;
+
+  ComputePreserveList(MustPreserveSymbols, AsmUndefinedRefs, TM, TheModule,
+                      ExternalSymbols, MustPreserveList, AsmUsed);
+
+  GlobalVariable *LLVMCompilerUsed =
+      TheModule.getGlobalVariable("llvm.compiler.used");
+  findUsedValues(LLVMCompilerUsed, AsmUsed);
+  if (LLVMCompilerUsed)
+    LLVMCompilerUsed->eraseFromParent();
+
+  if (!AsmUsed.empty()) {
+    llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext());
+    std::vector<Constant *> asmUsed2;
+    for (const auto *GV : AsmUsed) {
+      Constant *c =
+          ConstantExpr::getBitCast(const_cast<GlobalValue *>(GV), i8PTy);
+      asmUsed2.push_back(c);
+    }
+
+    llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
+    LLVMCompilerUsed = new llvm::GlobalVariable(
+        TheModule, ATy, false, llvm::GlobalValue::AppendingLinkage,
+        llvm::ConstantArray::get(ATy, asmUsed2), "llvm.compiler.used");
+
+    LLVMCompilerUsed->setSection("llvm.metadata");
+  }
+
+  passes.add(createInternalizePass(MustPreserveList));
+
+  // apply scope restrictions
+  passes.run(TheModule);
+}

Added: llvm/trunk/lib/LTO/LTOInternalize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOInternalize.h?rev=266047&view=auto
==============================================================================
--- llvm/trunk/lib/LTO/LTOInternalize.h (added)
+++ llvm/trunk/lib/LTO/LTOInternalize.h Tue Apr 12 01:34:10 2016
@@ -0,0 +1,30 @@
+//===-LTOInternalize.h - LLVM Link Time Optimizer Internalization Utility -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a helper class to run the internalization part of LTO.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LTO_LTOINTERNALIZE_H
+#define LLVM_LTO_LTOINTERNALIZE_H
+
+#include "llvm/ADT/StringSet.h"
+#include "llvm/IR/GlobalValue.h"
+
+namespace llvm {
+class Module;
+class TargetMachine;
+
+void LTOInternalize(Module &TheModule, const TargetMachine &TM,
+                    const StringSet<> &MustPreserveSymbols,
+                    const StringSet<> &AsmUndefinedRefs,
+                    StringMap<GlobalValue::LinkageTypes> *ExternalSymbols);
+}
+
+#endif // LLVM_LTO_LTOINTERNALIZE_H

Modified: llvm/trunk/test/LTO/X86/disable-verify.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/X86/disable-verify.ll?rev=266047&r1=266046&r2=266047&view=diff
==============================================================================
--- llvm/trunk/test/LTO/X86/disable-verify.ll (original)
+++ llvm/trunk/test/LTO/X86/disable-verify.ll Tue Apr 12 01:34:10 2016
@@ -6,10 +6,10 @@ target datalayout = "e-m:o-i64:64-f80:12
 target triple = "x86_64-apple-macosx10.10.0"
 
 ; -disable-verify should disable verification from the optimization pipeline.
-; CHECK: Pass Arguments: -verify -internalize
+; CHECK: Pass Arguments: -internalize
 ; CHECK-NOT: -verify
 
-; VERIFY: Pass Arguments: -verify -internalize
+; VERIFY: Pass Arguments: -internalize
 ; VERIFY: Pass Arguments: {{.*}} -verify {{.*}} -verify
 
 define void @f() {




More information about the llvm-commits mailing list