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