mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-27 06:54:30 +00:00
[CallSite removal] Move the legacy PM, call graph, and some inliner
code to `CallBase`. This patch focuses on the legacy PM, call graph, and some of inliner and legacy passes interacting with those APIs from `CallSite` to the new `CallBase` class. No interesting changes. Differential Revision: https://reviews.llvm.org/D60412 llvm-svn: 358739
This commit is contained in:
parent
7a739be2a3
commit
aa61c612af
@ -47,8 +47,8 @@
|
||||
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
@ -229,11 +229,11 @@ public:
|
||||
}
|
||||
|
||||
/// Adds a function to the list of functions called by this one.
|
||||
void addCalledFunction(CallSite CS, CallGraphNode *M) {
|
||||
assert(!CS.getInstruction() || !CS.getCalledFunction() ||
|
||||
!CS.getCalledFunction()->isIntrinsic() ||
|
||||
!Intrinsic::isLeaf(CS.getCalledFunction()->getIntrinsicID()));
|
||||
CalledFunctions.emplace_back(CS.getInstruction(), M);
|
||||
void addCalledFunction(CallBase *Call, CallGraphNode *M) {
|
||||
assert(!Call || !Call->getCalledFunction() ||
|
||||
!Call->getCalledFunction()->isIntrinsic() ||
|
||||
!Intrinsic::isLeaf(Call->getCalledFunction()->getIntrinsicID()));
|
||||
CalledFunctions.emplace_back(Call, M);
|
||||
M->AddRef();
|
||||
}
|
||||
|
||||
@ -246,7 +246,7 @@ public:
|
||||
/// Removes the edge in the node for the specified call site.
|
||||
///
|
||||
/// Note that this method takes linear time, so it should be used sparingly.
|
||||
void removeCallEdgeFor(CallSite CS);
|
||||
void removeCallEdgeFor(CallBase &Call);
|
||||
|
||||
/// Removes all call edges from this node to the specified callee
|
||||
/// function.
|
||||
@ -263,7 +263,8 @@ public:
|
||||
/// new one.
|
||||
///
|
||||
/// Note that this method takes linear time, so it should be used sparingly.
|
||||
void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode);
|
||||
void replaceCallEdge(CallBase &Call, CallBase &NewCall,
|
||||
CallGraphNode *NewNode);
|
||||
|
||||
private:
|
||||
friend class CallGraph;
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
@ -63,25 +62,25 @@ void CallGraph::addToCallGraph(Function *F) {
|
||||
// If this function has external linkage or has its address taken, anything
|
||||
// could call it.
|
||||
if (!F->hasLocalLinkage() || F->hasAddressTaken())
|
||||
ExternalCallingNode->addCalledFunction(CallSite(), Node);
|
||||
ExternalCallingNode->addCalledFunction(nullptr, Node);
|
||||
|
||||
// If this function is not defined in this translation unit, it could call
|
||||
// anything.
|
||||
if (F->isDeclaration() && !F->isIntrinsic())
|
||||
Node->addCalledFunction(CallSite(), CallsExternalNode.get());
|
||||
Node->addCalledFunction(nullptr, CallsExternalNode.get());
|
||||
|
||||
// Look for calls by this function.
|
||||
for (BasicBlock &BB : *F)
|
||||
for (Instruction &I : BB) {
|
||||
if (auto CS = CallSite(&I)) {
|
||||
const Function *Callee = CS.getCalledFunction();
|
||||
if (auto *Call = dyn_cast<CallBase>(&I)) {
|
||||
const Function *Callee = Call->getCalledFunction();
|
||||
if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID()))
|
||||
// Indirect calls of intrinsics are not allowed so no need to check.
|
||||
// We can be more precise here by using TargetArg returned by
|
||||
// Intrinsic::isLeaf.
|
||||
Node->addCalledFunction(CS, CallsExternalNode.get());
|
||||
Node->addCalledFunction(Call, CallsExternalNode.get());
|
||||
else if (!Callee->isIntrinsic())
|
||||
Node->addCalledFunction(CS, getOrInsertFunction(Callee));
|
||||
Node->addCalledFunction(Call, getOrInsertFunction(Callee));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -184,10 +183,10 @@ LLVM_DUMP_METHOD void CallGraphNode::dump() const { print(dbgs()); }
|
||||
/// removeCallEdgeFor - This method removes the edge in the node for the
|
||||
/// specified call site. Note that this method takes linear time, so it
|
||||
/// should be used sparingly.
|
||||
void CallGraphNode::removeCallEdgeFor(CallSite CS) {
|
||||
void CallGraphNode::removeCallEdgeFor(CallBase &Call) {
|
||||
for (CalledFunctionsVector::iterator I = CalledFunctions.begin(); ; ++I) {
|
||||
assert(I != CalledFunctions.end() && "Cannot find callsite to remove!");
|
||||
if (I->first == CS.getInstruction()) {
|
||||
if (I->first == &Call) {
|
||||
I->second->DropRef();
|
||||
*I = CalledFunctions.back();
|
||||
CalledFunctions.pop_back();
|
||||
@ -227,13 +226,13 @@ void CallGraphNode::removeOneAbstractEdgeTo(CallGraphNode *Callee) {
|
||||
/// replaceCallEdge - This method replaces the edge in the node for the
|
||||
/// specified call site with a new one. Note that this method takes linear
|
||||
/// time, so it should be used sparingly.
|
||||
void CallGraphNode::replaceCallEdge(CallSite CS,
|
||||
CallSite NewCS, CallGraphNode *NewNode){
|
||||
void CallGraphNode::replaceCallEdge(CallBase &Call, CallBase &NewCall,
|
||||
CallGraphNode *NewNode) {
|
||||
for (CalledFunctionsVector::iterator I = CalledFunctions.begin(); ; ++I) {
|
||||
assert(I != CalledFunctions.end() && "Cannot find callsite to remove!");
|
||||
if (I->first == CS.getInstruction()) {
|
||||
if (I->first == &Call) {
|
||||
I->second->DropRef();
|
||||
I->first = NewCS.getInstruction();
|
||||
I->first = &NewCall;
|
||||
I->second = NewNode;
|
||||
NewNode->AddRef();
|
||||
return;
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "llvm/ADT/SCCIterator.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRPrintingPasses.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
@ -201,7 +200,7 @@ bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
|
||||
/// This never happens in checking mode.
|
||||
bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
|
||||
bool CheckingMode) {
|
||||
DenseMap<Value*, CallGraphNode*> CallSites;
|
||||
DenseMap<Value *, CallGraphNode *> Calls;
|
||||
|
||||
LLVM_DEBUG(dbgs() << "CGSCCPASSMGR: Refreshing SCC with " << CurSCC.size()
|
||||
<< " nodes:\n";
|
||||
@ -230,21 +229,21 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
|
||||
for (CallGraphNode::iterator I = CGN->begin(), E = CGN->end(); I != E; ) {
|
||||
// If this call site is null, then the function pass deleted the call
|
||||
// entirely and the WeakTrackingVH nulled it out.
|
||||
auto *Call = dyn_cast_or_null<CallBase>(I->first);
|
||||
if (!I->first ||
|
||||
// If we've already seen this call site, then the FunctionPass RAUW'd
|
||||
// one call with another, which resulted in two "uses" in the edge
|
||||
// list of the same call.
|
||||
CallSites.count(I->first) ||
|
||||
Calls.count(I->first) ||
|
||||
|
||||
// If the call edge is not from a call or invoke, or it is a
|
||||
// instrinsic call, then the function pass RAUW'd a call with
|
||||
// another value. This can happen when constant folding happens
|
||||
// of well known functions etc.
|
||||
!CallSite(I->first) ||
|
||||
(CallSite(I->first).getCalledFunction() &&
|
||||
CallSite(I->first).getCalledFunction()->isIntrinsic() &&
|
||||
Intrinsic::isLeaf(
|
||||
CallSite(I->first).getCalledFunction()->getIntrinsicID()))) {
|
||||
!Call ||
|
||||
(Call->getCalledFunction() &&
|
||||
Call->getCalledFunction()->isIntrinsic() &&
|
||||
Intrinsic::isLeaf(Call->getCalledFunction()->getIntrinsicID()))) {
|
||||
assert(!CheckingMode &&
|
||||
"CallGraphSCCPass did not update the CallGraph correctly!");
|
||||
|
||||
@ -268,15 +267,14 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(!CallSites.count(I->first) &&
|
||||
assert(!Calls.count(I->first) &&
|
||||
"Call site occurs in node multiple times");
|
||||
|
||||
CallSite CS(I->first);
|
||||
if (CS) {
|
||||
Function *Callee = CS.getCalledFunction();
|
||||
if (Call) {
|
||||
Function *Callee = Call->getCalledFunction();
|
||||
// Ignore intrinsics because they're not really function calls.
|
||||
if (!Callee || !(Callee->isIntrinsic()))
|
||||
CallSites.insert(std::make_pair(I->first, I->second));
|
||||
Calls.insert(std::make_pair(I->first, I->second));
|
||||
}
|
||||
++I;
|
||||
}
|
||||
@ -287,23 +285,25 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
|
||||
|
||||
for (BasicBlock &BB : *F)
|
||||
for (Instruction &I : BB) {
|
||||
CallSite CS(&I);
|
||||
if (!CS) continue;
|
||||
Function *Callee = CS.getCalledFunction();
|
||||
if (Callee && Callee->isIntrinsic()) continue;
|
||||
auto *Call = dyn_cast<CallBase>(&I);
|
||||
if (!Call)
|
||||
continue;
|
||||
Function *Callee = Call->getCalledFunction();
|
||||
if (Callee && Callee->isIntrinsic())
|
||||
continue;
|
||||
|
||||
// If this call site already existed in the callgraph, just verify it
|
||||
// matches up to expectations and remove it from CallSites.
|
||||
DenseMap<Value*, CallGraphNode*>::iterator ExistingIt =
|
||||
CallSites.find(CS.getInstruction());
|
||||
if (ExistingIt != CallSites.end()) {
|
||||
// matches up to expectations and remove it from Calls.
|
||||
DenseMap<Value *, CallGraphNode *>::iterator ExistingIt =
|
||||
Calls.find(Call);
|
||||
if (ExistingIt != Calls.end()) {
|
||||
CallGraphNode *ExistingNode = ExistingIt->second;
|
||||
|
||||
// Remove from CallSites since we have now seen it.
|
||||
CallSites.erase(ExistingIt);
|
||||
// Remove from Calls since we have now seen it.
|
||||
Calls.erase(ExistingIt);
|
||||
|
||||
// Verify that the callee is right.
|
||||
if (ExistingNode->getFunction() == CS.getCalledFunction())
|
||||
if (ExistingNode->getFunction() == Call->getCalledFunction())
|
||||
continue;
|
||||
|
||||
// If we are in checking mode, we are not allowed to actually mutate
|
||||
@ -311,7 +311,7 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
|
||||
// callgraph is less precise than it could be (e.g. an indirect call
|
||||
// site could be turned direct), don't reject it in checking mode, and
|
||||
// don't tweak it to be more precise.
|
||||
if (CheckingMode && CS.getCalledFunction() &&
|
||||
if (CheckingMode && Call->getCalledFunction() &&
|
||||
ExistingNode->getFunction() == nullptr)
|
||||
continue;
|
||||
|
||||
@ -321,7 +321,7 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
|
||||
// If not, we either went from a direct call to indirect, indirect to
|
||||
// direct, or direct to different direct.
|
||||
CallGraphNode *CalleeNode;
|
||||
if (Function *Callee = CS.getCalledFunction()) {
|
||||
if (Function *Callee = Call->getCalledFunction()) {
|
||||
CalleeNode = CG.getOrInsertFunction(Callee);
|
||||
// Keep track of whether we turned an indirect call into a direct
|
||||
// one.
|
||||
@ -335,7 +335,7 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
|
||||
}
|
||||
|
||||
// Update the edge target in CGN.
|
||||
CGN->replaceCallEdge(CS, CS, CalleeNode);
|
||||
CGN->replaceCallEdge(*Call, *Call, CalleeNode);
|
||||
MadeChange = true;
|
||||
continue;
|
||||
}
|
||||
@ -345,7 +345,7 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
|
||||
|
||||
// If the call site didn't exist in the CGN yet, add it.
|
||||
CallGraphNode *CalleeNode;
|
||||
if (Function *Callee = CS.getCalledFunction()) {
|
||||
if (Function *Callee = Call->getCalledFunction()) {
|
||||
CalleeNode = CG.getOrInsertFunction(Callee);
|
||||
++NumDirectAdded;
|
||||
} else {
|
||||
@ -353,7 +353,7 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
|
||||
++NumIndirectAdded;
|
||||
}
|
||||
|
||||
CGN->addCalledFunction(CS, CalleeNode);
|
||||
CGN->addCalledFunction(Call, CalleeNode);
|
||||
MadeChange = true;
|
||||
}
|
||||
|
||||
@ -375,12 +375,12 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
|
||||
// they are dangling pointers. WeakTrackingVH should save us for this, so
|
||||
// abort if
|
||||
// this happens.
|
||||
assert(CallSites.empty() && "Dangling pointers found in call sites map");
|
||||
assert(Calls.empty() && "Dangling pointers found in call sites map");
|
||||
|
||||
// Periodically do an explicit clear to remove tombstones when processing
|
||||
// large scc's.
|
||||
if ((FunctionNo & 15) == 15)
|
||||
CallSites.clear();
|
||||
Calls.clear();
|
||||
}
|
||||
|
||||
LLVM_DEBUG(if (MadeChange) {
|
||||
|
@ -176,15 +176,15 @@ static void buildCGN(CallGraph &CG, CallGraphNode *Node) {
|
||||
|
||||
// Look for calls by this function.
|
||||
for (Instruction &I : instructions(F))
|
||||
if (CallSite CS = CallSite(cast<Value>(&I))) {
|
||||
const Function *Callee = CS.getCalledFunction();
|
||||
if (auto *Call = dyn_cast<CallBase>(&I)) {
|
||||
const Function *Callee = Call->getCalledFunction();
|
||||
if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID()))
|
||||
// Indirect calls of intrinsics are not allowed so no need to check.
|
||||
// We can be more precise here by using TargetArg returned by
|
||||
// Intrinsic::isLeaf.
|
||||
Node->addCalledFunction(CS, CG.getCallsExternalNode());
|
||||
Node->addCalledFunction(Call, CG.getCallsExternalNode());
|
||||
else if (!Callee->isIntrinsic())
|
||||
Node->addCalledFunction(CS, CG.getOrInsertFunction(Callee));
|
||||
Node->addCalledFunction(Call, CG.getOrInsertFunction(Callee));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1104,7 +1104,9 @@ bool ArgPromotion::runOnSCC(CallGraphSCC &SCC) {
|
||||
CallGraphNode *NewCalleeNode =
|
||||
CG.getOrInsertFunction(NewCS.getCalledFunction());
|
||||
CallGraphNode *CallerNode = CG[Caller];
|
||||
CallerNode->replaceCallEdge(OldCS, NewCS, NewCalleeNode);
|
||||
CallerNode->replaceCallEdge(*cast<CallBase>(OldCS.getInstruction()),
|
||||
*cast<CallBase>(NewCS.getInstruction()),
|
||||
NewCalleeNode);
|
||||
};
|
||||
|
||||
const TargetTransformInfo &TTI =
|
||||
|
@ -671,7 +671,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
|
||||
LLVM_DEBUG(dbgs() << " -> Deleting dead call: " << *Instr << "\n");
|
||||
// Update the call graph by deleting the edge from Callee to Caller.
|
||||
setInlineRemark(CS, "trivially dead");
|
||||
CG[Caller]->removeCallEdgeFor(CS);
|
||||
CG[Caller]->removeCallEdgeFor(*cast<CallBase>(CS.getInstruction()));
|
||||
Instr->eraseFromParent();
|
||||
++NumCallsDeleted;
|
||||
} else {
|
||||
|
@ -242,12 +242,12 @@ static void DeleteBasicBlock(BasicBlock *BB, CallGraph &CG) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (auto CS = CallSite (&*I)) {
|
||||
const Function *Callee = CS.getCalledFunction();
|
||||
if (auto *Call = dyn_cast<CallBase>(&*I)) {
|
||||
const Function *Callee = Call->getCalledFunction();
|
||||
if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID()))
|
||||
CGN->removeCallEdgeFor(CS);
|
||||
CGN->removeCallEdgeFor(*Call);
|
||||
else if (!Callee->isIntrinsic())
|
||||
CGN->removeCallEdgeFor(CS);
|
||||
CGN->removeCallEdgeFor(*Call);
|
||||
}
|
||||
|
||||
if (!I->use_empty())
|
||||
|
@ -1215,14 +1215,14 @@ static void UpdateCallGraphAfterInlining(CallSite CS,
|
||||
|
||||
// If the call was inlined, but then constant folded, there is no edge to
|
||||
// add. Check for this case.
|
||||
Instruction *NewCall = dyn_cast<Instruction>(VMI->second);
|
||||
auto *NewCall = dyn_cast<CallBase>(VMI->second);
|
||||
if (!NewCall)
|
||||
continue;
|
||||
|
||||
// We do not treat intrinsic calls like real function calls because we
|
||||
// expect them to become inline code; do not add an edge for an intrinsic.
|
||||
CallSite CS = CallSite(NewCall);
|
||||
if (CS && CS.getCalledFunction() && CS.getCalledFunction()->isIntrinsic())
|
||||
if (NewCall->getCalledFunction() &&
|
||||
NewCall->getCalledFunction()->isIntrinsic())
|
||||
continue;
|
||||
|
||||
// Remember that this call site got inlined for the client of
|
||||
@ -1235,19 +1235,19 @@ static void UpdateCallGraphAfterInlining(CallSite CS,
|
||||
// destination. This can also happen if the call graph node of the caller
|
||||
// was just unnecessarily imprecise.
|
||||
if (!I->second->getFunction())
|
||||
if (Function *F = CallSite(NewCall).getCalledFunction()) {
|
||||
if (Function *F = NewCall->getCalledFunction()) {
|
||||
// Indirect call site resolved to direct call.
|
||||
CallerNode->addCalledFunction(CallSite(NewCall), CG[F]);
|
||||
CallerNode->addCalledFunction(NewCall, CG[F]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
CallerNode->addCalledFunction(CallSite(NewCall), I->second);
|
||||
CallerNode->addCalledFunction(NewCall, I->second);
|
||||
}
|
||||
|
||||
// Update the call graph by deleting the edge from Callee to Caller. We must
|
||||
// do this after the loop above in case Caller and Callee are the same.
|
||||
CallerNode->removeCallEdgeFor(CS);
|
||||
CallerNode->removeCallEdgeFor(*cast<CallBase>(CS.getInstruction()));
|
||||
}
|
||||
|
||||
static void HandleByValArgumentInit(Value *Dst, Value *Src, Module *M,
|
||||
|
Loading…
x
Reference in New Issue
Block a user