28#define DEBUG_TYPE "pre-RA-sched" 
   46  struct FastPriorityQueue {
 
   49    bool empty()
 const { 
return Queue.empty(); }
 
   56      if (
empty()) 
return nullptr;
 
   57      return Queue.pop_back_val();
 
   67  FastPriorityQueue AvailableQueue;
 
   72  unsigned NumLiveRegs = 0
u;
 
   73  std::vector<SUnit*> LiveRegDefs;
 
   74  std::vector<unsigned> LiveRegCycles;
 
   77  ScheduleDAGFast(MachineFunction &mf)
 
   78    : ScheduleDAGSDNodes(mf) {}
 
   80  void Schedule() 
override;
 
   83  void AddPred(SUnit *SU, 
const SDep &
D) { SU->
addPred(
D); }
 
   86  void RemovePred(SUnit *SU, 
const SDep &
D) { SU->
removePred(
D); }
 
   89  void ReleasePred(SUnit *SU, SDep *PredEdge);
 
   90  void ReleasePredecessors(SUnit *SU, 
unsigned CurCycle);
 
   91  void ScheduleNodeBottomUp(SUnit*, 
unsigned);
 
   92  SUnit *CopyAndMoveSuccessors(SUnit*);
 
   93  void InsertCopiesAndMoveSuccs(SUnit*, 
unsigned,
 
   94                                const TargetRegisterClass*,
 
   95                                const TargetRegisterClass*,
 
   96                                SmallVectorImpl<SUnit*>&);
 
   97  bool DelayForLiveRegsBottomUp(SUnit*, SmallVectorImpl<unsigned>&);
 
   98  void ListScheduleBottomUp();
 
  101  bool forceUnitLatencies()
 const override { 
return true; }
 
  107void ScheduleDAGFast::Schedule() {
 
  111  LiveRegDefs.resize(
TRI->getNumRegs(), 
nullptr);
 
  112  LiveRegCycles.resize(
TRI->getNumRegs(), 0);
 
  120  ListScheduleBottomUp();
 
  129void ScheduleDAGFast::ReleasePred(SUnit *SU, SDep *PredEdge) {
 
  130  SUnit *PredSU = PredEdge->
getSUnit();
 
  134    dbgs() << 
"*** Scheduling failed! ***\n";
 
  136    dbgs() << 
" has been released too many times!\n";
 
  146    AvailableQueue.push(PredSU);
 
  150void ScheduleDAGFast::ReleasePredecessors(SUnit *SU, 
unsigned CurCycle) {
 
  152  for (SDep &Pred : SU->
Preds) {
 
  153    ReleasePred(SU, &Pred);
 
  159      if (!LiveRegDefs[Pred.
getReg()]) {
 
  162        LiveRegCycles[Pred.
getReg()] = CurCycle;
 
  171void ScheduleDAGFast::ScheduleNodeBottomUp(SUnit *SU, 
unsigned CurCycle) {
 
  175  assert(CurCycle >= SU->
getHeight() && 
"Node scheduled below its height!");
 
  179  ReleasePredecessors(SU, CurCycle);
 
  182  for (SDep &Succ : SU->
Succs) {
 
  185        assert(NumLiveRegs > 0 && 
"NumLiveRegs is already zero!");
 
  187               "Physical register dependency violated?");
 
  189        LiveRegDefs[Succ.
getReg()] = 
nullptr;
 
  190        LiveRegCycles[Succ.
getReg()] = 0;
 
  200SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) {
 
  209  bool TryUnfold = 
false;
 
  210  for (
unsigned i = 0, e = 
N->getNumValues(); i != e; ++i) {
 
  211    MVT VT = 
N->getSimpleValueType(i);
 
  214    else if (VT == MVT::Other)
 
  218    MVT VT = 
Op.getNode()->getSimpleValueType(
Op.getResNo());
 
  225    if (!
TII->unfoldMemoryOperand(*DAG, 
N, NewNodes))
 
  229    assert(NewNodes.
size() == 2 && 
"Expected a load folding node!");
 
  232    SDNode *LoadNode = NewNodes[0];
 
  233    unsigned NumVals = 
N->getNumValues();
 
  235    for (
unsigned i = 0; i != NumVals; ++i)
 
  237    DAG->ReplaceAllUsesOfValueWith(
SDValue(SU->
getNode(), OldNumVals-1),
 
  240    SUnit *NewSU = newSUnit(
N);
 
  241    assert(
N->getNodeId() == -1 && 
"Node already inserted!");
 
  244    const MCInstrDesc &MCID = 
TII->get(
N->getMachineOpcode());
 
  257    bool isNewLoad = 
true;
 
  263      LoadSU = newSUnit(LoadNode);
 
  272    for (SDep &Pred : SU->
Preds) {
 
  281    for (SDep &Succ : SU->
Succs) {
 
  289      RemovePred(SU, ChainPred);
 
  291        AddPred(LoadSU, ChainPred);
 
  293    for (
const SDep &Pred : LoadPreds) {
 
  294      RemovePred(SU, Pred);
 
  296        AddPred(LoadSU, Pred);
 
  299    for (
const SDep &Pred : NodePreds) {
 
  300      RemovePred(SU, Pred);
 
  301      AddPred(NewSU, Pred);
 
  303    for (SDep 
D : NodeSuccs) {
 
  304      SUnit *SuccDep = 
D.getSUnit();
 
  306      RemovePred(SuccDep, 
D);
 
  310    for (SDep 
D : ChainSuccs) {
 
  311      SUnit *SuccDep = 
D.getSUnit();
 
  313      RemovePred(SuccDep, 
D);
 
  338  for (SDep &Pred : SU->
Preds)
 
  340      AddPred(NewSU, Pred);
 
  345  for (SDep &Succ : SU->
Succs) {
 
  357  for (
const auto &[Del, Dep] : DelDeps)
 
  358    RemovePred(Del, Dep);
 
  366void ScheduleDAGFast::InsertCopiesAndMoveSuccs(SUnit *SU, 
unsigned Reg,
 
  367                                              const TargetRegisterClass *DestRC,
 
  368                                              const TargetRegisterClass *SrcRC,
 
  369                                              SmallVectorImpl<SUnit*> &
Copies) {
 
  370  SUnit *CopyFromSU = newSUnit(
static_cast<SDNode *
>(
nullptr));
 
  374  SUnit *CopyToSU = newSUnit(
static_cast<SDNode *
>(
nullptr));
 
  381  for (SDep &Succ : SU->
Succs) {
 
  389      DelDeps.
push_back(std::make_pair(SuccSU, Succ));
 
  392  for (
const auto &[Del, Dep] : DelDeps)
 
  393    RemovePred(Del, Dep);
 
  395  FromDep.setLatency(SU->
Latency);
 
  396  AddPred(CopyFromSU, FromDep);
 
  398  ToDep.setLatency(CopyFromSU->
Latency);
 
  399  AddPred(CopyToSU, ToDep);
 
  401  Copies.push_back(CopyFromSU);
 
  402  Copies.push_back(CopyToSU);
 
  419           "Physical reg def must be in implicit def list!");
 
  420    NumRes = 
MCID.getNumDefs();
 
  427  return N->getSimpleValueType(NumRes);
 
 
  433                               std::vector<SUnit *> &LiveRegDefs,
 
  441    if (!LiveRegDefs[*AI])
 
  445    if (LiveRegDefs[*AI] == SU)
 
  453    if (RegAdded.
insert(*AI).second) {
 
 
  465bool ScheduleDAGFast::DelayForLiveRegsBottomUp(SUnit *SU,
 
  466                                              SmallVectorImpl<unsigned> &LRegs){
 
  467  if (NumLiveRegs == 0)
 
  470  SmallSet<unsigned, 4> RegAdded;
 
  472  for (SDep &Pred : SU->
Preds) {
 
  475                         RegAdded, LRegs, 
TRI);
 
  479  for (SDNode *Node = SU->
getNode(); Node; Node = 
Node->getGluedNode()) {
 
  480    if (
Node->getOpcode() == ISD::INLINEASM ||
 
  481        Node->getOpcode() == ISD::INLINEASM_BR) {
 
  484      if (
Node->getOperand(
NumOps-1).getValueType() == MVT::Glue)
 
  488        unsigned Flags = 
Node->getConstantOperandVal(i);
 
  489        const InlineAsm::Flag 
F(Flags);
 
  490        unsigned NumVals = 
F.getNumOperandRegisters();
 
  493        if (
F.isRegDefKind() || 
F.isRegDefEarlyClobberKind() ||
 
  496          for (; NumVals; --NumVals, ++i) {
 
  510        SDNode *SrcNode = 
Node->getOperand(2).getNode();
 
  515    if (!
Node->isMachineOpcode())
 
  517    const MCInstrDesc &MCID = 
TII->get(
Node->getMachineOpcode());
 
  521  return !LRegs.
empty();
 
  527void ScheduleDAGFast::ListScheduleBottomUp() {
 
  528  unsigned CurCycle = 0;
 
  531  ReleasePredecessors(&ExitSU, CurCycle);
 
  534  if (!SUnits.empty()) {
 
  535    SUnit *RootSU = &SUnits[DAG->getRoot().getNode()->getNodeId()];
 
  536    assert(RootSU->
Succs.empty() && 
"Graph root shouldn't have successors!");
 
  538    AvailableQueue.push(RootSU);
 
  544  DenseMap<SUnit*, SmallVector<unsigned, 4> > LRegsMap;
 
  546  while (!AvailableQueue.empty()) {
 
  547    bool Delayed = 
false;
 
  549    SUnit *CurSU = AvailableQueue.pop();
 
  551      SmallVector<unsigned, 4> LRegs;
 
  552      if (!DelayForLiveRegsBottomUp(CurSU, LRegs))
 
  555      LRegsMap.
insert(std::make_pair(CurSU, LRegs));
 
  559      CurSU = AvailableQueue.pop();
 
  565    if (Delayed && !CurSU) {
 
  570        SUnit *TrySU = NotReady[0];
 
  571        SmallVectorImpl<unsigned> &LRegs = LRegsMap[TrySU];
 
  572        assert(LRegs.
size() == 1 && 
"Can't handle this yet!");
 
  573        unsigned Reg = LRegs[0];
 
  574        SUnit *LRDef = LiveRegDefs[
Reg];
 
  576        const TargetRegisterClass *RC =
 
  577          TRI->getMinimalPhysRegClass(
Reg, VT);
 
  578        const TargetRegisterClass *DestRC = 
TRI->getCrossCopyRegClass(RC);
 
  587        SUnit *NewDef = 
nullptr;
 
  589          NewDef = CopyAndMoveSuccessors(LRDef);
 
  590          if (!DestRC && !NewDef)
 
  592                               "register dependency!");
 
  597          InsertCopiesAndMoveSuccs(LRDef, 
Reg, DestRC, RC, 
Copies);
 
  599                            << 
" to SU #" << 
Copies.front()->NodeNum << 
"\n");
 
  605                          << 
" to SU #" << TrySU->
NodeNum << 
"\n");
 
  606        LiveRegDefs[
Reg] = NewDef;
 
  618    for (SUnit *SU : NotReady) {
 
  622        AvailableQueue.push(SU);
 
  627      ScheduleNodeBottomUp(CurSU, CurCycle);
 
  635  VerifyScheduledSequence(
true);
 
  646class ScheduleDAGLinearize : 
public ScheduleDAGSDNodes {
 
  648  ScheduleDAGLinearize(MachineFunction &mf) : ScheduleDAGSDNodes(mf) {}
 
  650  void Schedule() 
override;
 
  656  std::vector<SDNode*> Sequence;
 
  657  DenseMap<SDNode*, SDNode*> GluedMap;  
 
  659  void ScheduleNode(SDNode *
N);
 
  663void ScheduleDAGLinearize::ScheduleNode(SDNode *
N) {
 
  664  if (
N->getNodeId() != 0)
 
  667  if (!
N->isMachineOpcode() &&
 
  674  Sequence.push_back(
N);
 
  676  unsigned NumOps = 
N->getNumOperands();
 
  677  if (
unsigned NumLeft = 
NumOps) {
 
  678    SDNode *GluedOpN = 
nullptr;
 
  681      SDNode *OpN = 
Op.getNode();
 
  683      if (NumLeft == 
NumOps && 
Op.getValueType() == MVT::Glue) {
 
  696      DenseMap<SDNode*, SDNode*>::iterator DI = GluedMap.find(OpN);
 
  697      if (DI != GluedMap.end() && DI->second != 
N)
 
  702      assert(Degree > 0 && 
"Predecessor over-released!");
 
  713  while (
SDNode *Glued = 
N->getGluedUser())
 
 
  718void ScheduleDAGLinearize::Schedule() {
 
  719  LLVM_DEBUG(
dbgs() << 
"********** DAG Linearization **********\n");
 
  722  unsigned DAGSize = 0;
 
  723  for (SDNode &Node : DAG->allnodes()) {
 
  727    unsigned Degree = 
N->use_size();
 
  728    N->setNodeId(Degree);
 
  729    unsigned NumVals = 
N->getNumValues();
 
  730    if (NumVals && 
N->getValueType(NumVals-1) == MVT::Glue &&
 
  731        N->hasAnyUseOfValue(NumVals-1)) {
 
  735        GluedMap.insert(std::make_pair(
N, User));
 
  739    if (
N->isMachineOpcode() ||
 
  744  for (SDNode *Glue : Glues) {
 
  745    SDNode *GUser = GluedMap[Glue];
 
  746    unsigned Degree = Glue->getNodeId();
 
  751    SDNode *ImmGUser = Glue->getGluedUser();
 
  752    for (
const SDNode *U : Glue->users())
 
  759  Sequence.reserve(DAGSize);
 
  760  ScheduleNode(DAG->getRoot().getNode());
 
  765  InstrEmitter 
Emitter(DAG->getTarget(), BB, InsertPos);
 
  770  unsigned NumNodes = Sequence.size();
 
  771  MachineBasicBlock *BB = 
Emitter.getBlock();
 
  772  for (
unsigned i = 0; i != NumNodes; ++i) {
 
  773    SDNode *
N = Sequence[NumNodes-i-1];
 
  775    Emitter.EmitNode(
N, 
false, 
false, VRBaseMap);
 
  778    if (
N->getHasDebugValue()) {
 
  780      for (
auto *DV : DAG->GetDbgValues(
N)) {
 
  781        if (!DV->isEmitted())
 
  782          if (
auto *DbgMI = 
Emitter.EmitDbgValue(DV, VRBaseMap))
 
  783            BB->
insert(InsertPos, DbgMI);
 
  790  InsertPos = 
Emitter.getInsertPos();
 
  800  return new ScheduleDAGFast(*IS->
MF);
 
 
  805  return new ScheduleDAGLinearize(*IS->
MF);
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
 
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
 
dxil DXContainer Global Emitter
 
const HexagonInstrInfo * TII
 
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
 
Register const TargetRegisterInfo * TRI
 
Promote Memory to Register
 
static MVT getPhysicalRegisterVT(SDNode *N, unsigned Reg, const TargetInstrInfo *TII)
getPhysicalRegisterVT - Returns the ValueType of the physical register definition of the specified no...
 
static RegisterScheduler fastDAGScheduler("fast", "Fast suboptimal list scheduling", createFastDAGScheduler)
 
static bool CheckForLiveRegDef(SUnit *SU, MCRegister Reg, std::vector< SUnit * > &LiveRegDefs, SmallSet< unsigned, 4 > &RegAdded, SmallVectorImpl< unsigned > &LRegs, const TargetRegisterInfo *TRI, const SDNode *Node=nullptr)
CheckForLiveRegDef - Return true and update live register vector if the specified register def of the...
 
static RegisterScheduler linearizeDAGScheduler("linearize", "Linearize DAG, no scheduling", createDAGLinearizer)
 
static SDNode * findGluedUser(SDNode *N)
findGluedUser - Find the representative use of a glue value by walking the use chain.
 
This file defines the SmallSet class.
 
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
 
#define STATISTIC(VARNAME, DESC)
 
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
 
SmallDenseMap< SDValue, Register, 16 > VRBaseMapType
 
Describe properties that are true of each instruction in the target description file.
 
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
 
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
 
ArrayRef< MCPhysReg > implicit_defs() const
Return a list of registers that are potentially written by any instance of this machine instruction.
 
bool isCommutable() const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z,...
 
MCRegAliasIterator enumerates all registers aliasing Reg.
 
Wrapper class representing physical registers. Should be passed by value.
 
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
 
MachineInstrBundleIterator< MachineInstr > iterator
 
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
 
Represents one node in the SelectionDAG.
 
int getNodeId() const
Return the unique node id.
 
void setNodeId(int Id)
Set unique node id.
 
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
 
LLVM_ABI bool isOperandOf(const SDNode *N) const
Return true if this node is an operand of N.
 
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
 
@ Data
Regular data dependence (aka true-dependence).
 
@ Barrier
An unknown scheduling barrier.
 
@ Artificial
Arbitrary strong DAG edge (no real dependence).
 
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...
 
bool isCtrl() const
Shorthand for getKind() != SDep::Data.
 
Register getReg() const
Returns the register associated with this edge.
 
Scheduling unit. This is a node in the scheduling DAG.
 
LLVM_ABI void setHeightToAtLeast(unsigned NewHeight)
If NewHeight is greater than this node's height value, set it to be the new height value.
 
unsigned NodeNum
Entry # of node in the node vector.
 
const TargetRegisterClass * CopyDstRC
Is a special copy node if != nullptr.
 
unsigned getHeight() const
Returns the height of this node, which is the length of the maximum path down to any node which has n...
 
LLVM_ABI void removePred(const SDep &D)
Removes the specified edge as a pred of the current node if it exists.
 
unsigned short Latency
Node latency.
 
bool isPending
True once pending.
 
bool isScheduled
True once scheduled.
 
bool isAvailable
True once available.
 
SmallVector< SDep, 4 > Succs
All sunit successors.
 
const TargetRegisterClass * CopySrcRC
 
SDNode * getNode() const
Returns the representative SDNode for this SUnit.
 
bool isTwoAddress
Is a two-address instruction.
 
bool isCommutable
Is a commutable instruction.
 
SmallVector< SDep, 4 > Preds
All sunit predecessors.
 
LLVM_ABI bool addPred(const SDep &D, bool Required=true)
Adds the specified edge as a pred of the current node if not already.
 
ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs.
 
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
 
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
 
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
 
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
 
void push_back(const T &Elt)
 
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
 
TargetInstrInfo - Interface to description of machine instruction set.
 
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
 
@ EntryToken
EntryToken - This is the marker used to indicate the start of a region.
 
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
 
@ User
could "use" a pointer
 
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
 
NodeAddr< NodeBase * > Node
 
This is an optimization pass for GlobalISel generic memory operations.
 
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
 
LLVM_ABI ScheduleDAGSDNodes * createFastDAGScheduler(SelectionDAGISel *IS, CodeGenOptLevel OptLevel)
createFastDAGScheduler - This creates a "fast" scheduler.
 
LLVM_ABI ScheduleDAGSDNodes * createDAGLinearizer(SelectionDAGISel *IS, CodeGenOptLevel OptLevel)
createDAGLinearizer - This creates a "no-scheduling" scheduler which linearize the DAG using topologi...
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
 
CodeGenOptLevel
Code generation optimization level.
 
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
 
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
 
DWARFExpression::Operation Op
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.