brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.9 KiB · b2ee64a Raw
162 lines · c
1//=-- SystemZHazardRecognizer.h - SystemZ Hazard Recognizer -----*- C++ -*-===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file declares a hazard recognizer for the SystemZ scheduler.10//11// This class is used by the SystemZ scheduling strategy to maintain12// the state during scheduling, and provide cost functions for13// scheduling candidates. This includes:14//15// * Decoder grouping. A decoder group can maximally hold 3 uops, and16// instructions that always begin a new group should be scheduled when17// the current decoder group is empty.18// * Processor resources usage. It is beneficial to balance the use of19// resources.20//21// A goal is to consider all instructions, also those outside of any22// scheduling region. Such instructions are "advanced" past and include23// single instructions before a scheduling region, branches etc.24//25// A block that has only one predecessor continues scheduling with the state26// of it (which may be updated by emitting branches).27//28// ===---------------------------------------------------------------------===//29 30#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H31#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H32 33#include "SystemZSubtarget.h"34#include "llvm/ADT/SmallVector.h"35#include "llvm/CodeGen/MachineFunction.h"36#include "llvm/CodeGen/MachineScheduler.h"37#include "llvm/CodeGen/ScheduleHazardRecognizer.h"38#include "llvm/MC/MCInstrDesc.h"39#include "llvm/Support/raw_ostream.h"40#include <string>41 42namespace llvm {43 44/// SystemZHazardRecognizer maintains the state for one MBB during scheduling.45class SystemZHazardRecognizer : public ScheduleHazardRecognizer {46 47  const SystemZInstrInfo *TII;48  const TargetSchedModel *SchedModel;49 50  /// Keep track of the number of decoder slots used in the current51  /// decoder group.52  unsigned CurrGroupSize;53 54  /// True if an instruction with four reg operands have been scheduled into55  /// the current decoder group.56  bool CurrGroupHas4RegOps;57 58  /// The tracking of resources here are quite similar to the common59  /// code use of a critical resource. However, z13 differs in the way60  /// that it has two processor sides which may be interesting to61  /// model in the future (a work in progress).62 63  /// Counters for the number of uops scheduled per processor64  /// resource.65  SmallVector<int, 0> ProcResourceCounters;66 67  /// This is the resource with the greatest queue, which the68  /// scheduler tries to avoid.69  unsigned CriticalResourceIdx;70 71  /// Return the number of decoder slots MI requires.72  inline unsigned getNumDecoderSlots(SUnit *SU) const;73 74  /// Return true if MI fits into current decoder group.75  bool fitsIntoCurrentGroup(SUnit *SU) const;76 77  /// Return true if this instruction has four register operands.78  bool has4RegOps(const MachineInstr *MI) const;79 80  /// Two decoder groups per cycle are formed (for z13), meaning 2x381  /// instructions. This function returns a number between 0 and 5,82  /// representing the current decoder slot of the current cycle.  If an SU83  /// is passed which will begin a new decoder group, the returned value is84  /// the cycle index of the next group.85  unsigned getCurrCycleIdx(SUnit *SU = nullptr) const;86 87  /// LastFPdOpCycleIdx stores the numbeer returned by getCurrCycleIdx()88  /// when a stalling operation is scheduled (which uses the FPd resource).89  unsigned LastFPdOpCycleIdx;90 91  /// A counter of decoder groups scheduled.92  unsigned GrpCount;93 94  unsigned getCurrGroupSize() {return CurrGroupSize;};95 96  /// Start next decoder group.97  void nextGroup();98 99  /// Clear all counters for processor resources.100  void clearProcResCounters();101 102  /// With the goal of alternating processor sides for stalling (FPd)103  /// ops, return true if it seems good to schedule an FPd op next.104  bool isFPdOpPreferred_distance(SUnit *SU) const;105 106  /// Last emitted instruction or nullptr.107  MachineInstr *LastEmittedMI;108 109public:110  SystemZHazardRecognizer(const SystemZInstrInfo *tii,111                          const TargetSchedModel *SM)112      : TII(tii), SchedModel(SM) {113    Reset();114  }115 116  HazardType getHazardType(SUnit *SU, int Stalls = 0) override;117  void Reset() override;118  void EmitInstruction(SUnit *SU) override;119 120  /// Resolves and cache a resolved scheduling class for an SUnit.121  const MCSchedClassDesc *getSchedClass(SUnit *SU) const {122    if (!SU->SchedClass && SchedModel->hasInstrSchedModel())123      SU->SchedClass = SchedModel->resolveSchedClass(SU->getInstr());124    return SU->SchedClass;125  }126 127  /// Wrap a non-scheduled instruction in an SU and emit it.128  void emitInstruction(MachineInstr *MI, bool TakenBranch = false);129 130  // Cost functions used by SystemZPostRASchedStrategy while131  // evaluating candidates.132 133  /// Return the cost of decoder grouping for SU. If SU must start a134  /// new decoder group, this is negative if this fits the schedule or135  /// positive if it would mean ending a group prematurely. For normal136  /// instructions this returns 0.137  int groupingCost(SUnit *SU) const;138 139  /// Return the cost of SU in regards to processor resources usage.140  /// A positive value means it would be better to wait with SU, while141  /// a negative value means it would be good to schedule SU next.142  int resourcesCost(SUnit *SU);143 144#ifndef NDEBUG145  // Debug dumping.146  std::string CurGroupDbg; // current group as text147  void dumpSU(SUnit *SU, raw_ostream &OS) const;148  void dumpCurrGroup(std::string Msg = "") const;149  void dumpProcResourceCounters() const;150  void dumpState() const;151#endif152 153  MachineBasicBlock::iterator getLastEmittedMI() { return LastEmittedMI; }154 155  /// Copy counters from end of single predecessor.156  void copyState(SystemZHazardRecognizer *Incoming);157};158 159} // namespace llvm160 161#endif /* LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H */162