}
+/// Save the last formed packet
+void VLIWResourceModel::savePacket() {
+ OldPacket = Packet;
+}
+
/// Check if scheduling of this SU is possible
/// in the current packet.
/// It is _not_ precise (statefull), it is more like
// Artificially reset state.
if (!SU) {
ResourcesModel->clearResources();
+ savePacket();
Packet.clear();
TotalPackets++;
return false;
// start a new one.
if (!isResourceAvailable(SU)) {
ResourcesModel->clearResources();
+ savePacket();
Packet.clear();
TotalPackets++;
startNewCycle = true;
// we start fresh.
if (Packet.size() >= SchedModel->getIssueWidth()) {
ResourcesModel->clearResources();
+ savePacket();
Packet.clear();
TotalPackets++;
startNewCycle = true;
if (!SU || SU->isScheduled)
return ResCount;
+ MachineInstr *Instr = SU->getInstr();
+
// Forced priority is high.
if (SU->isScheduleHigh)
ResCount += PriorityOne;
ResCount -= (Delta.Excess.getUnitInc()*PriorityTwo);
ResCount -= (Delta.CriticalMax.getUnitInc()*PriorityTwo);
+ auto &QST = DAG->MF.getSubtarget<HexagonSubtarget>();
+ auto &QII = *QST.getInstrInfo();
+
+ // Give less preference to an instruction that will cause a stall with
+ // an instruction in the previous packet.
+ if (QII.isV60VectorInstruction(Instr)) {
+ // Check for stalls in the previous packet.
+ if (Q.getID() == TopQID) {
+ for (auto J : Top.ResourceModel->OldPacket)
+ if (QII.producesStall(J->getInstr(), Instr))
+ ResCount -= PriorityOne;
+ } else {
+ for (auto J : Bot.ResourceModel->OldPacket)
+ if (QII.producesStall(Instr, J->getInstr()))
+ ResCount -= PriorityOne;
+ }
+ }
+
DEBUG(if (verbose) dbgs() << " Total(" << ResCount << ")");
return ResCount;
unsigned TotalPackets;
public:
+ /// Save the last formed packet.
+ std::vector<SUnit*> OldPacket;
+
+public:
VLIWResourceModel(const TargetSubtargetInfo &STI, const TargetSchedModel *SM)
: SchedModel(SM), TotalPackets(0) {
- ResourcesModel = STI.getInstrInfo()->CreateTargetScheduleState(STI);
+ ResourcesModel = STI.getInstrInfo()->CreateTargetScheduleState(STI);
// This hard requirement could be relaxed,
// but for now do not let it proceed.
Packet.resize(SchedModel->getIssueWidth());
Packet.clear();
+ OldPacket.resize(SchedModel->getIssueWidth());
+ OldPacket.clear();
ResourcesModel->clearResources();
}
bool isResourceAvailable(SUnit *SU);
bool reserveResources(SUnit *SU);
+ void savePacket();
unsigned getTotalPackets() const { return TotalPackets; }
+
+ bool isInPacket(SUnit *SU) const {
+ return std::find(Packet.begin(), Packet.end(), SU) != Packet.end();
+ }
};
/// Extend the standard ScheduleDAGMI to provide more context and override the
/// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
/// time to do some work.
void schedule() override;
- /// Perform platform-specific DAG postprocessing.
- void postprocessDAG();
};
/// ConvergingVLIWScheduler shrinks the unscheduled zone using heuristics
void init(VLIWMachineScheduler *dag, const TargetSchedModel *smodel) {
DAG = dag;
SchedModel = smodel;
+ IssueCount = 0;
}
bool isTop() const {