diff options
Diffstat (limited to 'lib/Transforms/IPO/Internalize.cpp')
-rw-r--r-- | lib/Transforms/IPO/Internalize.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/lib/Transforms/IPO/Internalize.cpp b/lib/Transforms/IPO/Internalize.cpp index f20a7bd..e615918 100644 --- a/lib/Transforms/IPO/Internalize.cpp +++ b/lib/Transforms/IPO/Internalize.cpp @@ -11,6 +11,19 @@ // If the function or variable is not in the list of external names given to // the pass it is marked as internal. // +// This transformation would not be legal or profitable in a regular +// compilation, but it gets extra information from the linker about what is safe +// or profitable. +// +// As an example of a normally illegal transformation: Internalizing a function +// with external linkage. Only if we are told it is only used from within this +// module, it is safe to do it. +// +// On the profitability side: It is always legal to internalize a linkonce_odr +// whose address is not used. Doing so normally would introduce code bloat, but +// if we are told by the linker that the only use of this would be for a +// DSO symbol table, it is profitable to hide it. +// //===----------------------------------------------------------------------===// #define DEBUG_TYPE "internalize" @@ -23,6 +36,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/Utils/GlobalStatus.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include <fstream> #include <set> @@ -142,8 +156,11 @@ static bool shouldInternalize(const GlobalValue &GV, if (GV.hasUnnamedAddr()) return true; - // FIXME: Check if the address is used. - return false; + GlobalStatus GS; + if (GlobalStatus::analyzeGlobal(&GV, GS)) + return false; + + return !GS.IsCompared; } bool InternalizePass::runOnModule(Module &M) { |