aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-01-14 20:07:50 +0000
committerChris Lattner <sabre@nondot.org>2006-01-14 20:07:50 +0000
commit468fb1df7db466e5682ee44341c3990b599e8d6a (patch)
tree9607650a33bada402c2c96f8dea69d87b6e062c1 /lib
parent426b2455977432d014b6f60fae54da86713cd1fc (diff)
downloadexternal_llvm-468fb1df7db466e5682ee44341c3990b599e8d6a.zip
external_llvm-468fb1df7db466e5682ee44341c3990b599e8d6a.tar.gz
external_llvm-468fb1df7db466e5682ee44341c3990b599e8d6a.tar.bz2
Teach the inliner to update the CallGraph itself, and have it add edges to
llvm.stacksave/restore when it inserts calls to them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25320 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp57
1 files changed, 53 insertions, 4 deletions
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index 0c2be0f..22811e4 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -18,11 +18,16 @@
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
+#include "llvm/Analysis/CallGraph.h"
#include "llvm/Support/CallSite.h"
using namespace llvm;
-bool llvm::InlineFunction(CallInst *CI) { return InlineFunction(CallSite(CI)); }
-bool llvm::InlineFunction(InvokeInst *II) {return InlineFunction(CallSite(II));}
+bool llvm::InlineFunction(CallInst *CI, CallGraph *CG) {
+ return InlineFunction(CallSite(CI), CG);
+}
+bool llvm::InlineFunction(InvokeInst *II, CallGraph *CG) {
+ return InlineFunction(CallSite(II), CG);
+}
/// HandleInlinedInvoke - If we inlined an invoke site, we need to convert calls
/// in the body of the inlined function into invokes and turn unwind
@@ -131,6 +136,24 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
InvokeDest->removePredecessor(II->getParent());
}
+/// UpdateCallGraphAfterInlining - Once we have finished inlining a call from
+/// caller to callee, update the specified callgraph to reflect the changes we
+/// made.
+static void UpdateCallGraphAfterInlining(const Function *Caller,
+ const Function *Callee,
+ CallGraph &CG) {
+ // Update the call graph by deleting the edge from Callee to Caller
+ CallGraphNode *CalleeNode = CG[Callee];
+ CallGraphNode *CallerNode = CG[Caller];
+ CallerNode->removeCallEdgeTo(CalleeNode);
+
+ // Since we inlined all uninlined call sites in the callee into the caller,
+ // add edges from the caller to all of the callees of the callee.
+ for (CallGraphNode::iterator I = CalleeNode->begin(),
+ E = CalleeNode->end(); I != E; ++I)
+ CallerNode->addCalledFunction(*I);
+}
+
// InlineFunction - This function inlines the called function into the basic
// block of the caller. This returns false if it is not possible to inline this
@@ -141,7 +164,7 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
// exists in the instruction stream. Similiarly this will inline a recursive
// function by one level.
//
-bool llvm::InlineFunction(CallSite CS) {
+bool llvm::InlineFunction(CallSite CS, CallGraph *CG) {
Instruction *TheCall = CS.getInstruction();
assert(TheCall->getParent() && TheCall->getParent()->getParent() &&
"Instruction not in function!");
@@ -234,14 +257,33 @@ bool llvm::InlineFunction(CallSite CS) {
// inlined function.
for (unsigned i = 0, e = Returns.size(); i != e; ++i)
new CallInst(StackRestore, SavedPtr, "", Returns[i]);
+
+ // Count the number of StackRestore calls we insert.
+ unsigned NumStackRestores = Returns.size();
// If we are inlining an invoke instruction, insert restores before each
// unwind. These unwinds will be rewritten into branches later.
if (InlinedFunctionInfo.ContainsUnwinds && isa<InvokeInst>(TheCall)) {
for (Function::iterator BB = FirstNewBlock, E = Caller->end();
BB != E; ++BB)
- if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator()))
+ if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
new CallInst(StackRestore, SavedPtr, "", UI);
+ ++NumStackRestores;
+ }
+ }
+
+ // If we are supposed to update the callgraph, do so now.
+ if (CG) {
+ CallGraphNode *StackSaveCGN = CG->getOrInsertFunction(StackSave);
+ CallGraphNode *StackRestoreCGN = CG->getOrInsertFunction(StackRestore);
+ CallGraphNode *CallerNode = (*CG)[Caller];
+
+ // 'Caller' now calls llvm.stacksave one more time.
+ CallerNode->addCalledFunction(StackSaveCGN);
+
+ // 'Caller' now calls llvm.stackrestore the appropriate number of times.
+ for (unsigned i = 0; i != NumStackRestores; ++i)
+ CallerNode->addCalledFunction(StackRestoreCGN);
}
}
@@ -288,6 +330,9 @@ bool llvm::InlineFunction(CallSite CS) {
// Since we are now done with the return instruction, delete it also.
Returns[0]->getParent()->getInstList().erase(Returns[0]);
+ // Update the callgraph if requested.
+ if (CG) UpdateCallGraphAfterInlining(Caller, CalledFunc, *CG);
+
// We are now done with the inlining.
return true;
}
@@ -413,5 +458,9 @@ bool llvm::InlineFunction(CallSite CS) {
// Now we can remove the CalleeEntry block, which is now empty.
Caller->getBasicBlockList().erase(CalleeEntry);
+
+ // Update the callgraph if requested.
+ if (CG) UpdateCallGraphAfterInlining(Caller, CalledFunc, *CG);
+
return true;
}