//===----- ScheduleDAGFast.cpp - Fast poor list scheduler -----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This implements a fast scheduler. // //===----------------------------------------------------------------------===// #include "InstrEmitter.h" #include "SDNodeDbgValue.h" #include "ScheduleDAGSDNodes.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/IR/InlineAsm.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" usingnamespacellvm; #define DEBUG_TYPE … STATISTIC(NumUnfolds, "Number of nodes unfolded"); STATISTIC(NumDups, "Number of duplicated nodes"); STATISTIC(NumPRCopies, "Number of physical copies"); static RegisterScheduler fastDAGScheduler("fast", "Fast suboptimal list scheduling", createFastDAGScheduler); static RegisterScheduler linearizeDAGScheduler("linearize", "Linearize DAG, no scheduling", createDAGLinearizer); namespace { /// FastPriorityQueue - A degenerate priority queue that considers /// all nodes to have the same priority. /// struct FastPriorityQueue { … }; //===----------------------------------------------------------------------===// /// ScheduleDAGFast - The actual "fast" list scheduler implementation. /// class ScheduleDAGFast : public ScheduleDAGSDNodes { … }; } // end anonymous namespace /// Schedule - Schedule the DAG using list scheduling. void ScheduleDAGFast::Schedule() { … } //===----------------------------------------------------------------------===// // Bottom-Up Scheduling //===----------------------------------------------------------------------===// /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the AvailableQueue if the count reaches zero. Also update its cycle bound. void ScheduleDAGFast::ReleasePred(SUnit *SU, SDep *PredEdge) { … } void ScheduleDAGFast::ReleasePredecessors(SUnit *SU, unsigned CurCycle) { … } /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending /// count of its predecessors. If a predecessor pending count is zero, add it to /// the Available queue. void ScheduleDAGFast::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { … } /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled /// successors to the newly created node. SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) { … } /// InsertCopiesAndMoveSuccs - Insert register copies and move all /// scheduled successors of the given SUnit to the last copy. void ScheduleDAGFast::InsertCopiesAndMoveSuccs(SUnit *SU, unsigned Reg, const TargetRegisterClass *DestRC, const TargetRegisterClass *SrcRC, SmallVectorImpl<SUnit*> &Copies) { … } /// getPhysicalRegisterVT - Returns the ValueType of the physical register /// definition of the specified node. /// FIXME: Move to SelectionDAG? static MVT getPhysicalRegisterVT(SDNode *N, unsigned Reg, const TargetInstrInfo *TII) { … } /// CheckForLiveRegDef - Return true and update live register vector if the /// specified register def of the specified SUnit clobbers any "live" registers. static bool CheckForLiveRegDef(SUnit *SU, unsigned Reg, std::vector<SUnit *> &LiveRegDefs, SmallSet<unsigned, 4> &RegAdded, SmallVectorImpl<unsigned> &LRegs, const TargetRegisterInfo *TRI, const SDNode *Node = nullptr) { … } /// DelayForLiveRegsBottomUp - Returns true if it is necessary to delay /// scheduling of the given node to satisfy live physical register dependencies. /// If the specific node is the last one that's available to schedule, do /// whatever is necessary (i.e. backtracking or cloning) to make it possible. bool ScheduleDAGFast::DelayForLiveRegsBottomUp(SUnit *SU, SmallVectorImpl<unsigned> &LRegs){ … } /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up /// schedulers. void ScheduleDAGFast::ListScheduleBottomUp() { … } namespace { //===----------------------------------------------------------------------===// // ScheduleDAGLinearize - No scheduling scheduler, it simply linearize the // DAG in topological order. // IMPORTANT: this may not work for targets with phyreg dependency. // class ScheduleDAGLinearize : public ScheduleDAGSDNodes { … }; } // end anonymous namespace void ScheduleDAGLinearize::ScheduleNode(SDNode *N) { … } /// findGluedUser - Find the representative use of a glue value by walking /// the use chain. static SDNode *findGluedUser(SDNode *N) { … } void ScheduleDAGLinearize::Schedule() { … } MachineBasicBlock* ScheduleDAGLinearize::EmitSchedule(MachineBasicBlock::iterator &InsertPos) { … } //===----------------------------------------------------------------------===// // Public Constructor Functions //===----------------------------------------------------------------------===// llvm::ScheduleDAGSDNodes *llvm::createFastDAGScheduler(SelectionDAGISel *IS, CodeGenOptLevel) { … } llvm::ScheduleDAGSDNodes *llvm::createDAGLinearizer(SelectionDAGISel *IS, CodeGenOptLevel) { … }