15 #define DEBUG_TYPE "pre-RA-sched"
38 STATISTIC(LoadsClustered,
"Number of loads clustered together");
45 cl::desc(
"Roughly estimate the number of cycles that 'long latency'"
46 "instructions take for targets with no itinerary"));
50 InstrItins(mf.getTarget().getInstrItineraryData()) {}
70 const SUnit *Addr = 0;
75 assert((Addr == 0 || Addr == &
SUnits[0]) &&
76 "SUnits std::vector reallocated on the fly!");
113 unsigned &PhysReg,
int &Cost) {
142 if (ExtraOper.getNode())
167 if (GlueDestNode == N)
return false;
193 "expected an unused glue value");
207 void ScheduleDAGSDNodes::ClusterNeighboringLoads(
SDNode *Node) {
220 bool Cluster =
false;
225 if (User == Node || !Visited.
insert(User))
227 int64_t Offset1, Offset2;
233 if (O2SMap.
insert(std::make_pair(Offset1, Base)).second)
235 O2SMap.
insert(std::make_pair(Offset2, User));
237 if (Offset2 < Offset1)
246 std::sort(Offsets.
begin(), Offsets.
end());
250 unsigned NumLoads = 0;
251 int64_t BaseOff = Offsets[0];
252 SDNode *BaseLoad = O2SMap[BaseOff];
253 Loads.push_back(BaseLoad);
254 for (
unsigned i = 1, e = Offsets.
size(); i != e; ++i) {
255 int64_t Offset = Offsets[i];
259 Loads.push_back(Load);
270 if (
AddGlue(Lead, InGlue,
true, DAG))
272 for (
unsigned I = 1, E = Loads.size();
I != E; ++
I) {
273 bool OutGlue =
I < E - 1;
278 if (
AddGlue(Load, InGlue, OutGlue, DAG)) {
284 else if (!OutGlue && InGlue.
getNode())
291 void ScheduleDAGSDNodes::ClusterNodes() {
302 ClusterNeighboringLoads(Node);
306 void ScheduleDAGSDNodes::BuildSchedUnits() {
310 unsigned NumNodes = 0;
322 SUnits.reserve(NumNodes * 2);
331 while (!Worklist.
empty()) {
356 assert(N->
getNodeId() == -1 &&
"Node already inserted!");
368 bool HasGlueUse =
false;
371 if (GlueVal.isOperandOf(*UI)) {
373 assert(N->
getNodeId() == -1 &&
"Node already inserted!");
380 if (!HasGlueUse)
break;
396 assert(N->
getNodeId() == -1 &&
"Node already inserted!");
407 while (!CallSUnits.
empty()) {
421 void ScheduleDAGSDNodes::AddSchedEdges() {
428 for (
unsigned su = 0, e =
SUnits.size(); su != e; ++su) {
461 assert(OpSU &&
"Node has no SUnit!");
462 if (OpSU == SU)
continue;
465 assert(OpVT !=
MVT::Glue &&
"Glued nodes should be in same sunit!");
468 unsigned PhysReg = 0;
472 assert((PhysReg == 0 || !isChain) &&
473 "Chain dependence via physreg data?");
483 unsigned OpLatency = isChain ? 1 : OpSU->
Latency;
489 : SDep(OpSU, SDep::Data, PhysReg);
491 if (!isChain && !UnitLatencies) {
526 void ScheduleDAGSDNodes::RegDefIter::InitNodeNumDefs() {
554 : SchedDAG(SD), Node(SU->getNode()), DefIdx(0), NodeNumDefs(0) {
562 for (;DefIdx < NodeNumDefs; ++DefIdx) {
580 assert(SU->
NumRegDefsLeft < USHRT_MAX &&
"overflow is ok but unexpected");
620 unsigned OpIdx, SDep& dep)
const{
640 Latency = (Latency > 1) ? Latency - 1 : 1;
647 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
649 dbgs() <<
"PHYS REG COPY\n";
658 while (!GluedNodes.
empty()) {
667 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
669 for (
unsigned i = 0, e =
Sequence.size(); i != e; i++) {
673 dbgs() <<
"**** NOOP ****\n";
685 for (
unsigned i = 0, e =
Sequence.size(); i != e; ++i)
688 assert(
Sequence.size() - Noops == ScheduledNodes &&
689 "The number of nodes scheduled doesn't match the expected number!");
706 for (
unsigned i = 0, e = DVs.
size(); i != e; ++i) {
707 if (DVs[i]->isInvalidated())
709 unsigned DVOrder = DVs[i]->getOrder();
710 if (!Order || DVOrder == ++Order) {
713 Orders.push_back(std::make_pair(DVOrder, DbgMI));
714 BB->
insert(InsertPos, DbgMI);
716 DVs[i]->setIsInvalidated();
730 if (!Order || !Seen.
insert(Order)) {
751 void ScheduleDAGSDNodes::
756 if (
I->isCtrl())
continue;
757 if (
I->getSUnit()->CopyDstRC) {
760 assert(VRI != VRBaseMap.
end() &&
"Node emitted out of order - late");
764 EE = SU->
Succs.end(); II != EE; ++II) {
765 if (II->isCtrl())
continue;
772 .addReg(VRI->second);
775 assert(
I->getReg() &&
"Unknown physical register!");
777 bool isNew = VRBaseMap.
insert(std::make_pair(SU, VRBase)).second;
779 assert(isNew &&
"Node emitted out of order - early");
781 .addReg(
I->getReg());
804 for (; PDI != PDE; ++PDI) {
811 for (
unsigned i = 0, e =
Sequence.size(); i != e; i++) {
823 EmitPhysRegCopy(SU, CopyVRBaseMap, InsertPos);
830 while (!GluedNodes.
empty()) {
859 unsigned LastOrder = 0;
860 for (
unsigned i = 0, e = Orders.
size(); i != e && DI !=
DE; ++i) {
861 unsigned Order = Orders[i].first;
867 (*DI)->getOrder() >= LastOrder && (*DI)->getOrder() < Order; ++DI) {
868 if ((*DI)->isInvalidated())
889 if (!(*DI)->isInvalidated())
void push_back(const T &Elt)
const MachineFunction * getParent() const
bool isCtrl() const
isCtrl - Shorthand for getKind() != SDep::Data.
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, EVT VT=MVT::Other) const
void dump() const
dump - Dump this node, for debugging.
bool hasDebugValues() const
void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd)
bool isCommutable() const
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions. Register definitions always occur...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
virtual void computeOperandLatency(SDNode *Def, SDNode *Use, unsigned OpIdx, SDep &dep) const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
iterator getFirstTerminator()
SDNode * getGluedNode() const
static bool isVirtualRegister(unsigned Reg)
unsigned getOpcode() const
bool getHasDebugValue() const
getHasDebugValue - get this bit.
static unsigned CountResults(SDNode *Node)
unsigned getNumOperands() const
const SDValue & getOperand(unsigned Num) const
mmo_iterator memoperands_end() const
virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, int64_t Offset1, int64_t Offset2, unsigned NumLoads) const
void setNodeId(int Id)
setNodeId - Set unique node id.
const TargetRegisterClass * CopyDstRC
unsigned getResNo() const
get the index which selects a specific result in the SDNode
SmallVector< SDep, 4 > Preds
MachineBasicBlock * getBlock()
getBlock - Return the current basic block.
SDDbgInfo::DbgIterator DbgBegin()
void InitNumRegDefsLeft(SUnit *SU)
static void ProcessSDDbgValues(SDNode *N, SelectionDAG *DAG, InstrEmitter &Emitter, SmallVectorImpl< std::pair< unsigned, MachineInstr * > > &Orders, DenseMap< SDValue, unsigned > &VRBaseMap, unsigned Order)
ProcessSDDbgValues - Process SDDbgValues associated with this node.
mmo_iterator memoperands_begin() const
SDNode * MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps)
const HexagonInstrInfo * TII
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
virtual void dumpNode(const SUnit *SU) const
EVT getValueType(unsigned ResNo) const
Regular data dependence (aka true-dependence).
allnodes_const_iterator allnodes_end() const
void dumpSchedule() const
SDVTList getVTList(EVT VT)
ScheduleDAGSDNodes(MachineFunction &mf)
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
static cl::opt< int > HighLatencyCycles("sched-high-latency-cycles", cl::Hidden, cl::init(10), cl::desc("Roughly estimate the number of cycles that 'long latency'""instructions take for targets with no itinerary"))
unsigned getIROrder() const
unsigned getNumValues() const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op, const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, unsigned &PhysReg, int &Cost)
virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep &dep) const
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
size_t size() const
size - Get the array size.
const MachineBasicBlock * getParent() const
SDDbgInfo::DbgIterator ByvalParmDbgEnd()
SDNode * getNode() const
get the SDNode which holds the desired result
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
SUnit * newSUnit(SDNode *N)
void clearDAG()
clearDAG - clear the DAG state (between regions).
virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1, int64_t &Offset2) const
const InstrItineraryData * InstrItins
virtual void computeLatency(SUnit *SU)
ArrayRef< SDDbgValue * > GetDbgValues(const SDNode *SD)
GetDbgValues - Get the debug values which reference the given SDNode.
use_iterator use_begin() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
Sched::Preference SchedulingPref
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specific constraint if it is set. Returns -1 if it is not set...
const SDValue & getRoot() const
const MCInstrDesc & get(unsigned Opcode) const
An unknown scheduling barrier.
std::string getFullName() const
Return a hopefully unique identifier for this block.
static void RemoveUnusedGlue(SDNode *N, SelectionDAG *DAG)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
const STC & getSubtarget() const
virtual void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
allnodes_const_iterator allnodes_begin() const
SDDbgInfo::DbgIterator DbgEnd()
bool mayLoad() const
Return true if this instruction could possibly read memory. Instructions with this flag set are not n...
static void CloneNodeWithValues(SDNode *N, SelectionDAG *DAG, SmallVectorImpl< EVT > &VTs, SDValue ExtraOper=SDValue())
SDDbgInfo::DbgIterator ByvalParmDbgBegin()
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
static use_iterator use_end()
virtual unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr *MI, unsigned *PredCost=0) const
void setLatency(unsigned Lat)
setLatency - Set the latency for this edge.
static bool isPassiveNode(SDNode *Node)
unsigned VerifyScheduledDAG(bool isBottomUp)
const TargetRegisterInfo * TRI
void EmitNode(SDNode *Node, bool IsClone, bool IsCloned, DenseMap< SDValue, unsigned > &VRBaseMap)
static void ProcessSourceNode(SDNode *N, SelectionDAG *DAG, InstrEmitter &Emitter, DenseMap< SDValue, unsigned > &VRBaseMap, SmallVectorImpl< std::pair< unsigned, MachineInstr * > > &Orders, SmallSet< unsigned, 8 > &Seen)
bool hasAnyUseOfValue(unsigned Value) const
virtual std::string getDAGName() const
Return the basic block label.
RegDefIter(const SUnit *SU, const ScheduleDAGSDNodes *SD)
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
void BuildSchedGraph(AliasAnalysis *AA)
void push_back(MachineInstr *MI)
unsigned short NumRegDefsLeft
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
virtual int getOperandLatency(const InstrItineraryData *ItinData, SDNode *DefNode, unsigned DefIdx, SDNode *UseNode, unsigned UseIdx) const
Kind getKind() const
getKind - Return an enum value representing the kind of the dependence.
instr_iterator insert(instr_iterator I, MachineInstr *M)
void Run(SelectionDAG *dag, MachineBasicBlock *bb)
iterator getFirstNonPHI()
const TargetInstrInfo * TII
const uint16_t * ImplicitDefs
MachineInstr * EmitDbgValue(SDDbgValue *SD, DenseMap< SDValue, unsigned > &VRBaseMap)
bool addPred(const SDep &D, bool Required=true)
MachineBasicBlock::iterator getInsertPos()
getInsertPos - Return the current insertion position.
virtual MachineBasicBlock * EmitSchedule(MachineBasicBlock::iterator &InsertPos)
SmallVector< SDep, 4 > Succs
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction. Note that variadic (isVari...
BasicBlockListType::iterator iterator
const TargetLowering & getTargetLoweringInfo() const
ItTy prior(ItTy it, Dist n)
STATISTIC(LoadsClustered,"Number of loads clustered together")
virtual bool forceUnitLatencies() const
MachineRegisterInfo & MRI
std::vector< SUnit > SUnits
iterator find(const KeyT &Val)
MVT getSimpleValueType(unsigned ResNo) const
virtual void Schedule()=0
Function object to check whether the first component of a std::pair compares less than the first comp...
void dump(const ScheduleDAG *G) const
virtual bool isHighLatencyDef(int opc) const
SUnit - Scheduling unit. This is a node in the scheduling DAG.
static bool AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG)
bool isMachineOpcode() const
void VerifyScheduledSequence(bool isBottomUp)
unsigned getMachineOpcode() const