diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 92 | 
1 files changed, 37 insertions, 55 deletions
| diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 92671d1678c..0f2a5dff963 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -71,7 +71,9 @@ static const fltSemantics *EVTToAPFloatSemantics(EVT VT) {    }  } -SelectionDAG::DAGUpdateListener::~DAGUpdateListener() {} +// Default null implementations of the callbacks. +void SelectionDAG::DAGUpdateListener::NodeDeleted(SDNode*, SDNode*) {} +void SelectionDAG::DAGUpdateListener::NodeUpdated(SDNode*) {}  //===----------------------------------------------------------------------===//  //                              ConstantFPSDNode Class @@ -544,16 +546,15 @@ void SelectionDAG::RemoveDeadNodes() {  /// RemoveDeadNodes - This method deletes the unreachable nodes in the  /// given list, and any nodes that become unreachable as a result. -void SelectionDAG::RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes, -                                   DAGUpdateListener *UpdateListener) { +void SelectionDAG::RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes) {    // Process the worklist, deleting the nodes and adding their uses to the    // worklist.    while (!DeadNodes.empty()) {      SDNode *N = DeadNodes.pop_back_val(); -    if (UpdateListener) -      UpdateListener->NodeDeleted(N, 0); +    for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next) +      DUL->NodeDeleted(N, 0);      // Take the node out of the appropriate CSE map.      RemoveNodeFromCSEMaps(N); @@ -574,7 +575,7 @@ void SelectionDAG::RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes,    }  } -void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){ +void SelectionDAG::RemoveDeadNode(SDNode *N){    SmallVector<SDNode*, 16> DeadNodes(1, N);    // Create a dummy node that adds a reference to the root node, preventing @@ -582,7 +583,7 @@ void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){    // dead node.)    HandleSDNode Dummy(getRoot()); -  RemoveDeadNodes(DeadNodes, UpdateListener); +  RemoveDeadNodes(DeadNodes);  }  void SelectionDAG::DeleteNode(SDNode *N) { @@ -684,8 +685,7 @@ bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {  /// node. This transfer can potentially trigger recursive merging.  ///  void -SelectionDAG::AddModifiedNodeToCSEMaps(SDNode *N, -                                       DAGUpdateListener *UpdateListener) { +SelectionDAG::AddModifiedNodeToCSEMaps(SDNode *N) {    // For node types that aren't CSE'd, just act as if no identical node    // already exists.    if (!doNotCSE(N)) { @@ -694,20 +694,19 @@ SelectionDAG::AddModifiedNodeToCSEMaps(SDNode *N,        // If there was already an existing matching node, use ReplaceAllUsesWith        // to replace the dead one with the existing one.  This can cause        // recursive merging of other unrelated nodes down the line. -      ReplaceAllUsesWith(N, Existing, UpdateListener); +      ReplaceAllUsesWith(N, Existing); -      // N is now dead.  Inform the listener if it exists and delete it. -      if (UpdateListener) -        UpdateListener->NodeDeleted(N, Existing); +      // N is now dead. Inform the listeners and delete it. +      for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next) +        DUL->NodeDeleted(N, Existing);        DeleteNodeNotInCSEMaps(N);        return;      }    } -  // If the node doesn't already exist, we updated it.  Inform a listener if -  // it exists. -  if (UpdateListener) -    UpdateListener->NodeUpdated(N); +  // If the node doesn't already exist, we updated it.  Inform listeners. +  for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next) +    DUL->NodeUpdated(N);  }  /// FindModifiedNodeSlot - Find a slot for the specified node if its operands @@ -855,7 +854,7 @@ unsigned SelectionDAG::getEVTAlignment(EVT VT) const {  SelectionDAG::SelectionDAG(const TargetMachine &tm, CodeGenOpt::Level OL)    : TM(tm), TLI(*tm.getTargetLowering()), TSI(*tm.getSelectionDAGInfo()),      OptLevel(OL), EntryNode(ISD::EntryToken, DebugLoc(), getVTList(MVT::Other)), -    Root(getEntryNode()), Ordering(0) { +    Root(getEntryNode()), Ordering(0), UpdateListeners(0) {    AllNodes.push_back(&EntryNode);    Ordering = new SDNodeOrdering();    DbgInfo = new SDDbgInfo(); @@ -867,6 +866,7 @@ void SelectionDAG::init(MachineFunction &mf) {  }  SelectionDAG::~SelectionDAG() { +  assert(!UpdateListeners && "Dangling registered DAGUpdateListeners");    allnodes_clear();    delete Ordering;    delete DbgInfo; @@ -5237,11 +5237,7 @@ namespace {  /// pointed to by a use iterator is deleted, increment the use iterator  /// so that it doesn't dangle.  /// -/// This class also manages a "downlink" DAGUpdateListener, to forward -/// messages to ReplaceAllUsesWith's callers. -///  class RAUWUpdateListener : public SelectionDAG::DAGUpdateListener { -  SelectionDAG::DAGUpdateListener *DownLink;    SDNode::use_iterator &UI;    SDNode::use_iterator &UE; @@ -5249,21 +5245,13 @@ class RAUWUpdateListener : public SelectionDAG::DAGUpdateListener {      // Increment the iterator as needed.      while (UI != UE && N == *UI)        ++UI; - -    // Then forward the message. -    if (DownLink) DownLink->NodeDeleted(N, E); -  } - -  virtual void NodeUpdated(SDNode *N) { -    // Just forward the message. -    if (DownLink) DownLink->NodeUpdated(N);    }  public: -  RAUWUpdateListener(SelectionDAG::DAGUpdateListener *dl, +  RAUWUpdateListener(SelectionDAG &d,                       SDNode::use_iterator &ui,                       SDNode::use_iterator &ue) -    : DownLink(dl), UI(ui), UE(ue) {} +    : SelectionDAG::DAGUpdateListener(d), UI(ui), UE(ue) {}  };  } @@ -5273,8 +5261,7 @@ public:  ///  /// This version assumes From has a single result value.  /// -void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To, -                                      DAGUpdateListener *UpdateListener) { +void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To) {    SDNode *From = FromN.getNode();    assert(From->getNumValues() == 1 && FromN.getResNo() == 0 &&           "Cannot replace with this method!"); @@ -5288,7 +5275,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To,    // is replaced by To, we don't want to replace of all its users with To    // too. See PR3018 for more info.    SDNode::use_iterator UI = From->use_begin(), UE = From->use_end(); -  RAUWUpdateListener Listener(UpdateListener, UI, UE); +  RAUWUpdateListener Listener(*this, UI, UE);    while (UI != UE) {      SDNode *User = *UI; @@ -5307,7 +5294,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To,      // Now that we have modified User, add it back to the CSE maps.  If it      // already exists there, recursively merge the results together. -    AddModifiedNodeToCSEMaps(User, &Listener); +    AddModifiedNodeToCSEMaps(User);    }    // If we just RAUW'd the root, take note. @@ -5321,8 +5308,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To,  /// This version assumes that for each value of From, there is a  /// corresponding value in To in the same position with the same type.  /// -void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To, -                                      DAGUpdateListener *UpdateListener) { +void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To) {  #ifndef NDEBUG    for (unsigned i = 0, e = From->getNumValues(); i != e; ++i)      assert((!From->hasAnyUseOfValue(i) || @@ -5337,7 +5323,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To,    // Iterate over just the existing users of From. See the comments in    // the ReplaceAllUsesWith above.    SDNode::use_iterator UI = From->use_begin(), UE = From->use_end(); -  RAUWUpdateListener Listener(UpdateListener, UI, UE); +  RAUWUpdateListener Listener(*this, UI, UE);    while (UI != UE) {      SDNode *User = *UI; @@ -5356,7 +5342,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To,      // Now that we have modified User, add it back to the CSE maps.  If it      // already exists there, recursively merge the results together. -    AddModifiedNodeToCSEMaps(User, &Listener); +    AddModifiedNodeToCSEMaps(User);    }    // If we just RAUW'd the root, take note. @@ -5369,16 +5355,14 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To,  ///  /// This version can replace From with any result values.  To must match the  /// number and types of values returned by From. -void SelectionDAG::ReplaceAllUsesWith(SDNode *From, -                                      const SDValue *To, -                                      DAGUpdateListener *UpdateListener) { +void SelectionDAG::ReplaceAllUsesWith(SDNode *From, const SDValue *To) {    if (From->getNumValues() == 1)  // Handle the simple case efficiently. -    return ReplaceAllUsesWith(SDValue(From, 0), To[0], UpdateListener); +    return ReplaceAllUsesWith(SDValue(From, 0), To[0]);    // Iterate over just the existing users of From. See the comments in    // the ReplaceAllUsesWith above.    SDNode::use_iterator UI = From->use_begin(), UE = From->use_end(); -  RAUWUpdateListener Listener(UpdateListener, UI, UE); +  RAUWUpdateListener Listener(*this, UI, UE);    while (UI != UE) {      SDNode *User = *UI; @@ -5398,7 +5382,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From,      // Now that we have modified User, add it back to the CSE maps.  If it      // already exists there, recursively merge the results together. -    AddModifiedNodeToCSEMaps(User, &Listener); +    AddModifiedNodeToCSEMaps(User);    }    // If we just RAUW'd the root, take note. @@ -5409,14 +5393,13 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From,  /// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving  /// uses of other values produced by From.getNode() alone.  The Deleted  /// vector is handled the same way as for ReplaceAllUsesWith. -void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To, -                                             DAGUpdateListener *UpdateListener){ +void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To){    // Handle the really simple, really trivial case efficiently.    if (From == To) return;    // Handle the simple, trivial, case efficiently.    if (From.getNode()->getNumValues() == 1) { -    ReplaceAllUsesWith(From, To, UpdateListener); +    ReplaceAllUsesWith(From, To);      return;    } @@ -5424,7 +5407,7 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To,    // the ReplaceAllUsesWith above.    SDNode::use_iterator UI = From.getNode()->use_begin(),                         UE = From.getNode()->use_end(); -  RAUWUpdateListener Listener(UpdateListener, UI, UE); +  RAUWUpdateListener Listener(*this, UI, UE);    while (UI != UE) {      SDNode *User = *UI;      bool UserRemovedFromCSEMaps = false; @@ -5460,7 +5443,7 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To,      // Now that we have modified User, add it back to the CSE maps.  If it      // already exists there, recursively merge the results together. -    AddModifiedNodeToCSEMaps(User, &Listener); +    AddModifiedNodeToCSEMaps(User);    }    // If we just RAUW'd the root, take note. @@ -5489,11 +5472,10 @@ namespace {  /// handled the same way as for ReplaceAllUsesWith.  void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From,                                                const SDValue *To, -                                              unsigned Num, -                                              DAGUpdateListener *UpdateListener){ +                                              unsigned Num){    // Handle the simple, trivial case efficiently.    if (Num == 1) -    return ReplaceAllUsesOfValueWith(*From, *To, UpdateListener); +    return ReplaceAllUsesOfValueWith(*From, *To);    // Read up all the uses and make records of them. This helps    // processing new uses that are introduced during the @@ -5538,7 +5520,7 @@ void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From,      // Now that we have modified User, add it back to the CSE maps.  If it      // already exists there, recursively merge the results together. -    AddModifiedNodeToCSEMaps(User, UpdateListener); +    AddModifiedNodeToCSEMaps(User);    }  } | 

