1*e8d8bef9SDimitry Andric //===- MultiHazardRecognizer.cpp - Scheduler Support ----------------------===//
2*e8d8bef9SDimitry Andric //
3*e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e8d8bef9SDimitry Andric //
7*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8*e8d8bef9SDimitry Andric //
9*e8d8bef9SDimitry Andric // This file implements the MultiHazardRecognizer class, which is a wrapper
10*e8d8bef9SDimitry Andric // for a set of ScheduleHazardRecognizer instances
11*e8d8bef9SDimitry Andric //
12*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
13*e8d8bef9SDimitry Andric
14*e8d8bef9SDimitry Andric #include "llvm/CodeGen/MultiHazardRecognizer.h"
15*e8d8bef9SDimitry Andric #include "llvm/ADT/STLExtras.h"
16*e8d8bef9SDimitry Andric #include <algorithm>
17*e8d8bef9SDimitry Andric #include <functional>
18*e8d8bef9SDimitry Andric #include <numeric>
19*e8d8bef9SDimitry Andric
20*e8d8bef9SDimitry Andric using namespace llvm;
21*e8d8bef9SDimitry Andric
AddHazardRecognizer(std::unique_ptr<ScheduleHazardRecognizer> && R)22*e8d8bef9SDimitry Andric void MultiHazardRecognizer::AddHazardRecognizer(
23*e8d8bef9SDimitry Andric std::unique_ptr<ScheduleHazardRecognizer> &&R) {
24*e8d8bef9SDimitry Andric MaxLookAhead = std::max(MaxLookAhead, R->getMaxLookAhead());
25*e8d8bef9SDimitry Andric Recognizers.push_back(std::move(R));
26*e8d8bef9SDimitry Andric }
27*e8d8bef9SDimitry Andric
atIssueLimit() const28*e8d8bef9SDimitry Andric bool MultiHazardRecognizer::atIssueLimit() const {
29*e8d8bef9SDimitry Andric return llvm::any_of(Recognizers,
30*e8d8bef9SDimitry Andric std::mem_fn(&ScheduleHazardRecognizer::atIssueLimit));
31*e8d8bef9SDimitry Andric }
32*e8d8bef9SDimitry Andric
33*e8d8bef9SDimitry Andric ScheduleHazardRecognizer::HazardType
getHazardType(SUnit * SU,int Stalls)34*e8d8bef9SDimitry Andric MultiHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
35*e8d8bef9SDimitry Andric for (auto &R : Recognizers) {
36*e8d8bef9SDimitry Andric auto res = R->getHazardType(SU, Stalls);
37*e8d8bef9SDimitry Andric if (res != NoHazard)
38*e8d8bef9SDimitry Andric return res;
39*e8d8bef9SDimitry Andric }
40*e8d8bef9SDimitry Andric return NoHazard;
41*e8d8bef9SDimitry Andric }
42*e8d8bef9SDimitry Andric
Reset()43*e8d8bef9SDimitry Andric void MultiHazardRecognizer::Reset() {
44*e8d8bef9SDimitry Andric for (auto &R : Recognizers)
45*e8d8bef9SDimitry Andric R->Reset();
46*e8d8bef9SDimitry Andric }
47*e8d8bef9SDimitry Andric
EmitInstruction(SUnit * SU)48*e8d8bef9SDimitry Andric void MultiHazardRecognizer::EmitInstruction(SUnit *SU) {
49*e8d8bef9SDimitry Andric for (auto &R : Recognizers)
50*e8d8bef9SDimitry Andric R->EmitInstruction(SU);
51*e8d8bef9SDimitry Andric }
52*e8d8bef9SDimitry Andric
EmitInstruction(MachineInstr * MI)53*e8d8bef9SDimitry Andric void MultiHazardRecognizer::EmitInstruction(MachineInstr *MI) {
54*e8d8bef9SDimitry Andric for (auto &R : Recognizers)
55*e8d8bef9SDimitry Andric R->EmitInstruction(MI);
56*e8d8bef9SDimitry Andric }
57*e8d8bef9SDimitry Andric
PreEmitNoops(SUnit * SU)58*e8d8bef9SDimitry Andric unsigned MultiHazardRecognizer::PreEmitNoops(SUnit *SU) {
59*e8d8bef9SDimitry Andric auto MN = [=](unsigned a, std::unique_ptr<ScheduleHazardRecognizer> &R) {
60*e8d8bef9SDimitry Andric return std::max(a, R->PreEmitNoops(SU));
61*e8d8bef9SDimitry Andric };
62*e8d8bef9SDimitry Andric return std::accumulate(Recognizers.begin(), Recognizers.end(), 0u, MN);
63*e8d8bef9SDimitry Andric }
64*e8d8bef9SDimitry Andric
PreEmitNoops(MachineInstr * MI)65*e8d8bef9SDimitry Andric unsigned MultiHazardRecognizer::PreEmitNoops(MachineInstr *MI) {
66*e8d8bef9SDimitry Andric auto MN = [=](unsigned a, std::unique_ptr<ScheduleHazardRecognizer> &R) {
67*e8d8bef9SDimitry Andric return std::max(a, R->PreEmitNoops(MI));
68*e8d8bef9SDimitry Andric };
69*e8d8bef9SDimitry Andric return std::accumulate(Recognizers.begin(), Recognizers.end(), 0u, MN);
70*e8d8bef9SDimitry Andric }
71*e8d8bef9SDimitry Andric
ShouldPreferAnother(SUnit * SU)72*e8d8bef9SDimitry Andric bool MultiHazardRecognizer::ShouldPreferAnother(SUnit *SU) {
73*e8d8bef9SDimitry Andric auto SPA = [=](std::unique_ptr<ScheduleHazardRecognizer> &R) {
74*e8d8bef9SDimitry Andric return R->ShouldPreferAnother(SU);
75*e8d8bef9SDimitry Andric };
76*e8d8bef9SDimitry Andric return llvm::any_of(Recognizers, SPA);
77*e8d8bef9SDimitry Andric }
78*e8d8bef9SDimitry Andric
AdvanceCycle()79*e8d8bef9SDimitry Andric void MultiHazardRecognizer::AdvanceCycle() {
80*e8d8bef9SDimitry Andric for (auto &R : Recognizers)
81*e8d8bef9SDimitry Andric R->AdvanceCycle();
82*e8d8bef9SDimitry Andric }
83*e8d8bef9SDimitry Andric
RecedeCycle()84*e8d8bef9SDimitry Andric void MultiHazardRecognizer::RecedeCycle() {
85*e8d8bef9SDimitry Andric for (auto &R : Recognizers)
86*e8d8bef9SDimitry Andric R->RecedeCycle();
87*e8d8bef9SDimitry Andric }
88*e8d8bef9SDimitry Andric
EmitNoop()89*e8d8bef9SDimitry Andric void MultiHazardRecognizer::EmitNoop() {
90*e8d8bef9SDimitry Andric for (auto &R : Recognizers)
91*e8d8bef9SDimitry Andric R->EmitNoop();
92*e8d8bef9SDimitry Andric }
93