[llvm] 7144174 - [SelectionDAG] Add OPC_MoveSibling (#73643)

via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 12 01:48:49 PST 2023


Author: Wang Pengcheng
Date: 2023-12-12T17:48:45+08:00
New Revision: 714417455da34855290c3b575b8daabb78340e45

URL: https://github.com/llvm/llvm-project/commit/714417455da34855290c3b575b8daabb78340e45
DIFF: https://github.com/llvm/llvm-project/commit/714417455da34855290c3b575b8daabb78340e45.diff

LOG: [SelectionDAG] Add OPC_MoveSibling (#73643)

There are a lot of operations to move current node to parent and
then move to another child.

So `OPC_MoveSibling` and its space-optimized forms are added to do
this "move to sibling" operations.

These new operations will be generated when optimizing matcher in
`ContractNodes`. Currently `MoveParent+MoveChild` will be optimized
to `MoveSibling` and sequences `MoveParent+RecordChild+MoveChild`
will be transformed into `MoveSibling+RecordNode`.

Overall this reduces the llc binary size with all in-tree targets by
about 30K.

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/SelectionDAGISel.h
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/utils/TableGen/DAGISelMatcher.cpp
    llvm/utils/TableGen/DAGISelMatcher.h
    llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
    llvm/utils/TableGen/DAGISelMatcherOpt.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h
index 233e94c4e7439..c604e7eaa0887 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h
@@ -143,6 +143,15 @@ class SelectionDAGISel : public MachineFunctionPass {
     OPC_MoveChild5,
     OPC_MoveChild6,
     OPC_MoveChild7,
+    OPC_MoveSibling,
+    OPC_MoveSibling0,
+    OPC_MoveSibling1,
+    OPC_MoveSibling2,
+    OPC_MoveSibling3,
+    OPC_MoveSibling4,
+    OPC_MoveSibling5,
+    OPC_MoveSibling6,
+    OPC_MoveSibling7,
     OPC_MoveParent,
     OPC_CheckSame,
     OPC_CheckChild0Same,

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index b43847db32aa3..dd28ec09d0e2b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3285,6 +3285,29 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
       continue;
     }
 
+    case OPC_MoveSibling:
+    case OPC_MoveSibling0:
+    case OPC_MoveSibling1:
+    case OPC_MoveSibling2:
+    case OPC_MoveSibling3:
+    case OPC_MoveSibling4:
+    case OPC_MoveSibling5:
+    case OPC_MoveSibling6:
+    case OPC_MoveSibling7: {
+      // Pop the current node off the NodeStack.
+      NodeStack.pop_back();
+      assert(!NodeStack.empty() && "Node stack imbalance!");
+      N = NodeStack.back();
+
+      unsigned SiblingNo = Opcode == OPC_MoveSibling
+                               ? MatcherTable[MatcherIndex++]
+                               : Opcode - OPC_MoveSibling0;
+      if (SiblingNo >= N.getNumOperands())
+        break; // Match fails if out of range sibling #.
+      N = N.getOperand(SiblingNo);
+      NodeStack.push_back(N);
+      continue;
+    }
     case OPC_MoveParent:
       // Pop the current node off the NodeStack.
       NodeStack.pop_back();

diff  --git a/llvm/utils/TableGen/DAGISelMatcher.cpp b/llvm/utils/TableGen/DAGISelMatcher.cpp
index 0609f006763bc..1a5c728fafd9c 100644
--- a/llvm/utils/TableGen/DAGISelMatcher.cpp
+++ b/llvm/utils/TableGen/DAGISelMatcher.cpp
@@ -145,6 +145,10 @@ void MoveChildMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
   OS.indent(indent) << "MoveChild " << ChildNo << '\n';
 }
 
+void MoveSiblingMatcher::printImpl(raw_ostream &OS, unsigned Indent) const {
+  OS.indent(Indent) << "MoveSibling " << SiblingNo << '\n';
+}
+
 void MoveParentMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
   OS.indent(indent) << "MoveParent\n";
 }

diff  --git a/llvm/utils/TableGen/DAGISelMatcher.h b/llvm/utils/TableGen/DAGISelMatcher.h
index e3cf847edd127..e69f8fa9c5d30 100644
--- a/llvm/utils/TableGen/DAGISelMatcher.h
+++ b/llvm/utils/TableGen/DAGISelMatcher.h
@@ -52,28 +52,29 @@ class Matcher {
 public:
   enum KindTy {
     // Matcher state manipulation.
-    Scope,                // Push a checking scope.
-    RecordNode,           // Record the current node.
-    RecordChild,          // Record a child of the current node.
-    RecordMemRef,         // Record the memref in the current node.
-    CaptureGlueInput,     // If the current node has an input glue, save it.
-    MoveChild,            // Move current node to specified child.
-    MoveParent,           // Move current node to parent.
+    Scope,            // Push a checking scope.
+    RecordNode,       // Record the current node.
+    RecordChild,      // Record a child of the current node.
+    RecordMemRef,     // Record the memref in the current node.
+    CaptureGlueInput, // If the current node has an input glue, save it.
+    MoveChild,        // Move current node to specified child.
+    MoveSibling,      // Move current node to specified sibling.
+    MoveParent,       // Move current node to parent.
 
     // Predicate checking.
-    CheckSame,            // Fail if not same as prev match.
-    CheckChildSame,       // Fail if child not same as prev match.
+    CheckSame,      // Fail if not same as prev match.
+    CheckChildSame, // Fail if child not same as prev match.
     CheckPatternPredicate,
-    CheckPredicate,       // Fail if node predicate fails.
-    CheckOpcode,          // Fail if not opcode.
-    SwitchOpcode,         // Dispatch based on opcode.
-    CheckType,            // Fail if not correct type.
-    SwitchType,           // Dispatch based on type.
-    CheckChildType,       // Fail if child has wrong type.
-    CheckInteger,         // Fail if wrong val.
-    CheckChildInteger,    // Fail if child is wrong val.
-    CheckCondCode,        // Fail if not condcode.
-    CheckChild2CondCode,  // Fail if child is wrong condcode.
+    CheckPredicate,      // Fail if node predicate fails.
+    CheckOpcode,         // Fail if not opcode.
+    SwitchOpcode,        // Dispatch based on opcode.
+    CheckType,           // Fail if not correct type.
+    SwitchType,          // Dispatch based on type.
+    CheckChildType,      // Fail if child has wrong type.
+    CheckInteger,        // Fail if wrong val.
+    CheckChildInteger,   // Fail if child is wrong val.
+    CheckCondCode,       // Fail if not condcode.
+    CheckChild2CondCode, // Fail if child is wrong condcode.
     CheckValueType,
     CheckComplexPat,
     CheckAndImm,
@@ -342,6 +343,26 @@ class MoveChildMatcher : public Matcher {
   }
 };
 
+/// MoveSiblingMatcher - This tells the interpreter to move into the
+/// specified sibling node.
+class MoveSiblingMatcher : public Matcher {
+  unsigned SiblingNo;
+
+public:
+  MoveSiblingMatcher(unsigned SiblingNo)
+      : Matcher(MoveSibling), SiblingNo(SiblingNo) {}
+
+  unsigned getSiblingNo() const { return SiblingNo; }
+
+  static bool classof(const Matcher *N) { return N->getKind() == MoveSibling; }
+
+private:
+  void printImpl(raw_ostream &OS, unsigned Indent) const override;
+  bool isEqualImpl(const Matcher *M) const override {
+    return cast<MoveSiblingMatcher>(M)->getSiblingNo() == getSiblingNo();
+  }
+};
+
 /// MoveParentMatcher - This tells the interpreter to move to the parent
 /// of the current node.
 class MoveParentMatcher : public Matcher {

diff  --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
index 2ba57c30046ef..5f96f11279f24 100644
--- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -456,6 +456,17 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
     return (MCM->getChildNo() >= 8) ? 2 : 1;
   }
 
+  case Matcher::MoveSibling: {
+    const auto *MSM = cast<MoveSiblingMatcher>(N);
+
+    OS << "OPC_MoveSibling";
+    // Handle the specialized forms.
+    if (MSM->getSiblingNo() >= 8)
+      OS << ", ";
+    OS << MSM->getSiblingNo() << ",\n";
+    return (MSM->getSiblingNo() >= 8) ? 2 : 1;
+  }
+
   case Matcher::MoveParent:
     OS << "OPC_MoveParent,\n";
     return 1;
@@ -1128,6 +1139,8 @@ static StringRef getOpcodeString(Matcher::KindTy Kind) {
     return "OPC_CaptureGlueInput";
   case Matcher::MoveChild:
     return "OPC_MoveChild";
+  case Matcher::MoveSibling:
+    return "OPC_MoveSibling";
   case Matcher::MoveParent:
     return "OPC_MoveParent";
   case Matcher::CheckSame:

diff  --git a/llvm/utils/TableGen/DAGISelMatcherOpt.cpp b/llvm/utils/TableGen/DAGISelMatcherOpt.cpp
index bf2a24241e846..c4c25dc1a5fde 100644
--- a/llvm/utils/TableGen/DAGISelMatcherOpt.cpp
+++ b/llvm/utils/TableGen/DAGISelMatcherOpt.cpp
@@ -155,6 +155,30 @@ static void ContractNodes(std::unique_ptr<Matcher> &MatcherPtr,
     CheckType->setNext(Tail);
     return ContractNodes(MatcherPtr, CGP);
   }
+
+  // If we have a MoveParent followed by a MoveChild, we convert it to
+  // MoveSibling.
+  if (auto *MP = dyn_cast<MoveParentMatcher>(N)) {
+    if (auto *MC = dyn_cast<MoveChildMatcher>(MP->getNext())) {
+      auto *MS = new MoveSiblingMatcher(MC->getChildNo());
+      MS->setNext(MC->takeNext());
+      MatcherPtr.reset(MS);
+      return ContractNodes(MatcherPtr, CGP);
+    }
+    if (auto *RC = dyn_cast<RecordChildMatcher>(MP->getNext())) {
+      if (auto *MC = dyn_cast<MoveChildMatcher>(RC->getNext())) {
+        if (RC->getChildNo() == MC->getChildNo()) {
+          auto *MS = new MoveSiblingMatcher(MC->getChildNo());
+          auto *RM = new RecordMatcher(RC->getWhatFor(), RC->getResultNo());
+          // Insert the new node.
+          RM->setNext(MC->takeNext());
+          MS->setNext(RM);
+          MatcherPtr.reset(MS);
+          return ContractNodes(MatcherPtr, CGP);
+        }
+      }
+    }
+  }
 }
 
 /// FindNodeWithKind - Scan a series of matchers looking for a matcher with a


        


More information about the llvm-commits mailing list