This is an archive of the discontinued LLVM Phabricator instance.

[MLIR] Add SCF.if Condition Canonicalizations
ClosedPublic

Authored by wsmoses on Apr 21 2021, 7:28 PM.

Details

Summary

Add two canoncalizations for scf.if.

  1. A canonicalization that allows users of a condition within an if to assume the condition is true if in the true region, etc.
  2. A canonicalization that removes yielded statements that are equivalent to the condition or its negation

Diff Detail

Event Timeline

wsmoses created this revision.Apr 21 2021, 7:28 PM
wsmoses requested review of this revision.Apr 21 2021, 7:28 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 21 2021, 7:28 PM
mlir/lib/Dialect/SCF/SCF.cpp
1110

doc with (pseudo)-IR examples plz

1144

doc with (pseudo)-IR examples plz

1159

can you please fix casing and other clang-tidy stuff?
Filtering out the noise will make it easier to read.

1165

That's deep but we're not in NN land :)
Can you please turn into early continue and reduce nesting?

wsmoses updated this revision to Diff 340160.Apr 23 2021, 1:52 PM

Fix casing and add description as documentation

wsmoses updated this revision to Diff 340190.Apr 23 2021, 4:05 PM
wsmoses marked 4 inline comments as done.

Fix capitalization of Tup

mehdi_amini added inline comments.Apr 23 2021, 5:42 PM
mlir/lib/Dialect/SCF/SCF.cpp
1130

Nit: remove trivial braces.

1138–1139

Can you try to create a single constant op in the pattern instead of a new one for each new use?

1153

You can replace the if/else with : return success(changed);

1180

I don't understand this comment here

wsmoses updated this revision to Diff 340217.Apr 23 2021, 6:20 PM

Reduce redundant constantop creation and provide better comments

kumasento added inline comments.Apr 23 2021, 11:41 PM
mlir/lib/Dialect/SCF/SCF.cpp
1171

What would happen if the input is like:

%false = constant false
%res:2 = scf.if %cmp {
  yield something(), %false
} else {
  yield something2(), %false
}

return %res#0, %res#1

I think this case can be canonicalized, but the current implementation doesn't support it?

1206

nit: I would prefer std::tie instead of std::get especially in the case that you need to access every field in the tuple several times. The code can be more readble IMHO.

e.g.

Value trueResult, falseResult, opResult;
std::tie(trueResult, falseResult, opResult) = tup;
mlir/test/Dialect/SCF/canonicalize.mlir
705

nit: Add a newline at the end of the file (you can configure this in your editor, e.g., if you use VSCode: https://stackoverflow.com/questions/44704968/visual-studio-code-insert-new-line-at-the-end-of-files). It is just for not introducing unnecessary changes.

mlir/test/Transforms/canonicalize.mlir
1201–1202

Why we need %arg2 here?

mehdi_amini added inline comments.Apr 24 2021, 9:34 AM
mlir/lib/Dialect/SCF/SCF.cpp
1171

Seems like a different case that should be handle by a more generic canonicalizer which does not even require i1 : if the same SSA value is yielded in both regions it can be directly RAUW.

If it isn't handled elsewhere already, it could be added as a separate canonicalization, or by patching the loop below:

for (auto tup :  llvm::zip(trueYield.results(), falseYield.results(), op.results())) {
  if (std::get<0>(tup) == std::get<1>(tup)) {
     std::get<1>(tup).replaceAllUsesWith(std::get<2>(tup));
     changed = true;
     continue;
  }
  ....
}
wsmoses updated this revision to Diff 340386.Apr 25 2021, 2:51 PM
wsmoses marked 5 inline comments as done.

Add scf.if common yield elimination

wsmoses marked 3 inline comments as done.Apr 25 2021, 2:52 PM
wsmoses added inline comments.
mlir/lib/Dialect/SCF/SCF.cpp
1171

I would've thought this "if invariant " motion would already be handled, but indeed it's not. It's easy enough to add here so I'll bring it in. And yes I agree with medhi that this should be done in a more general way (in fact that just checks if the the operands are the same).

mlir/test/Transforms/canonicalize.mlir
1201–1202

Without modification this test would be optimized to have the nested if eliminated [since we know %0 is true]. Adding the extra arg was an easy way to preserve (what I believe to be) the intended behavior of the test. If you have a better suggestion, lmk!

ftynse accepted this revision.Apr 26 2021, 3:15 AM

LGTM with feedback from others addressed.

mlir/lib/Dialect/SCF/SCF.cpp
1122

Nit: top-level comments in MLIR use three slashes ///

1134

Nit: drop mlir::.

1136–1137

Nit: please use proper capitalization and punctuation (trailing periods) in comments.

1264–1268

This magic with updateRootInPlace isn't strictly necessary in canonicalizer patterns because the canonicalizer driver doesn't undo them anyway. It's probably nice to have for future-proofness, but you are already using direct RAUW in this pattern, so it's not safe anway. Maybe factor this loop out into a helper function and use it everywhere + propose this helper to be promoted to PatternRewriter interface? Otherwise, I'm fine with using RAUW everywhere in canonicalizer patterns.

mlir/test/Dialect/SCF/canonicalize.mlir
649

Do we care about lines being next to each other? I would rather use CHECK and make the test less constrained on unnecessary details.

727

Add newlines plz.

This revision is now accepted and ready to land.Apr 26 2021, 3:15 AM
wsmoses updated this revision to Diff 340682.Apr 26 2021, 4:41 PM
wsmoses marked 6 inline comments as done.

Address Alex's comments [and finally add newline]

This revision was landed with ongoing or failed builds.Apr 26 2021, 5:13 PM
This revision was automatically updated to reflect the committed changes.