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