LLVM 20.0.0git
|
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PriorityQueue.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/CodeGen/ScheduleDAGMutation.h"
#include "llvm/CodeGen/ScheduleDFS.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSchedule.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <limits>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
Go to the source code of this file.
Classes | |
struct | llvm::GraphTraits< ScheduleDAGMI * > |
struct | llvm::DOTGraphTraits< ScheduleDAGMI * > |
Namespaces | |
namespace | llvm |
This is an optimization pass for GlobalISel generic memory operations. | |
Macros | |
#define | DEBUG_TYPE "machine-scheduler" |
Typedefs | |
using | MBBRegionsVector = SmallVector< SchedRegion, 16 > |
Functions | |
STATISTIC (NumClustered, "Number of load/store pairs clustered") | |
cl::opt< MISched::Direction > | llvm::PreRADirection ("misched-prera-direction", cl::Hidden, cl::desc("Pre reg-alloc list scheduling direction"), cl::init(MISched::Unspecified), cl::values(clEnumValN(MISched::TopDown, "topdown", "Force top-down pre reg-alloc list scheduling"), clEnumValN(MISched::BottomUp, "bottomup", "Force bottom-up pre reg-alloc list scheduling"), clEnumValN(MISched::Bidirectional, "bidirectional", "Force bidirectional pre reg-alloc list scheduling"))) |
cl::opt< bool > | llvm::VerifyScheduling ("verify-misched", cl::Hidden, cl::desc("Verify machine instrs before and after machine scheduling")) |
cl::opt< bool > | llvm::ViewMISchedDAGs ("view-misched-dags", cl::Hidden, cl::desc("Pop up a window to show MISched dags after they are processed")) |
cl::opt< bool > | llvm::PrintDAGs ("misched-print-dags", cl::Hidden, cl::desc("Print schedule DAGs")) |
INITIALIZE_PASS_BEGIN (MachineScheduler, DEBUG_TYPE, "Machine Instruction Scheduler", false, false) INITIALIZE_PASS_END(MachineScheduler | |
INITIALIZE_PASS_BEGIN (PostMachineScheduler, "postmisched", "PostRA Machine Instruction Scheduler", false, false) INITIALIZE_PASS_END(PostMachineScheduler | |
static ScheduleDAGInstrs * | useDefaultMachineSched (MachineSchedContext *C) |
A dummy default scheduler factory indicates whether the scheduler is overridden on the command line. | |
static MachineBasicBlock::const_iterator | priorNonDebug (MachineBasicBlock::const_iterator I, MachineBasicBlock::const_iterator Beg) |
Decrement this iterator until reaching the top or a non-debug instr. | |
static MachineBasicBlock::iterator | priorNonDebug (MachineBasicBlock::iterator I, MachineBasicBlock::const_iterator Beg) |
Non-const version. | |
static MachineBasicBlock::const_iterator | nextIfDebug (MachineBasicBlock::const_iterator I, MachineBasicBlock::const_iterator End) |
If this iterator is a debug value, increment until reaching the End or a non-debug instruction. | |
static MachineBasicBlock::iterator | nextIfDebug (MachineBasicBlock::iterator I, MachineBasicBlock::const_iterator End) |
Non-const version. | |
static bool | isSchedBoundary (MachineBasicBlock::iterator MI, MachineBasicBlock *MBB, MachineFunction *MF, const TargetInstrInfo *TII) |
Return true of the given instruction should not be included in a scheduling region. | |
static void | getSchedRegions (MachineBasicBlock *MBB, MBBRegionsVector &Regions, bool RegionsTopDown) |
std::unique_ptr< ScheduleDAGMutation > | llvm::createLoadClusterDAGMutation (const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, bool ReorderWhileClustering=false) |
If ReorderWhileClustering is set to true, no attempt will be made to reduce reordering due to store clustering. | |
std::unique_ptr< ScheduleDAGMutation > | llvm::createStoreClusterDAGMutation (const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, bool ReorderWhileClustering=false) |
If ReorderWhileClustering is set to true, no attempt will be made to reduce reordering due to store clustering. | |
std::unique_ptr< ScheduleDAGMutation > | llvm::createCopyConstrainDAGMutation (const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) |
static bool | checkResourceLimit (unsigned LFactor, unsigned Count, unsigned Latency, bool AfterSchedNode) |
Given a Count of resource usage and a Latency value, return true if a SchedBoundary becomes resource limited. | |
static unsigned | computeRemLatency (SchedBoundary &CurrZone) |
Compute remaining latency. | |
bool | llvm::tryLess (int TryVal, int CandVal, GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, GenericSchedulerBase::CandReason Reason) |
Return true if this heuristic determines order. | |
bool | llvm::tryGreater (int TryVal, int CandVal, GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, GenericSchedulerBase::CandReason Reason) |
bool | llvm::tryLatency (GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, SchedBoundary &Zone) |
static void | tracePick (GenericSchedulerBase::CandReason Reason, bool IsTop) |
static void | tracePick (const GenericSchedulerBase::SchedCandidate &Cand) |
bool | llvm::tryPressure (const PressureChange &TryP, const PressureChange &CandP, GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, GenericSchedulerBase::CandReason Reason, const TargetRegisterInfo *TRI, const MachineFunction &MF) |
unsigned | llvm::getWeakLeft (const SUnit *SU, bool isTop) |
int | llvm::biasPhysReg (const SUnit *SU, bool isTop) |
Minimize physical register live ranges. | |
static ScheduleDAGInstrs * | createConvergingSched (MachineSchedContext *C) |
static ScheduleDAGInstrs * | createILPMaxScheduler (MachineSchedContext *C) |
static ScheduleDAGInstrs * | createILPMinScheduler (MachineSchedContext *C) |
static ScheduleDAGInstrs * | createInstructionShuffler (MachineSchedContext *C) |
static bool | sortIntervals (const ResourceSegments::IntervalTy &A, const ResourceSegments::IntervalTy &B) |
Sort predicate for the intervals stored in an instance of ResourceSegments. | |
Variables | |
cl::opt< MISched::Direction > | llvm::PostRADirection ("misched-postra-direction", cl::Hidden, cl::desc("Post reg-alloc list scheduling direction"), cl::init(MISched::Unspecified), cl::values(clEnumValN(MISched::TopDown, "topdown", "Force top-down post reg-alloc list scheduling"), clEnumValN(MISched::BottomUp, "bottomup", "Force bottom-up post reg-alloc list scheduling"), clEnumValN(MISched::Bidirectional, "bidirectional", "Force bidirectional post reg-alloc list scheduling"))) |
cl::opt< bool > | llvm::DumpCriticalPathLength ("misched-dcpl", cl::Hidden, cl::desc("Print critical path length to stdout")) |
cl::opt< bool > | llvm::MISchedDumpReservedCycles ("misched-dump-reserved-cycles", cl::Hidden, cl::init(false), cl::desc("Dump resource usage at schedule boundary.")) |
cl::opt< bool > | llvm::MischedDetailResourceBooking ("misched-detail-resource-booking", cl::Hidden, cl::init(false), cl::desc("Show details of invoking getNextResoufceCycle.")) |
static cl::opt< unsigned > | ViewMISchedCutoff ("view-misched-cutoff", cl::Hidden, cl::desc("Hide nodes with more predecessor/successor than cutoff")) |
In some situations a few uninteresting nodes depend on nearly all other nodes in the graph, provide a cutoff to hide them. | |
static cl::opt< unsigned > | MISchedCutoff ("misched-cutoff", cl::Hidden, cl::desc("Stop scheduling after N instructions"), cl::init(~0U)) |
static cl::opt< std::string > | SchedOnlyFunc ("misched-only-func", cl::Hidden, cl::desc("Only schedule this function")) |
static cl::opt< unsigned > | SchedOnlyBlock ("misched-only-block", cl::Hidden, cl::desc("Only schedule this MBB#")) |
static cl::opt< unsigned > | ReadyListLimit ("misched-limit", cl::Hidden, cl::desc("Limit ready list to N instructions"), cl::init(256)) |
Avoid quadratic complexity in unusually large basic blocks by limiting the size of the ready lists. | |
static cl::opt< bool > | EnableRegPressure ("misched-regpressure", cl::Hidden, cl::desc("Enable register pressure scheduling."), cl::init(true)) |
static cl::opt< bool > | EnableCyclicPath ("misched-cyclicpath", cl::Hidden, cl::desc("Enable cyclic critical path analysis."), cl::init(true)) |
static cl::opt< bool > | EnableMemOpCluster ("misched-cluster", cl::Hidden, cl::desc("Enable memop clustering."), cl::init(true)) |
static cl::opt< bool > | ForceFastCluster ("force-fast-cluster", cl::Hidden, cl::desc("Switch to fast cluster algorithm with the lost " "of some fusion opportunities"), cl::init(false)) |
static cl::opt< unsigned > | FastClusterThreshold ("fast-cluster-threshold", cl::Hidden, cl::desc("The threshold for fast cluster"), cl::init(1000)) |
static cl::opt< bool > | MISchedDumpScheduleTrace ("misched-dump-schedule-trace", cl::Hidden, cl::init(false), cl::desc("Dump resource usage at schedule boundary.")) |
static cl::opt< unsigned > | HeaderColWidth ("misched-dump-schedule-trace-col-header-width", cl::Hidden, cl::desc("Set width of the columns with " "the resources and schedule units"), cl::init(19)) |
static cl::opt< unsigned > | ColWidth ("misched-dump-schedule-trace-col-width", cl::Hidden, cl::desc("Set width of the columns showing resource booking."), cl::init(5)) |
static cl::opt< bool > | MISchedSortResourcesInTrace ("misched-sort-resources-in-trace", cl::Hidden, cl::init(true), cl::desc("Sort the resources printed in the dump trace")) |
static cl::opt< unsigned > | MIResourceCutOff ("misched-resource-cutoff", cl::Hidden, cl::desc("Number of intervals to track"), cl::init(10)) |
static const unsigned | MinSubtreeSize = 8 |
DEBUG_TYPE | |
Machine Instruction | Scheduler |
Machine Instruction | false |
postmisched | |
static cl::opt< MachineSchedRegistry::ScheduleDAGCtor, false, RegisterPassParser< MachineSchedRegistry > > | MachineSchedOpt ("misched", cl::init(&useDefaultMachineSched), cl::Hidden, cl::desc("Machine instruction scheduler to use")) |
MachineSchedOpt allows command line selection of the scheduler. | |
static MachineSchedRegistry | DefaultSchedRegistry ("default", "Use the target's default scheduler choice.", useDefaultMachineSched) |
static cl::opt< bool > | EnableMachineSched ("enable-misched", cl::desc("Enable the machine instruction scheduling pass."), cl::init(true), cl::Hidden) |
static cl::opt< bool > | EnablePostRAMachineSched ("enable-post-misched", cl::desc("Enable the post-ra machine instruction scheduling pass."), cl::init(true), cl::Hidden) |
static const char * | scheduleTableLegend = " i: issue\n x: resource booked" |
static const unsigned | InvalidCycle = ~0U |
static MachineSchedRegistry | GenericSchedRegistry ("converge", "Standard converging scheduler.", createConvergingSched) |
static MachineSchedRegistry | ILPMaxRegistry ("ilpmax", "Schedule bottom-up for max ILP", createILPMaxScheduler) |
static MachineSchedRegistry | ILPMinRegistry ("ilpmin", "Schedule bottom-up for min ILP", createILPMinScheduler) |
static MachineSchedRegistry | ShufflerRegistry ("shuffle", "Shuffle machine instructions alternating directions", createInstructionShuffler) |
#define DEBUG_TYPE "machine-scheduler" |
Definition at line 74 of file MachineScheduler.cpp.
using MBBRegionsVector = SmallVector<SchedRegion, 16> |
Definition at line 539 of file MachineScheduler.cpp.
|
static |
Given a Count of resource usage and a Latency value, return true if a SchedBoundary becomes resource limited.
If we are checking after scheduling a node, we should return true when we just reach the resource limit.
Definition at line 2235 of file MachineScheduler.cpp.
References llvm::Latency.
Referenced by llvm::SchedBoundary::bumpCycle(), llvm::SchedBoundary::bumpNode(), and llvm::GenericSchedulerBase::setPolicy().
|
static |
Compute remaining latency.
We need this both to determine whether the overall schedule has become latency-limited and whether the instructions outside this zone are resource or latency limited.
The "dependent" latency is updated incrementally during scheduling as the max height/depth of scheduled nodes minus the cycles since it was scheduled: DLat = max (N.depth - (CurrCycle - N.ReadyCycle) for N in Zone
The "independent" latency is the max ready queue depth: ILat = max N.depth for N in Available|Pending
RemainingLatency is the greater of independent and dependent latency.
These computations are expensive, especially in DAGs with many edges, so only do them if necessary.
Definition at line 3003 of file MachineScheduler.cpp.
References llvm::SchedBoundary::Available, llvm::ReadyQueue::elements(), llvm::SchedBoundary::findMaxLatency(), llvm::SchedBoundary::getDependentLatency(), and llvm::SchedBoundary::Pending.
Referenced by llvm::GenericSchedulerBase::setPolicy().
|
static |
Definition at line 3864 of file MachineScheduler.cpp.
References llvm::CallingConv::C, and llvm::createGenericSchedLive().
|
static |
Definition at line 4272 of file MachineScheduler.cpp.
References llvm::CallingConv::C.
|
static |
Definition at line 4275 of file MachineScheduler.cpp.
References llvm::CallingConv::C.
|
static |
Definition at line 4364 of file MachineScheduler.cpp.
References llvm::MISched::BottomUp, llvm::CallingConv::C, llvm::PreRADirection, and llvm::MISched::TopDown.
|
static |
Definition at line 542 of file MachineScheduler.cpp.
References llvm::SmallVectorTemplateCommon< T, typename >::begin(), llvm::MachineBasicBlock::begin(), llvm::SmallVectorTemplateCommon< T, typename >::end(), llvm::MachineBasicBlock::end(), llvm::TargetSubtargetInfo::getInstrInfo(), llvm::MachineBasicBlock::getParent(), llvm::MachineFunction::getSubtarget(), I, isSchedBoundary(), MBB, MI, llvm::SmallVectorTemplateBase< T, bool >::push_back(), and TII.
INITIALIZE_PASS_BEGIN | ( | MachineScheduler | , |
DEBUG_TYPE | , | ||
"Machine Instruction Scheduler" | , | ||
false | , | ||
false | |||
) |
INITIALIZE_PASS_BEGIN | ( | PostMachineScheduler | , |
"postmisched" | , | ||
"PostRA Machine Instruction Scheduler" | , | ||
false | , | ||
false | |||
) |
|
static |
Return true of the given instruction should not be included in a scheduling region.
MachineScheduler does not currently support scheduling across calls. To handle calls, the DAG builder needs to be modified to create register anti/output dependencies on the registers clobbered by the call's regmask operand. In PreRA scheduling, the stack pointer adjustment already prevents scheduling across calls. In PostRA scheduling, we need the isCall to enforce the boundary, but there would be no benefit to postRA scheduling across calls this late anyway.
Definition at line 513 of file MachineScheduler.cpp.
References llvm::HexagonInstrInfo::isSchedulingBoundary(), MBB, MI, and TII.
Referenced by getSchedRegions().
|
static |
If this iterator is a debug value, increment until reaching the End or a non-debug instruction.
Definition at line 371 of file MachineScheduler.cpp.
Referenced by llvm::ScheduleDAGMI::initQueues(), nextIfDebug(), llvm::ScheduleDAGMI::schedule(), llvm::ScheduleDAGMILive::scheduleMI(), and llvm::ScheduleDAGMILive::updatePressureDiffs().
|
static |
Non-const version.
Definition at line 382 of file MachineScheduler.cpp.
References End, llvm::MachineInstrBundleIterator< Ty, IsReverse >::getNonConstIterator(), I, and nextIfDebug().
|
static |
Decrement this iterator until reaching the top or a non-debug instr.
Definition at line 350 of file MachineScheduler.cpp.
Referenced by llvm::ScheduleDAGMILive::initRegPressure(), priorNonDebug(), llvm::ScheduleDAGMI::schedule(), and llvm::ScheduleDAGMILive::scheduleMI().
|
static |
Non-const version.
Definition at line 362 of file MachineScheduler.cpp.
References llvm::MachineInstrBundleIterator< Ty, IsReverse >::getNonConstIterator(), I, and priorNonDebug().
|
static |
Sort predicate for the intervals stored in an instance of ResourceSegments.
Intervals are always disjoint (no intersection for any pairs of intervals), therefore we can sort the totality of the intervals by looking only at the left boundary.
Definition at line 4471 of file MachineScheduler.cpp.
STATISTIC | ( | NumClustered | , |
"Number of load/store pairs clustered" | |||
) |
|
static |
Definition at line 3242 of file MachineScheduler.cpp.
References llvm::GenericSchedulerBase::SchedCandidate::AtTop, llvm::GenericSchedulerBase::SchedCandidate::Reason, and tracePick().
|
static |
Definition at line 3237 of file MachineScheduler.cpp.
References llvm::dbgs(), llvm::GenericSchedulerBase::getReasonStr(), and LLVM_DEBUG.
Referenced by llvm::GenericScheduler::pickNode(), llvm::PostGenericScheduler::pickNode(), llvm::GenericScheduler::pickNodeBidirectional(), llvm::PostGenericScheduler::pickNodeBidirectional(), and tracePick().
|
static |
A dummy default scheduler factory indicates whether the scheduler is overridden on the command line.
Definition at line 323 of file MachineScheduler.cpp.
|
static |
DEBUG_TYPE |
Definition at line 273 of file MachineScheduler.cpp.
|
static |
|
static |
Referenced by llvm::GenericScheduler::registerRoots().
|
static |
|
static |
Referenced by llvm::createLoadClusterDAGMutation(), and llvm::createStoreClusterDAGMutation().
|
static |
|
static |
Referenced by llvm::GenericScheduler::initPolicy().
PostRA Machine Instruction false |
Definition at line 274 of file MachineScheduler.cpp.
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
Definition at line 2227 of file MachineScheduler.cpp.
Referenced by llvm::SchedBoundary::getNextResourceCycle(), llvm::SchedBoundary::getNextResourceCycleByInstance(), and llvm::SchedBoundary::init().
|
static |
MachineSchedOpt allows command line selection of the scheduler.
Definition at line 197 of file MachineScheduler.cpp.
Referenced by llvm::ScheduleDAGMILive::computeDFSResult().
|
static |
Referenced by llvm::SchedBoundary::bumpNode().
|
static |
Referenced by llvm::ScheduleDAGMI::checkSchedLimit().
|
static |
Referenced by llvm::ScheduleDAGMI::dumpSchedule().
postmisched |
Definition at line 302 of file MachineScheduler.cpp.
|
static |
Avoid quadratic complexity in unusually large basic blocks by limiting the size of the ready lists.
Referenced by llvm::SchedBoundary::releaseNode(), and llvm::SchedBoundary::releasePending().
|
static |
|
static |
PostRA Machine Instruction Scheduler |
Definition at line 274 of file MachineScheduler.cpp.
Referenced by llvm::SIScheduleDAGMI::schedule(), and llvm::SIScheduler::scheduleVariant().
Definition at line 991 of file MachineScheduler.cpp.
Referenced by llvm::ScheduleDAGMI::dumpScheduleTraceBottomUp(), and llvm::ScheduleDAGMI::dumpScheduleTraceTopDown().
|
static |
|
static |
In some situations a few uninteresting nodes depend on nearly all other nodes in the graph, provide a cutoff to hide them.
Referenced by llvm::DOTGraphTraits< ScheduleDAGMI * >::isNodeHidden().