8
8
9
9
#include " llvm/Transforms/Scalar/StructurizeCFG.h"
10
10
#include " llvm/ADT/DenseMap.h"
11
- #include " llvm/ADT/EquivalenceClasses.h"
12
11
#include " llvm/ADT/MapVector.h"
13
12
#include " llvm/ADT/SCCIterator.h"
14
13
#include " llvm/ADT/STLExtras.h"
@@ -289,10 +288,6 @@ class StructurizeCFG {
289
288
void findUndefBlocks (BasicBlock *PHIBlock,
290
289
const SmallSet<BasicBlock *, 8 > &Incomings,
291
290
SmallVector<BasicBlock *> &UndefBlks) const ;
292
-
293
- void mergeIfCompatible (EquivalenceClasses<PHINode *> &PhiClasses, PHINode *A,
294
- PHINode *B);
295
-
296
291
void setPhiValues ();
297
292
298
293
void simplifyAffectedPhis ();
@@ -715,131 +710,39 @@ void StructurizeCFG::findUndefBlocks(
715
710
}
716
711
}
717
712
718
- // If two phi nodes have compatible incoming values (for each
719
- // incoming block, either they have the same incoming value or only one phi
720
- // node has an incoming value), let them share the merged incoming values. The
721
- // merge process is guided by the equivalence information from \p PhiClasses.
722
- // The function will possibly update the incoming values of leader phi in
723
- // DeletedPhis.
724
- void StructurizeCFG::mergeIfCompatible (
725
- EquivalenceClasses<PHINode *> &PhiClasses, PHINode *A, PHINode *B) {
726
- auto ItA = PhiClasses.findLeader (PhiClasses.insert (A));
727
- auto ItB = PhiClasses.findLeader (PhiClasses.insert (B));
728
- // They are already in the same class, no work needed.
729
- if (ItA == ItB)
730
- return ;
731
-
732
- PHINode *LeaderA = *ItA;
733
- PHINode *LeaderB = *ItB;
734
- BBValueVector &IncomingA = DeletedPhis[LeaderA->getParent ()][LeaderA];
735
- BBValueVector &IncomingB = DeletedPhis[LeaderB->getParent ()][LeaderB];
736
-
737
- DenseMap<BasicBlock *, Value *> Mergeable (IncomingA.begin (), IncomingA.end ());
738
- for (auto [BB, V] : IncomingB) {
739
- auto BBIt = Mergeable.find (BB);
740
- if (BBIt != Mergeable.end () && BBIt->second != V)
741
- return ;
742
- // Either IncomingA does not have this value or IncomingA has the same
743
- // value.
744
- Mergeable.insert ({BB, V});
745
- }
746
-
747
- // Update the incoming value of leaderA.
748
- IncomingA.assign (Mergeable.begin (), Mergeable.end ());
749
- PhiClasses.unionSets (ItA, ItB);
750
- }
751
-
752
713
// / Add the real PHI value as soon as everything is set up
753
714
void StructurizeCFG::setPhiValues () {
754
715
SmallVector<PHINode *, 8 > InsertedPhis;
755
716
SSAUpdater Updater (&InsertedPhis);
756
- DenseMap<BasicBlock *, SmallVector<BasicBlock *>> UndefBlksMap;
757
-
758
- // Find phi nodes that have compatible incoming values (either they have
759
- // the same value for the same block or only one phi node has an incoming
760
- // value, see example below). We only search again the phi's that are
761
- // referenced by another phi, which is the case we care about.
762
- //
763
- // For example (-- means no incoming value):
764
- // phi1 : BB1:phi2 BB2:v BB3:--
765
- // phi2: BB1:-- BB2:v BB3:w
766
- //
767
- // Then we can merge these incoming values and let phi1, phi2 use the
768
- // same set of incoming values:
769
- //
770
- // phi1&phi2: BB1:phi2 BB2:v BB3:w
771
- //
772
- // By doing this, phi1 and phi2 would share more intermediate phi nodes.
773
- // This would help reduce the number of phi nodes during SSA reconstruction
774
- // and ultimately result in fewer COPY instructions.
775
- //
776
- // This should be correct, because if a phi node does not have incoming
777
- // value from certain block, this means the block is not the predecessor
778
- // of the parent block, so we actually don't care about its incoming value.
779
- EquivalenceClasses<PHINode *> PhiClasses;
780
- for (const auto &[To, From] : AddedPhis) {
781
- auto OldPhiIt = DeletedPhis.find (To);
782
- if (OldPhiIt == DeletedPhis.end ())
783
- continue ;
784
-
785
- PhiMap &BlkPhis = OldPhiIt->second ;
786
- SmallVector<BasicBlock *> &UndefBlks =
787
- UndefBlksMap.FindAndConstruct (To).second ;
788
- SmallSet<BasicBlock *, 8 > Incomings;
789
-
790
- // Get the undefined blocks shared by all the phi nodes.
791
- if (!BlkPhis.empty ()) {
792
- for (const auto &VI : BlkPhis.front ().second )
793
- Incomings.insert (VI.first );
794
- findUndefBlocks (To, Incomings, UndefBlks);
795
- }
796
-
797
- for (const auto &[Phi, Incomings] : OldPhiIt->second ) {
798
- SmallVector<PHINode *> IncomingPHIs;
799
- for (const auto &[BB, V] : Incomings) {
800
- // First, for each phi, check whether it has incoming value which is
801
- // another phi.
802
- if (PHINode *P = dyn_cast<PHINode>(V))
803
- IncomingPHIs.push_back (P);
804
- }
805
-
806
- for (auto *OtherPhi : IncomingPHIs) {
807
- // Skip phis that are unrelated to the phi reconstruction for now.
808
- if (!DeletedPhis.contains (OtherPhi->getParent ()))
809
- continue ;
810
- mergeIfCompatible (PhiClasses, Phi, OtherPhi);
811
- }
812
- }
813
- }
814
-
815
717
for (const auto &AddedPhi : AddedPhis) {
816
718
BasicBlock *To = AddedPhi.first ;
817
719
const BBVector &From = AddedPhi.second ;
818
720
819
721
if (!DeletedPhis.count (To))
820
722
continue ;
821
723
724
+ SmallVector<BasicBlock *> UndefBlks;
725
+ bool CachedUndefs = false ;
822
726
PhiMap &Map = DeletedPhis[To];
823
- SmallVector<BasicBlock *> &UndefBlks = UndefBlksMap[To];
824
- for ( const auto &[ Phi, Incoming] : Map) {
727
+ for ( const auto &PI : Map) {
728
+ PHINode * Phi = PI. first ;
825
729
Value *Undef = UndefValue::get (Phi->getType ());
826
730
Updater.Initialize (Phi->getType (), " " );
827
731
Updater.AddAvailableValue (&Func->getEntryBlock (), Undef);
828
732
Updater.AddAvailableValue (To, Undef);
829
733
830
- // Use leader phi's incoming if there is.
831
- auto LeaderIt = PhiClasses.findLeader (Phi);
832
- bool UseIncomingOfLeader =
833
- LeaderIt != PhiClasses.member_end () && *LeaderIt != Phi;
834
- const auto &IncomingMap =
835
- UseIncomingOfLeader ? DeletedPhis[(*LeaderIt)->getParent ()][*LeaderIt]
836
- : Incoming;
837
-
734
+ SmallSet<BasicBlock *, 8 > Incomings;
838
735
SmallVector<BasicBlock *> ConstantPreds;
839
- for (const auto &[BB, V] : IncomingMap) {
840
- Updater.AddAvailableValue (BB, V);
841
- if (isa<Constant>(V))
842
- ConstantPreds.push_back (BB);
736
+ for (const auto &VI : PI.second ) {
737
+ Incomings.insert (VI.first );
738
+ Updater.AddAvailableValue (VI.first , VI.second );
739
+ if (isa<Constant>(VI.second ))
740
+ ConstantPreds.push_back (VI.first );
741
+ }
742
+
743
+ if (!CachedUndefs) {
744
+ findUndefBlocks (To, Incomings, UndefBlks);
745
+ CachedUndefs = true ;
843
746
}
844
747
845
748
for (auto UB : UndefBlks) {
@@ -850,18 +753,17 @@ void StructurizeCFG::setPhiValues() {
850
753
if (any_of (ConstantPreds,
851
754
[&](BasicBlock *CP) { return DT->dominates (CP, UB); }))
852
755
continue ;
853
- // Maybe already get a value through sharing with other phi nodes.
854
- if (Updater.HasValueForBlock (UB))
855
- continue ;
856
-
857
756
Updater.AddAvailableValue (UB, Undef);
858
757
}
859
758
860
759
for (BasicBlock *FI : From)
861
760
Phi->setIncomingValueForBlock (FI, Updater.GetValueAtEndOfBlock (FI));
862
761
AffectedPhis.push_back (Phi);
863
762
}
763
+
764
+ DeletedPhis.erase (To);
864
765
}
766
+ assert (DeletedPhis.empty ());
865
767
866
768
AffectedPhis.append (InsertedPhis.begin (), InsertedPhis.end ());
867
769
}
0 commit comments