40#ifndef LLVM_CODEGEN_MACHINEPIPELINER_H
41#define LLVM_CODEGEN_MACHINEPIPELINER_H
114 bool useSwingModuloScheduler();
115 bool useWindowScheduler(
bool Changed);
120 SUnit *Dst =
nullptr;
122 unsigned Distance = 0;
123 bool IsValidationOnly =
false;
131 bool IsValidationOnly)
132 : Dst(PredOrSucc), Pred(Dep), Distance(0u),
133 IsValidationOnly(IsValidationOnly) {
236 struct SwingSchedulerDDGEdges {
241 void initEdges(
SUnit *SU);
246 std::vector<SwingSchedulerDDGEdges> EdgesVec;
247 SwingSchedulerDDGEdges EntrySUEdges;
248 SwingSchedulerDDGEdges ExitSUEdges;
258 SwingSchedulerDDGEdges &getEdges(
const SUnit *SU);
259 const SwingSchedulerDDGEdges &getEdges(
const SUnit *SU)
const;
277 std::unique_ptr<SwingSchedulerDDG> DDG;
284 bool Scheduled =
false;
288 unsigned II_setByPragma = 0;
298 int ZeroLatencyDepth = 0;
299 int ZeroLatencyHeight = 0;
301 NodeInfo() =
default;
304 std::vector<NodeInfo> ScheduleInfo;
306 enum OrderKind { BottomUp = 0, TopDown = 1 };
323 std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
334 std::vector<SUnit> &SUnits;
340 std::vector<int> *Node2Idx;
341 unsigned NumPaths = 0u;
342 static unsigned MaxPaths;
346 : SUnits(SUs), Blocked(SUs.size()), B(SUs.size()), AdjK(SUs.size()) {
347 Node2Idx =
new std::vector<int>(SUs.size());
349 for (
const auto &NodeNum : Topo)
350 Node2Idx->at(NodeNum) =
Idx++;
352 Circuits &operator=(
const Circuits &other) =
delete;
353 Circuits(
const Circuits &other) =
delete;
354 ~Circuits() {
delete Node2Idx; }
379 RegClassInfo(rci), II_setByPragma(
II), LoopPipelinerInfo(PLI),
381 P.MF->getSubtarget().getSMSMutations(Mutations);
383 Mutations.push_back(std::make_unique<CopyToPhiMutation>());
409 return ScheduleInfo[
Node->NodeNum].ZeroLatencyDepth;
418 return ScheduleInfo[
Node->NodeNum].ZeroLatencyHeight;
431 InstrChanges.
find(SU);
432 if (It != InstrChanges.
end())
433 return It->second.first;
438 Mutations.push_back(std::move(
Mutation));
450 void updatePhiDependences();
451 void changeDependences();
452 unsigned calculateResMII();
453 unsigned calculateRecMII(NodeSetType &RecNodeSets);
454 void findCircuits(NodeSetType &NodeSets);
455 void fuseRecs(NodeSetType &NodeSets);
456 void removeDuplicateNodes(NodeSetType &NodeSets);
457 void computeNodeFunctions(NodeSetType &NodeSets);
458 void registerPressureFilter(NodeSetType &NodeSets);
459 void colocateNodeSets(NodeSetType &NodeSets);
460 void checkNodeSets(NodeSetType &NodeSets);
461 void groupRemainingNodes(NodeSetType &NodeSets);
464 void computeNodeOrder(NodeSetType &NodeSets);
465 void checkValidNodeOrder(
const NodeSetType &Circuits)
const;
470 unsigned &OffsetPos,
Register &NewBase,
472 void postProcessDAG();
474 void setMII(
unsigned ResMII,
unsigned RecMII);
483 bool HasRecurrence =
false;
486 unsigned MaxDepth = 0;
487 unsigned Colocate = 0;
488 SUnit *ExceedPressure =
nullptr;
489 unsigned Latency = 0;
496 : Nodes(S,
E), HasRecurrence(
true) {
513 for (
auto *
Node : Nodes)
514 SUnitToDistance[
Node] = 0;
516 for (
unsigned I = 1,
E = Nodes.size();
I <=
E; ++
I) {
518 SUnit *V = Nodes[
I % Nodes.size()];
520 SUnit *SuccSUnit = Succ.getDst();
523 unsigned &DU = SUnitToDistance[U];
524 unsigned &DV = SUnitToDistance[V];
525 if (DU + Succ.getLatency() > DV)
526 DV = DU + Succ.getLatency();
530 SUnit *FirstNode = Nodes[0];
531 SUnit *LastNode = Nodes[Nodes.size() - 1];
538 if (PI.getSrc() != FirstNode || !PI.isOrderDep() ||
541 unsigned &
First = SUnitToDistance[FirstNode];
542 unsigned Last = SUnitToDistance[LastNode];
547 Latency = SUnitToDistance[Nodes.front()];
554 template <
typename UnaryPredicate>
bool remove_if(UnaryPredicate
P) {
582 for (
SUnit *SU : *
this) {
583 MaxMOV = std::max(MaxMOV, SSD->
getMOV(SU));
584 MaxDepth = std::max(MaxDepth, SSD->
getDepth(SU));
595 HasRecurrence =
false;
599 ExceedPressure =
nullptr;
609 if (RecMII ==
RHS.RecMII) {
610 if (Colocate != 0 &&
RHS.Colocate != 0 && Colocate !=
RHS.Colocate)
611 return Colocate <
RHS.Colocate;
612 if (MaxMOV ==
RHS.MaxMOV)
613 return MaxDepth >
RHS.MaxDepth;
614 return MaxMOV <
RHS.MaxMOV;
616 return RecMII >
RHS.RecMII;
620 return RecMII ==
RHS.RecMII && MaxMOV ==
RHS.MaxMOV &&
621 MaxDepth ==
RHS.MaxDepth;
630#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
661 int InitiationInterval = 0;
665 int calculateResMIIDFA()
const;
667 bool isOverbooked()
const;
676 int positiveModulo(
int Dividend,
int Divisor)
const {
678 int R = Dividend % Divisor;
684#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
690 : STI(ST), SM(ST->getSchedModel()), ST(ST),
TII(ST->getInstrInfo()),
691 DAG(DAG), UseDFA(ST->useDFAforSMS()),
692 ProcResourceMasks(SM.getNumProcResourceKinds(), 0),
693 IssueWidth(SM.IssueWidth) {
733 std::map<SUnit *, int> InstrToCycle;
743 int InitiationInterval = 0;
755 : ST(mf->getSubtarget()),
MRI(mf->getRegInfo()),
756 ProcItinResources(&ST, DAG) {}
759 ScheduledInstrs.
clear();
760 InstrToCycle.clear();
763 InitiationInterval = 0;
768 InitiationInterval = ii;
769 ProcItinResources.
init(ii);
794 bool insert(
SUnit *SU,
int StartCycle,
int EndCycle,
int II);
809 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
810 if (it == InstrToCycle.end())
812 return (it->second - FirstCycle) / InitiationInterval;
818 std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
819 assert(it != InstrToCycle.end() &&
"Instruction hasn't been scheduled.");
820 return (it->second - FirstCycle) % InitiationInterval;
825 return (LastCycle - FirstCycle) / InitiationInterval;
830 return ScheduledInstrs[cycle];
839 const std::deque<SUnit *> &Instrs)
const;
847 std::deque<SUnit *> &Insts)
const;
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements a set that has insertion order iteration characteristics.
A private abstract base class describing the concept of an individual alias analysis implementation.
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...
void enableCrossIterationMode()
Assume that values may come from different cycle iterations.
iterator find(const_arg_type_t< KeyT > Val)
A possibly irreducible generalization of a Loop.
Itinerary data supplied by a subtarget to be used by a target.
Represents a single loop in the control flow graph.
Generic base class for all target subtargets.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
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
void print(raw_ostream &os) const
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
LLVM_DUMP_METHOD void dump() const
bool operator==(const NodeSet &RHS) const
bool remove_if(UnaryPredicate P)
void setExceedPressure(SUnit *SU)
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
Wrapper class representing virtual and physical registers.
int calculateResMII() const
void initProcResourceVectors(const MCSchedModel &SM, SmallVectorImpl< uint64_t > &Masks)
ResourceManager(const TargetSubtargetInfo *ST, ScheduleDAGInstrs *DAG)
void init(int II)
Initialize resources with the initiation interval II.
bool canReserveResources(SUnit &SU, int Cycle)
Check if the resources occupied by a machine instruction are available in the current state.
Kind getKind() const
Returns an enum value representing the kind of the dependence.
@ Output
A register output-dependence (aka WAW).
@ Order
Any other ordering dependency.
@ Anti
A register anti-dependence (aka WAR).
@ Data
Regular data dependence (aka true-dependence).
void setLatency(unsigned Lat)
Sets the latency for this edge.
unsigned getLatency() const
Returns the latency value for this edge, which roughly means the minimum number of cycles that must e...
bool isAssignedRegDep() const
Tests if this is a Data dependence that is associated with a register.
bool isArtificial() const
Tests if this is an Order dependence that is marked as "artificial", meaning it isn't necessary for c...
Register getReg() const
Returns the register associated with this edge.
bool isBarrier() const
Tests if this is an Order dependence that is marked as a barrier.
This class represents the scheduled code.
std::deque< SUnit * > reorderInstructions(const SwingSchedulerDAG *SSD, const std::deque< SUnit * > &Instrs) const
void setInitiationInterval(int ii)
Set the initiation interval for this schedule.
void dump() const
Utility function used for debugging to print the schedule.
bool insert(SUnit *SU, int StartCycle, int EndCycle, int II)
Try to schedule the node at the specified StartCycle and continue until the node is schedule or the E...
int earliestCycleInChain(const SwingSchedulerDDGEdge &Dep, const SwingSchedulerDDG *DDG)
Return the cycle of the earliest scheduled instruction in the dependence chain.
unsigned getMaxStageCount()
Return the maximum stage count needed for this schedule.
void print(raw_ostream &os) const
Print the schedule information to the given output.
bool onlyHasLoopCarriedOutputOrOrderPreds(SUnit *SU, const SwingSchedulerDDG *DDG) const
Return true if all scheduled predecessors are loop-carried output/order dependencies.
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.
void orderDependence(const SwingSchedulerDAG *SSD, SUnit *SU, std::deque< SUnit * > &Insts) const
Order the instructions within a cycle so that the definitions occur before the uses.
bool isValidSchedule(SwingSchedulerDAG *SSD)
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.
bool isLoopCarriedDefOfUse(const SwingSchedulerDAG *SSD, MachineInstr *Def, MachineOperand &MO) const
Return true if the instruction is a definition that is loop carried and defines the use on the next i...
unsigned cycleScheduled(SUnit *SU) const
Return the cycle for a scheduled instruction.
SmallPtrSet< SUnit *, 8 > computeUnpipelineableNodes(SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI)
Determine transitive dependences of unpipelineable instructions.
void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart, int II, SwingSchedulerDAG *DAG)
Compute the scheduling start slot for the instruction.
SMSchedule(MachineFunction *mf, SwingSchedulerDAG *DAG)
bool normalizeNonPipelinedInstructions(SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI)
bool isLoopCarried(const SwingSchedulerDAG *SSD, MachineInstr &Phi) const
Return true if the scheduled Phi has a loop carried operand.
int latestCycleInChain(const SwingSchedulerDDGEdge &Dep, const SwingSchedulerDDG *DDG)
Return the cycle of the latest scheduled instruction in the dependence chain.
int getFinalCycle() const
Return the last cycle in the finalized schedule.
void finalizeSchedule(SwingSchedulerDAG *SSD)
After the schedule has been formed, call this function to combine the instructions from the different...
Scheduling unit. This is a node in the scheduling DAG.
A ScheduleDAG for scheduling lists of MachineInstr.
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.
SUnit ExitSU
Special node for the region exit.
A vector that has set insertion semantics.
bool remove_if(UnaryPredicate P)
Remove items from the set vector based on a predicate function.
size_type size() const
Determine the number of elements in the SetVector.
iterator end()
Get an iterator to the end of the SetVector.
typename vector_type::const_iterator const_iterator
void clear()
Completely clear the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
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 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...
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.
template class LLVM_TEMPLATE_ABI opt< bool >
template class LLVM_TEMPLATE_ABI opt< int >
std::set< NodeId > NodeSet
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void initializeMachinePipelinerPass(PassRegistry &)
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
cl::opt< bool > SwpEnableCopyToPhi
static const int DefaultProcResSize
cl::opt< int > SwpForceIssueWidth
A command line argument to force pipeliner to use specified issue width.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Represents loop-carried dependencies.
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
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