[llvm] [SelectionDAG] Add OPC_MoveSibling (PR #73643)
Wang Pengcheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 28 05:10:13 PST 2023
https://github.com/wangpc-pp created https://github.com/llvm/llvm-project/pull/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`, 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.
>From 0c2746b92a6282d797202b255e5fe9bab49ce15c Mon Sep 17 00:00:00 2001
From: wangpc <wangpengcheng.pp at bytedance.com>
Date: Tue, 28 Nov 2023 20:57:06 +0800
Subject: [PATCH] [SelectionDAG] Add OPC_MoveSibling
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.
---
llvm/include/llvm/CodeGen/SelectionDAGISel.h | 9 +++
.../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 23 ++++++++
llvm/utils/TableGen/DAGISelMatcher.cpp | 4 ++
llvm/utils/TableGen/DAGISelMatcher.h | 59 +++++++++++++------
llvm/utils/TableGen/DAGISelMatcherEmitter.cpp | 14 +++++
llvm/utils/TableGen/DAGISelMatcherOpt.cpp | 14 +++++
6 files changed, 104 insertions(+), 19 deletions(-)
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
More information about the llvm-commits
mailing list