This is an archive of the discontinued LLVM Phabricator instance.

[PatternMatch] Stabilize the matching order of commutative matchers
ClosedPublic

Authored by lebedev.ri on Apr 19 2018, 10:33 AM.

Details

Summary

Currently, we

  1. match LHS matcher to the first operand of binary operator,
  2. and then match RHS matcher to the second operand of binary operator.

If that does not match, we swap the LHS and RHS matchers:

  1. match RHS matcher to the first operand of binary operator,
  2. and then match LHS matcher to the second operand of binary operator.

This works ok.
But it complicates writing of commutative matchers, where one would like to match
(m_Value()) the value on one side, and use (m_Specific()) it on the other side.

This is additionally complicated by the fact that m_Specific() stores the Value *,
not Value **, so it won't work at all out of the box.

The last problem is trivially solved by adding a new m_c_Specific() that stores the
Value **, not Value *. I'm choosing to add a new matcher, not change the existing
one because i guess all the current users are ok with existing behavior,
and this additional pointer indirection may have performance drawbacks.
Also, i'm storing pointer, not reference, because for some mysterious-to-me reason
it did not work with the reference.

The first one appears trivial, too.
Currently, we

  1. match LHS matcher to the first operand of binary operator,
  2. and then match RHS matcher to the second operand of binary operator.

If that does not match, we swap the LHS and RHS matchers operands:

  1. match RHS LHS matcher to the first second operand of binary operator,
  2. and then match LHS RHS matcher to the ~~second~ first operand of binary operator.

Surprisingly, $ ninja check-llvm still passes with this.
But i expect the bots will disagree..

The motivational unittest is included.
I'd like to use this in D45664.

Diff Detail

Repository
rL LLVM

Event Timeline

lebedev.ri created this revision.Apr 19 2018, 10:33 AM
craig.topper added inline comments.Apr 19 2018, 10:42 AM
include/llvm/IR/PatternMatch.h
495 ↗(On Diff #143120)

This doesn't only fix commutative so I don't think the name should be tied to that.

This was also not possible before, but would be with this new matcher.

match(m_And(m_Value(X), m_Or(m_Specific(X), m_Value(Y))
lebedev.ri added inline comments.Apr 19 2018, 10:46 AM
include/llvm/IR/PatternMatch.h
495 ↗(On Diff #143120)

Yes, i agree.
Any suggestions for a better name?

lebedev.ri added inline comments.Apr 19 2018, 2:54 PM
include/llvm/IR/PatternMatch.h
495 ↗(On Diff #143120)

Would m_Deferred() sound better?

I think it would convey the idea that the actual value
is only acquired [to be checked] at the time of the match() itself.

Ping. Would really like some feedback on this idea.

xbolva00 added inline comments.
include/llvm/IR/PatternMatch.h
495 ↗(On Diff #143120)

Yes, I vote for other name than "m_c_Specific" too.

Ping. Would really like some feedback on this idea.

My implementation knowledge is limited, so I defer to other reviewers for the actual diffs.

Are the eval-order-stabilization changes independent of the new matcher?
How often does this come up? Ie, besides the proposed patch in D45664, can you use this on existing code to simplify it? If so, it might be worth including at least one of those changes here to show the value of adding a new matcher.

lebedev.ri marked 4 inline comments as done.
  • Renamed it to m_Deferred().
  • Simplified some existing code using it.

Ping. Would really like some feedback on this idea.

My implementation knowledge is limited, so I defer to other reviewers for the actual diffs.

Are the eval-order-stabilization changes independent of the new matcher?

I suppose so.
The matcher can be separate, though then i'm not sure right now how to test the rest of the changes.

How often does this come up?

Not *too* often, but it does come up.

Ie, besides the proposed patch in D45664, can you use this on existing code to simplify it? If so, it might be worth including at least one of those changes here to show the value of adding a new matcher.

It's a bit cumbersome to find such instances, but sure, there you go.

I'd like to know more about why storing a reference didn't work.

unittests/IR/PatternMatch.cpp
68 ↗(On Diff #144207)

Rename based on the new name m_Deferred?

lebedev.ri marked an inline comment as done.

I'd like to know more about why storing a reference didn't work.

Uhm, that makes two of us :/
I'm very sure it did not work back then when i initially tried,
but now it just worked, and all the tests pass...

(i did check that there are tests for these commutative variants, even had to add some beforehand.)

This revision is now accepted and ready to land.Apr 27 2018, 2:08 PM

Make it Value *const &V, not Value *&V, for symmetry with m_Specific(), which takes const Value *V, not Value *V.

@craig.topper, @spatel thank you for the review!

I'm going to commit this, and watch the bots for a bit.
If something breaks i'd guess it would be msan bots.

This revision was automatically updated to reflect the committed changes.