Path: blob/main/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZHazardRecognizer.h
35268 views
//=-- SystemZHazardRecognizer.h - SystemZ Hazard Recognizer -----*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file declares a hazard recognizer for the SystemZ scheduler.9//10// This class is used by the SystemZ scheduling strategy to maintain11// the state during scheduling, and provide cost functions for12// scheduling candidates. This includes:13//14// * Decoder grouping. A decoder group can maximally hold 3 uops, and15// instructions that always begin a new group should be scheduled when16// the current decoder group is empty.17// * Processor resources usage. It is beneficial to balance the use of18// resources.19//20// A goal is to consider all instructions, also those outside of any21// scheduling region. Such instructions are "advanced" past and include22// single instructions before a scheduling region, branches etc.23//24// A block that has only one predecessor continues scheduling with the state25// of it (which may be updated by emitting branches).26//27// ===---------------------------------------------------------------------===//2829#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H30#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H3132#include "SystemZSubtarget.h"33#include "llvm/ADT/SmallVector.h"34#include "llvm/CodeGen/MachineFunction.h"35#include "llvm/CodeGen/MachineScheduler.h"36#include "llvm/CodeGen/ScheduleHazardRecognizer.h"37#include "llvm/MC/MCInstrDesc.h"38#include "llvm/Support/raw_ostream.h"39#include <string>4041namespace llvm {4243/// SystemZHazardRecognizer maintains the state for one MBB during scheduling.44class SystemZHazardRecognizer : public ScheduleHazardRecognizer {4546const SystemZInstrInfo *TII;47const TargetSchedModel *SchedModel;4849/// Keep track of the number of decoder slots used in the current50/// decoder group.51unsigned CurrGroupSize;5253/// True if an instruction with four reg operands have been scheduled into54/// the current decoder group.55bool CurrGroupHas4RegOps;5657/// The tracking of resources here are quite similar to the common58/// code use of a critical resource. However, z13 differs in the way59/// that it has two processor sides which may be interesting to60/// model in the future (a work in progress).6162/// Counters for the number of uops scheduled per processor63/// resource.64SmallVector<int, 0> ProcResourceCounters;6566/// This is the resource with the greatest queue, which the67/// scheduler tries to avoid.68unsigned CriticalResourceIdx;6970/// Return the number of decoder slots MI requires.71inline unsigned getNumDecoderSlots(SUnit *SU) const;7273/// Return true if MI fits into current decoder group.74bool fitsIntoCurrentGroup(SUnit *SU) const;7576/// Return true if this instruction has four register operands.77bool has4RegOps(const MachineInstr *MI) const;7879/// Two decoder groups per cycle are formed (for z13), meaning 2x380/// instructions. This function returns a number between 0 and 5,81/// representing the current decoder slot of the current cycle. If an SU82/// is passed which will begin a new decoder group, the returned value is83/// the cycle index of the next group.84unsigned getCurrCycleIdx(SUnit *SU = nullptr) const;8586/// LastFPdOpCycleIdx stores the numbeer returned by getCurrCycleIdx()87/// when a stalling operation is scheduled (which uses the FPd resource).88unsigned LastFPdOpCycleIdx;8990/// A counter of decoder groups scheduled.91unsigned GrpCount;9293unsigned getCurrGroupSize() {return CurrGroupSize;};9495/// Start next decoder group.96void nextGroup();9798/// Clear all counters for processor resources.99void clearProcResCounters();100101/// With the goal of alternating processor sides for stalling (FPd)102/// ops, return true if it seems good to schedule an FPd op next.103bool isFPdOpPreferred_distance(SUnit *SU) const;104105/// Last emitted instruction or nullptr.106MachineInstr *LastEmittedMI;107108public:109SystemZHazardRecognizer(const SystemZInstrInfo *tii,110const TargetSchedModel *SM)111: TII(tii), SchedModel(SM) {112Reset();113}114115HazardType getHazardType(SUnit *SU, int Stalls = 0) override;116void Reset() override;117void EmitInstruction(SUnit *SU) override;118119/// Resolves and cache a resolved scheduling class for an SUnit.120const MCSchedClassDesc *getSchedClass(SUnit *SU) const {121if (!SU->SchedClass && SchedModel->hasInstrSchedModel())122SU->SchedClass = SchedModel->resolveSchedClass(SU->getInstr());123return SU->SchedClass;124}125126/// Wrap a non-scheduled instruction in an SU and emit it.127void emitInstruction(MachineInstr *MI, bool TakenBranch = false);128129// Cost functions used by SystemZPostRASchedStrategy while130// evaluating candidates.131132/// Return the cost of decoder grouping for SU. If SU must start a133/// new decoder group, this is negative if this fits the schedule or134/// positive if it would mean ending a group prematurely. For normal135/// instructions this returns 0.136int groupingCost(SUnit *SU) const;137138/// Return the cost of SU in regards to processor resources usage.139/// A positive value means it would be better to wait with SU, while140/// a negative value means it would be good to schedule SU next.141int resourcesCost(SUnit *SU);142143#ifndef NDEBUG144// Debug dumping.145std::string CurGroupDbg; // current group as text146void dumpSU(SUnit *SU, raw_ostream &OS) const;147void dumpCurrGroup(std::string Msg = "") const;148void dumpProcResourceCounters() const;149void dumpState() const;150#endif151152MachineBasicBlock::iterator getLastEmittedMI() { return LastEmittedMI; }153154/// Copy counters from end of single predecessor.155void copyState(SystemZHazardRecognizer *Incoming);156};157158} // namespace llvm159160#endif /* LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H */161162163