From 755506e11dfa0c55bf6642b99591ae461f1d7c2e Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 16 Aug 2019 10:59:18 +0000 Subject: [PATCH] Revert "[CallGraph] Refine call graph for indirect calls with !callees metadata" This reverts commit r369025. Crashes clang, test case is on the mailing list. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369096 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/CallGraph.h | 17 -------- include/llvm/IR/CallSite.h | 24 ----------- lib/Analysis/CGSCCPassManager.cpp | 3 +- lib/Analysis/CallGraph.cpp | 40 +------------------ lib/Analysis/LazyCallGraph.cpp | 6 +-- test/Analysis/CallGraph/callees-metadata.ll | 34 ---------------- .../Analysis/CallGraph/non-leaf-intrinsics.ll | 4 +- .../LazyCallGraph/callees-metadata.ll | 38 ------------------ 8 files changed, 7 insertions(+), 159 deletions(-) delete mode 100644 test/Analysis/CallGraph/callees-metadata.ll delete mode 100644 test/Analysis/LazyCallGraph/callees-metadata.ll diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index a8f8629e6a9..7a10183c4d9 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -46,7 +46,6 @@ #define LLVM_ANALYSIS_CALLGRAPH_H #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" @@ -77,22 +76,9 @@ class CallGraph { using FunctionMapTy = std::map>; - /// \brief A type for maintaining dummy nodes. - /// - /// Dummy nodes (i.e., nodes having a null function) include, for example, - /// those created to represent !callees metadata. We use a void pointer as - /// the key to allow for various kinds of dummy nodes. We use a MapVector to - /// ensure a deterministic iteration order (there's no good way to sort dummy - /// nodes). A deterministic iteration order is primarily useful for printing. - using DummyNodeMapTy = - MapVector>; - /// A map from \c Function* to \c CallGraphNode*. FunctionMapTy FunctionMap; - /// \brief A map for maintaining dummy nodes. - DummyNodeMapTy DummyNodeMap; - /// This node has edges to all external functions and those internal /// functions that have their address taken. CallGraphNode *ExternalCallingNode; @@ -169,9 +155,6 @@ public: /// Similar to operator[], but this will insert a new CallGraphNode for /// \c F if one does not already exist. CallGraphNode *getOrInsertFunction(const Function *F); - - /// \brief Return the dummy node associated with the given metadata node. - CallGraphNode *getOrInsertNodeForCalleesMD(MDNode *Callees); }; /// A node in the call graph for a module. diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index e5235159776..b47a96c5d5f 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -663,30 +663,6 @@ public: return false; } - /// Return the set of functions this call site is known to call. For direct - /// calls, the returned set contains the called function. For indirect calls, - /// this function collects known callees from !callees metadata, if present. - SmallVector getKnownCallees() { - SmallVector Callees; - - if (getCalledFunction()) { - // If the call site is direct, just add the called function to the set. - Callees.push_back(getCalledFunction()); - return Callees; - } - - InstrTy *Inst = getInstruction(); - if (auto *Node = Inst->getMetadata(LLVMContext::MD_callees)) { - // Otherwise, if the call site is indirect, collect the known callees from - // !callees metadata if present. - for (const MDOperand &Op : Node->operands()) - if (auto *MDConstant = mdconst::extract_or_null(Op)) - Callees.push_back(cast(MDConstant)); - } - - return Callees; - } - private: IterTy getCallee() const { return cast(getInstruction())->op_end() - 1; diff --git a/lib/Analysis/CGSCCPassManager.cpp b/lib/Analysis/CGSCCPassManager.cpp index 54886d45a1d..a0b3f83cca6 100644 --- a/lib/Analysis/CGSCCPassManager.cpp +++ b/lib/Analysis/CGSCCPassManager.cpp @@ -449,7 +449,7 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass( // irrelevant. for (Instruction &I : instructions(F)) if (auto CS = CallSite(&I)) - for (Function *Callee : CS.getKnownCallees()) { + if (Function *Callee = CS.getCalledFunction()) if (Visited.insert(Callee).second && !Callee->isDeclaration()) { Node &CalleeN = *G.lookup(*Callee); Edge *E = N->lookup(CalleeN); @@ -467,7 +467,6 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass( if (!E->isCall()) PromotedRefTargets.insert(&CalleeN); } - } // Now walk all references. for (Instruction &I : instructions(F)) diff --git a/lib/Analysis/CallGraph.cpp b/lib/Analysis/CallGraph.cpp index a7bb16299a5..70aeb1a688e 100644 --- a/lib/Analysis/CallGraph.cpp +++ b/lib/Analysis/CallGraph.cpp @@ -37,7 +37,6 @@ CallGraph::CallGraph(Module &M) CallGraph::CallGraph(CallGraph &&Arg) : M(Arg.M), FunctionMap(std::move(Arg.FunctionMap)), - DummyNodeMap(std::move(Arg.DummyNodeMap)), ExternalCallingNode(Arg.ExternalCallingNode), CallsExternalNode(std::move(Arg.CallsExternalNode)) { Arg.FunctionMap.clear(); @@ -54,8 +53,6 @@ CallGraph::~CallGraph() { #ifndef NDEBUG for (auto &I : FunctionMap) I.second->allReferencesDropped(); - for (auto &N : DummyNodeMap) - N.second->allReferencesDropped(); #endif } @@ -77,14 +74,7 @@ void CallGraph::addToCallGraph(Function *F) { for (Instruction &I : BB) { if (auto *Call = dyn_cast(&I)) { const Function *Callee = Call->getCalledFunction(); - MDNode *CalleesMD = I.getMetadata(LLVMContext::MD_callees); - if (!Callee && CalleesMD) - // If an indirect call site has !callees metadata indicating its - // possible callees, we add an edge from the call site to a dummy - // node. When we construct the dummy node, we add edges from it to - // the functions indicated in the !callees metadata. - Node->addCalledFunction(Call, getOrInsertNodeForCalleesMD(CalleesMD)); - else if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID())) + 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. @@ -115,11 +105,6 @@ void CallGraph::print(raw_ostream &OS) const { for (CallGraphNode *CN : Nodes) CN->print(OS); - - // The iteration order of the DummyNodeMap is deterministic, so we don't need - // to sort the nodes. Just print them. - for (auto &Entry : DummyNodeMap) - Entry.second->print(OS); } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) @@ -135,12 +120,6 @@ LLVM_DUMP_METHOD void CallGraph::dump() const { print(dbgs()); } Function *CallGraph::removeFunctionFromModule(CallGraphNode *CGN) { assert(CGN->empty() && "Cannot remove function from call " "graph if it references other functions!"); - - // If any dummy node references the node for the given function, we first - // need to remove those edges. - for (auto &Entry : DummyNodeMap) - Entry.second->removeAnyCallEdgeTo(CGN); - Function *F = CGN->getFunction(); // Get the function for the call graph node FunctionMap.erase(F); // Remove the call graph node from the map @@ -175,21 +154,6 @@ CallGraphNode *CallGraph::getOrInsertFunction(const Function *F) { return CGN.get(); } -CallGraphNode *CallGraph::getOrInsertNodeForCalleesMD(MDNode *Callees) { - auto &CGN = DummyNodeMap[Callees]; - if (CGN) - return CGN.get(); - CGN = llvm::make_unique(nullptr); - for (const MDOperand &Op : Callees->operands()) - if (auto *MDConstant = mdconst::extract_or_null(Op)) { - auto *F = cast(MDConstant); - - assert(!F->isIntrinsic()); - CGN->addCalledFunction(nullptr, getOrInsertFunction(F)); - } - return CGN.get(); -} - //===----------------------------------------------------------------------===// // Implementations of the CallGraphNode class methods. // @@ -207,7 +171,7 @@ void CallGraphNode::print(raw_ostream &OS) const { if (Function *FI = I.second->getFunction()) OS << "function '" << FI->getName() <<"'\n"; else - OS << "<><<" << I.second << ">>\n"; + OS << "external node\n"; } OS << '\n'; } diff --git a/lib/Analysis/LazyCallGraph.cpp b/lib/Analysis/LazyCallGraph.cpp index c832dc94877..08d6e76ea03 100644 --- a/lib/Analysis/LazyCallGraph.cpp +++ b/lib/Analysis/LazyCallGraph.cpp @@ -100,14 +100,12 @@ LazyCallGraph::EdgeSequence &LazyCallGraph::Node::populateSlow() { for (BasicBlock &BB : *F) for (Instruction &I : BB) { if (auto CS = CallSite(&I)) - for (Function *Callee : CS.getKnownCallees()) + if (Function *Callee = CS.getCalledFunction()) if (!Callee->isDeclaration()) if (Callees.insert(Callee).second) { Visited.insert(Callee); - auto EdgeK = CS.getCalledFunction() ? LazyCallGraph::Edge::Call - : LazyCallGraph::Edge::Ref; addEdge(Edges->Edges, Edges->EdgeIndexMap, G->get(*Callee), - EdgeK); + LazyCallGraph::Edge::Call); } for (Value *Op : I.operand_values()) diff --git a/test/Analysis/CallGraph/callees-metadata.ll b/test/Analysis/CallGraph/callees-metadata.ll deleted file mode 100644 index fcc5042c0c9..00000000000 --- a/test/Analysis/CallGraph/callees-metadata.ll +++ /dev/null @@ -1,34 +0,0 @@ -; RUN: opt < %s -print-callgraph -disable-output 2>&1 | FileCheck %s - -; CHECK: Call graph node <><<{{.+}}>> #uses=0 -; CHECK-DAG: CS<0x0> calls function 'main' -; CHECK-DAG: CS<0x0> calls function 'add' -; CHECK-DAG: CS<0x0> calls function 'sub' -; -; CHECK: Call graph node for function: 'add'<<{{.+}}>> #uses=2 -; -; CHECK: Call graph node for function: 'main'<<{{.+}}>> #uses=1 -; CHECK-NEXT: CS<{{.+}}> calls <><<[[CALLEES:.+]]>> -; -; CHECK: Call graph node for function: 'sub'<<{{.+}}>> #uses=2 -; -; CHECK: Call graph node <><<[[CALLEES]]>> #uses=1 -; CHECK-DAG: CS<0x0> calls function 'add' -; CHECK-DAG: CS<0x0> calls function 'sub' - -define i64 @main(i64 %x, i64 %y, i64 (i64, i64)* %binop) { - %tmp0 = call i64 %binop(i64 %x, i64 %y), !callees !0 - ret i64 %tmp0 -} - -define i64 @add(i64 %x, i64 %y) { - %tmp0 = add i64 %x, %y - ret i64 %tmp0 -} - -define i64 @sub(i64 %x, i64 %y) { - %tmp0 = sub i64 %x, %y - ret i64 %tmp0 -} - -!0 = !{i64 (i64, i64)* @add, i64 (i64, i64)* @sub} diff --git a/test/Analysis/CallGraph/non-leaf-intrinsics.ll b/test/Analysis/CallGraph/non-leaf-intrinsics.ll index 4c5855f0219..5caecf7e224 100644 --- a/test/Analysis/CallGraph/non-leaf-intrinsics.ll +++ b/test/Analysis/CallGraph/non-leaf-intrinsics.ll @@ -26,7 +26,7 @@ entry: ; CHECK: CS<0x0> calls function 'f' ; CHECK: Call graph node for function: 'calls_patchpoint' -; CHECK-NEXT: CS<[[addr_1:[^>]+]]> calls <> +; CHECK-NEXT: CS<[[addr_1:[^>]+]]> calls external node ; CHECK: Call graph node for function: 'calls_statepoint' -; CHECK-NEXT: CS<[[addr_0:[^>]+]]> calls <> +; CHECK-NEXT: CS<[[addr_0:[^>]+]]> calls external node diff --git a/test/Analysis/LazyCallGraph/callees-metadata.ll b/test/Analysis/LazyCallGraph/callees-metadata.ll deleted file mode 100644 index a550e221a7f..00000000000 --- a/test/Analysis/LazyCallGraph/callees-metadata.ll +++ /dev/null @@ -1,38 +0,0 @@ -; RUN: opt < %s -passes=print-lcg -disable-output 2>&1 | FileCheck %s - -; CHECK: Edges in function: main -; CHECK-DAG: ref -> add -; CHECK-DAG: ref -> sub -; -; CHECK: Edges in function: add -; -; CHECK: Edges in function: sub -; -; CHECK: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: sub -; -; CHECK: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: add -; -; CHECK: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: main - -define i64 @main(i64 %x, i64 %y, i64 (i64, i64)* %binop) { - %tmp0 = call i64 %binop(i64 %x, i64 %y), !callees !0 - ret i64 %tmp0 -} - -define i64 @add(i64 %x, i64 %y) { - %tmp0 = add i64 %x, %y - ret i64 %tmp0 -} - -define i64 @sub(i64 %x, i64 %y) { - %tmp0 = sub i64 %x, %y - ret i64 %tmp0 -} - -!0 = !{i64 (i64, i64)* @add, i64 (i64, i64)* @sub} -- 2.50.1