aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen/MachineScheduler.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/CodeGen/MachineScheduler.h')
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h96
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);