[CallGraph] Given -print-callgraph a stable printing order.
authorSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 19 Jun 2015 23:20:31 +0000 (23:20 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 19 Jun 2015 23:20:31 +0000 (23:20 +0000)
Summary:
Since FunctionMap has llvm::Function pointers as keys, the order in
which the traversal happens can differ from run to run, causing spurious
FileCheck failures.  Have CallGraph::print sort the CallGraphNodes by
name before printing them.

Reviewers: bogner, chandlerc

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D10575

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240191 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/IPA/CallGraph.cpp
test/Analysis/CallGraph/non-leaf-intrinsics.ll

index 77c36033b47d42f61a841dbd969d8cb45dc2bdee..e2799d965a7dcd098056b14d0f360bb538fe34d8 100644 (file)
@@ -98,8 +98,26 @@ void CallGraph::print(raw_ostream &OS) const {
     OS << "<<null function: 0x" << Root << ">>\n";
   }
 
-  for (CallGraph::const_iterator I = begin(), E = end(); I != E; ++I)
-    I->second->print(OS);
+  // Print in a deterministic order by sorting CallGraphNodes by name.  We do
+  // this here to avoid slowing down the non-printing fast path.
+
+  SmallVector<CallGraphNode *, 16> Nodes;
+  Nodes.reserve(FunctionMap.size());
+
+  for (auto I = begin(), E = end(); I != E; ++I)
+    Nodes.push_back(I->second);
+
+  std::sort(Nodes.begin(), Nodes.end(),
+            [](CallGraphNode *LHS, CallGraphNode *RHS) {
+    if (Function *LF = LHS->getFunction())
+      if (Function *RF = RHS->getFunction())
+        return LF->getName() < RF->getName();
+
+    return RHS->getFunction() != nullptr;
+  });
+
+  for (CallGraphNode *CN : Nodes)
+    CN->print(OS);
 }
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
index ae6ba328e50f9c2b1741f6ef31a78027e08f6d28..11bed6abce601b90e65fc1328d27d03551d453a7 100644 (file)
@@ -25,8 +25,8 @@ entry:
 ; CHECK: Call graph node <<null function>>
 ; CHECK:  CS<0x0> calls function 'f'
 
-; CHECK: Call graph node for function: 'calls_statepoint'
-; CHECK-NEXT:  CS<[[addr_0:[^>]+]]> calls external node
-
 ; CHECK: Call graph node for function: 'calls_patchpoint'
 ; CHECK-NEXT:  CS<[[addr_1:[^>]+]]> calls external node
+
+; CHECK: Call graph node for function: 'calls_statepoint'
+; CHECK-NEXT:  CS<[[addr_0:[^>]+]]> calls external node