40#ifndef LLVM_CODEGEN_MACHINEPIPELINER_H
41#define LLVM_CODEGEN_MACHINEPIPELINER_H
98 unsigned Distance = 0;
99 bool IsValidationOnly =
false;
107 bool IsValidationOnly)
108 : Dst(PredOrSucc), Pred(Dep), Distance(0u),
109 IsValidationOnly(IsValidationOnly) {
118 if (Pred.getKind() ==
SDep::Anti && Src->getInstr()->isPHI()) {
121 auto Reg = Pred.getReg();
122 Pred = SDep(Src, SDep::Kind::Data, Reg);
213 struct SwingSchedulerDDGEdges {
226 void initEdges(
SUnit *SU);
231 std::vector<SwingSchedulerDDGEdges> EdgesVec;
232 SwingSchedulerDDGEdges EntrySUEdges;
233 SwingSchedulerDDGEdges ExitSUEdges;
243 SwingSchedulerDDGEdges &getEdges(
const SUnit *SU);
244 const SwingSchedulerDDGEdges &getEdges(
const SUnit *SU)
const;
264 std::unique_ptr<SwingSchedulerDDG> DDG;
271 bool Scheduled =
false;
275 unsigned II_setByPragma = 0;
288 int ZeroLatencyDepth = 0;
289 int ZeroLatencyHeight = 0;
291 NodeInfo() =
default;
294 std::vector<NodeInfo> ScheduleInfo;
296 enum OrderKind { BottomUp = 0, TopDown = 1 };
313 std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
324 std::vector<SUnit> &
SUnits;
330 std::vector<int> *Node2Idx;
331 unsigned NumPaths = 0u;
332 static unsigned MaxPaths;
336 :
SUnits(SUs), Blocked(SUs.size()),
B(SUs.size()), AdjK(SUs.size()) {
337 Node2Idx =
new std::vector<int>(SUs.size());
339 for (
const auto &NodeNum : Topo)
340 Node2Idx->at(NodeNum) = Idx++;
342 Circuits &
operator=(
const Circuits &other) =
delete;
343 Circuits(
const Circuits &other) =
delete;
344 ~Circuits() {
delete Node2Idx; }
355 LLVM_ABI bool circuit(
int V,
int S, NodeSetType &NodeSets,
357 bool HasBackedge =
false);
372 RegClassInfo(rci), II_setByPragma(
II), LoopPipelinerInfo(PLI),
375 MF.getSubtarget().getSMSMutations(Mutations);
377 Mutations.push_back(std::make_unique<CopyToPhiMutation>());
378 BAA.enableCrossIterationMode();
381 void schedule()
override;
382 void finishBlock()
override;
403 return ScheduleInfo[
Node->NodeNum].ZeroLatencyDepth;
412 return ScheduleInfo[
Node->NodeNum].ZeroLatencyHeight;
417 void fixupRegisterOverlaps(std::deque<SUnit *> &Instrs);
423 InstrChanges.find(SU);
424 if (It != InstrChanges.
end())
425 return It->second.first;
430 Mutations.push_back(std::move(
Mutation));
444 void updatePhiDependences();
445 void changeDependences();
446 unsigned calculateResMII();
447 unsigned calculateRecMII(NodeSetType &RecNodeSets);
448 void findCircuits(NodeSetType &NodeSets);
449 void fuseRecs(NodeSetType &NodeSets);
450 void removeDuplicateNodes(NodeSetType &NodeSets);
451 void computeNodeFunctions(NodeSetType &NodeSets);
452 void registerPressureFilter(NodeSetType &NodeSets);
453 void colocateNodeSets(NodeSetType &NodeSets);
454 void checkNodeSets(NodeSetType &NodeSets);
455 void groupRemainingNodes(NodeSetType &NodeSets);
458 void computeNodeOrder(NodeSetType &NodeSets);
459 void checkValidNodeOrder(
const NodeSetType &Circuits)
const;
464 unsigned &OffsetPos,
Register &NewBase,
466 void postProcessDAG();
468 void setMII(
unsigned ResMII,
unsigned RecMII);
477 bool HasRecurrence =
false;
480 unsigned MaxDepth = 0;
481 unsigned Colocate = 0;
482 SUnit *ExceedPressure =
nullptr;
483 unsigned Latency = 0;
490 : Nodes(S,
E), HasRecurrence(
true) {
507 for (
auto *
Node : Nodes)
508 SUnitToDistance[
Node] = 0;
510 for (
unsigned I = 1,
E = Nodes.size();
I <=
E; ++
I) {
511 SUnit *U = Nodes[I - 1];
512 SUnit *V = Nodes[I % Nodes.size()];
513 for (const SwingSchedulerDDGEdge &Succ : DDG->getOutEdges(U)) {
514 SUnit *SuccSUnit = Succ.getDst();
517 unsigned &DU = SUnitToDistance[U];
518 unsigned &DV = SUnitToDistance[V];
519 if (DU + Succ.getLatency() > DV)
520 DV = DU + Succ.getLatency();
524 SUnit *FirstNode = Nodes[0];
525 SUnit *LastNode = Nodes[Nodes.
size() - 1];
527 for (
SUnit *SU : DDG->getExtraOutEdges(LastNode)) {
533 unsigned &First = SUnitToDistance[FirstNode];
534 unsigned Last = SUnitToDistance[LastNode];
535 First = std::max(First, Last + 1);
546 template <
typename UnaryPredicate>
bool remove_if(UnaryPredicate
P) {
547 return Nodes.remove_if(
P);
554 unsigned size()
const {
return Nodes.size(); }
556 bool empty()
const {
return Nodes.empty(); }
574 for (
SUnit *SU : *
this) {
575 MaxMOV = std::max(MaxMOV, SSD->
getMOV(SU));
576 MaxDepth = std::max(MaxDepth, SSD->
getDepth(SU));
587 HasRecurrence =
false;
591 ExceedPressure =
nullptr;
601 if (RecMII ==
RHS.RecMII) {
602 if (Colocate != 0 &&
RHS.Colocate != 0 && Colocate !=
RHS.Colocate)
603 return Colocate <
RHS.Colocate;
604 if (MaxMOV ==
RHS.MaxMOV)
605 return MaxDepth >
RHS.MaxDepth;
606 return MaxMOV <
RHS.MaxMOV;
608 return RecMII >
RHS.RecMII;
612 return RecMII ==
RHS.RecMII && MaxMOV ==
RHS.MaxMOV &&
613 MaxDepth ==
RHS.MaxDepth;
622#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
653 int InitiationInterval = 0;
657 int calculateResMIIDFA()
const;
659 bool isOverbooked()
const;
668 int positiveModulo(
int Dividend,
int Divisor)
const {
670 int R = Dividend % Divisor;
676#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
682 : STI(ST), SM(ST->getSchedModel()), ST(ST), TII(ST->getInstrInfo()),
683 DAG(DAG), UseDFA(ST->useDFAforSMS()),
684 ProcResourceMasks(SM.getNumProcResourceKinds(), 0),
685 IssueWidth(SM.IssueWidth) {
705 LLVM_ABI int calculateResMII()
const;
725 std::map<SUnit *, int> InstrToCycle;
735 int InitiationInterval = 0;
747 : ST(mf->getSubtarget()), MRI(mf->getRegInfo()),
748 ProcItinResources(&ST, DAG) {}
751 ScheduledInstrs.clear();
752 InstrToCycle.clear();
755 InitiationInterval = 0;
760 InitiationInterval = ii;
761 ProcItinResources.init(ii);
774 LLVM_ABI void computeStart(
SUnit *SU,
int *MaxEarlyStart,
int *MinLateStart,
791 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
792 if (it == InstrToCycle.end())
794 return (it->second - FirstCycle) / InitiationInterval;
800 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
801 assert(it != InstrToCycle.end() &&
"Instruction hasn't been scheduled.");
802 return (it->second - FirstCycle) % InitiationInterval;
807 return (LastCycle - FirstCycle) / InitiationInterval;
812 return ScheduledInstrs[cycle];
821 const std::deque<SUnit *> &Instrs)
const;
829 std::deque<SUnit *> &Insts)
const;
837 onlyHasLoopCarriedOutputOrOrderPreds(
SUnit *SU,
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
BitVector & reset()
Reset all bits in the bitvector.
Generic base class for all target subtargets.
MachineFunctionPass(char &ID)
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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)
A set of analyses that are preserved following a run of a transformation pass.
Wrapper class representing virtual and physical registers.
LLVM_ABI 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.
const SwingSchedulerDDG * getDDG() const
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...
SwingSchedulerDAG(MachineFunction &MF, const MachineLoopInfo *MLI, MachineOptimizationRemarkEmitter *ORE, MachineLoop &L, LiveIntervals &lis, const RegisterClassInfo &rci, unsigned II, TargetInstrInfo::PipelinerLoopInfo *PLI, AliasAnalysis *AA)
int getMOV(SUnit *Node)
The mobility function, which the number of slots in which an instruction may be scheduled.
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.
LLVM_ABI 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...
LLVM_ABI SwingSchedulerDDG(std::vector< SUnit > &SUnits, SUnit *EntrySU, SUnit *ExitSU, const LoopCarriedEdges &LCE)
LLVM_ABI ArrayRef< SUnit * > getExtraOutEdges(const SUnit *SU) const
LLVM_ABI const EdgesType & getInEdges(const SUnit *SU) const
LLVM_ABI bool isValidSchedule(const SMSchedule &Schedule) const
Check if Schedule doesn't violate the validation-only dependencies.
LLVM_ABI 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)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
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
LLVM_ABI cl::opt< bool > SwpEnableCopyToPhi
LLVM_ABI 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
LLVM_ABI void modifySUnits(std::vector< SUnit > &SUnits, const TargetInstrInfo *TII)
Adds some edges to the original DAG that correspond to loop-carried dependencies.
LLVM_ABI 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.
Software pipelining policy for a loop, which a target can customize by implementing TargetSubtargetIn...
bool ShouldLimitRegPressure
Limit the register pressure of the scheduled loop, retrying at a higher II when a schedule needs too ...
A CRTP mix-in for passes that can be skipped.