1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 13:11:39 +01:00
llvm-mirror/lib/CodeGen/MultiHazardRecognizer.cpp
David Green c8c5cd6011 [Schedule] Add a MultiHazardRecognizer
This adds a MultiHazardRecognizer and starts to make use of it in the
ARM backend. The idea of the class is to allow multiple independent
hazard recognizers to be added to a single base MultiHazardRecognizer,
allowing them to all work in parallel without requiring them to be
chained into subclasses. They can then be added or not based on cpu or
subtarget features, which will become useful in the ARM backend once
more hazard recognizers are being used for various things.

This also renames ARMHazardRecognizer to ARMHazardRecognizerFPMLx in the
process, to more clearly explain what that recognizer is designed for.

Differential Revision: https://reviews.llvm.org/D72939
2020-10-26 08:06:17 +00:00

92 lines
2.7 KiB
C++

//===- MultiHazardRecognizer.cpp - Scheduler Support ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the MultiHazardRecognizer class, which is a wrapper
// for a set of ScheduleHazardRecognizer instances
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MultiHazardRecognizer.h"
#include <algorithm>
#include <functional>
#include <numeric>
using namespace llvm;
void MultiHazardRecognizer::AddHazardRecognizer(
std::unique_ptr<ScheduleHazardRecognizer> &&R) {
MaxLookAhead = std::max(MaxLookAhead, R->getMaxLookAhead());
Recognizers.push_back(std::move(R));
}
bool MultiHazardRecognizer::atIssueLimit() const {
return std::any_of(Recognizers.begin(), Recognizers.end(),
std::mem_fn(&ScheduleHazardRecognizer::atIssueLimit));
}
ScheduleHazardRecognizer::HazardType
MultiHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
for (auto &R : Recognizers) {
auto res = R->getHazardType(SU, Stalls);
if (res != NoHazard)
return res;
}
return NoHazard;
}
void MultiHazardRecognizer::Reset() {
for (auto &R : Recognizers)
R->Reset();
}
void MultiHazardRecognizer::EmitInstruction(SUnit *SU) {
for (auto &R : Recognizers)
R->EmitInstruction(SU);
}
void MultiHazardRecognizer::EmitInstruction(MachineInstr *MI) {
for (auto &R : Recognizers)
R->EmitInstruction(MI);
}
unsigned MultiHazardRecognizer::PreEmitNoops(SUnit *SU) {
auto MN = [=](unsigned a, std::unique_ptr<ScheduleHazardRecognizer> &R) {
return std::max(a, R->PreEmitNoops(SU));
};
return std::accumulate(Recognizers.begin(), Recognizers.end(), 0u, MN);
}
unsigned MultiHazardRecognizer::PreEmitNoops(MachineInstr *MI) {
auto MN = [=](unsigned a, std::unique_ptr<ScheduleHazardRecognizer> &R) {
return std::max(a, R->PreEmitNoops(MI));
};
return std::accumulate(Recognizers.begin(), Recognizers.end(), 0u, MN);
}
bool MultiHazardRecognizer::ShouldPreferAnother(SUnit *SU) {
auto SPA = [=](std::unique_ptr<ScheduleHazardRecognizer> &R) {
return R->ShouldPreferAnother(SU);
};
return std::any_of(Recognizers.begin(), Recognizers.end(), SPA);
}
void MultiHazardRecognizer::AdvanceCycle() {
for (auto &R : Recognizers)
R->AdvanceCycle();
}
void MultiHazardRecognizer::RecedeCycle() {
for (auto &R : Recognizers)
R->RecedeCycle();
}
void MultiHazardRecognizer::EmitNoop() {
for (auto &R : Recognizers)
R->EmitNoop();
}