@@ -739,6 +739,217 @@ class SchedBoundary {
739
739
#endif
740
740
};
741
741
742
+ // / Base class for GenericScheduler. This class maintains information about
743
+ // / scheduling candidates based on TargetSchedModel making it easy to implement
744
+ // / heuristics for either preRA or postRA scheduling.
745
+ class GenericSchedulerBase : public MachineSchedStrategy {
746
+ public:
747
+ // / Represent the type of SchedCandidate found within a single queue.
748
+ // / pickNodeBidirectional depends on these listed by decreasing priority.
749
+ enum CandReason {
750
+ NoCand, PhysRegCopy, RegExcess, RegCritical, Stall, Cluster, Weak, RegMax,
751
+ ResourceReduce, ResourceDemand, BotHeightReduce, BotPathReduce,
752
+ TopDepthReduce, TopPathReduce, NextDefUse, NodeOrder};
753
+
754
+ #ifndef NDEBUG
755
+ static const char *getReasonStr (GenericSchedulerBase::CandReason Reason);
756
+ #endif
757
+
758
+ // / Policy for scheduling the next instruction in the candidate's zone.
759
+ struct CandPolicy {
760
+ bool ReduceLatency;
761
+ unsigned ReduceResIdx;
762
+ unsigned DemandResIdx;
763
+
764
+ CandPolicy (): ReduceLatency(false ), ReduceResIdx(0 ), DemandResIdx(0 ) {}
765
+ };
766
+
767
+ // / Status of an instruction's critical resource consumption.
768
+ struct SchedResourceDelta {
769
+ // Count critical resources in the scheduled region required by SU.
770
+ unsigned CritResources;
771
+
772
+ // Count critical resources from another region consumed by SU.
773
+ unsigned DemandedResources;
774
+
775
+ SchedResourceDelta (): CritResources(0 ), DemandedResources(0 ) {}
776
+
777
+ bool operator ==(const SchedResourceDelta &RHS) const {
778
+ return CritResources == RHS.CritResources
779
+ && DemandedResources == RHS.DemandedResources ;
780
+ }
781
+ bool operator !=(const SchedResourceDelta &RHS) const {
782
+ return !operator ==(RHS);
783
+ }
784
+ };
785
+
786
+ // / Store the state used by GenericScheduler heuristics, required for the
787
+ // / lifetime of one invocation of pickNode().
788
+ struct SchedCandidate {
789
+ CandPolicy Policy;
790
+
791
+ // The best SUnit candidate.
792
+ SUnit *SU;
793
+
794
+ // The reason for this candidate.
795
+ CandReason Reason;
796
+
797
+ // Set of reasons that apply to multiple candidates.
798
+ uint32_t RepeatReasonSet;
799
+
800
+ // Register pressure values for the best candidate.
801
+ RegPressureDelta RPDelta;
802
+
803
+ // Critical resource consumption of the best candidate.
804
+ SchedResourceDelta ResDelta;
805
+
806
+ SchedCandidate (const CandPolicy &policy)
807
+ : Policy(policy), SU(nullptr ), Reason(NoCand), RepeatReasonSet(0 ) {}
808
+
809
+ bool isValid () const { return SU; }
810
+
811
+ // Copy the status of another candidate without changing policy.
812
+ void setBest (SchedCandidate &Best) {
813
+ assert (Best.Reason != NoCand && " uninitialized Sched candidate" );
814
+ SU = Best.SU ;
815
+ Reason = Best.Reason ;
816
+ RPDelta = Best.RPDelta ;
817
+ ResDelta = Best.ResDelta ;
818
+ }
819
+
820
+ bool isRepeat (CandReason R) { return RepeatReasonSet & (1 << R); }
821
+ void setRepeat (CandReason R) { RepeatReasonSet |= (1 << R); }
822
+
823
+ void initResourceDelta (const ScheduleDAGMI *DAG,
824
+ const TargetSchedModel *SchedModel);
825
+ };
826
+
827
+ protected:
828
+ const MachineSchedContext *Context;
829
+ const TargetSchedModel *SchedModel;
830
+ const TargetRegisterInfo *TRI;
831
+
832
+ SchedRemainder Rem;
833
+ protected:
834
+ GenericSchedulerBase (const MachineSchedContext *C):
835
+ Context (C), SchedModel(nullptr ), TRI(nullptr ) {}
836
+
837
+ void setPolicy (CandPolicy &Policy, bool IsPostRA, SchedBoundary &CurrZone,
838
+ SchedBoundary *OtherZone);
839
+
840
+ #ifndef NDEBUG
841
+ void traceCandidate (const SchedCandidate &Cand);
842
+ #endif
843
+ };
844
+
845
+ // / GenericScheduler shrinks the unscheduled zone using heuristics to balance
846
+ // / the schedule.
847
+ class GenericScheduler : public GenericSchedulerBase {
848
+ ScheduleDAGMILive *DAG;
849
+
850
+ // State of the top and bottom scheduled instruction boundaries.
851
+ SchedBoundary Top;
852
+ SchedBoundary Bot;
853
+
854
+ MachineSchedPolicy RegionPolicy;
855
+ public:
856
+ GenericScheduler (const MachineSchedContext *C):
857
+ GenericSchedulerBase (C), DAG(nullptr ), Top(SchedBoundary::TopQID, " TopQ" ),
858
+ Bot (SchedBoundary::BotQID, " BotQ" ) {}
859
+
860
+ void initPolicy (MachineBasicBlock::iterator Begin,
861
+ MachineBasicBlock::iterator End,
862
+ unsigned NumRegionInstrs) override ;
863
+
864
+ bool shouldTrackPressure () const override {
865
+ return RegionPolicy.ShouldTrackPressure ;
866
+ }
867
+
868
+ void initialize (ScheduleDAGMI *dag) override ;
869
+
870
+ SUnit *pickNode (bool &IsTopNode) override ;
871
+
872
+ void schedNode (SUnit *SU, bool IsTopNode) override ;
873
+
874
+ void releaseTopNode (SUnit *SU) override {
875
+ Top.releaseTopNode (SU);
876
+ }
877
+
878
+ void releaseBottomNode (SUnit *SU) override {
879
+ Bot.releaseBottomNode (SU);
880
+ }
881
+
882
+ void registerRoots () override ;
883
+
884
+ protected:
885
+ void checkAcyclicLatency ();
886
+
887
+ void tryCandidate (SchedCandidate &Cand,
888
+ SchedCandidate &TryCand,
889
+ SchedBoundary &Zone,
890
+ const RegPressureTracker &RPTracker,
891
+ RegPressureTracker &TempTracker);
892
+
893
+ SUnit *pickNodeBidirectional (bool &IsTopNode);
894
+
895
+ void pickNodeFromQueue (SchedBoundary &Zone,
896
+ const RegPressureTracker &RPTracker,
897
+ SchedCandidate &Candidate);
898
+
899
+ void reschedulePhysRegCopies (SUnit *SU, bool isTop);
900
+ };
901
+
902
+ // / PostGenericScheduler - Interface to the scheduling algorithm used by
903
+ // / ScheduleDAGMI.
904
+ // /
905
+ // / Callbacks from ScheduleDAGMI:
906
+ // / initPolicy -> initialize(DAG) -> registerRoots -> pickNode ...
907
+ class PostGenericScheduler : public GenericSchedulerBase {
908
+ ScheduleDAGMI *DAG;
909
+ SchedBoundary Top;
910
+ SmallVector<SUnit*, 8 > BotRoots;
911
+ public:
912
+ PostGenericScheduler (const MachineSchedContext *C):
913
+ GenericSchedulerBase (C), Top(SchedBoundary::TopQID, " TopQ" ) {}
914
+
915
+ virtual ~PostGenericScheduler () {}
916
+
917
+ void initPolicy (MachineBasicBlock::iterator Begin,
918
+ MachineBasicBlock::iterator End,
919
+ unsigned NumRegionInstrs) override {
920
+ /* no configurable policy */
921
+ };
922
+
923
+ // / PostRA scheduling does not track pressure.
924
+ bool shouldTrackPressure () const override { return false ; }
925
+
926
+ void initialize (ScheduleDAGMI *Dag) override ;
927
+
928
+ void registerRoots () override ;
929
+
930
+ SUnit *pickNode (bool &IsTopNode) override ;
931
+
932
+ void scheduleTree (unsigned SubtreeID) override {
933
+ llvm_unreachable (" PostRA scheduler does not support subtree analysis." );
934
+ }
935
+
936
+ void schedNode (SUnit *SU, bool IsTopNode) override ;
937
+
938
+ void releaseTopNode (SUnit *SU) override {
939
+ Top.releaseTopNode (SU);
940
+ }
941
+
942
+ // Only called for roots.
943
+ void releaseBottomNode (SUnit *SU) override {
944
+ BotRoots.push_back (SU);
945
+ }
946
+
947
+ protected:
948
+ void tryCandidate (SchedCandidate &Cand, SchedCandidate &TryCand);
949
+
950
+ void pickNodeFromQueue (SchedCandidate &Cand);
951
+ };
952
+
742
953
} // namespace llvm
743
954
744
955
#endif
0 commit comments