[PATCH] D84951: [LV] Try to sink users recursively for first-order recurrences.
Florian Hahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed May 26 13:28:14 PDT 2021
fhahn added inline comments.
================
Comment at: llvm/lib/Analysis/IVDescriptors.cpp:748
+ // TODO: Consider extending this sinking to handle memory instructions.
+ SetVector<Instruction *> UserWorkList;
+ auto PushUsers = [&UserWorkList](Instruction *I) {
----------------
Ayal wrote:
> The candidates need to be maintained in a **set** in order to avoid considering them repeatedly. May as well have this set ordered by dominance relation, instead of sorting it at the end.
> E.g., let UserWorkList be a SmallVector that is pushed and popped until empty, where candidates are checked to be sunkable when being pushed into it (instead of when being popped/traversed), after successfully inserting them into the sorted InstrsToSink set. WDYT?
I updated the code to use a ordered set for InstrToSink as suggested. I think the only thing is that we might check the same instruction multiple times, if it is already dominated by `Previous`. In that case, it won't get inserted into `InstrToSink`. But I think that should be fine.
================
Comment at: llvm/lib/Analysis/IVDescriptors.cpp:778
+ // If we reach a PHI node that is not dominated by Previous, we reached a
+ // header PHI. No need for sinking.
+ if (isa<PHINode>(I))
----------------
Ayal wrote:
> This sounds right, given that we only consider I's that post-dominate the FOR phi.
> Seems somewhat odd though, calls for an assert and a testcase.
I think there's already a test case where this can happen: `@sink_into_replication_region`. I added an assert that the instruction must be in the same BB as the starting phi.
================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:9136
// Apply Sink-After legal constraints.
- for (auto &Entry : SinkAfter) {
+ for (auto &Entry : reverse(SinkAfter)) {
VPRecipeBase *Sink = RecipeBuilder.getRecipe(Entry.first);
----------------
Ayal wrote:
> Ayal wrote:
> > Sort multiple users in reverse instead of reversing all here?
> > Or rather - have them sink after each other instead of all sinking after Previous, thereby expressing their desired order and dependencies directly?
> (BTW, note that by having multiple users sink after each other, it is also possible to reorder them lazily instead of sorting: when moving Sink after Target, check if Target should also be sunk - and if so sink it first, recursively, while taking care to sink each SinkAfter instruction once. Multiple users is the only exception to sinking an instruction after a Target that should itself sink.)
I went with `Or rather - have them sink after each other instead of all sinking after Previous, thereby expressing their desired order and dependencies directly`
The dependencies are chained together in `SinkAfter` now. But keeping them sorted to start with seems simpler overall and ensures that map is accurate. WDYT?
================
Comment at: llvm/test/Transforms/LoopVectorize/first-order-recurrence-complex.ll:287
+
+; Users that are phi nodes cannot be sunk.
+define void @cannot_sink_phi(i32* %ptr) {
----------------
Ayal wrote:
> bmahjour wrote:
> > The comment implies that all phi nodes prevent sinking, but I think here the reason `%first_time.1` cannot be sunk past `%for.next` is because (one of) the user(s) of `%first_time.1` is the Previous itself. If that's correct, can we say "some phi nodes"?
> The (first) reason `%first_time.1` cannot be sunk is because it appears outside the header and is not dominated by Previous. The fact that it feeds Previous is a second sinking-preventing reason.
Good point, I adjusted the comment.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D84951/new/
https://reviews.llvm.org/D84951
More information about the llvm-commits
mailing list