Simplify LTOInternalize into UpdateLLVMCompilerUsed
authorMehdi Amini <mehdi.amini@apple.com>
Wed, 13 Apr 2016 06:32:46 +0000 (06:32 +0000)
committerMehdi Amini <mehdi.amini@apple.com>
Wed, 13 Apr 2016 06:32:46 +0000 (06:32 +0000)
It is now only doing the update to the llvm.compiler_used global.
The client has to call separately the internalization stage.
Hopefully the code is simpler to understand this way.

From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 266174

llvm/lib/LTO/CMakeLists.txt
llvm/lib/LTO/LTOCodeGenerator.cpp
llvm/lib/LTO/PreserveLibCalls.h [deleted file]
llvm/lib/LTO/UpdateCompilerUsed.cpp [moved from llvm/lib/LTO/PreserveLibCalls.cpp with 57% similarity]
llvm/lib/LTO/UpdateCompilerUsed.h [new file with mode: 0644]

index 6c8dcc6..1a592f0 100644 (file)
@@ -1,7 +1,7 @@
 add_llvm_library(LLVMLTO
   LTOModule.cpp
   LTOCodeGenerator.cpp
-  LTOInternalize.cpp
+  UpdateCompilerUsed.cpp
   ThinLTOCodeGenerator.cpp
 
   ADDITIONAL_HEADER_DIRS
index bfa534e..bc50008 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "llvm/LTO/LTOCodeGenerator.h"
 
-#include "LTOInternalize.h"
+#include "UpdateCompilerUsed.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Analysis/Passes.h"
@@ -54,6 +54,7 @@
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetSubtargetInfo.h"
 #include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/Internalize.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include <system_error>
@@ -354,6 +355,10 @@ void LTOCodeGenerator::applyScopeRestrictions() {
       RecordLinkage(GV);
   }
 
+  // Update the llvm.compiler_used globals to force preserving libcalls and
+  // symbols referenced from asm
+  UpdateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);
+
   // Declare a callback for the internalize pass that will ask for every
   // candidate GlobalValue if it can be internalized or not.
   Mangler Mangler;
@@ -369,7 +374,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
     return MustPreserveSymbols.count(MangledName);
   };
 
-  LTOInternalize(*MergedModule, *TargetMach, MustPreserveGV, AsmUndefinedRefs);
+  internalizeModule(*MergedModule, MustPreserveGV);
 
   ScopeRestrictionsDone = true;
 }
diff --git a/llvm/lib/LTO/PreserveLibCalls.h b/llvm/lib/LTO/PreserveLibCalls.h
deleted file mode 100644 (file)
index ec104c1..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//===-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"
-
-#include <functional>
-
-namespace llvm {
-class Module;
-class TargetMachine;
-
-void LTOInternalize(
-    Module &TheModule, const TargetMachine &TM,
-    const std::function<bool(const GlobalValue &)> &MustPreserveSymbols,
-    const StringSet<> &AsmUndefinedRefs);
-}
-
-#endif // LLVM_LTO_LTOINTERNALIZE_H
similarity index 57%
rename from llvm/lib/LTO/PreserveLibCalls.cpp
rename to llvm/lib/LTO/UpdateCompilerUsed.cpp
index f8d9f77..bed784a 100644 (file)
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "LTOInternalize.h"
+#include "UpdateCompilerUsed.h"
 
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/IR/LegacyPassManager.h"
 using namespace llvm;
 
 namespace {
-// Helper class that populate the array of symbols used in inlined assembly.
-class ComputeAsmUsed {
+
+// Helper class that collects AsmUsed and user supplied libcalls.
+class PreserveLibCallsAndAsmUsed {
 public:
-  ComputeAsmUsed(const StringSet<> &AsmUndefinedRefs, const TargetMachine &TM,
-                 const Module &TheModule,
-                 SmallPtrSetImpl<const GlobalValue *> &AsmUsed)
-      : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), AsmUsed(AsmUsed) {
-    accumulateAndSortLibcalls(TheModule);
+  PreserveLibCallsAndAsmUsed(const StringSet<> &AsmUndefinedRefs,
+                             const TargetMachine &TM,
+                             SmallPtrSetImpl<const GlobalValue *> &LLVMUsed)
+      : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), LLVMUsed(LLVMUsed) {}
+
+  void findInModule(const Module &TheModule) {
+    initializeLibCalls(TheModule);
     for (const Function &F : TheModule)
-      findAsmUses(F);
+      findLibCallsAndAsm(F);
     for (const GlobalVariable &GV : TheModule.globals())
-      findAsmUses(GV);
+      findLibCallsAndAsm(GV);
     for (const GlobalAlias &GA : TheModule.aliases())
-      findAsmUses(GA);
+      findLibCallsAndAsm(GA);
   }
 
 private:
@@ -49,12 +52,12 @@ private:
   StringSet<> Libcalls;
 
   // Output
-  SmallPtrSetImpl<const GlobalValue *> &AsmUsed;
+  SmallPtrSetImpl<const GlobalValue *> &LLVMUsed;
 
   // 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) {
+  void initializeLibCalls(const Module &TheModule) {
     TargetLibraryInfoImpl TLII(Triple(TM.getTargetTriple()));
     TargetLibraryInfo TLI(TLII);
 
@@ -84,7 +87,7 @@ private:
     }
   }
 
-  void findAsmUses(const GlobalValue &GV) {
+  void findLibCallsAndAsm(const GlobalValue &GV) {
     // There are no restrictions to apply to declarations.
     if (GV.isDeclaration())
       return;
@@ -93,66 +96,52 @@ private:
     if (GV.hasPrivateLinkage())
       return;
 
-    SmallString<64> Buffer;
-    TM.getNameWithPrefix(Buffer, &GV, Mangler);
-
-    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) && Libcalls.count(GV.getName()))
-      AsmUsed.insert(&GV);
+      LLVMUsed.insert(&GV);
+
+    SmallString<64> Buffer;
+    TM.getNameWithPrefix(Buffer, &GV, Mangler);
+    if (AsmUndefinedRefs.count(Buffer))
+      LLVMUsed.insert(&GV);
   }
 };
 
 } // 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::UpdateCompilerUsed(Module &TheModule, const TargetMachine &TM,
+                              const StringSet<> &AsmUndefinedRefs) {
+  SmallPtrSet<const GlobalValue *, 8> UsedValues;
+  PreserveLibCallsAndAsmUsed(AsmUndefinedRefs, TM, UsedValues)
+      .findInModule(TheModule);
 
-// mark which symbols can not be internalized
-void llvm::LTOInternalize(
-    Module &TheModule, const TargetMachine &TM,
-    const std::function<bool(const GlobalValue &)> &MustPreserveSymbols,
-    const StringSet<> &AsmUndefinedRefs) {
-  SmallPtrSet<const GlobalValue *, 8> AsmUsed;
-  ComputeAsmUsed(AsmUndefinedRefs, TM, TheModule, 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);
-    }
+  if (UsedValues.empty())
+    return;
 
-    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");
+  llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext());
+  std::vector<Constant *> UsedValuesList;
+  for (const auto *GV : UsedValues) {
+    Constant *c =
+        ConstantExpr::getBitCast(const_cast<GlobalValue *>(GV), i8PTy);
+    UsedValuesList.push_back(c);
+  }
 
-    LLVMCompilerUsed->setSection("llvm.metadata");
+  GlobalVariable *LLVMUsed = TheModule.getGlobalVariable("llvm.compiler.used");
+  if (LLVMUsed) {
+    ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
+    for (auto &V : Inits->operands())
+      UsedValuesList.push_back(cast<Constant>(&V));
+    LLVMUsed->eraseFromParent();
   }
 
-  internalizeModule(TheModule, MustPreserveSymbols);
+  llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, UsedValuesList.size());
+  LLVMUsed = new llvm::GlobalVariable(
+      TheModule, ATy, false, llvm::GlobalValue::AppendingLinkage,
+      llvm::ConstantArray::get(ATy, UsedValuesList), "llvm.compiler.used");
+
+  LLVMUsed->setSection("llvm.metadata");
 }
diff --git a/llvm/lib/LTO/UpdateCompilerUsed.h b/llvm/lib/LTO/UpdateCompilerUsed.h
new file mode 100644 (file)
index 0000000..e36fe4c
--- /dev/null
@@ -0,0 +1,34 @@
+//==------ UpdateCompilerUsed.h - LLVM Link Time Optimizer 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 update llvm.compiler_used metadata.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LTO_UPDATE_COMPILER_USED_H
+#define LLVM_LTO_UPDATE_COMPILER_USED_H
+
+#include "llvm/ADT/StringSet.h"
+#include "llvm/IR/GlobalValue.h"
+
+#include <functional>
+
+namespace llvm {
+class Module;
+class TargetMachine;
+
+/// Find all globals in \p TheModule that are referenced in
+/// \p AsmUndefinedRefs, as well as the user-supplied functions definitions that
+/// are also libcalls, and create or update the magic "llvm.compiler_used"
+/// global in \p TheModule.
+void UpdateCompilerUsed(Module &TheModule, const TargetMachine &TM,
+                        const StringSet<> &AsmUndefinedRefs);
+}
+
+#endif // LLVM_LTO_LTOINTERNALIZE_H