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