10b57cec5SDimitry Andric //===- HexagonMachineScheduler.cpp - MI Scheduler for Hexagon -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // MachineScheduler schedules machine instructions after phi elimination. It
100b57cec5SDimitry Andric // preserves LiveIntervals so it can be invoked before register allocation.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "HexagonMachineScheduler.h"
150b57cec5SDimitry Andric #include "HexagonInstrInfo.h"
160b57cec5SDimitry Andric #include "HexagonSubtarget.h"
17*0eae32dcSDimitry Andric #include "llvm/CodeGen/MachineScheduler.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/ScheduleDAG.h"
19*0eae32dcSDimitry Andric #include "llvm/CodeGen/VLIWMachineScheduler.h"
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric using namespace llvm;
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric #define DEBUG_TYPE "machine-scheduler"
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric /// Return true if there is a dependence between SUd and SUu.
hasDependence(const SUnit * SUd,const SUnit * SUu)26*0eae32dcSDimitry Andric bool HexagonVLIWResourceModel::hasDependence(const SUnit *SUd,
27*0eae32dcSDimitry Andric const SUnit *SUu) {
28*0eae32dcSDimitry Andric const auto *QII = static_cast<const HexagonInstrInfo *>(TII);
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric // Enable .cur formation.
31*0eae32dcSDimitry Andric if (QII->mayBeCurLoad(*SUd->getInstr()))
320b57cec5SDimitry Andric return false;
330b57cec5SDimitry Andric
34*0eae32dcSDimitry Andric if (QII->canExecuteInBundle(*SUd->getInstr(), *SUu->getInstr()))
350b57cec5SDimitry Andric return false;
360b57cec5SDimitry Andric
37*0eae32dcSDimitry Andric return VLIWResourceModel::hasDependence(SUd, SUu);
380b57cec5SDimitry Andric }
390b57cec5SDimitry Andric
createVLIWResourceModel(const TargetSubtargetInfo & STI,const TargetSchedModel * SchedModel) const40*0eae32dcSDimitry Andric VLIWResourceModel *HexagonConvergingVLIWScheduler::createVLIWResourceModel(
41*0eae32dcSDimitry Andric const TargetSubtargetInfo &STI, const TargetSchedModel *SchedModel) const {
42*0eae32dcSDimitry Andric return new HexagonVLIWResourceModel(STI, SchedModel);
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric
SchedulingCost(ReadyQueue & Q,SUnit * SU,SchedCandidate & Candidate,RegPressureDelta & Delta,bool verbose)45*0eae32dcSDimitry Andric int HexagonConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU,
460b57cec5SDimitry Andric SchedCandidate &Candidate,
470b57cec5SDimitry Andric RegPressureDelta &Delta,
480b57cec5SDimitry Andric bool verbose) {
49*0eae32dcSDimitry Andric int ResCount =
50*0eae32dcSDimitry Andric ConvergingVLIWScheduler::SchedulingCost(Q, SU, Candidate, Delta, verbose);
510b57cec5SDimitry Andric
520b57cec5SDimitry Andric if (!SU || SU->isScheduled)
530b57cec5SDimitry Andric return ResCount;
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric auto &QST = DAG->MF.getSubtarget<HexagonSubtarget>();
560b57cec5SDimitry Andric auto &QII = *QST.getInstrInfo();
570b57cec5SDimitry Andric if (SU->isInstr() && QII.mayBeCurLoad(*SU->getInstr())) {
580b57cec5SDimitry Andric if (Q.getID() == TopQID &&
590b57cec5SDimitry Andric Top.ResourceModel->isResourceAvailable(SU, true)) {
600b57cec5SDimitry Andric ResCount += PriorityTwo;
610b57cec5SDimitry Andric LLVM_DEBUG(if (verbose) dbgs() << "C|");
620b57cec5SDimitry Andric } else if (Q.getID() == BotQID &&
630b57cec5SDimitry Andric Bot.ResourceModel->isResourceAvailable(SU, false)) {
640b57cec5SDimitry Andric ResCount += PriorityTwo;
650b57cec5SDimitry Andric LLVM_DEBUG(if (verbose) dbgs() << "C|");
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric
690b57cec5SDimitry Andric return ResCount;
700b57cec5SDimitry Andric }
71