This is an archive of the discontinued LLVM Phabricator instance.

[NFC][SLP] Cleanup: Simplify traversal loop in SLPVectorizerPass::vectorizeHorReduction().
ClosedPublic

Authored by vporpo on May 1 2023, 6:51 PM.

Details

Summary

This includes a couple of changes:

  1. Moves the code that changes the root node out of the TryToReduce lambda and out of the traversal loop.
  2. Since that code moved, there isn't much left in TryToReduce so the code was inlined.
  3. The phi node variable P was also being used as a flag that turns on/off the exploration of operands as new seeds. This patch uses a new variable TryOperandsAsNewSeeds for this.
  4. Simplifies the code executed when vectorization fails.

The logic of the code should be identical to the original, but I may be missing something not caught by tests.

Diff Detail

Event Timeline

vporpo created this revision.May 1 2023, 6:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 1 2023, 6:51 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
vporpo requested review of this revision.May 1 2023, 6:51 PM
ABataev added inline comments.May 2 2023, 6:03 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
13985
  1. Make a separate NFC patch.
  2. Format, the second parameter is not aligned
14027–14029

bool TryOperandsAsNewSeeds = P && isa<BinaryOperator>(Root);

14035–14042
if (P && isa<BinaryOperator>(Root) && HorizontalReduction::getRdxKind(Root) != RecurKind::None)
  Root = tryGetSecondaryReductionRoot(P, Root);
14071

What if Inst is one of the P operands here, but not Root?

14086

I think this is not quite same as before, it should not be a Root, it may be another P operand.

vporpo updated this revision to Diff 518783.May 2 2023, 10:04 AM
vporpo marked an inline comment as done.

Addressed comments.

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
13985

OK I will do this in a separate patch.

14035–14042

I kept NewRoot because we need the original Root for Inst == Root later, otherwise the logic changes a bit. I also prefer to use TryOperandsAsNewSeeds instead of P as it shows intent. Same for isReductionCandidate() instead of isa<BinaryOperator>().

14071

This should work as the original code. This condition is the same as line 14028 and 14032.

14086

In the original code P was set to nullptr after visiting the root node, so this would only enter if Inst == Root.

ABataev added inline comments.May 2 2023, 10:37 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14008

auto *Op

14008–14010

return dyn_cast<Instruction>(Op0 == Phi ? Op1 : Op0);

14070–14077

Better to keep this as lambda.

14086

The original code does not compare with Root, it compares with P. What if Inst is an instruction with P operand, but not Root?

14089

Why break here?

vporpo updated this revision to Diff 518809.May 2 2023, 11:13 AM
vporpo marked 2 inline comments as done.

Brought back the lambda and addressed comments.

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14008–14010

Phi and Op are already Instruction * so I will use this instead: return Op == Phi ? dyn_cast<Instruction>(Val: Op1) : Op;

14086

P is set to null after visiting the root node (lines 14060, 14075 and 14081). So the code will enter this if only if Inst is the root node. If it is any other instruction it won't enter.

14089

This can only happen if Inst is the root node and at this point Stack is empty so it effectively breaks out of the loop, so it is better to be explicit about it.

ABataev added inline comments.May 2 2023, 12:34 PM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14006

Better:

if (!match(...))
  return nullptr;
14008–14010

You just don't need Op at all, just
return dyn_cast<Instruction>(Op0 == Phi ? Op1 : Op0);
after assert is enough.

14085–14088

This logic also better to represent as lambda

14089

Add an assert(Stack.empty()) here and check with at least Spec that it does not crash

vporpo updated this revision to Diff 518869.May 2 2023, 2:55 PM
vporpo marked 2 inline comments as done.

Created lambda TryAppendToPostponedInsts and addressed comments.

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14089

I checked with Spec 2017 and our presubmit tests and Stack is always empty.

ABataev added inline comments.May 2 2023, 3:39 PM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14089

Add the assert here

vporpo updated this revision to Diff 518896.May 2 2023, 3:58 PM

Added the assertion.

vporpo marked an inline comment as done.May 2 2023, 3:59 PM
ABataev added inline comments.May 3 2023, 4:29 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14034–14038

Can you turn into lambda too:

auto SelectRoot = [&]() {
  if (TryOperandsAsNewSeeds && isReductionCandidate(Root) &&
      HorizontalReduction::getRdxKind(Root) != RecurKind::None)
    return tryGetSecondaryReductionRoot(P, Root);
  return Root;
}
...
Stack.emplace(SelectRoot(), 0);
14036

TryOperandsAsNewSeeds && isReductionCandidate(Root) && to avoid extra call when TryOperandsAsNewSeeds is false.

14065–14066

auto TryAppendToPostponedInsts = [&]

vporpo updated this revision to Diff 519144.May 3 2023, 10:07 AM
vporpo marked 3 inline comments as done.

Addressed comments.

ABataev added inline comments.May 3 2023, 10:20 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

Replace the message with something meaningful, like 'Empty Stack is expected.'

vporpo added inline comments.May 3 2023, 10:39 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

I think we should also mention why we are checking that Stack is empty, so that we know how to fix this if it triggers the assertion. How about: "Empty Stack expected. Change break to continue?"

ABataev added inline comments.May 3 2023, 10:41 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

The change continue to break is actual only for this patch, not for the codebase. So just Empty stack expected, the original root is reached or something like this should be enough

vporpo added inline comments.May 3 2023, 10:51 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

I don't understand what you mean. We are adding the assertion specifically for checking that changing continue to break was correct, and you are arguing that we should not mention this in the assertion message, and instead write some generic message that provides no information about why this assertion exists.
How will a message like "Empty stack expected, the original root is reached" is supposed to help a third person fix the code if the assertion triggers?

vporpo added inline comments.May 3 2023, 10:55 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

Anyway I don't feel to strongly about this I will change it to what you are proposing.

ABataev added inline comments.May 3 2023, 10:57 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

The assert is not about the change itself. It should not inform about changes you made but about the precondition expected here. asserts are for precondition/postcondition messages, not change history.

So a message like "expecting loop to exit" would

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

Yes the precondition is that the loop will exit right after this point, which explains why we are using break. Shouldn't we mention this in the message? I just don't like assertion messages that repeat the obvious like mentioning "Expected empty stack" when the assertion is assert(Stack.empty()).

ABataev added inline comments.May 3 2023, 11:16 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

You don't need to describe git history in the message, better describe better why Stack is expected to be empty (the original root is reached should help with this). Also, check https://llvm.org/docs/CodingStandards.html#assert-liberally and message examples.

vporpo updated this revision to Diff 519177.May 3 2023, 11:17 AM

Updated assertion message. How about this?

Updated assertion message. How about this?

The break below already means it, better to describe why Stack is expected to be empty here.

vporpo added inline comments.May 3 2023, 11:35 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

The break below already means it, better to describe why Stack is expected to be empty here.

I don't understand why you don't like the message "Expected empty stack, loop should exit".
The precondition is that the loop should exit at this point. The fact that there is a break is exactly what is being checked by the assertion.

ABataev accepted this revision.May 3 2023, 11:46 AM
ABataev added inline comments.
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

It is obvious already, that the loop should exit.

This revision is now accepted and ready to land.May 3 2023, 11:46 AM
vporpo added inline comments.May 3 2023, 11:52 AM
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
14087

How is it obvious? This is exactly what the assertion is checking: if the assertion triggers it means that the loop should not exit and that break is wrong.

Anyway, I think we have already spent too much time on this and it is not that important. I will change it to "Expected stack is epxected" as you originally proposed, even though I think such messages are not very useful.

vporpo updated this revision to Diff 519196.May 3 2023, 11:56 AM

Changed assertion message to "Expected empty stack".

ABataev accepted this revision.May 3 2023, 12:25 PM

Still LG

This revision was landed with ongoing or failed builds.May 3 2023, 12:49 PM
This revision was automatically updated to reflect the committed changes.