//=-- SystemZHazardRecognizer.h - SystemZ Hazard Recognizer -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file declares a hazard recognizer for the SystemZ scheduler. // // This class is used by the SystemZ scheduling strategy to maintain // the state during scheduling, and provide cost functions for // scheduling candidates. This includes: // // * Decoder grouping. A decoder group can maximally hold 3 uops, and // instructions that always begin a new group should be scheduled when // the current decoder group is empty. // * Processor resources usage. It is beneficial to balance the use of // resources. // // ===---------------------------------------------------------------------===// #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H #include "SystemZSubtarget.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineScheduler.h" #include "llvm/CodeGen/ScheduleHazardRecognizer.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/Support/raw_ostream.h" #include namespace llvm { /// SystemZHazardRecognizer maintains the state during scheduling. class SystemZHazardRecognizer : public ScheduleHazardRecognizer { ScheduleDAGMI *DAG; const TargetSchedModel *SchedModel; /// Keep track of the number of decoder slots used in the current /// decoder group. unsigned CurrGroupSize; /// The tracking of resources here are quite similar to the common /// code use of a critical resource. However, z13 differs in the way /// that it has two processor sides which may be interesting to /// model in the future (a work in progress). /// Counters for the number of uops scheduled per processor /// resource. SmallVector ProcResourceCounters; /// This is the resource with the greatest queue, which the /// scheduler tries to avoid. unsigned CriticalResourceIdx; /// Return the number of decoder slots MI requires. inline unsigned getNumDecoderSlots(SUnit *SU) const; /// Return true if MI fits into current decoder group. bool fitsIntoCurrentGroup(SUnit *SU) const; /// Two decoder groups per cycle are formed (for z13), meaning 2x3 /// instructions. This function returns a number between 0 and 5, /// representing the current decoder slot of the current cycle. unsigned getCurrCycleIdx(); /// LastFPdOpCycleIdx stores the numbeer returned by getCurrCycleIdx() /// when a stalling operation is scheduled (which uses the FPd resource). unsigned LastFPdOpCycleIdx; /// A counter of decoder groups scheduled. unsigned GrpCount; unsigned getCurrGroupSize() {return CurrGroupSize;}; /// Start next decoder group. void nextGroup(bool DbgOutput = true); /// Clear all counters for processor resources. void clearProcResCounters(); /// With the goal of alternating processor sides for stalling (FPd) /// ops, return true if it seems good to schedule an FPd op next. bool isFPdOpPreferred_distance(const SUnit *SU); public: SystemZHazardRecognizer(const MachineSchedContext *C); void setDAG(ScheduleDAGMI *dag) { DAG = dag; SchedModel = dag->getSchedModel(); } HazardType getHazardType(SUnit *m, int Stalls = 0) override; void Reset() override; void EmitInstruction(SUnit *SU) override; // Cost functions used by SystemZPostRASchedStrategy while // evaluating candidates. /// Return the cost of decoder grouping for SU. If SU must start a /// new decoder group, this is negative if this fits the schedule or /// positive if it would mean ending a group prematurely. For normal /// instructions this returns 0. int groupingCost(SUnit *SU) const; /// Return the cost of SU in regards to processor resources usage. /// A positive value means it would be better to wait with SU, while /// a negative value means it would be good to schedule SU next. int resourcesCost(SUnit *SU); #ifndef NDEBUG // Debug dumping. std::string CurGroupDbg; // current group as text void dumpSU(SUnit *SU, raw_ostream &OS) const; void dumpCurrGroup(std::string Msg = "") const; void dumpProcResourceCounters() const; #endif }; } // namespace llvm #endif /* LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H */