diff options
Diffstat (limited to 'include/llvm/CodeGen/MachineScheduler.h')
-rw-r--r-- | include/llvm/CodeGen/MachineScheduler.h | 96 |
1 files changed, 67 insertions, 29 deletions
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index 358fd5a3732a..06e992179031 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -66,8 +66,6 @@ // // void <SubTarget>Subtarget:: // overrideSchedPolicy(MachineSchedPolicy &Policy, -// MachineInstr *begin, -// MachineInstr *end, // unsigned NumRegionInstrs) const { // Policy.<Flag> = true; // } @@ -81,6 +79,7 @@ #include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/RegisterPressure.h" #include "llvm/CodeGen/ScheduleDAGInstrs.h" +#include "llvm/CodeGen/ScheduleDAGMutation.h" #include <memory> namespace llvm { @@ -150,6 +149,9 @@ class ScheduleDAGMI; struct MachineSchedPolicy { // Allow the scheduler to disable register pressure tracking. bool ShouldTrackPressure; + /// Track LaneMasks to allow reordering of independent subregister writes + /// of the same vreg. \sa MachineSchedStrategy::shouldTrackLaneMasks() + bool ShouldTrackLaneMasks; // Allow the scheduler to force top-down or bottom-up scheduling. If neither // is true, the scheduler runs in both directions and converges. @@ -160,8 +162,8 @@ struct MachineSchedPolicy { // first. bool DisableLatencyHeuristic; - MachineSchedPolicy(): ShouldTrackPressure(false), OnlyTopDown(false), - OnlyBottomUp(false), DisableLatencyHeuristic(false) {} + MachineSchedPolicy(): ShouldTrackPressure(false), ShouldTrackLaneMasks(false), + OnlyTopDown(false), OnlyBottomUp(false), DisableLatencyHeuristic(false) {} }; /// MachineSchedStrategy - Interface to the scheduling algorithm used by @@ -185,6 +187,11 @@ public: /// initializing this strategy. Called after initPolicy. virtual bool shouldTrackPressure() const { return true; } + /// Returns true if lanemasks should be tracked. LaneMask tracking is + /// necessary to reorder independent subregister defs for the same vreg. + /// This has to be enabled in combination with shouldTrackPressure(). + virtual bool shouldTrackLaneMasks() const { return false; } + /// Initialize the strategy after building the DAG for a new region. virtual void initialize(ScheduleDAGMI *DAG) = 0; @@ -212,15 +219,6 @@ public: virtual void releaseBottomNode(SUnit *SU) = 0; }; -/// Mutate the DAG as a postpass after normal DAG building. -class ScheduleDAGMutation { - virtual void anchor(); -public: - virtual ~ScheduleDAGMutation() {} - - virtual void apply(ScheduleDAGMI *DAG) = 0; -}; - /// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply /// schedules machine instructions according to the given MachineSchedStrategy /// without much extra book-keeping. This is the common functionality between @@ -371,6 +369,7 @@ protected: /// Register pressure in this region computed by initRegPressure. bool ShouldTrackPressure; + bool ShouldTrackLaneMasks; IntervalPressure RegPressure; RegPressureTracker RPTracker; @@ -387,13 +386,18 @@ protected: IntervalPressure BotPressure; RegPressureTracker BotRPTracker; + /// True if disconnected subregister components are already renamed. + /// The renaming is only done on demand if lane masks are tracked. + bool DisconnectedComponentsRenamed; + public: ScheduleDAGMILive(MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S) : ScheduleDAGMI(C, std::move(S), /*RemoveKillFlags=*/false), RegClassInfo(C->RegClassInfo), DFSResult(nullptr), - ShouldTrackPressure(false), RPTracker(RegPressure), - TopRPTracker(TopPressure), BotRPTracker(BotPressure) {} + ShouldTrackPressure(false), ShouldTrackLaneMasks(false), + RPTracker(RegPressure), TopRPTracker(TopPressure), + BotRPTracker(BotPressure), DisconnectedComponentsRenamed(false) {} ~ScheduleDAGMILive() override; @@ -455,6 +459,10 @@ protected: /// bottom of the DAG region without covereing any unscheduled instruction. void buildDAGWithRegPressure(); + /// Release ExitSU predecessors and setup scheduler queues. Re-position + /// the Top RP tracker in case the region beginning has changed. + void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots); + /// Move an instruction and update register pressure. void scheduleMI(SUnit *SU, bool IsTopNode); @@ -462,7 +470,7 @@ protected: void initRegPressure(); - void updatePressureDiffs(ArrayRef<unsigned> LiveUses); + void updatePressureDiffs(ArrayRef<RegisterMaskPair> LiveUses); void updateScheduledPressure(const SUnit *SU, const std::vector<unsigned> &NewMaxPressure); @@ -753,9 +761,9 @@ class GenericSchedulerBase : public MachineSchedStrategy { public: /// Represent the type of SchedCandidate found within a single queue. /// pickNodeBidirectional depends on these listed by decreasing priority. - enum CandReason { - NoCand, PhysRegCopy, RegExcess, RegCritical, Stall, Cluster, Weak, RegMax, - ResourceReduce, ResourceDemand, BotHeightReduce, BotPathReduce, + enum CandReason : uint8_t { + NoCand, Only1, PhysRegCopy, RegExcess, RegCritical, Stall, Cluster, Weak, + RegMax, ResourceReduce, ResourceDemand, BotHeightReduce, BotPathReduce, TopDepthReduce, TopPathReduce, NextDefUse, NodeOrder}; #ifndef NDEBUG @@ -769,6 +777,15 @@ public: unsigned DemandResIdx; CandPolicy(): ReduceLatency(false), ReduceResIdx(0), DemandResIdx(0) {} + + bool operator==(const CandPolicy &RHS) const { + return ReduceLatency == RHS.ReduceLatency && + ReduceResIdx == RHS.ReduceResIdx && + DemandResIdx == RHS.DemandResIdx; + } + bool operator!=(const CandPolicy &RHS) const { + return !(*this == RHS); + } }; /// Status of an instruction's critical resource consumption. @@ -801,8 +818,8 @@ public: // The reason for this candidate. CandReason Reason; - // Set of reasons that apply to multiple candidates. - uint32_t RepeatReasonSet; + // Whether this candidate should be scheduled at top/bottom. + bool AtTop; // Register pressure values for the best candidate. RegPressureDelta RPDelta; @@ -810,8 +827,17 @@ public: // Critical resource consumption of the best candidate. SchedResourceDelta ResDelta; - SchedCandidate(const CandPolicy &policy) - : Policy(policy), SU(nullptr), Reason(NoCand), RepeatReasonSet(0) {} + SchedCandidate() { reset(CandPolicy()); } + SchedCandidate(const CandPolicy &Policy) { reset(Policy); } + + void reset(const CandPolicy &NewPolicy) { + Policy = NewPolicy; + SU = nullptr; + Reason = NoCand; + AtTop = false; + RPDelta = RegPressureDelta(); + ResDelta = SchedResourceDelta(); + } bool isValid() const { return SU; } @@ -820,13 +846,11 @@ public: assert(Best.Reason != NoCand && "uninitialized Sched candidate"); SU = Best.SU; Reason = Best.Reason; + AtTop = Best.AtTop; RPDelta = Best.RPDelta; ResDelta = Best.ResDelta; } - bool isRepeat(CandReason R) { return RepeatReasonSet & (1 << R); } - void setRepeat(CandReason R) { RepeatReasonSet |= (1 << R); } - void initResourceDelta(const ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel); }; @@ -858,6 +882,11 @@ class GenericScheduler : public GenericSchedulerBase { SchedBoundary Top; SchedBoundary Bot; + /// Candidate last picked from Top boundary. + SchedCandidate TopCand; + /// Candidate last picked from Bot boundary. + SchedCandidate BotCand; + MachineSchedPolicy RegionPolicy; public: GenericScheduler(const MachineSchedContext *C): @@ -874,6 +903,10 @@ public: return RegionPolicy.ShouldTrackPressure; } + bool shouldTrackLaneMasks() const override { + return RegionPolicy.ShouldTrackLaneMasks; + } + void initialize(ScheduleDAGMI *dag) override; SUnit *pickNode(bool &IsTopNode) override; @@ -882,10 +915,12 @@ public: void releaseTopNode(SUnit *SU) override { Top.releaseTopNode(SU); + TopCand.SU = nullptr; } void releaseBottomNode(SUnit *SU) override { Bot.releaseBottomNode(SU); + BotCand.SU = nullptr; } void registerRoots() override; @@ -893,15 +928,18 @@ public: protected: void checkAcyclicLatency(); + void initCandidate(SchedCandidate &Cand, SUnit *SU, bool AtTop, + const RegPressureTracker &RPTracker, + RegPressureTracker &TempTracker); + void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, - SchedBoundary &Zone, - const RegPressureTracker &RPTracker, - RegPressureTracker &TempTracker); + SchedBoundary *Zone); SUnit *pickNodeBidirectional(bool &IsTopNode); void pickNodeFromQueue(SchedBoundary &Zone, + const CandPolicy &ZonePolicy, const RegPressureTracker &RPTracker, SchedCandidate &Candidate); |