summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-10-03 18:29:09 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-10-03 18:29:09 +0000
commit438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7 (patch)
treeee292d94cfa7c8661cc4cd598f32e66289df9aeb /include
parent1df59ef1aa271a4e33cf8973e14bcaf55c585231 (diff)
downloadllvm-438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7.tar.gz
llvm-438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7.tar.bz2
llvm-438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7.tar.xz
Optimize linkonce_odr unnamed_addr functions during LTO.
Generalize the API so we can distinguish symbols that are needed just for a DSO symbol table from those that are used from some native .o. The symbols that are only wanted for the dso symbol table can be dropped if llvm can prove every other dso has a copy (linkonce_odr) and the address is not important (unnamed_addr). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191922 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm-c/lto.h16
-rw-r--r--include/llvm/LTO/LTOCodeGenerator.h6
-rw-r--r--include/llvm/Transforms/IPO.h26
3 files changed, 41 insertions, 7 deletions
diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h
index 58d58336b5..85d5439ec9 100644
--- a/include/llvm-c/lto.h
+++ b/include/llvm-c/lto.h
@@ -29,7 +29,7 @@
* @{
*/
-#define LTO_API_VERSION 4
+#define LTO_API_VERSION 5
typedef enum {
LTO_SYMBOL_ALIGNMENT_MASK = 0x0000001F, /* log2 of alignment */
@@ -253,13 +253,21 @@ lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
int nargs);
/**
- * Adds to a list of all global symbols that must exist in the final
- * generated code. If a function is not listed, it might be
- * inlined into every usage and optimized away.
+ * Tells LTO optimization passes that this symbol must be preserved
+ * because it is referenced by native code or a command line option.
*/
extern void
lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol);
+
+/**
+ * Tells LTO optimization passes that a dynamic shared library is being
+ * built and this symbol may be exported. Unless IR semantics allow the symbol
+ * to be made local to the library, it should remain so it can be exported by
+ * the shared library.
+ */
+extern void lto_codegen_add_dso_symbol(lto_code_gen_t cg, const char *symbol);
+
/**
* Writes a new object file at the specified path that contains the
* merged contents of all modules added so far.
diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h
index 97a5066339..9f50770dcd 100644
--- a/include/llvm/LTO/LTOCodeGenerator.h
+++ b/include/llvm/LTO/LTOCodeGenerator.h
@@ -73,6 +73,10 @@ struct LTOCodeGenerator {
void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; }
+ void addDSOSymbol(const char* Sym) {
+ DSOSymbols[Sym] = 1;
+ }
+
// To pass options to the driver and optimization passes. These options are
// not necessarily for debugging purpose (The function name is misleading).
// This function should be called before LTOCodeGenerator::compilexxx(),
@@ -126,6 +130,7 @@ private:
void applyScopeRestrictions();
void applyRestriction(llvm::GlobalValue &GV,
std::vector<const char*> &MustPreserveList,
+ std::vector<const char*> &SymtabList,
llvm::SmallPtrSet<llvm::GlobalValue*, 8> &AsmUsed,
llvm::Mangler &Mangler);
bool determineTarget(std::string &errMsg);
@@ -138,6 +143,7 @@ private:
bool EmitDwarfDebugInfo;
bool ScopeRestrictionsDone;
lto_codegen_model CodeModel;
+ StringSet DSOSymbols;
StringSet MustPreserveSymbols;
StringSet AsmUndefinedRefs;
llvm::MemoryBuffer *NativeObjectFile;
diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h
index 6ebb6c4658..ed2823098a 100644
--- a/include/llvm/Transforms/IPO.h
+++ b/include/llvm/Transforms/IPO.h
@@ -104,12 +104,32 @@ Pass *createPruneEHPass();
//===----------------------------------------------------------------------===//
/// createInternalizePass - This pass loops over all of the functions in the
-/// input module, internalizing all globals (functions and variables) not in the
-/// given exportList.
+/// input module, internalizing all globals (functions and variables) it can.
+////
+/// The symbols in \p ExportList are never internalized.
+///
+/// The symbol in DSOList are internalized if it is safe to drop them from
+/// the symbol table.
+///
+/// For example of the difference, consider a dynamic library being built from
+/// two translation units. The first one compiled to a native object
+/// (ELF/MachO/COFF) and second one compiled to IL. Translation unit A has a
+/// copy of linkonce_odr unnamed_addr function F. The translation unit B has a
+/// copy of the linkonce_odr unnamed_addr functions F and G.
+///
+/// Assume the linker decides to keep the copy of F in B. This means that LLVM
+/// must produce F in the object file it passes to the linker, otherwise we
+/// will have an undefined reference. For G the situation is different. The
+/// linker puts the function in the DSOList, since it is only wanted for the
+/// symbol table. With this information internalize can now reason that since
+/// the function is a linkonce_odr and its address is not important, it can be
+/// omitted. Any other shared library needing this function will have a copy of
+/// it.
///
/// Note that commandline options that are used with the above function are not
/// used now!
-ModulePass *createInternalizePass(ArrayRef<const char *> ExportList);
+ModulePass *createInternalizePass(ArrayRef<const char *> ExportList,
+ ArrayRef<const char *> DSOList);
/// createInternalizePass - Same as above, but with an empty exportList.
ModulePass *createInternalizePass();