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