diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZMachineScheduler.h')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZMachineScheduler.h | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZMachineScheduler.h b/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZMachineScheduler.h new file mode 100644 index 000000000000..0d5cc2e03e8d --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZMachineScheduler.h @@ -0,0 +1,155 @@ +//==- SystemZMachineScheduler.h - SystemZ Scheduler Interface ----*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// -------------------------- Post RA scheduling ---------------------------- // +// SystemZPostRASchedStrategy is a scheduling strategy which is plugged into +// the MachineScheduler. It has a sorted Available set of SUs and a pickNode() +// implementation that looks to optimize decoder grouping and balance the +// usage of processor resources. Scheduler states are saved for the end +// region of each MBB, so that a successor block can learn from it. +//===----------------------------------------------------------------------===// + +#include "SystemZHazardRecognizer.h" +#include "llvm/CodeGen/MachineScheduler.h" +#include "llvm/CodeGen/ScheduleDAG.h" +#include <set> + +#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H +#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H + +using namespace llvm; + +namespace llvm { + +/// A MachineSchedStrategy implementation for SystemZ post RA scheduling. +class SystemZPostRASchedStrategy : public MachineSchedStrategy { + + const MachineLoopInfo *MLI; + const SystemZInstrInfo *TII; + + // A SchedModel is needed before any DAG is built while advancing past + // non-scheduled instructions, so it would not always be possible to call + // DAG->getSchedClass(SU). + TargetSchedModel SchedModel; + + /// A candidate during instruction evaluation. + struct Candidate { + SUnit *SU = nullptr; + + /// The decoding cost. + int GroupingCost = 0; + + /// The processor resources cost. + int ResourcesCost = 0; + + Candidate() = default; + Candidate(SUnit *SU_, SystemZHazardRecognizer &HazardRec); + + // Compare two candidates. + bool operator<(const Candidate &other); + + // Check if this node is free of cost ("as good as any"). + bool noCost() const { + return (GroupingCost <= 0 && !ResourcesCost); + } + +#ifndef NDEBUG + void dumpCosts() { + if (GroupingCost != 0) + dbgs() << " Grouping cost:" << GroupingCost; + if (ResourcesCost != 0) + dbgs() << " Resource cost:" << ResourcesCost; + } +#endif + }; + + // A sorter for the Available set that makes sure that SUs are considered + // in the best order. + struct SUSorter { + bool operator() (SUnit *lhs, SUnit *rhs) const { + if (lhs->isScheduleHigh && !rhs->isScheduleHigh) + return true; + if (!lhs->isScheduleHigh && rhs->isScheduleHigh) + return false; + + if (lhs->getHeight() > rhs->getHeight()) + return true; + else if (lhs->getHeight() < rhs->getHeight()) + return false; + + return (lhs->NodeNum < rhs->NodeNum); + } + }; + // A set of SUs with a sorter and dump method. + struct SUSet : std::set<SUnit*, SUSorter> { + #ifndef NDEBUG + void dump(SystemZHazardRecognizer &HazardRec) const; + #endif + }; + + /// The set of available SUs to schedule next. + SUSet Available; + + /// Current MBB + MachineBasicBlock *MBB; + + /// Maintain hazard recognizers for all blocks, so that the scheduler state + /// can be maintained past BB boundaries when appropariate. + typedef std::map<MachineBasicBlock*, SystemZHazardRecognizer*> MBB2HazRec; + MBB2HazRec SchedStates; + + /// Pointer to the HazardRecognizer that tracks the scheduler state for + /// the current region. + SystemZHazardRecognizer *HazardRec; + + /// Update the scheduler state by emitting (non-scheduled) instructions + /// up to, but not including, NextBegin. + void advanceTo(MachineBasicBlock::iterator NextBegin); + +public: + SystemZPostRASchedStrategy(const MachineSchedContext *C); + virtual ~SystemZPostRASchedStrategy(); + + /// Called for a region before scheduling. + void initPolicy(MachineBasicBlock::iterator Begin, + MachineBasicBlock::iterator End, + unsigned NumRegionInstrs) override; + + /// PostRA scheduling does not track pressure. + bool shouldTrackPressure() const override { return false; } + + // Process scheduling regions top-down so that scheduler states can be + // transferrred over scheduling boundaries. + bool doMBBSchedRegionsTopDown() const override { return true; } + + void initialize(ScheduleDAGMI *dag) override; + + /// Tell the strategy that MBB is about to be processed. + void enterMBB(MachineBasicBlock *NextMBB) override; + + /// Tell the strategy that current MBB is done. + void leaveMBB() override; + + /// Pick the next node to schedule, or return NULL. + SUnit *pickNode(bool &IsTopNode) override; + + /// ScheduleDAGMI has scheduled an instruction - tell HazardRec + /// about it. + void schedNode(SUnit *SU, bool IsTopNode) override; + + /// SU has had all predecessor dependencies resolved. Put it into + /// Available. + void releaseTopNode(SUnit *SU) override; + + /// Currently only scheduling top-down, so this method is empty. + void releaseBottomNode(SUnit *SU) override {}; +}; + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H |
