1dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner//===-- Internalize.cpp - Mark functions internal -------------------------===// 2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 9dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner// 10e5551ed9cec1ae777c4e4b8852a1d7842c2e1c3dRafael Espindola// This pass loops over all of the functions and variables in the input module. 11e5551ed9cec1ae777c4e4b8852a1d7842c2e1c3dRafael Espindola// If the function or variable is not in the list of external names given to 12e5551ed9cec1ae777c4e4b8852a1d7842c2e1c3dRafael Espindola// the pass it is marked as internal. 13dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner// 147e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola// This transformation would not be legal in a regular compilation, but it gets 157e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola// extra information from the linker about what is safe. 16713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola// 177e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola// For example: Internalizing a function with external linkage. Only if we are 187e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola// told it is only used from within this module, it is safe to do it. 19713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola// 20dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner//===----------------------------------------------------------------------===// 21dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner 22568ddabc8f9015baf2d42cc425618412972f1b92Chris Lattner#include "llvm/Transforms/IPO.h" 234ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola#include "llvm/ADT/SmallPtrSet.h" 24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h" 25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Analysis/CallGraph.h" 260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Pass.h" 28551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h" 29551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h" 30ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar#include "llvm/Support/raw_ostream.h" 31713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola#include "llvm/Transforms/Utils/GlobalStatus.h" 324ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola#include "llvm/Transforms/Utils/ModuleUtils.h" 33c7a2c7f0c9900c6658bc567211d695f0593484c2Chris Lattner#include <fstream> 34c7a2c7f0c9900c6658bc567211d695f0593484c2Chris Lattner#include <set> 351e2385b941242f2f96398dc62767420622856149Chris Lattnerusing namespace llvm; 36d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "internalize" 38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 3927a53009efcf1b0334dc17c3d54382798686ff59Duncan SandsSTATISTIC(NumAliases , "Number of aliases internalized"); 4086453c52ba02e743d29c08456e51006500041456Chris LattnerSTATISTIC(NumFunctions, "Number of functions internalized"); 4186453c52ba02e743d29c08456e51006500041456Chris LattnerSTATISTIC(NumGlobals , "Number of global vars internalized"); 4286453c52ba02e743d29c08456e51006500041456Chris Lattner 43844731a7f1909f55935e3514c9e713a62d67662eDan Gohman// APIFile - A file which contains a list of symbols that should not be marked 44844731a7f1909f55935e3514c9e713a62d67662eDan Gohman// external. 45844731a7f1909f55935e3514c9e713a62d67662eDan Gohmanstatic cl::opt<std::string> 46844731a7f1909f55935e3514c9e713a62d67662eDan GohmanAPIFile("internalize-public-api-file", cl::value_desc("filename"), 47844731a7f1909f55935e3514c9e713a62d67662eDan Gohman cl::desc("A file containing list of symbol names to preserve")); 482345d71853e75fd56a8ca66d40bf36eba0a9edb6Chris Lattner 49844731a7f1909f55935e3514c9e713a62d67662eDan Gohman// APIList - A list of symbols that should not be marked internal. 50844731a7f1909f55935e3514c9e713a62d67662eDan Gohmanstatic cl::list<std::string> 51844731a7f1909f55935e3514c9e713a62d67662eDan GohmanAPIList("internalize-public-api-list", cl::value_desc("list"), 52844731a7f1909f55935e3514c9e713a62d67662eDan Gohman cl::desc("A list of symbol names to preserve"), 53844731a7f1909f55935e3514c9e713a62d67662eDan Gohman cl::CommaSeparated); 54fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman 55844731a7f1909f55935e3514c9e713a62d67662eDan Gohmannamespace { 566726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky class InternalizePass : public ModulePass { 57c7a2c7f0c9900c6658bc567211d695f0593484c2Chris Lattner std::set<std::string> ExternalNames; 58c7a2c7f0c9900c6658bc567211d695f0593484c2Chris Lattner public: 59ecd94c804a563f2a86572dcf1d2e81f397e19daaNick Lewycky static char ID; // Pass identification, replacement for typeid 60e5551ed9cec1ae777c4e4b8852a1d7842c2e1c3dRafael Espindola explicit InternalizePass(); 617e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola explicit InternalizePass(ArrayRef<const char *> ExportList); 624eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner void LoadFile(const char *Filename); 63cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar bool maybeInternalize(GlobalValue &GV, 64cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const std::set<const Comdat *> &ExternalComdats); 65cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar void checkComdatVisibility(GlobalValue &GV, 66cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar std::set<const Comdat *> &ExternalComdats); 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 680483d018c4f15f206a83364e498957127e74f431Nuno Lopes 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 700483d018c4f15f206a83364e498957127e74f431Nuno Lopes AU.setPreservesCFG(); 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addPreserved<CallGraphWrapperPass>(); 720483d018c4f15f206a83364e498957127e74f431Nuno Lopes } 734eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner }; 744eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner} // end anonymous namespace 7593fbd733e778c2623436ed5a0b9cf7f394407b1aChris Lattner 76844731a7f1909f55935e3514c9e713a62d67662eDan Gohmanchar InternalizePass::ID = 0; 77d13db2c59cc94162d6cf0a04187d408bfef6d4a7Owen AndersonINITIALIZE_PASS(InternalizePass, "internalize", 78ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson "Internalize Global Symbols", false, false) 79844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesInternalizePass::InternalizePass() : ModulePass(ID) { 81081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson initializeInternalizePassPass(*PassRegistry::getPassRegistry()); 82ef3682a4fbfc3ff1a593adf95740ad8ab0d1d487Devang Patel if (!APIFile.empty()) // If a filename is specified, use it. 834eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner LoadFile(APIFile.c_str()); 841d7df349ab7fa051ffe88589b06a1aa514f84a00Rafael Espindola ExternalNames.insert(APIList.begin(), APIList.end()); 854eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner} 86c7a2c7f0c9900c6658bc567211d695f0593484c2Chris Lattner 877e667c56cf7e27ff521ceb86518beab32bfb630dRafael EspindolaInternalizePass::InternalizePass(ArrayRef<const char *> ExportList) 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : ModulePass(ID) { 89081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson initializeInternalizePassPass(*PassRegistry::getPassRegistry()); 90775079c227083be3fe22f6ae071d5b74a7ade745Rafael Espindola for(ArrayRef<const char *>::const_iterator itr = ExportList.begin(); 91775079c227083be3fe22f6ae071d5b74a7ade745Rafael Espindola itr != ExportList.end(); itr++) { 92753d94a1c8fe02f64eb4f482d396712c68db1d84Devang Patel ExternalNames.insert(*itr); 93753d94a1c8fe02f64eb4f482d396712c68db1d84Devang Patel } 94753d94a1c8fe02f64eb4f482d396712c68db1d84Devang Patel} 95753d94a1c8fe02f64eb4f482d396712c68db1d84Devang Patel 964eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattnervoid InternalizePass::LoadFile(const char *Filename) { 974eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner // Load the APIFile... 984eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner std::ifstream In(Filename); 994eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner if (!In.good()) { 1004437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "WARNING: Internalize couldn't load file '" << Filename 101ef3682a4fbfc3ff1a593adf95740ad8ab0d1d487Devang Patel << "'! Continuing as if it's empty.\n"; 102ef3682a4fbfc3ff1a593adf95740ad8ab0d1d487Devang Patel return; // Just continue as if the file were empty 1034eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner } 1044eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner while (In) { 1054eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner std::string Symbol; 1064eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner In >> Symbol; 1074eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner if (!Symbol.empty()) 1084eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner ExternalNames.insert(Symbol); 1094eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner } 1104eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner} 1114eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner 112cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic bool isExternallyVisible(const GlobalValue &GV, 113cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const std::set<std::string> &ExternalNames) { 1140fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola // Function must be defined here 1150fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola if (GV.isDeclaration()) 116cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return true; 1170fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola 1180fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola // Available externally is really just a "declaration with a body". 1190fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola if (GV.hasAvailableExternallyLinkage()) 120cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return true; 1210fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Assume that dllexported symbols are referenced elsewhere 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (GV.hasDLLExportStorageClass()) 124cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return true; 1250fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola 1260fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola // Marked to keep external? 127cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!GV.hasLocalLinkage() && ExternalNames.count(GV.getName())) 128cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return true; 129cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 130cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 131cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 1320fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola 133cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// Internalize GV if it is possible to do so, i.e. it is not externally visible 134cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// and is not a member of an externally visible comdat. 135cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarbool InternalizePass::maybeInternalize( 136cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar GlobalValue &GV, const std::set<const Comdat *> &ExternalComdats) { 137cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Comdat *C = GV.getComdat()) { 138cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (ExternalComdats.count(C)) 139cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 140cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 141cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // If a comdat is not externally visible we can drop it. 142cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (auto GO = dyn_cast<GlobalObject>(&GV)) 143cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar GO->setComdat(nullptr); 144cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 145cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (GV.hasLocalLinkage()) 146cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 147cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } else { 148cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (GV.hasLocalLinkage()) 149cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 150cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 151cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (isExternallyVisible(GV, ExternalNames)) 152cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 153cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 154cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 155cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar GV.setVisibility(GlobalValue::DefaultVisibility); 156cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar GV.setLinkage(GlobalValue::InternalLinkage); 1577e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola return true; 1580fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola} 1590fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola 160cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// If GV is part of a comdat and is externally visible, keep track of its 161cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// comdat so that we don't internalize any of its members. 162cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarvoid InternalizePass::checkComdatVisibility( 163cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar GlobalValue &GV, std::set<const Comdat *> &ExternalComdats) { 164cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Comdat *C = GV.getComdat(); 165cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!C) 166cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return; 167cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 168cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (isExternallyVisible(GV, ExternalNames)) 169cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ExternalComdats.insert(C); 170cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 171cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 1724eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattnerbool InternalizePass::runOnModule(Module &M) { 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CallGraphWrapperPass *CGPass = getAnalysisIfAvailable<CallGraphWrapperPass>(); 174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CallGraph *CG = CGPass ? &CGPass->getCallGraph() : nullptr; 175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : nullptr; 1762631ac3b5b4c2d7eaf8d1db178dc98071a708ad2Duncan Sands 1774ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola SmallPtrSet<GlobalValue *, 8> Used; 1784ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola collectUsedGlobalVariables(M, Used, false); 1794ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola 180cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Collect comdat visiblity information for the module. 181cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar std::set<const Comdat *> ExternalComdats; 182cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!M.getComdatSymbolTable().empty()) { 183cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (Function &F : M) 184cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar checkComdatVisibility(F, ExternalComdats); 185cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (GlobalVariable &GV : M.globals()) 186cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar checkComdatVisibility(GV, ExternalComdats); 187cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (GlobalAlias &GA : M.aliases()) 188cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar checkComdatVisibility(GA, ExternalComdats); 189cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 190cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 1914ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola // We must assume that globals in llvm.used have a reference that not even 1924ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola // the linker can see, so we don't internalize them. 1934ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola // For llvm.compiler.used the situation is a bit fuzzy. The assembler and 1944ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola // linker can drop those symbols. If this pass is running as part of LTO, 1954ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola // one might think that it could just drop llvm.compiler.used. The problem 1964ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola // is that even in LTO llvm doesn't see every reference. For example, 1974ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola // we don't see references from function local inline assembly. To be 1984ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola // conservative, we internalize symbols in llvm.compiler.used, but we 1994ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola // keep llvm.compiler.used so that the symbol is not deleted by llvm. 20037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (GlobalValue *V : Used) { 2014ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola ExternalNames.insert(V->getName()); 2024ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola } 2034ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola 204ef3682a4fbfc3ff1a593adf95740ad8ab0d1d487Devang Patel // Mark all functions not in the api as internal. 205cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (Function &I : M) { 206cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!maybeInternalize(I, ExternalComdats)) 2070fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola continue; 2080fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola 2090fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola if (ExternalNode) 2100fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola // Remove a callgraph edge from the external node to this function. 211cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ExternalNode->removeOneAbstractEdgeTo((*CG)[&I]); 2120fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola 2130fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola ++NumFunctions; 214cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DEBUG(dbgs() << "Internalizing func " << I.getName() << "\n"); 2150fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola } 2162631ac3b5b4c2d7eaf8d1db178dc98071a708ad2Duncan Sands 2174eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner // Never internalize the llvm.used symbol. It is used to implement 2184eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner // attribute((used)). 219401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner // FIXME: Shouldn't this just filter on llvm.metadata section?? 2204eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner ExternalNames.insert("llvm.used"); 221401e10c4fbfcdcfade5065093e2ca97f69a1d144Chris Lattner ExternalNames.insert("llvm.compiler.used"); 2222631ac3b5b4c2d7eaf8d1db178dc98071a708ad2Duncan Sands 22344c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey // Never internalize anchors used by the machine module info, else the info 22444c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey // won't find them. (see MachineModuleInfo.) 2254e2288b9de2fc30d4b88b437c86594cd8ec332faChris Lattner ExternalNames.insert("llvm.global_ctors"); 2264e2288b9de2fc30d4b88b437c86594cd8ec332faChris Lattner ExternalNames.insert("llvm.global_dtors"); 227088b5913ef6f91fccc3c931653e16bfeb330c90bTanya Lattner ExternalNames.insert("llvm.global.annotations"); 2282631ac3b5b4c2d7eaf8d1db178dc98071a708ad2Duncan Sands 229aab3c0cb077f741af3447cc030c28bedd23b491cBill Wendling // Never internalize symbols code-gen inserts. 230d275ff5d4c4f4f8bf9a77acd70605caa98c14246Bill Wendling // FIXME: We should probably add this (and the __stack_chk_guard) via some 231d275ff5d4c4f4f8bf9a77acd70605caa98c14246Bill Wendling // type of call-back in CodeGen. 232d275ff5d4c4f4f8bf9a77acd70605caa98c14246Bill Wendling ExternalNames.insert("__stack_chk_fail"); 233aab3c0cb077f741af3447cc030c28bedd23b491cBill Wendling ExternalNames.insert("__stack_chk_guard"); 234aab3c0cb077f741af3447cc030c28bedd23b491cBill Wendling 235ef3682a4fbfc3ff1a593adf95740ad8ab0d1d487Devang Patel // Mark all global variables with initializers that are not in the api as 236ef3682a4fbfc3ff1a593adf95740ad8ab0d1d487Devang Patel // internal as well. 2374eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 2380fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola I != E; ++I) { 239cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!maybeInternalize(*I, ExternalComdats)) 2400fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola continue; 2410fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola 2420fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola ++NumGlobals; 2430fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n"); 2440fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola } 2452631ac3b5b4c2d7eaf8d1db178dc98071a708ad2Duncan Sands 24627a53009efcf1b0334dc17c3d54382798686ff59Duncan Sands // Mark all aliases that are not in the api as internal as well. 24727a53009efcf1b0334dc17c3d54382798686ff59Duncan Sands for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); 2480fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola I != E; ++I) { 249cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!maybeInternalize(*I, ExternalComdats)) 2500fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola continue; 2510fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola 2520fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola ++NumAliases; 2530fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n"); 2540fb771667eb2f8a5cd623ce0ee3775b4d1416576Rafael Espindola } 25527a53009efcf1b0334dc17c3d54382798686ff59Duncan Sands 256cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // We do not keep track of whether this pass changed the module because 257cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // it adds unnecessary complexity: 258cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // 1) This pass will generally be near the start of the pass pipeline, so 259cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // there will be no analyses to invalidate. 260cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // 2) This pass will most likely end up changing the module and it isn't worth 261cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // worrying about optimizing the case where the module is unchanged. 262cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return true; 2634eb40df1a839c08bca6dcab90ba1a4831e5ef52dChris Lattner} 264f629309f74cf1a64aa7fd1cd5784fd7db9a8f59eChris Lattner 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesModulePass *llvm::createInternalizePass() { return new InternalizePass(); } 266753d94a1c8fe02f64eb4f482d396712c68db1d84Devang Patel 2677e667c56cf7e27ff521ceb86518beab32bfb630dRafael EspindolaModulePass *llvm::createInternalizePass(ArrayRef<const char *> ExportList) { 2687e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola return new InternalizePass(ExportList); 269753d94a1c8fe02f64eb4f482d396712c68db1d84Devang Patel} 270