[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Chris Lattner sabre at nondot.org
Fri Nov 10 16:39:57 PST 2006



Changes in directory llvm/lib/CodeGen/SelectionDAG:

DAGCombiner.cpp updated: 1.249 -> 1.250
---
Log message:

move big chunks of code out-of-line, no functionality change.



---
Diffs of the changes:  (+241 -235)

 DAGCombiner.cpp |  476 ++++++++++++++++++++++++++++----------------------------
 1 files changed, 241 insertions(+), 235 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.249 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.250
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.249	Fri Nov 10 15:37:15 2006
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp	Fri Nov 10 18:39:41 2006
@@ -178,241 +178,10 @@
       return true;
     }
 
-    /// CombineToPreIndexedLoadStore - Try turning a load / store and a
-    /// pre-indexed load / store when the base pointer is a add or subtract
-    /// and it has other uses besides the load / store. After the
-    /// transformation, the new indexed load / store has effectively folded
-    /// the add / subtract in and all of its other uses are redirected to the
-    /// new load / store.
-    bool CombineToPreIndexedLoadStore(SDNode *N) {
-      if (!AfterLegalize)
-        return false;
-
-      bool isLoad = true;
-      SDOperand Ptr;
-      MVT::ValueType VT;
-      if (LoadSDNode *LD  = dyn_cast<LoadSDNode>(N)) {
-        VT = LD->getLoadedVT();
-        if (!TLI.isIndexedLoadLegal(ISD::PRE_INC, VT) &&
-            !TLI.isIndexedLoadLegal(ISD::PRE_DEC, VT))
-          return false;
-        Ptr = LD->getBasePtr();
-      } else if (StoreSDNode *ST  = dyn_cast<StoreSDNode>(N)) {
-        VT = ST->getStoredVT();
-        if (!TLI.isIndexedStoreLegal(ISD::PRE_INC, VT) &&
-            !TLI.isIndexedStoreLegal(ISD::PRE_DEC, VT))
-          return false;
-        Ptr = ST->getBasePtr();
-        isLoad = false;
-      } else
-        return false;
-
-      if ((Ptr.getOpcode() == ISD::ADD || Ptr.getOpcode() == ISD::SUB) &&
-          Ptr.Val->use_size() > 1) {
-        SDOperand BasePtr;
-        SDOperand Offset;
-        ISD::MemIndexedMode AM = ISD::UNINDEXED;
-        if (TLI.getPreIndexedAddressParts(N, BasePtr, Offset, AM, DAG)) {
-          // Try turning it into a pre-indexed load / store except when
-          // 1) If N is a store and the ptr is either the same as or is a
-          //    predecessor of the value being stored.
-          // 2) Another use of base ptr is a predecessor of N. If ptr is folded
-          //    that would create a cycle.
-          // 3) All uses are load / store ops that use it as base ptr.
-
-          // Checking #1.
-          if (!isLoad) {
-            SDOperand Val = cast<StoreSDNode>(N)->getValue();
-            if (Val == Ptr || Ptr.Val->isPredecessor(Val.Val))
-              return false;
-          }
-
-          // Now check for #2 and #3.
-          bool RealUse = false;
-          for (SDNode::use_iterator I = Ptr.Val->use_begin(),
-                 E = Ptr.Val->use_end(); I != E; ++I) {
-            SDNode *Use = *I;
-            if (Use == N)
-              continue;
-            if (Use->isPredecessor(N))
-              return false;
-
-            if (!((Use->getOpcode() == ISD::LOAD &&
-                   cast<LoadSDNode>(Use)->getBasePtr() == Ptr) ||
-                  (Use->getOpcode() == ISD::STORE) &&
-                  cast<StoreSDNode>(Use)->getBasePtr() == Ptr))
-              RealUse = true;
-          }
-          if (!RealUse)
-            return false;
-
-          SDOperand Result = isLoad
-            ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
-            : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
-          ++PreIndexedNodes;
-          ++NodesCombined;
-          DEBUG(std::cerr << "\nReplacing.4 "; N->dump();
-                std::cerr << "\nWith: "; Result.Val->dump(&DAG);
-                std::cerr << '\n');
-          std::vector<SDNode*> NowDead;
-          if (isLoad) {
-            DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
-                                          NowDead);
-            DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
-                                          NowDead);
-          } else {
-            DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
-                                          NowDead);
-          }
-
-          // Nodes can end up on the worklist more than once.  Make sure we do
-          // not process a node that has been replaced.
-          for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
-            removeFromWorkList(NowDead[i]);
-          // Finally, since the node is now dead, remove it from the graph.
-          DAG.DeleteNode(N);
-
-          // Replace the uses of Ptr with uses of the updated base value.
-          DAG.ReplaceAllUsesOfValueWith(Ptr, Result.getValue(isLoad ? 1 : 0),
-                                        NowDead);
-          removeFromWorkList(Ptr.Val);
-          for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
-            removeFromWorkList(NowDead[i]);
-          DAG.DeleteNode(Ptr.Val);
-
-          return true;
-        }
-      }
-      return false;
-    }
-
-    /// CombineToPostIndexedLoadStore - Try combine a load / store with a
-    /// add / sub of the base pointer node into a post-indexed load / store.
-    /// The transformation folded the add / subtract into the new indexed
-    /// load / store effectively and all of its uses are redirected to the
-    /// new load / store.
-    bool CombineToPostIndexedLoadStore(SDNode *N) {
-      if (!AfterLegalize)
-        return false;
-
-      bool isLoad = true;
-      SDOperand Ptr;
-      MVT::ValueType VT;
-      if (LoadSDNode *LD  = dyn_cast<LoadSDNode>(N)) {
-        VT = LD->getLoadedVT();
-        if (!TLI.isIndexedLoadLegal(ISD::POST_INC, VT) &&
-            !TLI.isIndexedLoadLegal(ISD::POST_DEC, VT))
-          return false;
-        Ptr = LD->getBasePtr();
-      } else if (StoreSDNode *ST  = dyn_cast<StoreSDNode>(N)) {
-        VT = ST->getStoredVT();
-        if (!TLI.isIndexedStoreLegal(ISD::POST_INC, VT) &&
-            !TLI.isIndexedStoreLegal(ISD::POST_DEC, VT))
-          return false;
-        Ptr = ST->getBasePtr();
-        isLoad = false;
-      } else
-        return false;
-
-      if (Ptr.Val->use_size() > 1) {
-        for (SDNode::use_iterator I = Ptr.Val->use_begin(),
-               E = Ptr.Val->use_end(); I != E; ++I) {
-          SDNode *Op = *I;
-          if (Op == N ||
-              (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB))
-            continue;
-
-          SDOperand BasePtr;
-          SDOperand Offset;
-          ISD::MemIndexedMode AM = ISD::UNINDEXED;
-          if (TLI.getPostIndexedAddressParts(N, Op, BasePtr, Offset, AM, DAG)) {
-            if (Ptr == Offset)
-              std::swap(BasePtr, Offset);
-            if (Ptr != BasePtr)
-              continue;
-
-            // Try turning it into a post-indexed load / store except when
-            // 1) All uses are load / store ops that use it as base ptr.
-            // 2) Op must be independent of N, i.e. Op is neither a predecessor
-            //    nor a successor of N. Otherwise, if Op is folded that would
-            //    create a cycle.
-
-            // Check for #1.
-            bool TryNext = false;
-            for (SDNode::use_iterator II = BasePtr.Val->use_begin(),
-                   EE = BasePtr.Val->use_end(); II != EE; ++II) {
-              SDNode *Use = *II;
-              if (Use == Ptr.Val)
-                continue;
-
-              // If all the uses are load / store addresses, then don't do the
-              // transformation.
-              if (Use->getOpcode() == ISD::ADD || Use->getOpcode() == ISD::SUB){
-                bool RealUse = false;
-                for (SDNode::use_iterator III = Use->use_begin(),
-                       EEE = Use->use_end(); III != EEE; ++III) {
-                  SDNode *UseUse = *III;
-                  if (!((UseUse->getOpcode() == ISD::LOAD &&
-                         cast<LoadSDNode>(UseUse)->getBasePtr().Val == Use) ||
-                        (UseUse->getOpcode() == ISD::STORE) &&
-                        cast<StoreSDNode>(UseUse)->getBasePtr().Val == Use))
-                    RealUse = true;
-                }
-
-                if (!RealUse) {
-                  TryNext = true;
-                  break;
-                }
-              }
-            }
-            if (TryNext)
-              continue;
-
-            // Check for #2
-            if (!Op->isPredecessor(N) && !N->isPredecessor(Op)) {
-              SDOperand Result = isLoad
-                ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
-                : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
-              ++PostIndexedNodes;
-              ++NodesCombined;
-              DEBUG(std::cerr << "\nReplacing.5 "; N->dump();
-                    std::cerr << "\nWith: "; Result.Val->dump(&DAG);
-                    std::cerr << '\n');
-              std::vector<SDNode*> NowDead;
-              if (isLoad) {
-                DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
-                                              NowDead);
-                DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
-                                              NowDead);
-              } else {
-                DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
-                                              NowDead);
-              }
-
-              // Nodes can end up on the worklist more than once.  Make sure we do
-              // not process a node that has been replaced.
-              for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
-                removeFromWorkList(NowDead[i]);
-              // Finally, since the node is now dead, remove it from the graph.
-              DAG.DeleteNode(N);
-
-              // Replace the uses of Use with uses of the updated base value.
-              DAG.ReplaceAllUsesOfValueWith(SDOperand(Op, 0),
-                                            Result.getValue(isLoad ? 1 : 0),
-                                            NowDead);
-              removeFromWorkList(Op);
-              for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
-                removeFromWorkList(NowDead[i]);
-              DAG.DeleteNode(Op);
-
-              return true;
-            }
-          }
-        }
-      }
-      return false;
-    }
-
+    bool CombineToPreIndexedLoadStore(SDNode *N);
+    bool CombineToPostIndexedLoadStore(SDNode *N);
+    
+    
     /// visit - call the node-specific routine that knows how to fold each
     /// particular type of node.
     SDOperand visit(SDNode *N);
@@ -2938,6 +2707,243 @@
   return SDOperand();
 }
 
+
+/// CombineToPreIndexedLoadStore - Try turning a load / store and a
+/// pre-indexed load / store when the base pointer is a add or subtract
+/// and it has other uses besides the load / store. After the
+/// transformation, the new indexed load / store has effectively folded
+/// the add / subtract in and all of its other uses are redirected to the
+/// new load / store.
+bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
+  if (!AfterLegalize)
+    return false;
+
+  bool isLoad = true;
+  SDOperand Ptr;
+  MVT::ValueType VT;
+  if (LoadSDNode *LD  = dyn_cast<LoadSDNode>(N)) {
+    VT = LD->getLoadedVT();
+    if (!TLI.isIndexedLoadLegal(ISD::PRE_INC, VT) &&
+        !TLI.isIndexedLoadLegal(ISD::PRE_DEC, VT))
+      return false;
+    Ptr = LD->getBasePtr();
+  } else if (StoreSDNode *ST  = dyn_cast<StoreSDNode>(N)) {
+    VT = ST->getStoredVT();
+    if (!TLI.isIndexedStoreLegal(ISD::PRE_INC, VT) &&
+        !TLI.isIndexedStoreLegal(ISD::PRE_DEC, VT))
+      return false;
+    Ptr = ST->getBasePtr();
+    isLoad = false;
+  } else
+    return false;
+
+  if ((Ptr.getOpcode() == ISD::ADD || Ptr.getOpcode() == ISD::SUB) &&
+      Ptr.Val->use_size() > 1) {
+    SDOperand BasePtr;
+    SDOperand Offset;
+    ISD::MemIndexedMode AM = ISD::UNINDEXED;
+    if (TLI.getPreIndexedAddressParts(N, BasePtr, Offset, AM, DAG)) {
+      // Try turning it into a pre-indexed load / store except when
+      // 1) If N is a store and the ptr is either the same as or is a
+      //    predecessor of the value being stored.
+      // 2) Another use of base ptr is a predecessor of N. If ptr is folded
+      //    that would create a cycle.
+      // 3) All uses are load / store ops that use it as base ptr.
+
+      // Checking #1.
+      if (!isLoad) {
+        SDOperand Val = cast<StoreSDNode>(N)->getValue();
+        if (Val == Ptr || Ptr.Val->isPredecessor(Val.Val))
+          return false;
+      }
+
+      // Now check for #2 and #3.
+      bool RealUse = false;
+      for (SDNode::use_iterator I = Ptr.Val->use_begin(),
+             E = Ptr.Val->use_end(); I != E; ++I) {
+        SDNode *Use = *I;
+        if (Use == N)
+          continue;
+        if (Use->isPredecessor(N))
+          return false;
+
+        if (!((Use->getOpcode() == ISD::LOAD &&
+               cast<LoadSDNode>(Use)->getBasePtr() == Ptr) ||
+              (Use->getOpcode() == ISD::STORE) &&
+              cast<StoreSDNode>(Use)->getBasePtr() == Ptr))
+          RealUse = true;
+      }
+      if (!RealUse)
+        return false;
+
+      SDOperand Result = isLoad
+        ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
+        : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
+      ++PreIndexedNodes;
+      ++NodesCombined;
+      DEBUG(std::cerr << "\nReplacing.4 "; N->dump();
+            std::cerr << "\nWith: "; Result.Val->dump(&DAG);
+            std::cerr << '\n');
+      std::vector<SDNode*> NowDead;
+      if (isLoad) {
+        DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
+                                      NowDead);
+        DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
+                                      NowDead);
+      } else {
+        DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
+                                      NowDead);
+      }
+
+      // Nodes can end up on the worklist more than once.  Make sure we do
+      // not process a node that has been replaced.
+      for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+        removeFromWorkList(NowDead[i]);
+      // Finally, since the node is now dead, remove it from the graph.
+      DAG.DeleteNode(N);
+
+      // Replace the uses of Ptr with uses of the updated base value.
+      DAG.ReplaceAllUsesOfValueWith(Ptr, Result.getValue(isLoad ? 1 : 0),
+                                    NowDead);
+      removeFromWorkList(Ptr.Val);
+      for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+        removeFromWorkList(NowDead[i]);
+      DAG.DeleteNode(Ptr.Val);
+
+      return true;
+    }
+  }
+  return false;
+}
+
+/// CombineToPostIndexedLoadStore - Try combine a load / store with a
+/// add / sub of the base pointer node into a post-indexed load / store.
+/// The transformation folded the add / subtract into the new indexed
+/// load / store effectively and all of its uses are redirected to the
+/// new load / store.
+bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
+  if (!AfterLegalize)
+    return false;
+
+  bool isLoad = true;
+  SDOperand Ptr;
+  MVT::ValueType VT;
+  if (LoadSDNode *LD  = dyn_cast<LoadSDNode>(N)) {
+    VT = LD->getLoadedVT();
+    if (!TLI.isIndexedLoadLegal(ISD::POST_INC, VT) &&
+        !TLI.isIndexedLoadLegal(ISD::POST_DEC, VT))
+      return false;
+    Ptr = LD->getBasePtr();
+  } else if (StoreSDNode *ST  = dyn_cast<StoreSDNode>(N)) {
+    VT = ST->getStoredVT();
+    if (!TLI.isIndexedStoreLegal(ISD::POST_INC, VT) &&
+        !TLI.isIndexedStoreLegal(ISD::POST_DEC, VT))
+      return false;
+    Ptr = ST->getBasePtr();
+    isLoad = false;
+  } else
+    return false;
+
+  if (Ptr.Val->use_size() > 1) {
+    for (SDNode::use_iterator I = Ptr.Val->use_begin(),
+           E = Ptr.Val->use_end(); I != E; ++I) {
+      SDNode *Op = *I;
+      if (Op == N ||
+          (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB))
+        continue;
+
+      SDOperand BasePtr;
+      SDOperand Offset;
+      ISD::MemIndexedMode AM = ISD::UNINDEXED;
+      if (TLI.getPostIndexedAddressParts(N, Op, BasePtr, Offset, AM, DAG)) {
+        if (Ptr == Offset)
+          std::swap(BasePtr, Offset);
+        if (Ptr != BasePtr)
+          continue;
+
+        // Try turning it into a post-indexed load / store except when
+        // 1) All uses are load / store ops that use it as base ptr.
+        // 2) Op must be independent of N, i.e. Op is neither a predecessor
+        //    nor a successor of N. Otherwise, if Op is folded that would
+        //    create a cycle.
+
+        // Check for #1.
+        bool TryNext = false;
+        for (SDNode::use_iterator II = BasePtr.Val->use_begin(),
+               EE = BasePtr.Val->use_end(); II != EE; ++II) {
+          SDNode *Use = *II;
+          if (Use == Ptr.Val)
+            continue;
+
+          // If all the uses are load / store addresses, then don't do the
+          // transformation.
+          if (Use->getOpcode() == ISD::ADD || Use->getOpcode() == ISD::SUB){
+            bool RealUse = false;
+            for (SDNode::use_iterator III = Use->use_begin(),
+                   EEE = Use->use_end(); III != EEE; ++III) {
+              SDNode *UseUse = *III;
+              if (!((UseUse->getOpcode() == ISD::LOAD &&
+                     cast<LoadSDNode>(UseUse)->getBasePtr().Val == Use) ||
+                    (UseUse->getOpcode() == ISD::STORE) &&
+                    cast<StoreSDNode>(UseUse)->getBasePtr().Val == Use))
+                RealUse = true;
+            }
+
+            if (!RealUse) {
+              TryNext = true;
+              break;
+            }
+          }
+        }
+        if (TryNext)
+          continue;
+
+        // Check for #2
+        if (!Op->isPredecessor(N) && !N->isPredecessor(Op)) {
+          SDOperand Result = isLoad
+            ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
+            : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
+          ++PostIndexedNodes;
+          ++NodesCombined;
+          DEBUG(std::cerr << "\nReplacing.5 "; N->dump();
+                std::cerr << "\nWith: "; Result.Val->dump(&DAG);
+                std::cerr << '\n');
+          std::vector<SDNode*> NowDead;
+          if (isLoad) {
+            DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
+                                          NowDead);
+            DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
+                                          NowDead);
+          } else {
+            DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
+                                          NowDead);
+          }
+
+          // Nodes can end up on the worklist more than once.  Make sure we do
+          // not process a node that has been replaced.
+          for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+            removeFromWorkList(NowDead[i]);
+          // Finally, since the node is now dead, remove it from the graph.
+          DAG.DeleteNode(N);
+
+          // Replace the uses of Use with uses of the updated base value.
+          DAG.ReplaceAllUsesOfValueWith(SDOperand(Op, 0),
+                                        Result.getValue(isLoad ? 1 : 0),
+                                        NowDead);
+          removeFromWorkList(Op);
+          for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+            removeFromWorkList(NowDead[i]);
+          DAG.DeleteNode(Op);
+
+          return true;
+        }
+      }
+    }
+  }
+  return false;
+}
+
+
 SDOperand DAGCombiner::visitLOAD(SDNode *N) {
   LoadSDNode *LD  = cast<LoadSDNode>(N);
   SDOperand Chain = LD->getChain();






More information about the llvm-commits mailing list