From 31ce1f6172cb9f0691fcbb3f1fd7facff9adad03 Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Wed, 13 Apr 2016 06:32:46 +0000 Subject: [PATCH] Simplify LTOInternalize into UpdateLLVMCompilerUsed 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266174 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/LTO/CMakeLists.txt | 2 +- lib/LTO/LTOCodeGenerator.cpp | 9 +- lib/LTO/PreserveLibCalls.h | 32 ----- ...rveLibCalls.cpp => UpdateCompilerUsed.cpp} | 111 ++++++++---------- lib/LTO/UpdateCompilerUsed.h | 34 ++++++ 5 files changed, 92 insertions(+), 96 deletions(-) delete mode 100644 lib/LTO/PreserveLibCalls.h rename lib/LTO/{PreserveLibCalls.cpp => UpdateCompilerUsed.cpp} (57%) create mode 100644 lib/LTO/UpdateCompilerUsed.h diff --git a/lib/LTO/CMakeLists.txt b/lib/LTO/CMakeLists.txt index 6c8dcc67a2f..1a592f0b755 100644 --- a/lib/LTO/CMakeLists.txt +++ b/lib/LTO/CMakeLists.txt @@ -1,7 +1,7 @@ add_llvm_library(LLVMLTO LTOModule.cpp LTOCodeGenerator.cpp - LTOInternalize.cpp + UpdateCompilerUsed.cpp ThinLTOCodeGenerator.cpp ADDITIONAL_HEADER_DIRS diff --git a/lib/LTO/LTOCodeGenerator.cpp b/lib/LTO/LTOCodeGenerator.cpp index bfa534efdeb..bc500085a72 100644 --- a/lib/LTO/LTOCodeGenerator.cpp +++ b/lib/LTO/LTOCodeGenerator.cpp @@ -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 @@ -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/lib/LTO/PreserveLibCalls.h b/lib/LTO/PreserveLibCalls.h deleted file mode 100644 index ec104c13b4a..00000000000 --- a/lib/LTO/PreserveLibCalls.h +++ /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 - -namespace llvm { -class Module; -class TargetMachine; - -void LTOInternalize( - Module &TheModule, const TargetMachine &TM, - const std::function &MustPreserveSymbols, - const StringSet<> &AsmUndefinedRefs); -} - -#endif // LLVM_LTO_LTOINTERNALIZE_H diff --git a/lib/LTO/PreserveLibCalls.cpp b/lib/LTO/UpdateCompilerUsed.cpp similarity index 57% rename from lib/LTO/PreserveLibCalls.cpp rename to lib/LTO/UpdateCompilerUsed.cpp index f8d9f77e890..bed784a5d64 100644 --- a/lib/LTO/PreserveLibCalls.cpp +++ b/lib/LTO/UpdateCompilerUsed.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "LTOInternalize.h" +#include "UpdateCompilerUsed.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/LegacyPassManager.h" @@ -23,20 +23,23 @@ 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 &AsmUsed) - : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), AsmUsed(AsmUsed) { - accumulateAndSortLibcalls(TheModule); + PreserveLibCallsAndAsmUsed(const StringSet<> &AsmUndefinedRefs, + const TargetMachine &TM, + SmallPtrSetImpl &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 &AsmUsed; + SmallPtrSetImpl &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(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 &UsedValues) { - if (!LLVMUsed) +void llvm::UpdateCompilerUsed(Module &TheModule, const TargetMachine &TM, + const StringSet<> &AsmUndefinedRefs) { + SmallPtrSet UsedValues; + PreserveLibCallsAndAsmUsed(AsmUndefinedRefs, TM, UsedValues) + .findInModule(TheModule); + + if (UsedValues.empty()) return; - ConstantArray *Inits = cast(LLVMUsed->getInitializer()); - for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) - if (GlobalValue *GV = - dyn_cast(Inits->getOperand(i)->stripPointerCasts())) - UsedValues.insert(GV); -} - -// mark which symbols can not be internalized -void llvm::LTOInternalize( - Module &TheModule, const TargetMachine &TM, - const std::function &MustPreserveSymbols, - const StringSet<> &AsmUndefinedRefs) { - SmallPtrSet 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 asmUsed2; - for (const auto *GV : AsmUsed) { - Constant *c = - ConstantExpr::getBitCast(const_cast(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"); + llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext()); + std::vector UsedValuesList; + for (const auto *GV : UsedValues) { + Constant *c = + ConstantExpr::getBitCast(const_cast(GV), i8PTy); + UsedValuesList.push_back(c); } - internalizeModule(TheModule, MustPreserveSymbols); + GlobalVariable *LLVMUsed = TheModule.getGlobalVariable("llvm.compiler.used"); + if (LLVMUsed) { + ConstantArray *Inits = cast(LLVMUsed->getInitializer()); + for (auto &V : Inits->operands()) + UsedValuesList.push_back(cast(&V)); + LLVMUsed->eraseFromParent(); + } + + 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/lib/LTO/UpdateCompilerUsed.h b/lib/LTO/UpdateCompilerUsed.h new file mode 100644 index 00000000000..e36fe4c75ce --- /dev/null +++ b/lib/LTO/UpdateCompilerUsed.h @@ -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 + +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