LLVM  4.0.0
UpdateCompilerUsed.cpp
Go to the documentation of this file.
1 //==-LTOInternalize.cpp - LLVM Link Time Optimizer Internalization Utility -==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a helper to run the internalization part of LTO.
11 //
12 //===----------------------------------------------------------------------===//
13 
17 #include "llvm/IR/Mangler.h"
22 
23 using namespace llvm;
24 
25 namespace {
26 
27 // Helper class that collects AsmUsed and user supplied libcalls.
28 class PreserveLibCallsAndAsmUsed {
29 public:
30  PreserveLibCallsAndAsmUsed(const StringSet<> &AsmUndefinedRefs,
31  const TargetMachine &TM,
32  std::vector<GlobalValue *> &LLVMUsed)
33  : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), LLVMUsed(LLVMUsed) {}
34 
35  void findInModule(Module &TheModule) {
36  initializeLibCalls(TheModule);
37  for (Function &F : TheModule)
38  findLibCallsAndAsm(F);
39  for (GlobalVariable &GV : TheModule.globals())
40  findLibCallsAndAsm(GV);
41  for (GlobalAlias &GA : TheModule.aliases())
42  findLibCallsAndAsm(GA);
43  }
44 
45 private:
46  // Inputs
47  const StringSet<> &AsmUndefinedRefs;
48  const TargetMachine &TM;
49 
50  // Temps
52  StringSet<> Libcalls;
53 
54  // Output
55  std::vector<GlobalValue *> &LLVMUsed;
56 
57  // Collect names of runtime library functions. User-defined functions with the
58  // same names are added to llvm.compiler.used to prevent them from being
59  // deleted by optimizations.
60  void initializeLibCalls(const Module &TheModule) {
61  TargetLibraryInfoImpl TLII(Triple(TM.getTargetTriple()));
62  TargetLibraryInfo TLI(TLII);
63 
64  // TargetLibraryInfo has info on C runtime library calls on the current
65  // target.
66  for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
67  I != E; ++I) {
68  LibFunc::Func F = static_cast<LibFunc::Func>(I);
69  if (TLI.has(F))
70  Libcalls.insert(TLI.getName(F));
71  }
72 
74 
75  for (const Function &F : TheModule) {
76  const TargetLowering *Lowering =
77  TM.getSubtargetImpl(F)->getTargetLowering();
78 
79  if (Lowering && TLSet.insert(Lowering).second)
80  // TargetLowering has info on library calls that CodeGen expects to be
81  // available, both from the C runtime and compiler-rt.
82  for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
83  I != E; ++I)
84  if (const char *Name =
85  Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
86  Libcalls.insert(Name);
87  }
88  }
89 
90  void findLibCallsAndAsm(GlobalValue &GV) {
91  // There are no restrictions to apply to declarations.
92  if (GV.isDeclaration())
93  return;
94 
95  // There is nothing more restrictive than private linkage.
96  if (GV.hasPrivateLinkage())
97  return;
98 
99  // Conservatively append user-supplied runtime library functions to
100  // llvm.compiler.used. These could be internalized and deleted by
101  // optimizations like -globalopt, causing problems when later optimizations
102  // add new library calls (e.g., llvm.memset => memset and printf => puts).
103  // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
104  if (isa<Function>(GV) && Libcalls.count(GV.getName())) {
105  LLVMUsed.push_back(&GV);
106  return;
107  }
108 
109  SmallString<64> Buffer;
110  TM.getNameWithPrefix(Buffer, &GV, Mangler);
111  if (AsmUndefinedRefs.count(Buffer))
112  LLVMUsed.push_back(&GV);
113  }
114 };
115 
116 } // namespace anonymous
117 
119  const StringSet<> &AsmUndefinedRefs) {
120  std::vector<GlobalValue *> UsedValues;
121  PreserveLibCallsAndAsmUsed(AsmUndefinedRefs, TM, UsedValues)
122  .findInModule(TheModule);
123 
124  if (UsedValues.empty())
125  return;
126 
127  appendToCompilerUsed(TheModule, UsedValues);
128 }
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
Implementation of the target library information.
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:191
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool hasPrivateLinkage() const
Definition: GlobalValue.h:414
#define F(x, y, z)
Definition: MD5.cpp:51
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:368
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Definition: SmallPtrSet.h:425
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
shadow stack gc Shadow Stack GC Lowering
Provides information about what library functions are available for the current target.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:188
#define I(x, y, z)
Definition: MD5.cpp:54
void updateCompilerUsed(Module &TheModule, const TargetMachine &TM, const StringSet<> &AsmUndefinedRefs)
Find all globals in TheModule that are referenced in AsmUndefinedRefs, as well as the user-supplied f...
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:23
Primary interface to the complete machine description for the target machine.
This file describes how to lower LLVM code to machine code.