-
Notifications
You must be signed in to change notification settings - Fork 10.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SelectionDAG] Add OPC_MoveSibling #73643
[SelectionDAG] Add OPC_MoveSibling #73643
Conversation
@llvm/pr-subscribers-llvm-selectiondag Author: Wang Pengcheng (wangpc-pp) ChangesThere are a lot of operations to move current node to parent and So These new operations will be generated when optimizing matcher in Overall this reduces the llc binary size with all in-tree targets by Full diff: https://github.com/llvm/llvm-project/pull/73643.diff 6 Files Affected:
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
|
b9f84a8
to
a784e31
Compare
Ping. |
a784e31
to
5e739d0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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.
5e739d0
to
a6a9ad9
Compare
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 dothis "move to sibling" operations.
These new operations will be generated when optimizing matcher in
ContractNodes
. CurrentlyMoveParent+MoveChild
will be optimizedto
MoveSibling
and sequencesMoveParent+RecordChild+MoveChild
will be transformed into
MoveSibling+RecordNode
.Overall this reduces the llc binary size with all in-tree targets by
about 30K.