Skip to content

Commit

Permalink
[SelectionDAG] Add OPC_MoveSibling (#73643)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wangpc-pp committed Dec 12, 2023
1 parent 43e6aec commit 7144174
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 19 deletions.
9 changes: 9 additions & 0 deletions llvm/include/llvm/CodeGen/SelectionDAGISel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
23 changes: 23 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 4 additions & 0 deletions llvm/utils/TableGen/DAGISelMatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Expand Down
59 changes: 40 additions & 19 deletions llvm/utils/TableGen/DAGISelMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
13 changes: 13 additions & 0 deletions llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down
24 changes: 24 additions & 0 deletions llvm/utils/TableGen/DAGISelMatcherOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 7144174

Please sign in to comment.