From ce3f75df1fffdb8bcef66ff82e83fa895e00260e Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Fri, 19 Apr 2019 05:59:42 +0000 Subject: [PATCH] [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 --- llvm/include/llvm/Analysis/CallGraph.h | 17 ++++---- llvm/lib/Analysis/CallGraph.cpp | 25 ++++++----- llvm/lib/Analysis/CallGraphSCCPass.cpp | 62 +++++++++++++-------------- llvm/lib/Transforms/Coroutines/Coroutines.cpp | 8 ++-- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp | 4 +- llvm/lib/Transforms/IPO/Inliner.cpp | 2 +- llvm/lib/Transforms/IPO/PruneEH.cpp | 8 ++-- llvm/lib/Transforms/Utils/InlineFunction.cpp | 14 +++--- 8 files changed, 71 insertions(+), 69 deletions(-) diff --git a/llvm/include/llvm/Analysis/CallGraph.h b/llvm/include/llvm/Analysis/CallGraph.h index a743cbc..7a10183 100644 --- a/llvm/include/llvm/Analysis/CallGraph.h +++ b/llvm/include/llvm/Analysis/CallGraph.h @@ -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; diff --git a/llvm/lib/Analysis/CallGraph.cpp b/llvm/lib/Analysis/CallGraph.cpp index e4e9e71..ec5e94d 100644 --- a/llvm/lib/Analysis/CallGraph.cpp +++ b/llvm/lib/Analysis/CallGraph.cpp @@ -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(&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; diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp index eb02042..196ef40 100644 --- a/llvm/lib/Analysis/CallGraphSCCPass.cpp +++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp @@ -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 CallSites; + DenseMap 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(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(&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::iterator ExistingIt = - CallSites.find(CS.getInstruction()); - if (ExistingIt != CallSites.end()) { + // matches up to expectations and remove it from Calls. + DenseMap::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) { diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp index 7bd87fd..a581d1d 100644 --- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp +++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp @@ -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(&I))) { - const Function *Callee = CS.getCalledFunction(); + if (auto *Call = dyn_cast(&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)); } } diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp index dbbe03d..5f99462 100644 --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -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(OldCS.getInstruction()), + *cast(NewCS.getInstruction()), + NewCalleeNode); }; const TargetTransformInfo &TTI = diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp index 4047c0a..f6e8b53 100644 --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -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(CS.getInstruction())); Instr->eraseFromParent(); ++NumCallsDeleted; } else { diff --git a/llvm/lib/Transforms/IPO/PruneEH.cpp b/llvm/lib/Transforms/IPO/PruneEH.cpp index ef7b43e..cb3915d 100644 --- a/llvm/lib/Transforms/IPO/PruneEH.cpp +++ b/llvm/lib/Transforms/IPO/PruneEH.cpp @@ -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(&*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()) diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 7443a7f..a29fbc8 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -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(VMI->second); + auto *NewCall = dyn_cast(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(CS.getInstruction())); } static void HandleByValArgumentInit(Value *Dst, Value *Src, Module *M, -- 2.7.4