forked from OSchip/llvm-project
129 lines
4.4 KiB
C++
129 lines
4.4 KiB
C++
//=-- 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/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineScheduler.h"
|
|
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
|
#include "llvm/ADT/SmallVector.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 */
|