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
20using namespace llvm;
21
22void MultiHazardRecognizer::AddHazardRecognizer(
23    std::unique_ptr<ScheduleHazardRecognizer> &&R) {
24  MaxLookAhead = std::max(MaxLookAhead, R->getMaxLookAhead());
25  Recognizers.push_back(std::move(R));
26}
27
28bool MultiHazardRecognizer::atIssueLimit() const {
29  return llvm::any_of(Recognizers,
30                      std::mem_fn(&ScheduleHazardRecognizer::atIssueLimit));
31}
32
33ScheduleHazardRecognizer::HazardType
34MultiHazardRecognizer::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
43void MultiHazardRecognizer::Reset() {
44  for (auto &R : Recognizers)
45    R->Reset();
46}
47
48void MultiHazardRecognizer::EmitInstruction(SUnit *SU) {
49  for (auto &R : Recognizers)
50    R->EmitInstruction(SU);
51}
52
53void MultiHazardRecognizer::EmitInstruction(MachineInstr *MI) {
54  for (auto &R : Recognizers)
55    R->EmitInstruction(MI);
56}
57
58unsigned 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
65unsigned 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
72bool 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
79void MultiHazardRecognizer::AdvanceCycle() {
80  for (auto &R : Recognizers)
81    R->AdvanceCycle();
82}
83
84void MultiHazardRecognizer::RecedeCycle() {
85  for (auto &R : Recognizers)
86    R->RecedeCycle();
87}
88
89void MultiHazardRecognizer::EmitNoop() {
90  for (auto &R : Recognizers)
91    R->EmitNoop();
92}
93