This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Add PHINode operands to worklist on instruction erasure
AbandonedPublic

Authored by luke on Jan 21 2023, 5:11 PM.

Details

Summary

If a phi node has one use, and that user has only one use itself, and
that one use is in turn the phi node, then the phi node is erased.
Simultaneously, whenever an instruction is erased, its operands are
added to the worklist as their use counts have changed.

But it's possible that the operand now only has one use and that use is
a phi node: So add the phi node to worklist so the phi node elimination
can occur.

This prevents the need to do lots of cascading iterations over a
function when eliminating phi nodes unlocks more potential phi node
eliminations.

Fixes #50564

Diff Detail

Event Timeline

luke created this revision.Jan 21 2023, 5:11 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 21 2023, 5:11 PM
luke requested review of this revision.Jan 21 2023, 5:11 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 21 2023, 5:11 PM
luke updated this revision to Diff 491111.Jan 21 2023, 5:11 PM

Remove erroneous include

luke added inline comments.Jan 21 2023, 5:15 PM
llvm/lib/Transforms/InstCombine/InstCombineInternal.h
422

Will this cause much extra work?
It certainly improves the pathological case in https://github.com/llvm/llvm-project/issues/50564, but not sure how this affects day to day cases.

The PHI node elimination that kicks in is at InstCombinePHI.cpp:1439

cpp
 // If this phi has a single use, and if that use just computes a value for 
 // the next iteration of a loop, delete the phi.  This occurs with unused 
 // induction variables, e.g. "for (int j = 0; ; ++j);".  Detecting this 
 // common case here is good because the only other things that catch this 
 // are induction variable analysis (sometimes) and ADCE, which is only run 
 // late. 
 if (PHIUser->hasOneUse() && 
     (isa<BinaryOperator>(PHIUser) || isa<GetElementPtrInst>(PHIUser)) && 
     PHIUser->user_back() == &PN) { 
   return replaceInstUsesWith(PN, PoisonValue::get(PN.getType())); 
 }

Another possible idea could be to somehow invert this and instead check on every instruction if it has one use that's a phi node.

luke added inline comments.Jan 21 2023, 5:21 PM
llvm/test/Transforms/InstCombine/phi-elimination-iteration.ll
17

Prior to this patch, three iterations are carried out because the %phi.a isn't added to the worklist

nikic added a comment.Jan 25 2023, 1:32 AM

Hm, this feels very hacky. I don't like the idea of adjusting the worklist management for specific patterns.

To suggest a possible alternative, it might be possible to extend isDeadPHICycle(), by making it look through side-effect free instructions, as well as multiple users. This will allow it to remove larger dead phi cycles, so it would not just peel off one phi cycle at a time, but could remove the whole graph at once. (Of course subject to the visitation limit -- with the current one of 16, that would mean we could remove 8 nested phi cycles in one go, which is probably good enough?)

llvm/test/Transforms/InstCombine/phi-elimination-iteration.ll
1

Use -instcombine-infinite-loop-threshold=2 to make sure it folds in one iteration instead.

luke added a comment.Jan 25 2023, 1:46 AM

Hm, this feels very hacky. I don't like the idea of adjusting the worklist management for specific patterns.

To suggest a possible alternative, it might be possible to extend isDeadPHICycle(), by making it look through side-effect free instructions, as well as multiple users. This will allow it to remove larger dead phi cycles, so it would not just peel off one phi cycle at a time, but could remove the whole graph at once. (Of course subject to the visitation limit -- with the current one of 16, that would mean we could remove 8 nested phi cycles in one go, which is probably good enough?)

I agree, I'm not a huge fan of this either. That sounds like a better direction: I'll look into it, thanks

nikic requested changes to this revision.Jan 25 2023, 2:59 AM

Marking this as changes requested for now, we'll can go back to it if that doesn't work out.

This revision now requires changes to proceed.Jan 25 2023, 2:59 AM
luke abandoned this revision.Jan 25 2023, 8:06 AM

Superseded by D142551