[llvm-commits] [llvm] r56270 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp

Dan Gohman gohman at apple.com
Tue Sep 16 18:39:10 PDT 2008


Author: djg
Date: Tue Sep 16 20:39:10 2008
New Revision: 56270

URL: http://llvm.org/viewvc/llvm-project?rev=56270&view=rev
Log:
Simplify and generalize X86DAGToDAGISel::CanBeFoldedBy, and draw
up some new ascii art to illustrate what it does. This change
currently has no effect on generated code.

Modified:
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=56270&r1=56269&r2=56270&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Sep 16 20:39:10 2008
@@ -268,7 +268,7 @@
 /// non-immediate use of "Def". This function recursively traversing
 /// up the operand chain ignoring certain nodes.
 static void findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,
-                          SDNode *Root, SDNode *Skip, bool &found,
+                          SDNode *Root, bool &found,
                           SmallPtrSet<SDNode*, 16> &Visited) {
   if (found ||
       Use->getNodeId() > Def->getNodeId() ||
@@ -277,26 +277,16 @@
   
   for (unsigned i = 0, e = Use->getNumOperands(); !found && i != e; ++i) {
     SDNode *N = Use->getOperand(i).getNode();
-    if (N == Skip)
-      continue;
     if (N == Def) {
-      if (Use == ImmedUse)
+      if (Use == ImmedUse || Use == Root)
         continue;  // We are not looking for immediate use.
-      if (Use == Root) {
-        // Must be a chain reading node where it is possible to reach its own
-        // chain operand through a path started from another operand.
-        assert(Use->getOpcode() == ISD::STORE ||
-               Use->getOpcode() == X86ISD::CMP ||
-               Use->getOpcode() == ISD::INTRINSIC_W_CHAIN ||
-               Use->getOpcode() == ISD::INTRINSIC_VOID);
-        continue;
-      }
+      assert(N != Root);
       found = true;
       break;
     }
 
     // Traverse up the operand chain.
-    findNonImmUse(N, Def, ImmedUse, Root, Skip, found, Visited);
+    findNonImmUse(N, Def, ImmedUse, Root, found, Visited);
   }
 }
 
@@ -309,11 +299,10 @@
 /// have one non-chain use, we only need to watch out for load/op/store
 /// and load/op/cmp case where the root (store / cmp) may reach the load via
 /// its chain operand.
-static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse,
-                               SDNode *Skip = NULL) {
+static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) {
   SmallPtrSet<SDNode*, 16> Visited;
   bool found = false;
-  findNonImmUse(Root, Def, ImmedUse, Root, Skip, found, Visited);
+  findNonImmUse(Root, Def, ImmedUse, Root, found, Visited);
   return found;
 }
 
@@ -321,55 +310,58 @@
 bool X86DAGToDAGISel::CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root) const {
   if (Fast) return false;
 
-  // If U use can somehow reach N through another path then U can't fold N or
-  // it will create a cycle. e.g. In the following diagram, U can reach N
-  // through X. If N is folded into into U, then X is both a predecessor and
-  // a successor of U.
+  // If Root use can somehow reach N through a path that that doesn't contain
+  // U then folding N would create a cycle. e.g. In the following
+  // diagram, Root can reach N through X. If N is folded into into Root, then
+  // X is both a predecessor and a successor of U.
   //
-  //         [ N ]
-  //         ^  ^
-  //         |  |
-  //        /   \---
-  //      /        [X]
-  //      |         ^
-  //     [U]--------|
-
-  if (isNonImmUse(Root, N, U))
-    return false;
-
-  // If U produces a flag, then it gets (even more) interesting. Since it
-  // would have been "glued" together with its flag use, we need to check if
-  // it might reach N:
+  //          [N*]           //
+  //         ^   ^           //
+  //        /     \          //
+  //      [U*]    [X]?       //
+  //        ^     ^          //
+  //         \   /           //
+  //          \ /            //
+  //         [Root*]         //
   //
-  //       [ N ]
-  //        ^ ^
-  //        | |
-  //       [U] \--
-  //        ^   [TF]
-  //        |    ^
-  //        |    |
-  //         \  /
-  //          [FU]
+  // * indicates nodes to be folded together.
   //
-  // If FU (flag use) indirectly reach N (the load), and U fold N (call it
-  // NU), then TF is a predecessor of FU and a successor of NU. But since
-  // NU and FU are flagged together, this effectively creates a cycle.
-  bool HasFlagUse = false;
+  // If Root produces a flag, then it gets (even more) interesting. Since it
+  // will be "glued" together with its flag use in the scheduler, we need to
+  // check if it might reach N.
+  //
+  //          [N*]           //
+  //         ^   ^           //
+  //        /     \          //
+  //      [U*]    [X]?       //
+  //        ^       ^        //
+  //         \       \       //
+  //          \      |       //
+  //         [Root*] |       //
+  //          ^      |       //
+  //          f      |       //
+  //          |      /       //
+  //         [Y]    /        //
+  //           ^   /         //
+  //           f  /          //
+  //           | /           //
+  //          [FU]           //
+  //
+  // If FU (flag use) indirectly reaches N (the load), and Root folds N
+  // (call it Fold), then X is a predecessor of FU and a successor of
+  // Fold. But since Fold and FU are flagged together, this will create
+  // a cycle in the scheduling graph.
+
   MVT VT = Root->getValueType(Root->getNumValues()-1);
-  while ((VT == MVT::Flag && !Root->use_empty())) {
+  while (VT == MVT::Flag) {
     SDNode *FU = findFlagUse(Root);
     if (FU == NULL)
       break;
-    else {
-      Root = FU;
-      HasFlagUse = true;
-    }
+    Root = FU;
     VT = Root->getValueType(Root->getNumValues()-1);
   }
 
-  if (HasFlagUse)
-    return !isNonImmUse(Root, N, Root, U);
-  return true;
+  return !isNonImmUse(Root, N, U);
 }
 
 /// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand





More information about the llvm-commits mailing list