LLVM: lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
29#include "llvm/Config/llvm-config.h"
36using namespace llvm;
37
38#define DEBUG_TYPE "pre-RA-sched"
39
40STATISTIC(LoadsClustered, "Number of loads clustered together");
41
42
43
44
47 cl::desc("Roughly estimate the number of cycles that 'long latency' "
48 "instructions take for targets with no itinerary"));
49
52
53
54
56 BB = bb;
57 DAG = dag;
58
59
62
63
65}
66
67
68
70#ifndef NDEBUG
71 const SUnit *Addr = nullptr;
74#endif
76 assert((Addr == nullptr || Addr == &SUnits[0]) &&
77 "SUnits std::vector reallocated on the fly!");
81 if ( ||
82 (N->isMachineOpcode() &&
83 N->getMachineOpcode() == TargetOpcode::IMPLICIT_DEF))
85 else
87 return SU;
88}
89
107
108
109
110
116 return;
117
119 if (Reg.isVirtual())
120 return;
121
125 PhysReg = Reg;
126 } else if (Def->isMachineOpcode()) {
128 if (ResNo >= II.getNumDefs() && II.hasImplicitDefOfPhysReg(Reg))
129 PhysReg = Reg;
130 }
131
132 if (PhysReg) {
134 TRI->getMinimalPhysRegClass(Reg, Def->getSimpleValueType(ResNo));
136 }
137}
138
139
143 if (ExtraOper.getNode())
144 Ops.push_back(ExtraOper);
145
148
149
151 if (MN)
153
155
156
157 if (MN)
159}
160
163
164
165 if (GlueDestNode == N) return false;
166
167
168 if (GlueDestNode &&
169 N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) {
170 return false;
171 }
172
173 if (N->getValueType(N->getNumValues() - 1) == MVT::Glue) return false;
174
178
180
181 return true;
182}
183
184
185
187 assert((N->getValueType(N->getNumValues() - 1) == MVT::Glue &&
188 ->hasAnyUseOfValue(N->getNumValues() - 1)) &&
189 "expected an unused glue value");
190
192 ArrayRef(N->value_begin(), N->getNumValues() - 1));
193}
194
195
196
197
198
199
200void ScheduleDAGSDNodes::ClusterNeighboringLoads(SDNode *Node) {
202 unsigned NumOps = Node->getNumOperands();
203 if (Node->getOperand(NumOps-1).getValueType() == MVT::Other)
205 if (!Chain)
206 return;
207
208
209
210
211 auto hasTiedInput = [this](const SDNode *N) {
212 const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
215 return true;
216 }
217
218 return false;
219 };
220
221
222
223 SmallPtrSet<SDNode*, 16> Visited;
225 DenseMap<long long, SDNode*> O2SMap;
228
229 if (hasTiedInput(Base))
230 return;
231
232
233
234 unsigned UseCount = 0;
236 I != E && UseCount < 100; ++I, ++UseCount) {
237 if (I.getUse().getResNo() != Chain.getResNo())
238 continue;
239
241 if (User == Node || !Visited.insert(User).second)
242 continue;
243 int64_t Offset1, Offset2;
244 if (->areLoadsFromSameBasePtr(Base, User, Offset1, Offset2) ||
245 Offset1 == Offset2 ||
246 hasTiedInput(User)) {
247
248
249 continue;
250 }
251 if (O2SMap.insert(std::make_pair(Offset1, Base)).second)
252 Offsets.push_back(Offset1);
253 O2SMap.insert(std::make_pair(Offset2, User));
254 Offsets.push_back(Offset2);
255 if (Offset2 < Offset1)
258
259 UseCount = 0;
260 }
261
262 if (!Cluster)
263 return;
264
265
267
268
270 unsigned NumLoads = 0;
271 int64_t BaseOff = Offsets[0];
272 SDNode *BaseLoad = O2SMap[BaseOff];
274 for (unsigned i = 1, e = Offsets.size(); i != e; ++i) {
277 if (->shouldScheduleLoadsNear(BaseLoad, Load, BaseOff, Offset,NumLoads))
278 break;
280 ++NumLoads;
281 }
282
283 if (NumLoads == 0)
284 return;
285
286
287
288 SDNode *Lead = Loads[0];
290 if (AddGlue(Lead, InGlue, true, DAG))
292 for (unsigned I = 1, E = Loads.size(); I != E; ++I) {
295
296
297
298 if (AddGlue(Load, InGlue, OutGlue, DAG)) {
299 if (OutGlue)
300 InGlue = SDValue(Load, Load->getNumValues() - 1);
301
302 ++LoadsClustered;
303 }
304 else if (!OutGlue && InGlue.getNode())
306 }
307}
308
309
310
311void ScheduleDAGSDNodes::ClusterNodes() {
312 for (SDNode &NI : DAG->allnodes()) {
313 SDNode *Node = &NI;
314 if (!Node || ->isMachineOpcode())
315 continue;
316
317 unsigned Opc = Node->getMachineOpcode();
318 const MCInstrDesc &MCID = TII->get(Opc);
320
321 ClusterNeighboringLoads(Node);
322 }
323}
324
325void ScheduleDAGSDNodes::BuildSchedUnits() {
326
327
328
329 unsigned NumNodes = 0;
330 for (SDNode &NI : DAG->allnodes()) {
331 NI.setNodeId(-1);
332 ++NumNodes;
333 }
334
335
336
337
338
339
340 SUnits.reserve(NumNodes * 2);
341
342
344 SmallPtrSet<SDNode*, 32> Visited;
345 Worklist.push_back(DAG->getRoot().getNode());
346 Visited.insert(DAG->getRoot().getNode());
347
349 while (!Worklist.empty()) {
351
352
354 if (Visited.insert(Op.getNode()).second)
356
357 if (isPassiveNode(NI))
358 continue;
359
360
361 if (NI->getNodeId() != -1) continue;
362
363 SUnit *NodeSUnit = newSUnit(NI);
364
365
366
367
368
369
370 SDNode *N = NI;
371 while (N->getNumOperands() &&
372 N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) {
373 N = N->getOperand(N->getNumOperands()-1).getNode();
374 assert(N->getNodeId() == -1 && "Node already inserted!");
375 N->setNodeId(NodeSUnit->NodeNum);
376 if (N->isMachineOpcode() && TII->get(N->getMachineOpcode()).isCall())
377 NodeSUnit->isCall = true;
378 }
379
380
381 N = NI;
382 while (N->getValueType(N->getNumValues()-1) == MVT::Glue) {
383 SDValue GlueVal(N, N->getNumValues()-1);
384
385
386 bool HasGlueUse = false;
387 for (SDNode *U : N->users())
388 if (GlueVal.isOperandOf(U)) {
389 HasGlueUse = true;
390 assert(N->getNodeId() == -1 && "Node already inserted!");
391 N->setNodeId(NodeSUnit->NodeNum);
393 if (N->isMachineOpcode() && TII->get(N->getMachineOpcode()).isCall())
394 NodeSUnit->isCall = true;
395 break;
396 }
397 if (!HasGlueUse) break;
398 }
399
400 if (NodeSUnit->isCall)
402
403
404
405
408
409
410
411
413 assert(N->getNodeId() == -1 && "Node already inserted!");
414 N->setNodeId(NodeSUnit->NodeNum);
415
416
418
419
421 }
422
423
424 while (!CallSUnits.empty()) {
426 for (const SDNode *SUNode = SU->getNode(); SUNode;
429 continue;
430 SDNode *SrcN = SUNode->getOperand(2).getNode();
431 if (isPassiveNode(SrcN)) continue;
434 }
435 }
436}
437
438void ScheduleDAGSDNodes::AddSchedEdges() {
439 const TargetSubtargetInfo &ST = MF.getSubtarget();
440
441
443
444
445 for (SUnit &SU : SUnits) {
446 SDNode *MainNode = SU.getNode();
447
450 const MCInstrDesc &MCID = TII->get(Opc);
451 for (unsigned i = 0; i != MCID.getNumOperands(); ++i) {
454 break;
455 }
456 }
459 }
460
461
463 if (N->isMachineOpcode() &&
464 ->get(N->getMachineOpcode()).implicit_defs().empty()) {
467 while (NumUsed != 0 && ->hasAnyUseOfValue(NumUsed - 1))
468 --NumUsed;
469 if (NumUsed > TII->get(N->getMachineOpcode()).getNumDefs())
471 }
472
473 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
474 SDNode *OpN = N->getOperand(i).getNode();
475 unsigned DefIdx = N->getOperand(i).getResNo();
476 if (isPassiveNode(OpN)) continue;
478 assert(OpSU && "Node has no SUnit!");
479 if (OpSU == &SU)
480 continue;
481
482 EVT OpVT = N->getOperand(i).getValueType();
483 assert(OpVT != MVT::Glue && "Glued nodes should be in same sunit!");
484 bool isChain = OpVT == MVT::Other;
485
486 MCRegister PhysReg;
487 int Cost = 1;
488
490 assert((!PhysReg || !isChain) && "Chain dependence via physreg data?");
491
492
493
494
495
497 PhysReg = MCRegister();
498
499
500 unsigned OpLatency = isChain ? 1 : OpSU->Latency;
501
503 OpLatency = 0;
504
506 : SDep(OpSU, SDep::Data, PhysReg);
508 if (!isChain && !UnitLatencies) {
510 ST.adjustSchedDependency(OpSU, DefIdx, &SU, i, Dep, nullptr);
511 }
512
514
515
516
517
518
519
520
521
522 --OpSU->NumRegDefsLeft;
523 }
524 }
525 }
526 }
527}
528
529
530
531
532
534
535 ClusterNodes();
536
537 BuildSchedUnits();
538
539 AddSchedEdges();
540}
541
542
543void ScheduleDAGSDNodes::RegDefIter::InitNodeNumDefs() {
544
546 return;
547
548 if (->isMachineOpcode()) {
550 NodeNumDefs = 1;
551 else
552 NodeNumDefs = 0;
553 return;
554 }
555 unsigned POpc = Node->getMachineOpcode();
556 if (POpc == TargetOpcode::IMPLICIT_DEF) {
557
558 NodeNumDefs = 0;
559 return;
560 }
561 if (POpc == TargetOpcode::PATCHPOINT &&
562 Node->getValueType(0) == MVT::Other) {
563
564
565
566 NodeNumDefs = 0;
567 return;
568 }
569 unsigned NRegDefs = SchedDAG->TII->get(Node->getMachineOpcode()).getNumDefs();
570
571
572 NodeNumDefs = std::min(Node->getNumValues(), NRegDefs);
573 DefIdx = 0;
574}
575
576
579 : SchedDAG(SD), Node(SU->getNode()) {
580 InitNodeNumDefs();
582}
583
584
586 for (;Node;) {
587 for (;DefIdx < NodeNumDefs; ++DefIdx) {
588 if (!Node->hasAnyUseOfValue(DefIdx))
589 continue;
590 ValueType = Node->getSimpleValueType(DefIdx);
591 ++DefIdx;
592 return;
593 }
594 Node = Node->getGluedNode();
595 if (!Node) {
596 return;
597 }
598 InitNodeNumDefs();
599 }
600}
601
604 for (RegDefIter I(SU, this); I.IsValid(); I.Advance()) {
607 }
608}
609
612
613
614
615
618 return;
619 }
620
621
624 return;
625 }
626
628 if (N && N->isMachineOpcode() &&
629 TII->isHighLatencyDef(N->getMachineOpcode()))
631 else
633 return;
634 }
635
636
637
640 if (N->isMachineOpcode())
642}
643
645 unsigned OpIdx, SDep& dep) const{
646
648 return;
649
651 return;
652
653 unsigned DefIdx = Use->getOperand(OpIdx).getResNo();
654 if (Use->isMachineOpcode())
655
656 OpIdx += TII->get(Use->getMachineOpcode()).getNumDefs();
657 std::optional Latency =
660 ->succ_empty()) {
662 if (Reg.isVirtual())
663
664
665
667 }
670}
671
673#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
675 dbgs() << ": ";
676
678 dbgs() << "PHYS REG COPY\n";
679 return;
680 }
681
683 dbgs() << "\n";
687 while (!GluedNodes.empty()) {
688 dbgs() << " ";
689 GluedNodes.back()->dump(DAG);
690 dbgs() << "\n";
692 }
693#endif
694}
695
697#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
698 if (EntrySU.getNode() != nullptr)
702 if (ExitSU.getNode() != nullptr)
704#endif
705}
706
707#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
710 if (SU)
712 else
713 dbgs() << "**** NOOP ****\n";
714 }
715}
716#endif
717
718#ifndef NDEBUG
719
720
721
726 "The number of nodes scheduled doesn't match the expected number!");
727}
728#endif
729
730
731static void
733 SmallVectorImpl<std::pair<unsigned, MachineInstr*> > &Orders,
735 if (->getHasDebugValue())
736 return;
737
738
739
740 auto HasUnknownVReg = [&VRBaseMap](SDDbgValue *DV) {
741 for (const SDDbgOperand &L : DV->getLocationOps()) {
743 VRBaseMap.count({L.getSDNode(), L.getResNo()}) == 0)
744 return true;
745 }
746 return false;
747 };
748
749
750
754 if (DV->isEmitted())
755 continue;
756 unsigned DVOrder = DV->getOrder();
757 if (Order != 0 && DVOrder != Order)
758 continue;
759
760
761
762
763
764 if (!DV->isInvalidated() && HasUnknownVReg(DV))
765 continue;
767 if (!DbgMI)
768 continue;
769 Orders.push_back({DVOrder, DbgMI});
770 BB->insert(InsertPos, DbgMI);
771 }
772}
773
774
775
776
777static void
780 SmallVectorImpl<std::pair<unsigned, MachineInstr *>> &Orders,
782 unsigned Order = N->getIROrder();
783 if (!Order || Seen.count(Order)) {
784
785
787 return;
788 }
789
790
791
792
793
794 if (NewInsn) {
796 Orders.push_back({Order, NewInsn});
797 }
798
799
800
802}
803
804void ScheduleDAGSDNodes::
805EmitPhysRegCopy(SUnit *SU, SmallDenseMap<SUnit *, Register, 16> &VRBaseMap,
807 for (const SDep &Pred : SU->Preds) {
809 continue;
811
814 assert(VRI != VRBaseMap.end() && "Node emitted out of order - late");
815
817 for (const SDep &Succ : SU->Succs) {
819 continue;
822 break;
823 }
824 }
826 .addReg(VRI->second);
827 } else {
828
829 assert(Pred.getReg() && "Unknown physical register!");
831 bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second;
832 (void)isNew;
833 assert(isNew && "Node emitted out of order - early");
836 }
837 break;
838 }
839}
840
841
842
843
844
852 bool HasDbg = DAG->hasDebugValues();
853
854
855
856 auto EmitNode =
857 [&](SDNode *Node, bool IsClone, bool IsCloned,
859
862 return BB->end();
863 else
864 return std::prev(Emitter.getInsertPos());
865 };
866
868 Emitter.EmitNode(Node, IsClone, IsCloned, VRBaseMap);
870
871
872 if (Before == After)
873 return nullptr;
874
876 if (Before == BB->end()) {
877
878
879 MI = &Emitter.getBlock()->instr_front();
880 } else {
881
882 MI = &*std::next(Before);
883 }
884
885 if (MI->isCandidateForAdditionalCallInfo()) {
886 if (DAG->getTarget().Options.EmitCallSiteInfo ||
887 DAG->getTarget().Options.EmitCallGraphSection)
888 MF.addCallSiteInfo(MI, DAG->getCallSiteInfo(Node));
889
890 if (auto CalledGlobal = DAG->getCalledGlobal(Node))
891 if (CalledGlobal->Callee)
892 MF.addCalledGlobal(MI, *CalledGlobal);
893 }
894
895 if (DAG->getNoMergeSiteInfo(Node)) {
897 }
898
900 MI->setPCSections(MF, MD);
901
902
905 End = std::next(After);
906 It != End; ++It)
907 It->setMMRAMetadata(MF, MMRA);
908 }
909
910 return MI;
911 };
912
913
917 for (; PDI != PDE; ++PDI) {
919 if (DbgMI) {
920 BB->insert(InsertPos, DbgMI);
921
922
923 (*PDI)->clearIsEmitted();
924 }
925 }
926 }
927
929 if (!SU) {
930
931 TII->insertNoop(*Emitter.getBlock(), InsertPos);
932 continue;
933 }
934
935
936
938
939 EmitPhysRegCopy(SU, CopyVRBaseMap, InsertPos);
940 continue;
941 }
942
946 while (!GluedNodes.empty()) {
948 auto NewInsn = EmitNode(N, SU->OrigNode != SU, SU->isCloned, VRBaseMap);
949
950 if (HasDbg)
952
953 if (MDNode *MD = DAG->getHeapAllocSite(N))
954 if (NewInsn && NewInsn->isCall())
955 NewInsn->setHeapAllocMarker(MF, MD);
956
958 }
959 auto NewInsn =
961
962 if (HasDbg)
964 NewInsn);
965
967 if (NewInsn && NewInsn->isCall())
968 NewInsn->setHeapAllocMarker(MF, MD);
969 }
970 }
971
972
973
974 if (HasDbg) {
976
977
978
979
981 std::stable_sort(DAG->DbgBegin(), DAG->DbgEnd(),
983 return LHS->getOrder() < RHS->getOrder();
984 });
985
988
989 unsigned LastOrder = 0;
990 for (unsigned i = 0, e = Orders.size(); i != e && DI != DE; ++i) {
991 unsigned Order = Orders[i].first;
993
995 for (; DI != DE; ++DI) {
996 if ((*DI)->getOrder() < LastOrder || (*DI)->getOrder() >= Order)
997 break;
998 if ((*DI)->isEmitted())
999 continue;
1000
1002 if (DbgMI) {
1003 if (!LastOrder)
1004
1005 BB->insert(BBBegin, DbgMI);
1006 else {
1007
1008
1010 MI->getParent()->insert(Pos, DbgMI);
1011 }
1012 }
1013 }
1014 LastOrder = Order;
1015 }
1016
1017
1019 for (; DI != DE; ++DI) {
1020 if ((*DI)->isEmitted())
1021 continue;
1022 assert((*DI)->getOrder() >= LastOrder &&
1023 "emitting DBG_VALUE out of order");
1026 }
1027
1030 InsertBB->insert(Pos, DbgMIs.begin(), DbgMIs.end());
1031
1034
1035 LastOrder = 0;
1036 for (const auto &InstrOrder : Orders) {
1037 unsigned Order = InstrOrder.first;
1039 if ()
1040 continue;
1041
1042
1043 for (; DLI != DLE &&
1044 (*DLI)->getOrder() >= LastOrder && (*DLI)->getOrder() < Order;
1045 ++DLI) {
1047 if (DbgMI) {
1048 if (!LastOrder)
1049
1050 BB->insert(BBBegin, DbgMI);
1051 else {
1052
1053
1055 MI->getParent()->insert(Pos, DbgMI);
1056 }
1057 }
1058 }
1059 if (DLI == DLE)
1060 break;
1061
1062 LastOrder = Order;
1063 }
1064 }
1065
1066 InsertPos = Emitter.getInsertPos();
1067
1068
1069
1072 if (FirstTerm != InsertBB->end()) {
1073 assert(!FirstTerm->isDebugValue() &&
1074 "first terminator cannot be a debug value");
1076 make_range(std::next(FirstTerm), InsertBB->end()))) {
1077
1078 if (&MI == InsertPos)
1079 break;
1080
1081 if (.isDebugValue())
1082 continue;
1083
1084
1085
1086 MI.getOperand(0).ChangeToRegister(0, false);
1087 MI.moveBefore(&*FirstTerm);
1088 }
1089 }
1090 return InsertBB;
1091}
1092
1093
1095 return "sunit-dag." + BB->getFullName();
1096}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
dxil DXContainer Global Emitter
This file defines the DenseMap class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
Promote Memory to Register
This file provides utility for Memory Model Relaxation Annotations (MMRAs).
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
static void ProcessSourceNode(SDNode *N, SelectionDAG *DAG, InstrEmitter &Emitter, InstrEmitter::VRBaseMapType &VRBaseMap, SmallVectorImpl< std::pair< unsigned, MachineInstr * > > &Orders, SmallSet< Register, 8 > &Seen, MachineInstr *NewInsn)
Definition ScheduleDAGSDNodes.cpp:778
static bool AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG)
Definition ScheduleDAGSDNodes.cpp:161
static void RemoveUnusedGlue(SDNode *N, SelectionDAG *DAG)
Definition ScheduleDAGSDNodes.cpp:186
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"))
static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op, const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, MCRegister &PhysReg, int &Cost)
CheckForPhysRegDependency - Check if the dependency between def and use of a specified operand is a p...
Definition ScheduleDAGSDNodes.cpp:111
static void ProcessSDDbgValues(SDNode *N, SelectionDAG *DAG, InstrEmitter &Emitter, SmallVectorImpl< std::pair< unsigned, MachineInstr * > > &Orders, InstrEmitter::VRBaseMapType &VRBaseMap, unsigned Order)
ProcessSDDbgValues - Process SDDbgValues associated with this node.
Definition ScheduleDAGSDNodes.cpp:732
static void CloneNodeWithValues(SDNode *N, SelectionDAG *DAG, ArrayRef< EVT > VTs, SDValue ExtraOper=SDValue())
Definition ScheduleDAGSDNodes.cpp:140
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
iterator find(const_arg_type_t< KeyT > Val)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
SmallDenseMap< SDValue, Register, 16 > VRBaseMapType
static unsigned CountResults(SDNode *Node)
CountResults - The results of target nodes have register or immediate operands first,...
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.
bool mayLoad() const
Return true if this instruction could possibly read memory.
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
bool isCommutable() const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z,...
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.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
BasicBlockListType::iterator iterator
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
An SDNode that represents everything that will be needed to construct a MachineInstr.
mmo_iterator memoperands_begin() const
mmo_iterator memoperands_end() const
Wrapper class representing virtual and physical registers.
SmallVectorImpl< SDDbgLabel * >::iterator DbgLabelIterator
SmallVectorImpl< SDDbgValue * >::iterator DbgIterator
Holds the information for a single machine location through SDISel; either an SDNode,...
@ SDNODE
Value is the result of an expression.
Holds the information from a dbg_value node through SDISel.
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
int getNodeId() const
Return the unique node id.
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
iterator_range< value_op_iterator > op_values() const
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
static user_iterator user_end()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
unsigned getResNo() const
get the index which selects a specific result in the SDNode
Kind getKind() const
Returns an enum value representing the kind of the dependence.
@ Data
Regular data dependence (aka true-dependence).
void setLatency(unsigned Lat)
Sets the latency for this edge.
@ Barrier
An unknown scheduling barrier.
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.
bool isCloned
True if this node has been cloned.
bool isCall
Is a function call.
void setNode(SDNode *N)
Assigns the representative SDNode for this SUnit.
unsigned NodeNum
Entry # of node in the node vector.
bool hasPhysRegClobbers
Has any physreg defs, used or not.
bool isCallOp
Is a function call operand.
const TargetRegisterClass * CopyDstRC
Is a special copy node if != nullptr.
unsigned short Latency
Node latency.
unsigned short NumRegDefsLeft
bool isScheduleHigh
True if preferable to schedule high.
bool isScheduleLow
True if preferable to schedule low.
bool hasPhysRegDefs
Has physreg defs that are being used.
SmallVector< SDep, 4 > Succs
All sunit successors.
Sched::Preference SchedulingPref
Scheduling preference.
SDNode * getNode() const
Returns the representative SDNode for this SUnit.
bool isTwoAddress
Is a two-address instruction.
bool isCommutable
Is a commutable instruction.
bool isVRegCycle
May use and def the same vreg.
SmallVector< SDep, 4 > Preds
All sunit predecessors.
SUnit * OrigNode
If not this, the node from which this node was cloned.
LLVM_ABI bool addPred(const SDep &D, bool Required=true)
Adds the specified edge as a pred of the current node if not already.
RegDefIter - In place iteration over the values defined by an SUnit.
RegDefIter(const SUnit *SU, const ScheduleDAGSDNodes *SD)
Definition ScheduleDAGSDNodes.cpp:577
void Advance()
Definition ScheduleDAGSDNodes.cpp:585
SUnit * newSUnit(SDNode *N)
NewSUnit - Creates a new SUnit and return a ptr to it.
Definition ScheduleDAGSDNodes.cpp:69
void VerifyScheduledSequence(bool isBottomUp)
VerifyScheduledSequence - Verify that all SUnits are scheduled and consistent with the Sequence of sc...
Definition ScheduleDAGSDNodes.cpp:722
virtual void Schedule()=0
Schedule - Order nodes according to selected style, filling in the Sequence member.
virtual void computeLatency(SUnit *SU)
computeLatency - Compute node latency.
Definition ScheduleDAGSDNodes.cpp:610
std::string getDAGName() const override
Return the basic block label.
Definition ScheduleDAGSDNodes.cpp:1094
virtual MachineBasicBlock * EmitSchedule(MachineBasicBlock::iterator &InsertPos)
EmitSchedule - Insert MachineInstrs into the MachineBasicBlock according to the order specified in Se...
Definition ScheduleDAGSDNodes.cpp:846
virtual bool forceUnitLatencies() const
ForceUnitLatencies - Return true if all scheduling edges should be given a latency value of one.
static bool isPassiveNode(SDNode *Node)
isPassiveNode - Return true if the node is a non-scheduled leaf.
const InstrItineraryData * InstrItins
void InitNumRegDefsLeft(SUnit *SU)
InitNumRegDefsLeft - Determine the # of regs defined by this node.
Definition ScheduleDAGSDNodes.cpp:602
std::vector< SUnit * > Sequence
The schedule. Null SUnit*'s represent noop instructions.
void Run(SelectionDAG *dag, MachineBasicBlock *bb)
Run - perform scheduling.
Definition ScheduleDAGSDNodes.cpp:55
void BuildSchedGraph()
BuildSchedGraph - Build the SUnit graph from the selection dag that we are input.
Definition ScheduleDAGSDNodes.cpp:533
void dump() const override
Definition ScheduleDAGSDNodes.cpp:696
void dumpNode(const SUnit &SU) const override
Definition ScheduleDAGSDNodes.cpp:672
SUnit * Clone(SUnit *Old)
Clone - Creates a clone of the specified SUnit.
Definition ScheduleDAGSDNodes.cpp:90
ScheduleDAGSDNodes(MachineFunction &mf)
Definition ScheduleDAGSDNodes.cpp:50
void dumpSchedule() const
Definition ScheduleDAGSDNodes.cpp:708
virtual void computeOperandLatency(SDNode *Def, SDNode *Use, unsigned OpIdx, SDep &dep) const
Definition ScheduleDAGSDNodes.cpp:644
MachineRegisterInfo & MRI
Virtual/real register map.
void clearDAG()
Clears the DAG state (between regions).
const TargetInstrInfo * TII
Target instruction information.
std::vector< SUnit > SUnits
The scheduling units.
const TargetRegisterInfo * TRI
Target processor register info.
SUnit EntrySU
Special node for the region entry.
MachineFunction & MF
Machine function.
ScheduleDAG(const ScheduleDAG &)=delete
void dumpNodeAll(const SUnit &SU) const
unsigned VerifyScheduledDAG(bool isBottomUp)
Verifies that all SUnits were scheduled and that their state is consistent.
void dumpNodeName(const SUnit &SU) const
SUnit ExitSU
Special node for the region exit.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDNode * MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs, ArrayRef< SDValue > Ops)
This mutates the specified node to have the specified return type, opcode, and operands.
LLVM_ABI void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
ArrayRef< SDDbgValue * > GetDbgValues(const SDNode *SD) const
Get the debug values which reference the given SDNode.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
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 assign(size_type NumElts, ValueParamT Elt)
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.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
uint8_t getCopyCost() const
Return the cost of copying a value between two registers in this class.
bool expensiveOrImpossibleToCopy() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Offsets
Offsets in bytes from the start of the input buffer.
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FunctionAddr VTableAddr uintptr_t uintptr_t Data
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
Function object to check whether the first component of a container supported by std::get (like std::...