Revert "[CallGraph] Refine call graph for indirect calls with !callees metadata"
authorBenjamin Kramer <benny.kra@googlemail.com>
Fri, 16 Aug 2019 10:59:18 +0000 (10:59 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Fri, 16 Aug 2019 10:59:18 +0000 (10:59 +0000)
This reverts commit r369025. Crashes clang, test case is on the mailing
list.

llvm-svn: 369096

llvm/include/llvm/Analysis/CallGraph.h
llvm/include/llvm/IR/CallSite.h
llvm/lib/Analysis/CGSCCPassManager.cpp
llvm/lib/Analysis/CallGraph.cpp
llvm/lib/Analysis/LazyCallGraph.cpp
llvm/test/Analysis/CallGraph/callees-metadata.ll [deleted file]
llvm/test/Analysis/CallGraph/non-leaf-intrinsics.ll
llvm/test/Analysis/LazyCallGraph/callees-metadata.ll [deleted file]

index a8f8629..7a10183 100644 (file)
@@ -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<const Function *, std::unique_ptr<CallGraphNode>>;
 
-  /// \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<const MDNode *, std::unique_ptr<CallGraphNode>>;
-
   /// 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.
index e523515..b47a96c 100644 (file)
@@ -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<FunTy *, 1> getKnownCallees() {
-    SmallVector<FunTy *, 1> 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<Constant>(Op))
-          Callees.push_back(cast<FunTy>(MDConstant));
-    }
-
-    return Callees;
-  }
-
 private:
   IterTy getCallee() const {
     return cast<CallBase>(getInstruction())->op_end() - 1;
index 54886d4..a0b3f83 100644 (file)
@@ -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))
index a7bb162..70aeb1a 100644 (file)
@@ -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<CallBase>(&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<CallGraphNode>(nullptr);
-  for (const MDOperand &Op : Callees->operands())
-    if (auto *MDConstant = mdconst::extract_or_null<Constant>(Op)) {
-      auto *F = cast<Function>(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 << "<<null function>><<" << I.second << ">>\n";
+      OS << "external node\n";
   }
   OS << '\n';
 }
index c832dc9..08d6e76 100644 (file)
@@ -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/llvm/test/Analysis/CallGraph/callees-metadata.ll b/llvm/test/Analysis/CallGraph/callees-metadata.ll
deleted file mode 100644 (file)
index fcc5042..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-; RUN: opt < %s -print-callgraph -disable-output 2>&1 | FileCheck %s
-
-; CHECK:      Call graph node <<null function>><<{{.+}}>> #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 <<null function>><<[[CALLEES:.+]]>>
-;
-; CHECK:      Call graph node for function: 'sub'<<{{.+}}>> #uses=2
-;
-; CHECK:      Call graph node <<null function>><<[[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}
index 4c5855f..5caecf7 100644 (file)
@@ -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 <<null function>>
+; CHECK-NEXT:  CS<[[addr_1:[^>]+]]> calls external node
 
 ; CHECK: Call graph node for function: 'calls_statepoint'
-; CHECK-NEXT:  CS<[[addr_0:[^>]+]]> calls <<null function>>
+; CHECK-NEXT:  CS<[[addr_0:[^>]+]]> calls external node
diff --git a/llvm/test/Analysis/LazyCallGraph/callees-metadata.ll b/llvm/test/Analysis/LazyCallGraph/callees-metadata.ll
deleted file mode 100644 (file)
index a550e22..0000000
+++ /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}