[llvm] [SelectionDAG] Add OPC_MoveSibling (PR #73643)

via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 28 05:10:44 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-selectiondag

Author: Wang Pengcheng (wangpc-pp)

<details>
<summary>Changes</summary>

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`, but we can do further in the future. For example,
we can transform sequences `MoveParent+RecordChild+MoveChild` to
`MoveSibling+RecordNode`.

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


---
Full diff: https://github.com/llvm/llvm-project/pull/73643.diff


6 Files Affected:

- (modified) llvm/include/llvm/CodeGen/SelectionDAGISel.h (+9) 
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (+23) 
- (modified) llvm/utils/TableGen/DAGISelMatcher.cpp (+4) 
- (modified) llvm/utils/TableGen/DAGISelMatcher.h (+40-19) 
- (modified) llvm/utils/TableGen/DAGISelMatcherEmitter.cpp (+14) 
- (modified) llvm/utils/TableGen/DAGISelMatcherOpt.cpp (+14) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h
index aa71be5d1960ff5..b15ac901656e49b 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 a0af6faa7fbcefb..9e1c32198623757 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3238,6 +3238,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 0609f006763bc5b..1a5c728fafd9ca1 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 e3cf847edd1273b..e69f8fa9c5d30d6 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 4da06197658cd0a..ef8b112effe5826 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;
@@ -1066,6 +1077,9 @@ static StringRef getOpcodeString(Matcher::KindTy Kind) {
   case Matcher::RecordMemRef: return "OPC_RecordMemRef"; break;
   case Matcher::CaptureGlueInput: return "OPC_CaptureGlueInput"; break;
   case Matcher::MoveChild: return "OPC_MoveChild"; break;
+  case Matcher::MoveSibling:
+    return "OPC_MoveSibling";
+    break;
   case Matcher::MoveParent: return "OPC_MoveParent"; break;
   case Matcher::CheckSame: return "OPC_CheckSame"; break;
   case Matcher::CheckChildSame: return "OPC_CheckChildSame"; break;
diff --git a/llvm/utils/TableGen/DAGISelMatcherOpt.cpp b/llvm/utils/TableGen/DAGISelMatcherOpt.cpp
index bf2a24241e84629..f1ee10f183419aa 100644
--- a/llvm/utils/TableGen/DAGISelMatcherOpt.cpp
+++ b/llvm/utils/TableGen/DAGISelMatcherOpt.cpp
@@ -155,6 +155,20 @@ 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());
+      // Insert the new node.
+      MS->setNext(MatcherPtr.release());
+      MatcherPtr.reset(MS);
+      // Remove the old one.
+      MS->setNext(MC->takeNext());
+      return ContractNodes(MatcherPtr, CGP);
+    }
+  }
 }
 
 /// FindNodeWithKind - Scan a series of matchers looking for a matcher with a

``````````

</details>


https://github.com/llvm/llvm-project/pull/73643


More information about the llvm-commits mailing list