1//===- HexagonMachineScheduler.cpp - MI Scheduler for Hexagon -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// MachineScheduler schedules machine instructions after phi elimination. It
10// preserves LiveIntervals so it can be invoked before register allocation.
11//
12//===----------------------------------------------------------------------===//
13
14#include "HexagonMachineScheduler.h"
15#include "HexagonInstrInfo.h"
16#include "HexagonSubtarget.h"
17#include "llvm/CodeGen/MachineScheduler.h"
18#include "llvm/CodeGen/ScheduleDAG.h"
19#include "llvm/CodeGen/VLIWMachineScheduler.h"
20
21using namespace llvm;
22
23#define DEBUG_TYPE "machine-scheduler"
24
25/// Return true if there is a dependence between SUd and SUu.
26bool HexagonVLIWResourceModel::hasDependence(const SUnit *SUd,
27 const SUnit *SUu) {
28 const auto *QII = static_cast<const HexagonInstrInfo *>(TII);
29
30 // Enable .cur formation.
31 if (QII->mayBeCurLoad(MI: *SUd->getInstr()))
32 return false;
33
34 if (QII->canExecuteInBundle(First: *SUd->getInstr(), Second: *SUu->getInstr()))
35 return false;
36
37 return VLIWResourceModel::hasDependence(SUd, SUu);
38}
39
40VLIWResourceModel *HexagonConvergingVLIWScheduler::createVLIWResourceModel(
41 const TargetSubtargetInfo &STI, const TargetSchedModel *SchedModel) const {
42 return new HexagonVLIWResourceModel(STI, SchedModel);
43}
44
45int HexagonConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU,
46 SchedCandidate &Candidate,
47 RegPressureDelta &Delta,
48 bool verbose) {
49 int ResCount =
50 ConvergingVLIWScheduler::SchedulingCost(Q, SU, Candidate, Delta, verbose);
51
52 if (!SU || SU->isScheduled)
53 return ResCount;
54
55 auto &QST = DAG->MF.getSubtarget<HexagonSubtarget>();
56 auto &QII = *QST.getInstrInfo();
57 if (SU->isInstr() && QII.mayBeCurLoad(MI: *SU->getInstr())) {
58 if (Q.getID() == TopQID &&
59 Top.ResourceModel->isResourceAvailable(SU, IsTop: true)) {
60 ResCount += PriorityTwo;
61 LLVM_DEBUG(if (verbose) dbgs() << "C|");
62 } else if (Q.getID() == BotQID &&
63 Bot.ResourceModel->isResourceAvailable(SU, IsTop: false)) {
64 ResCount += PriorityTwo;
65 LLVM_DEBUG(if (verbose) dbgs() << "C|");
66 }
67 }
68
69 return ResCount;
70}
71