X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FIPO%2FInternalize.cpp;h=7950163f757dd6a8866f49ce4c1da5d4de3712d0;hb=9ba744b0890819cb602281779dfacc4efd54db70;hp=e61591870bc57d01e19da15c810ac773bc43aa69;hpb=713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2;p=oota-llvm.git diff --git a/lib/Transforms/IPO/Internalize.cpp b/lib/Transforms/IPO/Internalize.cpp index e61591870bc..7950163f757 100644 --- a/lib/Transforms/IPO/Internalize.cpp +++ b/lib/Transforms/IPO/Internalize.cpp @@ -11,22 +11,14 @@ // 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. +// This transformation would not be legal in a regular compilation, but it gets +// extra information from the linker about what is safe. // -// 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. +// For example: 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. // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "internalize" #include "llvm/Transforms/IPO.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" @@ -42,6 +34,8 @@ #include using namespace llvm; +#define DEBUG_TYPE "internalize" + STATISTIC(NumAliases , "Number of aliases internalized"); STATISTIC(NumFunctions, "Number of functions internalized"); STATISTIC(NumGlobals , "Number of global vars internalized"); @@ -58,26 +52,19 @@ APIList("internalize-public-api-list", cl::value_desc("list"), cl::desc("A list of symbol names to preserve"), cl::CommaSeparated); -static cl::list -DSOList("internalize-dso-list", cl::value_desc("list"), - cl::desc("A list of symbol names need for a dso symbol table"), - cl::CommaSeparated); - namespace { class InternalizePass : public ModulePass { std::set ExternalNames; - std::set DSONames; public: static char ID; // Pass identification, replacement for typeid explicit InternalizePass(); - explicit InternalizePass(ArrayRef ExportList, - ArrayRef DSOList); + explicit InternalizePass(ArrayRef ExportList); void LoadFile(const char *Filename); - virtual bool runOnModule(Module &M); + bool runOnModule(Module &M) override; - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); - AU.addPreserved(); + AU.addPreserved(); } }; } // end anonymous namespace @@ -86,27 +73,20 @@ char InternalizePass::ID = 0; INITIALIZE_PASS(InternalizePass, "internalize", "Internalize Global Symbols", false, false) -InternalizePass::InternalizePass() - : ModulePass(ID) { +InternalizePass::InternalizePass() : ModulePass(ID) { initializeInternalizePassPass(*PassRegistry::getPassRegistry()); if (!APIFile.empty()) // If a filename is specified, use it. LoadFile(APIFile.c_str()); ExternalNames.insert(APIList.begin(), APIList.end()); - DSONames.insert(DSOList.begin(), DSOList.end()); } -InternalizePass::InternalizePass(ArrayRef ExportList, - ArrayRef DSOList) - : ModulePass(ID){ +InternalizePass::InternalizePass(ArrayRef ExportList) + : ModulePass(ID) { initializeInternalizePassPass(*PassRegistry::getPassRegistry()); for(ArrayRef::const_iterator itr = ExportList.begin(); itr != ExportList.end(); itr++) { ExternalNames.insert(*itr); } - for(ArrayRef::const_iterator itr = DSOList.begin(); - itr != DSOList.end(); itr++) { - DSONames.insert(*itr); - } } void InternalizePass::LoadFile(const char *Filename) { @@ -126,8 +106,7 @@ void InternalizePass::LoadFile(const char *Filename) { } static bool shouldInternalize(const GlobalValue &GV, - const std::set &ExternalNames, - const std::set &DSONames) { + const std::set &ExternalNames) { // Function must be defined here if (GV.isDeclaration()) return false; @@ -136,6 +115,10 @@ static bool shouldInternalize(const GlobalValue &GV, if (GV.hasAvailableExternallyLinkage()) return false; + // Assume that dllexported symbols are referenced elsewhere + if (GV.hasDLLExportStorageClass()) + return false; + // Already has internal linkage if (GV.hasLocalLinkage()) return false; @@ -144,28 +127,13 @@ static bool shouldInternalize(const GlobalValue &GV, if (ExternalNames.count(GV.getName())) return false; - // Not needed for the symbol table? - if (!DSONames.count(GV.getName())) - return true; - - // Not a linkonce. Someone can depend on it being on the symbol table. - if (!GV.hasLinkOnceLinkage()) - return false; - - // The address is not important, we can hide it. - if (GV.hasUnnamedAddr()) - return true; - - GlobalStatus GS; - if (GlobalStatus::analyzeGlobal(&GV, GS)) - return false; - - return !GS.IsCompared; + return true; } bool InternalizePass::runOnModule(Module &M) { - CallGraph *CG = getAnalysisIfAvailable(); - CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0; + CallGraphWrapperPass *CGPass = getAnalysisIfAvailable(); + CallGraph *CG = CGPass ? &CGPass->getCallGraph() : nullptr; + CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : nullptr; bool Changed = false; SmallPtrSet Used; @@ -180,18 +148,16 @@ bool InternalizePass::runOnModule(Module &M) { // we don't see references from function local inline assembly. To be // conservative, we internalize symbols in llvm.compiler.used, but we // keep llvm.compiler.used so that the symbol is not deleted by llvm. - for (SmallPtrSet::iterator I = Used.begin(), E = Used.end(); - I != E; ++I) { - GlobalValue *V = *I; + for (GlobalValue *V : Used) { ExternalNames.insert(V->getName()); } // Mark all functions not in the api as internal. - // FIXME: maybe use private linkage? for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { - if (!shouldInternalize(*I, ExternalNames, DSONames)) + if (!shouldInternalize(*I, ExternalNames)) continue; + I->setVisibility(GlobalValue::DefaultVisibility); I->setLinkage(GlobalValue::InternalLinkage); if (ExternalNode) @@ -223,12 +189,12 @@ bool InternalizePass::runOnModule(Module &M) { // Mark all global variables with initializers that are not in the api as // internal as well. - // FIXME: maybe use private linkage? for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { - if (!shouldInternalize(*I, ExternalNames, DSONames)) + if (!shouldInternalize(*I, ExternalNames)) continue; + I->setVisibility(GlobalValue::DefaultVisibility); I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumGlobals; @@ -238,9 +204,10 @@ bool InternalizePass::runOnModule(Module &M) { // Mark all aliases that are not in the api as internal as well. for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { - if (!shouldInternalize(*I, ExternalNames, DSONames)) + if (!shouldInternalize(*I, ExternalNames)) continue; + I->setVisibility(GlobalValue::DefaultVisibility); I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumAliases; @@ -250,11 +217,8 @@ bool InternalizePass::runOnModule(Module &M) { return Changed; } -ModulePass *llvm::createInternalizePass() { - return new InternalizePass(); -} +ModulePass *llvm::createInternalizePass() { return new InternalizePass(); } -ModulePass *llvm::createInternalizePass(ArrayRef ExportList, - ArrayRef DSOList) { - return new InternalizePass(ExportList, DSOList); +ModulePass *llvm::createInternalizePass(ArrayRef ExportList) { + return new InternalizePass(ExportList); }