diff options
| author | Duncan Sands <baldrick@free.fr> | 2008-10-03 07:36:09 +0000 |
|---|---|---|
| committer | Duncan Sands <baldrick@free.fr> | 2008-10-03 07:36:09 +0000 |
| commit | 3a813a5d3fdfc3e3f1f78d3ce6e149779e361f37 (patch) | |
| tree | 0d46f25760794035c2d812a6d8b560571150bcf6 /llvm/lib | |
| parent | 74056ae3d535128ab5d3a8f59e2b59e6fd6083de (diff) | |
| download | bcm5719-llvm-3a813a5d3fdfc3e3f1f78d3ce6e149779e361f37.tar.gz bcm5719-llvm-3a813a5d3fdfc3e3f1f78d3ce6e149779e361f37.zip | |
Teach internalize to preserve the callgraph.
Why? Because it was there!
llvm-svn: 56996
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Analysis/IPA/CallGraph.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Transforms/IPO/Internalize.cpp | 7 |
2 files changed, 20 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/IPA/CallGraph.cpp b/llvm/lib/Analysis/IPA/CallGraph.cpp index fba1d00d48c..5aac2968b22 100644 --- a/llvm/lib/Analysis/IPA/CallGraph.cpp +++ b/llvm/lib/Analysis/IPA/CallGraph.cpp @@ -282,6 +282,19 @@ void CallGraphNode::removeAnyCallEdgeTo(CallGraphNode *Callee) { } } +/// removeOneAbstractEdgeTo - Remove one edge associated with a null callsite +/// from this node to the specified callee function. +void CallGraphNode::removeOneAbstractEdgeTo(CallGraphNode *Callee) { + for (unsigned i = CalledFunctions.size(); ; --i) { + assert(i && "Cannot find callee to remove!"); + CallRecord &CR = CalledFunctions[i-1]; + if (CR.second == Callee && !CR.first.getInstruction()) { + CalledFunctions.erase(CalledFunctions.begin()+i-1); + return; + } + } +} + /// replaceCallSite - Make the edge in the node for Old CallSite be for /// New CallSite instead. Note that this method takes linear time, so it /// should be used sparingly. diff --git a/llvm/lib/Transforms/IPO/Internalize.cpp b/llvm/lib/Transforms/IPO/Internalize.cpp index 47fe5fe85ad..462daab0264 100644 --- a/llvm/lib/Transforms/IPO/Internalize.cpp +++ b/llvm/lib/Transforms/IPO/Internalize.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "internalize" +#include "llvm/Analysis/CallGraph.h" #include "llvm/Transforms/IPO.h" #include "llvm/Pass.h" #include "llvm/Module.h" @@ -55,6 +56,7 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addPreserved<CallGraph>(); } }; } // end anonymous namespace @@ -96,6 +98,9 @@ void InternalizePass::LoadFile(const char *Filename) { } bool InternalizePass::runOnModule(Module &M) { + CallGraph *CG = getAnalysisToUpdate<CallGraph>(); + CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0; + if (ExternalNames.empty()) { // Return if we're not in 'all but main' mode and have no external api if (!AllButMain) @@ -120,6 +125,8 @@ bool InternalizePass::runOnModule(Module &M) { !I->hasInternalLinkage() && // Can't already have internal linkage !ExternalNames.count(I->getName())) {// Not marked to keep external? I->setLinkage(GlobalValue::InternalLinkage); + // Remove a callgraph edge from the external node to this function. + if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]); Changed = true; ++NumFunctions; DOUT << "Internalizing func " << I->getName() << "\n"; |

