diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp
index 0f0f31e..11e1166 100644
--- a/llvm/lib/Analysis/LazyCallGraph.cpp
+++ b/llvm/lib/Analysis/LazyCallGraph.cpp
@@ -20,30 +20,36 @@
 
 #define DEBUG_TYPE "lcg"
 
-static void findCallees(
-    SmallVectorImpl<Constant *> &Worklist, SmallPtrSetImpl<Constant *> &Visited,
-    SmallVectorImpl<PointerUnion<Function *, LazyCallGraph::Node *>> &Callees,
-    DenseMap<Function *, size_t> &CalleeIndexMap) {
+static void addEdge(SmallVectorImpl<LazyCallGraph::Edge> &Edges,
+                    DenseMap<Function *, size_t> &EdgeIndexMap, Function &F,
+                    LazyCallGraph::Edge::Kind EK) {
+  // Note that we consider *any* function with a definition to be a viable
+  // edge. Even if the function's definition is subject to replacement by
+  // some other module (say, a weak definition) there may still be
+  // optimizations which essentially speculate based on the definition and
+  // a way to check that the specific definition is in fact the one being
+  // used. For example, this could be done by moving the weak definition to
+  // a strong (internal) definition and making the weak definition be an
+  // alias. Then a test of the address of the weak function against the new
+  // strong definition's address would be an effective way to determine the
+  // safety of optimizing a direct call edge.
+  if (!F.isDeclaration() &&
+      EdgeIndexMap.insert(std::make_pair(&F, Edges.size())).second) {
+    DEBUG(dbgs() << "    Added callable function: " << F.getName() << "\n");
+    Edges.emplace_back(LazyCallGraph::Edge(F, EK));
+  }
+}
+
+static void findReferences(
+                      SmallVectorImpl<Constant *> &Worklist,
+                      SmallPtrSetImpl<Constant *> &Visited,
+                      SmallVectorImpl<LazyCallGraph::Edge> &Edges,
+                      DenseMap<Function *, size_t> &EdgeIndexMap) {
   while (!Worklist.empty()) {
     Constant *C = Worklist.pop_back_val();
 
     if (Function *F = dyn_cast<Function>(C)) {
-      // Note that we consider *any* function with a definition to be a viable
-      // edge. Even if the function's definition is subject to replacement by
-      // some other module (say, a weak definition) there may still be
-      // optimizations which essentially speculate based on the definition and
-      // a way to check that the specific definition is in fact the one being
-      // used. For example, this could be done by moving the weak definition to
-      // a strong (internal) definition and making the weak definition be an
-      // alias. Then a test of the address of the weak function against the new
-      // strong definition's address would be an effective way to determine the
-      // safety of optimizing a direct call edge.
-      if (!F->isDeclaration() &&
-          CalleeIndexMap.insert(std::make_pair(F, Callees.size())).second) {
-        DEBUG(dbgs() << "    Added callable function: " << F->getName()
-                     << "\n");
-        Callees.push_back(F);
-      }
+      addEdge(Edges, EdgeIndexMap, *F, LazyCallGraph::Edge::Ref);
       continue;
     }
 
@@ -59,42 +65,55 @@
                << "' to the graph.\n");
 
   SmallVector<Constant *, 16> Worklist;
+  SmallPtrSet<Function *, 4> Callees;
   SmallPtrSet<Constant *, 16> Visited;
-  // Find all the potential callees in this function. First walk the
-  // instructions and add every operand which is a constant to the worklist.
+
+  // Find all the potential call graph edges in this function. We track both
+  // actual call edges and indirect references to functions. The direct calls
+  // are trivially added, but to accumulate the latter we walk the instructions
+  // and add every operand which is a constant to the worklist to process
+  // afterward.
   for (BasicBlock &BB : F)
-    for (Instruction &I : BB)
+    for (Instruction &I : BB) {
+      if (auto CS = CallSite(&I))
+        if (Function *Callee = CS.getCalledFunction())
+          if (Callees.insert(Callee).second) {
+            Visited.insert(Callee);
+            addEdge(Edges, EdgeIndexMap, *Callee, LazyCallGraph::Edge::Call);
+          }
+
       for (Value *Op : I.operand_values())
         if (Constant *C = dyn_cast<Constant>(Op))
           if (Visited.insert(C).second)
             Worklist.push_back(C);
+    }
 
   // We've collected all the constant (and thus potentially function or
   // function containing) operands to all of the instructions in the function.
   // Process them (recursively) collecting every function found.
-  findCallees(Worklist, Visited, Callees, CalleeIndexMap);
+  findReferences(Worklist, Visited, Edges, EdgeIndexMap);
 }
 
-void LazyCallGraph::Node::insertEdgeInternal(Function &Callee) {
-  if (Node *N = G->lookup(Callee))
-    return insertEdgeInternal(*N);
+void LazyCallGraph::Node::insertEdgeInternal(Function &Child, Edge::Kind EK) {
+  if (Node *N = G->lookup(Child))
+    return insertEdgeInternal(*N, EK);
 
-  CalleeIndexMap.insert(std::make_pair(&Callee, Callees.size()));
-  Callees.push_back(&Callee);
+  EdgeIndexMap.insert(std::make_pair(&Child, Edges.size()));
+  Edges.emplace_back(Child, EK);
 }
 
-void LazyCallGraph::Node::insertEdgeInternal(Node &CalleeN) {
-  CalleeIndexMap.insert(std::make_pair(&CalleeN.getFunction(), Callees.size()));
-  Callees.push_back(&CalleeN);
+void LazyCallGraph::Node::insertEdgeInternal(Node &ChildN, Edge::Kind EK) {
+  EdgeIndexMap.insert(std::make_pair(&ChildN.getFunction(), Edges.size()));
+  Edges.emplace_back(ChildN, EK);
 }
 
-void LazyCallGraph::Node::removeEdgeInternal(Function &Callee) {
-  auto IndexMapI = CalleeIndexMap.find(&Callee);
-  assert(IndexMapI != CalleeIndexMap.end() &&
-         "Callee not in the callee set for this caller?");
+void LazyCallGraph::Node::removeEdgeInternal(Function &Child) {
+  auto IndexMapI = EdgeIndexMap.find(&Child);
+  assert(IndexMapI != EdgeIndexMap.end() &&
+         "Child not in the edge set for this caller?");
 
-  Callees[IndexMapI->second] = nullptr;
-  CalleeIndexMap.erase(IndexMapI);
+  Edges[IndexMapI->second] = Edge();
+  EdgeIndexMap.erase(IndexMapI);
 }
 
 LazyCallGraph::LazyCallGraph(Module &M) : NextDFSNumber(0) {
@@ -102,10 +121,10 @@
                << "\n");
   for (Function &F : M)
     if (!F.isDeclaration() && !F.hasLocalLinkage())
-      if (EntryIndexMap.insert(std::make_pair(&F, EntryNodes.size())).second) {
+      if (EntryIndexMap.insert(std::make_pair(&F, EntryEdges.size())).second) {
         DEBUG(dbgs() << "  Adding '" << F.getName()
                      << "' to entry set of the graph.\n");
-        EntryNodes.push_back(&F);
+        EntryEdges.emplace_back(F, Edge::Ref);
       }
 
   // Now add entry nodes for functions reachable via initializers to globals.
@@ -118,21 +137,15 @@
 
   DEBUG(dbgs() << "  Adding functions referenced by global initializers to the "
                   "entry set.\n");
-  findCallees(Worklist, Visited, EntryNodes, EntryIndexMap);
+  findReferences(Worklist, Visited, EntryEdges, EntryIndexMap);
 
-  for (auto &Entry : EntryNodes) {
-    assert(!Entry.isNull() &&
-           "We can't have removed edges before we finish the constructor!");
-    if (Function *F = Entry.dyn_cast<Function *>())
-      SCCEntryNodes.push_back(F);
-    else
-      SCCEntryNodes.push_back(&Entry.get<Node *>()->getFunction());
-  }
+  for (const Edge &E : EntryEdges)
+    SCCEntryNodes.push_back(&E.getFunction());
 }
 
 LazyCallGraph::LazyCallGraph(LazyCallGraph &&G)
     : BPA(std::move(G.BPA)), NodeMap(std::move(G.NodeMap)),
-      EntryNodes(std::move(G.EntryNodes)),
+      EntryEdges(std::move(G.EntryEdges)),
       EntryIndexMap(std::move(G.EntryIndexMap)), SCCBPA(std::move(G.SCCBPA)),
       SCCMap(std::move(G.SCCMap)), LeafSCCs(std::move(G.LeafSCCs)),
       DFSStack(std::move(G.DFSStack)),
@@ -144,7 +157,7 @@
 LazyCallGraph &LazyCallGraph::operator=(LazyCallGraph &&G) {
   BPA = std::move(G.BPA);
   NodeMap = std::move(G.NodeMap);
-  EntryNodes = std::move(G.EntryNodes);
+  EntryEdges = std::move(G.EntryEdges);
   EntryIndexMap = std::move(G.EntryIndexMap);
   SCCBPA = std::move(G.SCCBPA);
   SCCMap = std::move(G.SCCMap);
@@ -177,43 +190,46 @@
   return false;
 }
 
-void LazyCallGraph::SCC::insertIntraSCCEdge(Node &CallerN, Node &CalleeN) {
+void LazyCallGraph::SCC::insertIntraSCCEdge(Node &ParentN, Node &ChildN,
+                                            Edge::Kind EK) {
   // First insert it into the caller.
-  CallerN.insertEdgeInternal(CalleeN);
+  ParentN.insertEdgeInternal(ChildN, EK);
 
-  assert(G->SCCMap.lookup(&CallerN) == this && "Caller must be in this SCC.");
-  assert(G->SCCMap.lookup(&CalleeN) == this && "Callee must be in this SCC.");
+  assert(G->SCCMap.lookup(&ParentN) == this && "Parent must be in this SCC.");
+  assert(G->SCCMap.lookup(&ChildN) == this && "Child must be in this SCC.");
 
   // Nothing changes about this SCC or any other.
 }
 
-void LazyCallGraph::SCC::insertOutgoingEdge(Node &CallerN, Node &CalleeN) {
+void LazyCallGraph::SCC::insertOutgoingEdge(Node &ParentN, Node &ChildN,
+                                            Edge::Kind EK) {
   // First insert it into the caller.
-  CallerN.insertEdgeInternal(CalleeN);
+  ParentN.insertEdgeInternal(ChildN, EK);
 
-  assert(G->SCCMap.lookup(&CallerN) == this && "Caller must be in this SCC.");
+  assert(G->SCCMap.lookup(&ParentN) == this && "Parent must be in this SCC.");
 
-  SCC &CalleeC = *G->SCCMap.lookup(&CalleeN);
-  assert(&CalleeC != this && "Callee must not be in this SCC.");
-  assert(CalleeC.isDescendantOf(*this) &&
-         "Callee must be a descendant of the Caller.");
+  SCC &ChildC = *G->SCCMap.lookup(&ChildN);
+  assert(&ChildC != this && "Child must not be in this SCC.");
+  assert(ChildC.isDescendantOf(*this) &&
+         "Child must be a descendant of the Parent.");
 
   // The only change required is to add this SCC to the parent set of the
   // callee.
-  CalleeC.ParentSCCs.insert(this);
+  ChildC.ParentSCCs.insert(this);
 }
 
 SmallVector<LazyCallGraph::SCC *, 1>
-LazyCallGraph::SCC::insertIncomingEdge(Node &CallerN, Node &CalleeN) {
+LazyCallGraph::SCC::insertIncomingEdge(Node &ParentN, Node &ChildN,
+                                       Edge::Kind EK) {
   // First insert it into the caller.
-  CallerN.insertEdgeInternal(CalleeN);
+  ParentN.insertEdgeInternal(ChildN, EK);
 
-  assert(G->SCCMap.lookup(&CalleeN) == this && "Callee must be in this SCC.");
+  assert(G->SCCMap.lookup(&ChildN) == this && "Child must be in this SCC.");
 
-  SCC &CallerC = *G->SCCMap.lookup(&CallerN);
-  assert(&CallerC != this && "Caller must not be in this SCC.");
-  assert(CallerC.isDescendantOf(*this) &&
-         "Caller must be a descendant of the Callee.");
+  SCC &ParentC = *G->SCCMap.lookup(&ParentN);
+  assert(&ParentC != this && "Parent must not be in this SCC.");
+  assert(ParentC.isDescendantOf(*this) &&
+         "Parent must be a descendant of the Child.");
 
   // The algorithm we use for merging SCCs based on the cycle introduced here
   // is to walk the SCC inverted DAG formed by the parent SCC sets. The inverse
@@ -231,7 +247,7 @@
   // participate in the merged connected component.
   SmallPtrSet<SCC *, 8> ConnectedSCCs;
   ConnectedSCCs.insert(this);
-  ConnectedSCCs.insert(&CallerC);
+  ConnectedSCCs.insert(&ParentC);
 
   // We build up a DFS stack of the parents chains.
   SmallVector<std::pair<SCC *, SCC::parent_iterator>, 8> DFSSCCs;
@@ -298,8 +314,9 @@
     C->ParentSCCs.clear();
 
     for (Node *N : *C) {
-      for (Node &ChildN : *N) {
-        SCC &ChildC = *G->SCCMap.lookup(&ChildN);
+      for (Edge &E : *N) {
+        assert(E.getNode() && "Cannot have a null node within a visited SCC!");
+        SCC &ChildC = *G->SCCMap.lookup(E.getNode());
         if (&ChildC != C)
           ChildC.ParentSCCs.erase(C);
       }
@@ -309,8 +326,9 @@
     C->Nodes.clear();
   }
   for (auto I = Nodes.begin() + NewNodeBeginIdx, E = Nodes.end(); I != E; ++I)
-    for (Node &ChildN : **I) {
-      SCC &ChildC = *G->SCCMap.lookup(&ChildN);
+    for (Edge &E : **I) {
+      assert(E.getNode() && "Cannot have a null node within a visited SCC!");
+      SCC &ChildC = *G->SCCMap.lookup(E.getNode());
       if (&ChildC != this)
         ChildC.ParentSCCs.insert(this);
     }
@@ -322,64 +340,65 @@
   return SmallVector<SCC *, 1>(ConnectedSCCs.begin(), ConnectedSCCs.end());
 }
 
-void LazyCallGraph::SCC::removeInterSCCEdge(Node &CallerN, Node &CalleeN) {
+void LazyCallGraph::SCC::removeInterSCCEdge(Node &ParentN, Node &ChildN) {
   // First remove it from the node.
-  CallerN.removeEdgeInternal(CalleeN.getFunction());
+  ParentN.removeEdgeInternal(ChildN.getFunction());
 
-  assert(G->SCCMap.lookup(&CallerN) == this &&
+  assert(G->SCCMap.lookup(&ParentN) == this &&
          "The caller must be a member of this SCC.");
 
-  SCC &CalleeC = *G->SCCMap.lookup(&CalleeN);
-  assert(&CalleeC != this &&
+  SCC &ChildC = *G->SCCMap.lookup(&ChildN);
+  assert(&ChildC != this &&
          "This API only supports the rmoval of inter-SCC edges.");
 
   assert(std::find(G->LeafSCCs.begin(), G->LeafSCCs.end(), this) ==
              G->LeafSCCs.end() &&
          "Cannot have a leaf SCC caller with a different SCC callee.");
 
-  bool HasOtherCallToCalleeC = false;
-  bool HasOtherCallOutsideSCC = false;
+  bool HasOtherEdgeToChildC = false;
+  bool HasOtherChildC = false;
   for (Node *N : *this) {
-    for (Node &OtherCalleeN : *N) {
-      SCC &OtherCalleeC = *G->SCCMap.lookup(&OtherCalleeN);
-      if (&OtherCalleeC == &CalleeC) {
-        HasOtherCallToCalleeC = true;
+    for (Edge &E : *N) {
+      assert(E.getNode() && "Cannot have a missing node in a visited SCC!");
+      SCC &OtherChildC = *G->SCCMap.lookup(E.getNode());
+      if (&OtherChildC == &ChildC) {
+        HasOtherEdgeToChildC = true;
         break;
       }
-      if (&OtherCalleeC != this)
-        HasOtherCallOutsideSCC = true;
+      if (&OtherChildC != this)
+        HasOtherChildC = true;
     }
-    if (HasOtherCallToCalleeC)
+    if (HasOtherEdgeToChildC)
       break;
   }
   // Because the SCCs form a DAG, deleting such an edge cannot change the set
   // of SCCs in the graph. However, it may cut an edge of the SCC DAG, making
-  // the caller no longer a parent of the callee. Walk the other call edges
-  // in the caller to tell.
-  if (!HasOtherCallToCalleeC) {
-    bool Removed = CalleeC.ParentSCCs.erase(this);
+  // the parent SCC no longer connected to the child SCC. If so, we need to
+  // update the child SCC's map of its parents.
+  if (!HasOtherEdgeToChildC) {
+    bool Removed = ChildC.ParentSCCs.erase(this);
     (void)Removed;
     assert(Removed &&
-           "Did not find the caller SCC in the callee SCC's parent list!");
+           "Did not find the parent SCC in the child SCC's parent list!");
 
     // It may orphan an SCC if it is the last edge reaching it, but that does
     // not violate any invariants of the graph.
-    if (CalleeC.ParentSCCs.empty())
-      DEBUG(dbgs() << "LCG: Update removing " << CallerN.getFunction().getName()
-                   << " -> " << CalleeN.getFunction().getName()
+    if (ChildC.ParentSCCs.empty())
+      DEBUG(dbgs() << "LCG: Update removing " << ParentN.getFunction().getName()
+                   << " -> " << ChildN.getFunction().getName()
                    << " edge orphaned the callee's SCC!\n");
   }
 
-  // It may make the Caller SCC a leaf SCC.
-  if (!HasOtherCallOutsideSCC)
+  // It may make the Parent SCC a leaf SCC.
+  if (!HasOtherChildC)
     G->LeafSCCs.push_back(this);
 }
 
 void LazyCallGraph::SCC::internalDFS(
-    SmallVectorImpl<std::pair<Node *, Node::iterator>> &DFSStack,
+    SmallVectorImpl<std::pair<Node *, Node::edge_iterator>> &DFSStack,
     SmallVectorImpl<Node *> &PendingSCCStack, Node *N,
     SmallVectorImpl<SCC *> &ResultSCCs) {
-  Node::iterator I = N->begin();
+  auto I = N->begin();
   N->LowLink = N->DFSNumber = 1;
   int NextDFSNumber = 2;
   for (;;) {
@@ -387,9 +406,9 @@
                                 "before processing a node.");
 
     // We simulate recursion by popping out of the nested loop and continuing.
-    Node::iterator E = N->end();
+    auto E = N->end();
     while (I != E) {
-      Node &ChildN = *I;
+      Node &ChildN = I->getNode(*G);
       if (SCC *ChildSCC = G->SCCMap.lookup(&ChildN)) {
         // Check if we have reached a node in the new (known connected) set of
         // this SCC. If so, the entire stack is necessarily in that set and we
@@ -455,15 +474,15 @@
 }
 
 SmallVector<LazyCallGraph::SCC *, 1>
-LazyCallGraph::SCC::removeIntraSCCEdge(Node &CallerN, Node &CalleeN) {
+LazyCallGraph::SCC::removeIntraSCCEdge(Node &ParentN, Node &ChildN) {
   // First remove it from the node.
-  CallerN.removeEdgeInternal(CalleeN.getFunction());
+  ParentN.removeEdgeInternal(ChildN.getFunction());
 
   // We return a list of the resulting *new* SCCs in postorder.
   SmallVector<SCC *, 1> ResultSCCs;
 
   // Direct recursion doesn't impact the SCC graph at all.
-  if (&CallerN == &CalleeN)
+  if (&ParentN == &ChildN)
     return ResultSCCs;
 
   // The worklist is every node in the original SCC.
@@ -478,16 +497,16 @@
   assert(Worklist.size() > 1 && "We have to have at least two nodes to have an "
                                 "edge between them that is within the SCC.");
 
-  // The callee can already reach every node in this SCC (by definition). It is
+  // The child can already reach every node in this SCC (by definition). It is
   // the only node we know will stay inside this SCC. Everything which
-  // transitively reaches Callee will also remain in the SCC. To model this we
+  // transitively reaches Child will also remain in the SCC. To model this we
   // incrementally add any chain of nodes which reaches something in the new
   // node set to the new node set. This short circuits one side of the Tarjan's
   // walk.
-  insert(CalleeN);
+  insert(ChildN);
 
   // We're going to do a full mini-Tarjan's walk using a local stack here.
-  SmallVector<std::pair<Node *, Node::iterator>, 4> DFSStack;
+  SmallVector<std::pair<Node *, Node::edge_iterator>, 4> DFSStack;
   SmallVector<Node *, 4> PendingSCCStack;
   do {
     Node *N = Worklist.pop_back_val();
@@ -501,8 +520,9 @@
   // Now we need to reconnect the current SCC to the graph.
   bool IsLeafSCC = true;
   for (Node *N : Nodes) {
-    for (Node &ChildN : *N) {
-      SCC &ChildSCC = *G->SCCMap.lookup(&ChildN);
+    for (Edge &E : *N) {
+      assert(E.getNode() && "Cannot have a missing node in a visited SCC!");
+      SCC &ChildSCC = *G->SCCMap.lookup(E.getNode());
       if (&ChildSCC == this)
         continue;
       ChildSCC.ParentSCCs.insert(this);
@@ -528,18 +548,18 @@
   return ResultSCCs;
 }
 
-void LazyCallGraph::insertEdge(Node &CallerN, Function &Callee) {
+void LazyCallGraph::insertEdge(Node &ParentN, Function &Child, Edge::Kind EK) {
   assert(SCCMap.empty() && DFSStack.empty() &&
          "This method cannot be called after SCCs have been formed!");
 
-  return CallerN.insertEdgeInternal(Callee);
+  return ParentN.insertEdgeInternal(Child, EK);
 }
 
-void LazyCallGraph::removeEdge(Node &CallerN, Function &Callee) {
+void LazyCallGraph::removeEdge(Node &ParentN, Function &Child) {
   assert(SCCMap.empty() && DFSStack.empty() &&
          "This method cannot be called after SCCs have been formed!");
 
-  return CallerN.removeEdgeInternal(Callee);
+  return ParentN.removeEdgeInternal(Child);
 }
 
 LazyCallGraph::Node &LazyCallGraph::insertInto(Function &F, Node *&MappedN) {
@@ -550,17 +570,16 @@
   // Process all nodes updating the graph pointers.
   {
     SmallVector<Node *, 16> Worklist;
-    for (auto &Entry : EntryNodes)
-      if (Node *EntryN = Entry.dyn_cast<Node *>())
+    for (Edge &E : EntryEdges)
+      if (Node *EntryN = E.getNode())
         Worklist.push_back(EntryN);
 
     while (!Worklist.empty()) {
       Node *N = Worklist.pop_back_val();
       N->G = this;
-      for (auto &Callee : N->Callees)
-        if (!Callee.isNull())
-          if (Node *CalleeN = Callee.dyn_cast<Node *>())
-            Worklist.push_back(CalleeN);
+      for (Edge &E : N->Edges)
+        if (Node *ChildN = E.getNode())
+          Worklist.push_back(ChildN);
     }
   }
 
@@ -596,8 +615,9 @@
   // its children.
   bool IsLeafSCC = true;
   for (Node *SCCN : NewSCC->Nodes)
-    for (Node &SCCChildN : *SCCN) {
-      SCC &ChildSCC = *SCCMap.lookup(&SCCChildN);
+    for (Edge &E : *SCCN) {
+      assert(E.getNode() && "Cannot have a missing node in a visited SCC!");
+      SCC &ChildSCC = *SCCMap.lookup(E.getNode());
       if (&ChildSCC == NewSCC)
         continue;
       ChildSCC.ParentSCCs.insert(NewSCC);
@@ -613,7 +633,7 @@
 
 LazyCallGraph::SCC *LazyCallGraph::getNextSCCInPostOrder() {
   Node *N;
-  Node::iterator I;
+  Node::edge_iterator I;
   if (!DFSStack.empty()) {
     N = DFSStack.back().first;
     I = DFSStack.back().second;
@@ -635,9 +655,9 @@
     assert(N->DFSNumber != 0 && "We should always assign a DFS number "
                                 "before placing a node onto the stack.");
 
-    Node::iterator E = N->end();
+    auto E = N->end();
     while (I != E) {
-      Node &ChildN = *I;
+      Node &ChildN = I->getNode(*this);
       if (ChildN.DFSNumber == 0) {
         // Mark that we should start at this child when next this node is the
         // top of the stack. We don't start at the next child to ensure this
@@ -686,14 +706,19 @@
 
 static void printNodes(raw_ostream &OS, LazyCallGraph::Node &N,
                        SmallPtrSetImpl<LazyCallGraph::Node *> &Printed) {
+  LazyCallGraph &G = N.getGraph();
+
   // Recurse depth first through the nodes.
-  for (LazyCallGraph::Node &ChildN : N)
+  for (LazyCallGraph::Edge &E : N) {
+    LazyCallGraph::Node &ChildN = E.getNode(G);
     if (Printed.insert(&ChildN).second)
       printNodes(OS, ChildN, Printed);
+  }
 
-  OS << "  Call edges in function: " << N.getFunction().getName() << "\n";
-  for (LazyCallGraph::iterator I = N.begin(), E = N.end(); I != E; ++I)
-    OS << "    -> " << I->getFunction().getName() << "\n";
+  OS << "  Edges in function: " << N.getFunction().getName() << "\n";
+  for (const LazyCallGraph::Edge &E : N)
+    OS << "    " << (E.isCall() ? "call" : "ref ") << " -> "
+       << E.getFunction().getName() << "\n";
 
   OS << "\n";
 }
@@ -716,9 +741,11 @@
      << "\n\n";
 
   SmallPtrSet<LazyCallGraph::Node *, 16> Printed;
-  for (LazyCallGraph::Node &N : G)
+  for (LazyCallGraph::Edge &E : G) {
+    LazyCallGraph::Node &N = E.getNode(G);
     if (Printed.insert(&N).second)
       printNodes(OS, N, Printed);
+  }
 
   for (LazyCallGraph::SCC &SCC : G.postorder_sccs())
     printSCC(OS, SCC);
