34
34
#include " llvm/Support/Debug.h"
35
35
#include " llvm/Support/KnownBits.h"
36
36
37
+ #include < set>
38
+
37
39
using namespace llvm ;
38
40
using namespace llvm ::PatternMatch;
39
41
@@ -715,7 +717,7 @@ bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop,
715
717
716
718
bool RecurrenceDescriptor::isFirstOrderRecurrence (
717
719
PHINode *Phi, Loop *TheLoop,
718
- DenseMap <Instruction *, Instruction *> &SinkAfter, DominatorTree *DT) {
720
+ MapVector <Instruction *, Instruction *> &SinkAfter, DominatorTree *DT) {
719
721
720
722
// Ensure the phi node is in the loop header and has two incoming values.
721
723
if (Phi->getParent () != TheLoop->getHeader () ||
@@ -741,51 +743,76 @@ bool RecurrenceDescriptor::isFirstOrderRecurrence(
741
743
SinkAfter.count (Previous)) // Cannot rely on dominance due to motion.
742
744
return false ;
743
745
744
- // Ensure every user of the phi node is dominated by the previous value.
745
- // The dominance requirement ensures the loop vectorizer will not need to
746
- // vectorize the initial value prior to the first iteration of the loop.
747
- // TODO: Consider extending this sinking to handle memory instructions and
748
- // phis with multiple users .
749
-
750
- // Returns true, if all users of I are dominated by DominatedBy.
751
- auto allUsesDominatedBy = [DT](Instruction *I, Instruction *DominatedBy) {
752
- return all_of (I-> uses (), [DT, DominatedBy](Use &U) {
753
- return DT-> dominates (DominatedBy, U);
754
- } );
746
+ // Ensure every user of the phi node (recursively) is dominated by the
747
+ // previous value. The dominance requirement ensures the loop vectorizer will
748
+ // not need to vectorize the initial value prior to the first iteration of the
749
+ // loop.
750
+ // TODO: Consider extending this sinking to handle memory instructions .
751
+
752
+ // We optimistically assume we can sink all users after Previous. Keep a set
753
+ // of instructions to sink after Previous ordered by dominance in the common
754
+ // basic block. It will be applied to SinkAfter if all users can be sunk.
755
+ auto CompareByComesBefore = []( const Instruction *A, const Instruction *B) {
756
+ return A-> comesBefore (B );
755
757
};
758
+ std::set<Instruction *, decltype (CompareByComesBefore)> InstrsToSink (
759
+ CompareByComesBefore);
760
+
761
+ BasicBlock *PhiBB = Phi->getParent ();
762
+ SmallVector<Instruction *, 8 > WorkList;
763
+ auto TryToPushSinkCandidate = [&](Instruction *SinkCandidate) {
764
+ // Already sunk SinkCandidate.
765
+ if (SinkCandidate->getParent () == PhiBB &&
766
+ InstrsToSink.find (SinkCandidate) != InstrsToSink.end ())
767
+ return true ;
756
768
757
- if (Phi->hasOneUse ()) {
758
- Instruction *I = Phi->user_back ();
759
-
760
- // If the user of the PHI is also the incoming value, we potentially have a
761
- // reduction and which cannot be handled by sinking.
762
- if (Previous == I)
769
+ // Cyclic dependence.
770
+ if (Previous == SinkCandidate)
763
771
return false ;
764
772
765
- // We cannot sink terminator instructions.
766
- if (I->getParent ()->getTerminator () == I)
773
+ if (DT->dominates (Previous,
774
+ SinkCandidate)) // We already are good w/o sinking.
775
+ return true ;
776
+
777
+ if (SinkCandidate->getParent () != PhiBB ||
778
+ SinkCandidate->mayHaveSideEffects () ||
779
+ SinkCandidate->mayReadFromMemory () || SinkCandidate->isTerminator ())
767
780
return false ;
768
781
769
782
// Do not try to sink an instruction multiple times (if multiple operands
770
783
// are first order recurrences).
771
784
// TODO: We can support this case, by sinking the instruction after the
772
785
// 'deepest' previous instruction.
773
- if (SinkAfter.find (I ) != SinkAfter.end ())
786
+ if (SinkAfter.find (SinkCandidate ) != SinkAfter.end ())
774
787
return false ;
775
788
776
- if (DT->dominates (Previous, I)) // We already are good w/o sinking.
789
+ // If we reach a PHI node that is not dominated by Previous, we reached a
790
+ // header PHI. No need for sinking.
791
+ if (isa<PHINode>(SinkCandidate))
777
792
return true ;
778
793
779
- // We can sink any instruction without side effects, as long as all users
780
- // are dominated by the instruction we are sinking after.
781
- if (I->getParent () == Phi->getParent () && !I->mayHaveSideEffects () &&
782
- allUsesDominatedBy (I, Previous)) {
783
- SinkAfter[I] = Previous;
784
- return true ;
794
+ // Sink User tentatively and check its users
795
+ InstrsToSink.insert (SinkCandidate);
796
+ WorkList.push_back (SinkCandidate);
797
+ return true ;
798
+ };
799
+
800
+ WorkList.push_back (Phi);
801
+ // Try to recursively sink instructions and their users after Previous.
802
+ while (!WorkList.empty ()) {
803
+ Instruction *Current = WorkList.pop_back_val ();
804
+ for (User *User : Current->users ()) {
805
+ if (!TryToPushSinkCandidate (cast<Instruction>(User)))
806
+ return false ;
785
807
}
786
808
}
787
809
788
- return allUsesDominatedBy (Phi, Previous);
810
+ // We can sink all users of Phi. Update the mapping.
811
+ for (Instruction *I : InstrsToSink) {
812
+ SinkAfter[I] = Previous;
813
+ Previous = I;
814
+ }
815
+ return true ;
789
816
}
790
817
791
818
// / This function returns the identity element (or neutral element) for
0 commit comments