diff options
Diffstat (limited to 'contrib/llvm/lib/Target/SystemZ/SystemZHazardRecognizer.h')
-rw-r--r-- | contrib/llvm/lib/Target/SystemZ/SystemZHazardRecognizer.h | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/SystemZ/SystemZHazardRecognizer.h b/contrib/llvm/lib/Target/SystemZ/SystemZHazardRecognizer.h new file mode 100644 index 000000000000..0c755c9ad1b9 --- /dev/null +++ b/contrib/llvm/lib/Target/SystemZ/SystemZHazardRecognizer.h @@ -0,0 +1,128 @@ +//=-- 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 <string> + +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<int, 0> 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 */ |