-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SelectionDAG] Introducing the SelectionDAG pattern matching framework #78654
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] Introducing the SelectionDAG pattern matching framework #78654
Conversation
Note: I only added the most basic and hopefully the most common patterns in this patch. Feel free to propose other patterns that you thought are important. |
explicit NUses_match(const Pattern &P) : P(P) {} | ||
|
||
bool match(const SelectionDAG *DAG, SDValue N) { | ||
return N && N->hasNUsesOfValue(NumUses, N.getResNo()) && P.match(DAG, N); |
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.
hasNUsesOfValue can be expensive on nodes with multiple results. It can't return true until it has checked all uses. Uses for all results are stored in the same list.
We try to always check opcode first before checking number of uses. It's better to ask if an opcode is an ISD::ADD first since it only has 1 result. Than to ask for the number of uses without knowing what type of node it is.
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.
We try to always check opcode first before checking number of uses. It's better to ask if an opcode is an ISD::ADD first since it only has 1 result. Than to ask for the number of uses without knowing what type of node it is.
I think a simple solution could be swapping hasNUsesOfValue
with the succeeding P.match
call, as we have to fulfills these two conditions anyway:
P.match(DAG, N) && N->hasNUsesOfValue(NumUses, N.getResNo())
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.
Done.
As SDNode::hasNUsesOfValue is pretty expensive
Random question - will this play nice with the template approach taken for VP node (e.g. #80105)? |
@mshockwave reverse-ping |
My apologies for the delay. |
I'd just introduced the concept of match context to SDPatternMatch: now a user can pattern match a SDValue under certain match context using Switching to this match context design also solves one of the problem where previously, the user had to provide a SelectionDAG in order to use any TLI hook, which was inconvenient in places lack of SelectionDAG. Now we can independently provide TLI instances to |
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.
Please can you add m_Deferred handling?
// Optional trait function(s) | ||
|
||
/// Return true if N effectively has opcode Opcode. | ||
// bool match(SDValue N, unsigned Opcode) |
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.
Why make this optional instead of having a default implementation of N->getOpcode() == Opcode
?
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.
Users won't necessary inherit BasicContext here to create a new match context. The default implementation for match
is implemented in places like Opcode_match::match
, toggled by ctx_has_match
.
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.
Do we expect there to be more contexts than BaseContext and VPMatchContext? I don't think that custom context will be common enough that we have to optimize for implementing one method less.
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.
Do we expect there to be more contexts than BaseContext and VPMatchContext? I don't think that custom context will be common enough that we have to optimize for implementing one method less.
I'm convinced, I'll change this in the next update.
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.
It's fixed now.
|
The major one was simplifying Node_match into Operands_match.
explicit Opcode_match(unsigned Opc) : Opcode(Opc) {} | ||
|
||
template <typename MatchContext> | ||
std::enable_if_t<is_detected<ctx_has_match, MatchContext>::value, bool> |
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.
I think these enable_ifs are not needed anymore now that we have the match() implementation in BasicMatchContext?
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.
Oh yeah I forgot. It's fixed now.
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, but please wait a bit in case other people have more feedback.
Akin to
llvm::PatternMatch
andllvm::MIPatternMatch
, thellvm::SDPatternMatch
introduced in this patch provides a DSL-alike framework to match SDValue / SDNode with a more succinct syntax.