40#ifndef LLVM_CODEGEN_MACHINEPIPELINER_H
41#define LLVM_CODEGEN_MACHINEPIPELINER_H
111 bool useSwingModuloScheduler();
112 bool useWindowScheduler(
bool Changed);
117 SUnit *Dst =
nullptr;
119 unsigned Distance = 0;
120 bool IsValidationOnly =
false;
128 bool IsValidationOnly)
129 : Dst(PredOrSucc), Pred(Dep), Distance(0u),
130 IsValidationOnly(IsValidationOnly) {
139 if (Pred.getKind() ==
SDep::Anti && Src->getInstr()->isPHI()) {
142 auto Reg = Pred.getReg();
143 Pred = SDep(Src, SDep::Kind::Data, Reg);
233 struct SwingSchedulerDDGEdges {
238 void initEdges(
SUnit *SU);
243 std::vector<SwingSchedulerDDGEdges> EdgesVec;
244 SwingSchedulerDDGEdges EntrySUEdges;
245 SwingSchedulerDDGEdges ExitSUEdges;
255 SwingSchedulerDDGEdges &getEdges(
const SUnit *SU);
256 const SwingSchedulerDDGEdges &getEdges(
const SUnit *SU)
const;
274 std::unique_ptr<SwingSchedulerDDG> DDG;
281 bool Scheduled =
false;
285 unsigned II_setByPragma = 0;
295 int ZeroLatencyDepth = 0;
296 int ZeroLatencyHeight = 0;
298 NodeInfo() =
default;
301 std::vector<NodeInfo> ScheduleInfo;
303 enum OrderKind { BottomUp = 0, TopDown = 1 };
320 std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
331 std::vector<SUnit> &
SUnits;
337 std::vector<int> *Node2Idx;
338 unsigned NumPaths = 0u;
339 static unsigned MaxPaths;
343 :
SUnits(SUs), Blocked(SUs.size()),
B(SUs.size()), AdjK(SUs.size()) {
344 Node2Idx =
new std::vector<int>(SUs.size());
346 for (
const auto &NodeNum : Topo)
347 Node2Idx->at(NodeNum) = Idx++;
349 Circuits &
operator=(
const Circuits &other) =
delete;
350 Circuits(
const Circuits &other) =
delete;
351 ~Circuits() {
delete Node2Idx; }
362 bool circuit(
int V,
int S, NodeSetType &NodeSets,
376 RegClassInfo(rci), II_setByPragma(
II), LoopPipelinerInfo(PLI),
378 P.MF->getSubtarget().getSMSMutations(Mutations);
380 Mutations.push_back(std::make_unique<CopyToPhiMutation>());
381 BAA.enableCrossIterationMode();
406 return ScheduleInfo[
Node->NodeNum].ZeroLatencyDepth;
415 return ScheduleInfo[
Node->NodeNum].ZeroLatencyHeight;
428 InstrChanges.find(SU);
429 if (It != InstrChanges.
end())
430 return It->second.first;
435 Mutations.push_back(std::move(
Mutation));
447 void updatePhiDependences();
448 void changeDependences();
449 unsigned calculateResMII();
450 unsigned calculateRecMII(NodeSetType &RecNodeSets);
451 void findCircuits(NodeSetType &NodeSets);
452 void fuseRecs(NodeSetType &NodeSets);
453 void removeDuplicateNodes(NodeSetType &NodeSets);
454 void computeNodeFunctions(NodeSetType &NodeSets);
455 void registerPressureFilter(NodeSetType &NodeSets);
456 void colocateNodeSets(NodeSetType &NodeSets);
457 void checkNodeSets(NodeSetType &NodeSets);
458 void groupRemainingNodes(NodeSetType &NodeSets);
461 void computeNodeOrder(NodeSetType &NodeSets);
462 void checkValidNodeOrder(
const NodeSetType &Circuits)
const;
467 unsigned &OffsetPos,
Register &NewBase,
469 void postProcessDAG();
471 void setMII(
unsigned ResMII,
unsigned RecMII);
480 bool HasRecurrence =
false;
483 unsigned MaxDepth = 0;
484 unsigned Colocate = 0;
485 SUnit *ExceedPressure =
nullptr;
486 unsigned Latency = 0;
493 : Nodes(S,
E), HasRecurrence(
true) {
510 for (
auto *
Node : Nodes)
511 SUnitToDistance[
Node] = 0;
513 for (
unsigned I = 1,
E = Nodes.size();
I <=
E; ++
I) {
514 SUnit *U = Nodes[I - 1];
515 SUnit *V = Nodes[I % Nodes.size()];
516 for (const SwingSchedulerDDGEdge &Succ : DDG->getOutEdges(U)) {
517 SUnit *SuccSUnit = Succ.getDst();
520 unsigned &DU = SUnitToDistance[U];
521 unsigned &DV = SUnitToDistance[V];
522 if (DU + Succ.getLatency() > DV)
523 DV = DU + Succ.getLatency();
527 SUnit *FirstNode = Nodes[0];
528 SUnit *LastNode = Nodes[Nodes.
size() - 1];
530 for (
auto &PI : DDG->getInEdges(LastNode)) {
535 if (PI.getSrc() != FirstNode || !PI.isOrderDep() ||
536 !DAG->isLoopCarriedDep(PI))
538 unsigned &First = SUnitToDistance[FirstNode];
539 unsigned Last = SUnitToDistance[LastNode];
540 First = std::max(First, Last + 1);
551 template <
typename UnaryPredicate>
bool remove_if(UnaryPredicate
P) {
552 return Nodes.remove_if(
P);
559 unsigned size()
const {
return Nodes.size(); }
561 bool empty()
const {
return Nodes.empty(); }
579 for (
SUnit *SU : *
this) {
580 MaxMOV = std::max(MaxMOV, SSD->
getMOV(SU));
581 MaxDepth = std::max(MaxDepth, SSD->
getDepth(SU));
592 HasRecurrence =
false;
596 ExceedPressure =
nullptr;
606 if (RecMII ==
RHS.RecMII) {
607 if (Colocate != 0 &&
RHS.Colocate != 0 && Colocate !=
RHS.Colocate)
608 return Colocate <
RHS.Colocate;
609 if (MaxMOV ==
RHS.MaxMOV)
610 return MaxDepth >
RHS.MaxDepth;
611 return MaxMOV <
RHS.MaxMOV;
613 return RecMII >
RHS.RecMII;
617 return RecMII ==
RHS.RecMII && MaxMOV ==
RHS.MaxMOV &&
618 MaxDepth ==
RHS.MaxDepth;
627#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
658 int InitiationInterval = 0;
662 int calculateResMIIDFA()
const;
664 bool isOverbooked()
const;
673 int positiveModulo(
int Dividend,
int Divisor)
const {
675 int R = Dividend % Divisor;
681#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
687 : STI(ST), SM(ST->getSchedModel()), ST(ST), TII(ST->getInstrInfo()),
688 DAG(DAG), UseDFA(ST->useDFAforSMS()),
689 ProcResourceMasks(SM.getNumProcResourceKinds(), 0),
690 IssueWidth(SM.IssueWidth) {
704 bool canReserveResources(
SUnit &SU,
int Cycle);
710 int calculateResMII()
const;
730 std::map<SUnit *, int> InstrToCycle;
740 int InitiationInterval = 0;
752 : ST(mf->getSubtarget()), MRI(mf->getRegInfo()),
753 ProcItinResources(&ST, DAG) {}
756 ScheduledInstrs.clear();
757 InstrToCycle.clear();
760 InitiationInterval = 0;
765 InitiationInterval = ii;
766 ProcItinResources.init(ii);
789 void computeStart(
SUnit *SU,
int *MaxEarlyStart,
int *MinLateStart,
int II,
791 bool insert(
SUnit *SU,
int StartCycle,
int EndCycle,
int II);
806 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
807 if (it == InstrToCycle.end())
809 return (it->second - FirstCycle) / InitiationInterval;
815 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
816 assert(it != InstrToCycle.end() &&
"Instruction hasn't been scheduled.");
817 return (it->second - FirstCycle) % InitiationInterval;
822 return (LastCycle - FirstCycle) / InitiationInterval;
827 return ScheduledInstrs[cycle];
836 const std::deque<SUnit *> &Instrs)
const;
844 std::deque<SUnit *> &Insts)
const;
849 bool onlyHasLoopCarriedOutputOrOrderPreds(
SUnit *SU,
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
This file implements a set that has insertion order iteration characteristics.
Represent the analysis usage information of a pass.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
Itinerary data supplied by a subtarget to be used by a target.
Generic base class for all target subtargets.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass(char &ID)
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
The main class in the implementation of the target independent software pipeliner pass.
bool runOnMachineFunction(MachineFunction &MF) override
The "main" function for implementing Swing Modulo Scheduling.
const TargetInstrInfo * TII
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineDominatorTree * MDT
const MachineLoopInfo * MLI
MachineOptimizationRemarkEmitter * ORE
RegisterClassInfo RegClassInfo
const InstrItineraryData * InstrItins
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A NodeSet contains a set of SUnit DAG nodes with additional information that assigns a priority to th...
SUnit * getNode(unsigned i) const
SetVector< SUnit * >::const_iterator iterator
bool isExceedSU(SUnit *SU)
void insert(iterator S, iterator E)
void setRecMII(unsigned mii)
void computeNodeSetInfo(SwingSchedulerDAG *SSD)
Summarize node functions for the entire node set.
unsigned count(SUnit *SU) const
void setColocate(unsigned c)
NodeSet(iterator S, iterator E, const SwingSchedulerDAG *DAG)
bool operator>(const NodeSet &RHS) const
Sort the node sets by importance.
int compareRecMII(NodeSet &RHS)
bool operator!=(const NodeSet &RHS) const
bool operator==(const NodeSet &RHS) const
bool remove_if(UnaryPredicate P)
void setExceedPressure(SUnit *SU)
Wrapper class representing virtual and physical registers.
void initProcResourceVectors(const MCSchedModel &SM, SmallVectorImpl< uint64_t > &Masks)
ResourceManager(const TargetSubtargetInfo *ST, ScheduleDAGInstrs *DAG)
@ Output
A register output-dependence (aka WAW).
@ Order
Any other ordering dependency.
@ Anti
A register anti-dependence (aka WAR).
This class represents the scheduled code.
void setInitiationInterval(int ii)
Set the initiation interval for this schedule.
unsigned getMaxStageCount()
Return the maximum stage count needed for this schedule.
int stageScheduled(SUnit *SU) const
Return the stage for a scheduled instruction.
bool isScheduledAtStage(SUnit *SU, unsigned StageNum)
Return true if the instruction is scheduled at the specified stage.
int getInitiationInterval() const
Return the initiation interval for this schedule.
std::deque< SUnit * > & getInstructions(int cycle)
Return the instructions that are scheduled at the specified cycle.
int getFirstCycle() const
Return the first cycle in the completed schedule.
DenseMap< int, std::deque< SUnit * > >::const_iterator const_sched_iterator
DenseMap< int, std::deque< SUnit * > >::iterator sched_iterator
Iterators for the cycle to instruction map.
unsigned cycleScheduled(SUnit *SU) const
Return the cycle for a scheduled instruction.
SMSchedule(MachineFunction *mf, SwingSchedulerDAG *DAG)
int getFinalCycle() const
Return the last cycle in the finalized schedule.
Scheduling unit. This is a node in the scheduling DAG.
A ScheduleDAG for scheduling lists of MachineInstr.
ScheduleDAGInstrs(MachineFunction &mf, const MachineLoopInfo *mli, bool RemoveKillFlags=false)
const MachineLoopInfo * MLI
Mutate the DAG as a postpass after normal DAG building.
This class can compute a topological ordering for SUnits and provides methods for dynamically updatin...
std::vector< SUnit > SUnits
The scheduling units.
MachineFunction & MF
Machine function.
ScheduleDAG & operator=(const ScheduleDAG &)=delete
SUnit ExitSU
Special node for the region exit.
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
const value_type & front() const
Return the first element of the SetVector.
typename vector_type::const_iterator const_iterator
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class builds the dependence graph for the instructions in a loop, and attempts to schedule the i...
unsigned getDepth(SUnit *Node)
The depth, in the dependence graph, for a node.
int getASAP(SUnit *Node)
Return the earliest time an instruction may be scheduled.
void applyInstrChange(MachineInstr *MI, SMSchedule &Schedule)
Apply changes to the instruction if needed.
const SwingSchedulerDDG * getDDG() const
void finishBlock() override
Clean up after the software pipeliner runs.
void fixupRegisterOverlaps(std::deque< SUnit * > &Instrs)
Attempt to fix the degenerate cases when the instruction serialization causes the register lifetimes ...
bool hasNewSchedule()
Return true if the loop kernel has been scheduled.
void addMutation(std::unique_ptr< ScheduleDAGMutation > Mutation)
int getZeroLatencyDepth(SUnit *Node)
The maximum unweighted length of a path from an arbitrary node to the given node in which each edge h...
bool isLoopCarriedDep(const SwingSchedulerDDGEdge &Edge) const
Return true for an order or output dependence that is loop carried potentially.
void schedule() override
We override the schedule function in ScheduleDAGInstrs to implement the scheduling part of the Swing ...
bool mayOverlapInLaterIter(const MachineInstr *BaseMI, const MachineInstr *OtherMI) const
Return false if there is no overlap between the region accessed by BaseMI in an iteration and the reg...
int getMOV(SUnit *Node)
The mobility function, which the number of slots in which an instruction may be scheduled.
SwingSchedulerDAG(MachinePipeliner &P, MachineLoop &L, LiveIntervals &lis, const RegisterClassInfo &rci, unsigned II, TargetInstrInfo::PipelinerLoopInfo *PLI, AliasAnalysis *AA)
int getZeroLatencyHeight(SUnit *Node)
The maximum unweighted length of a path from the given node to an arbitrary node in which each edge h...
Register getInstrBaseReg(SUnit *SU) const
Return the new base register that was stored away for the changed instruction.
static bool classof(const ScheduleDAGInstrs *DAG)
unsigned getHeight(SUnit *Node)
The height, in the dependence graph, for a node.
int getALAP(SUnit *Node)
Return the latest time an instruction my be scheduled.
Represents a dependence between two instruction.
SUnit * getDst() const
Returns the SUnit to which the edge points (destination node).
Register getReg() const
Returns the register associated with the edge.
void setDistance(unsigned D)
Sets the distance value for the edge.
bool isBarrier() const
Returns true if the edge represents unknown scheduling barrier.
void setLatency(unsigned Latency)
Sets the latency for the edge.
SwingSchedulerDDGEdge(SUnit *PredOrSucc, const SDep &Dep, bool IsSucc, bool IsValidationOnly)
Creates an edge corresponding to an edge represented by PredOrSucc and Dep in the original DAG.
bool isAntiDep() const
Returns true if the edge represents anti dependence.
bool isAssignedRegDep() const
Tests if this is a Data dependence that is associated with a register.
bool isArtificial() const
Returns true if the edge represents an artificial dependence.
bool ignoreDependence(bool IgnoreAnti) const
Returns true for DDG nodes that we ignore when computing the cost functions.
bool isOrderDep() const
Returns true if the edge represents a dependence that is not data, anti or output dependence.
unsigned getLatency() const
Returns the latency value for the edge.
SUnit * getSrc() const
Returns the SUnit from which the edge comes (source node).
bool isValidationOnly() const
Returns true if this edge is intended to be used only for validating the schedule.
unsigned getDistance() const
Returns the distance value for the edge.
bool isOutputDep() const
Returns true if the edge represents output dependence.
This class provides APIs to retrieve edges from/to an SUnit node, with a particular focus on loop-car...
SwingSchedulerDDG(std::vector< SUnit > &SUnits, SUnit *EntrySU, SUnit *ExitSU, const LoopCarriedEdges &LCE)
const EdgesType & getInEdges(const SUnit *SU) const
bool isValidSchedule(const SMSchedule &Schedule) const
Check if Schedule doesn't violate the validation-only dependencies.
const EdgesType & getOutEdges(const SUnit *SU) const
Object returned by analyzeLoopForPipelining.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
This class implements an extremely fast bulk output stream that can only output to a stream.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
static int64_t computeDelta(SectionEntry *A, SectionEntry *B)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
cl::opt< bool > SwpEnableCopyToPhi
cl::opt< int > SwpForceIssueWidth
A command line argument to force pipeliner to use specified issue width.
static const int DefaultProcResSize
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Represents loop-carried dependencies.
SmallSetVector< SUnit *, 8 > OrderDep
const OrderDep * getOrderDepOrNull(SUnit *Key) const
void modifySUnits(std::vector< SUnit > &SUnits, const TargetInstrInfo *TII)
Adds some edges to the original DAG that correspond to loop-carried dependencies.
void dump(SUnit *SU, const TargetRegisterInfo *TRI, const MachineRegisterInfo *MRI) const
DenseMap< SUnit *, OrderDep > OrderDepsType
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Machine model for scheduling, bundling, and heuristics.
Cache the target analysis information about the loop.
MachineInstr * LoopInductionVar
SmallVector< MachineOperand, 4 > BrCond
MachineInstr * LoopCompare
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > LoopPipelinerInfo