1//===- ResourcePriorityQueue.cpp - A DFA-oriented priority queue -*- C++ -*-==//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the ResourcePriorityQueue class, which is a
11// SchedulingPriorityQueue that prioritizes instructions using DFA state to
12// reduce the length of the critical path through the basic block
13// on VLIW platforms.
14// The scheduler is basically a top-down adaptable list scheduler with DFA
15// resource tracking added to the cost function.
16// DFA is queried as a state machine to model "packets/bundles" during
17// schedule. Currently packets/bundles are discarded at the end of
18// scheduling, affecting only order of instructions.
19//
20//===----------------------------------------------------------------------===//
21
22#include "llvm/CodeGen/ResourcePriorityQueue.h"
23#include "llvm/CodeGen/MachineInstr.h"
24#include "llvm/CodeGen/SelectionDAGNodes.h"
25#include "llvm/Support/CommandLine.h"
26#include "llvm/Support/Debug.h"
27#include "llvm/Support/raw_ostream.h"
28#include "llvm/Target/TargetLowering.h"
29#include "llvm/Target/TargetMachine.h"
30#include "llvm/Target/TargetSubtargetInfo.h"
31
32using namespace llvm;
33
34#define DEBUG_TYPE "scheduler"
35
36static cl::opt<bool> DisableDFASched("disable-dfa-sched", cl::Hidden,
37  cl::ZeroOrMore, cl::init(false),
38  cl::desc("Disable use of DFA during scheduling"));
39
40static cl::opt<signed> RegPressureThreshold(
41  "dfa-sched-reg-pressure-threshold", cl::Hidden, cl::ZeroOrMore, cl::init(5),
42  cl::desc("Track reg pressure and switch priority to in-depth"));
43
44ResourcePriorityQueue::ResourcePriorityQueue(SelectionDAGISel *IS)
45    : Picker(this), InstrItins(IS->MF->getSubtarget().getInstrItineraryData()) {
46  const TargetSubtargetInfo &STI = IS->MF->getSubtarget();
47  TRI = STI.getRegisterInfo();
48  TLI = IS->TLI;
49  TII = STI.getInstrInfo();
50  ResourcesModel.reset(TII->CreateTargetScheduleState(STI));
51  // This hard requirement could be relaxed, but for now
52  // do not let it proceed.
53  assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
54
55  unsigned NumRC = TRI->getNumRegClasses();
56  RegLimit.resize(NumRC);
57  RegPressure.resize(NumRC);
58  std::fill(RegLimit.begin(), RegLimit.end(), 0);
59  std::fill(RegPressure.begin(), RegPressure.end(), 0);
60  for (TargetRegisterInfo::regclass_iterator I = TRI->regclass_begin(),
61                                             E = TRI->regclass_end();
62       I != E; ++I)
63    RegLimit[(*I)->getID()] = TRI->getRegPressureLimit(*I, *IS->MF);
64
65  ParallelLiveRanges = 0;
66  HorizontalVerticalBalance = 0;
67}
68
69unsigned
70ResourcePriorityQueue::numberRCValPredInSU(SUnit *SU, unsigned RCId) {
71  unsigned NumberDeps = 0;
72  for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
73       I != E; ++I) {
74    if (I->isCtrl())
75      continue;
76
77    SUnit *PredSU = I->getSUnit();
78    const SDNode *ScegN = PredSU->getNode();
79
80    if (!ScegN)
81      continue;
82
83    // If value is passed to CopyToReg, it is probably
84    // live outside BB.
85    switch (ScegN->getOpcode()) {
86      default:  break;
87      case ISD::TokenFactor:    break;
88      case ISD::CopyFromReg:    NumberDeps++;  break;
89      case ISD::CopyToReg:      break;
90      case ISD::INLINEASM:      break;
91    }
92    if (!ScegN->isMachineOpcode())
93      continue;
94
95    for (unsigned i = 0, e = ScegN->getNumValues(); i != e; ++i) {
96      MVT VT = ScegN->getSimpleValueType(i);
97      if (TLI->isTypeLegal(VT)
98          && (TLI->getRegClassFor(VT)->getID() == RCId)) {
99        NumberDeps++;
100        break;
101      }
102    }
103  }
104  return NumberDeps;
105}
106
107unsigned ResourcePriorityQueue::numberRCValSuccInSU(SUnit *SU,
108                                                    unsigned RCId) {
109  unsigned NumberDeps = 0;
110  for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
111       I != E; ++I) {
112    if (I->isCtrl())
113      continue;
114
115    SUnit *SuccSU = I->getSUnit();
116    const SDNode *ScegN = SuccSU->getNode();
117    if (!ScegN)
118      continue;
119
120    // If value is passed to CopyToReg, it is probably
121    // live outside BB.
122    switch (ScegN->getOpcode()) {
123      default:  break;
124      case ISD::TokenFactor:    break;
125      case ISD::CopyFromReg:    break;
126      case ISD::CopyToReg:      NumberDeps++;  break;
127      case ISD::INLINEASM:      break;
128    }
129    if (!ScegN->isMachineOpcode())
130      continue;
131
132    for (unsigned i = 0, e = ScegN->getNumOperands(); i != e; ++i) {
133      const SDValue &Op = ScegN->getOperand(i);
134      MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
135      if (TLI->isTypeLegal(VT)
136          && (TLI->getRegClassFor(VT)->getID() == RCId)) {
137        NumberDeps++;
138        break;
139      }
140    }
141  }
142  return NumberDeps;
143}
144
145static unsigned numberCtrlDepsInSU(SUnit *SU) {
146  unsigned NumberDeps = 0;
147  for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
148       I != E; ++I)
149    if (I->isCtrl())
150      NumberDeps++;
151
152  return NumberDeps;
153}
154
155static unsigned numberCtrlPredInSU(SUnit *SU) {
156  unsigned NumberDeps = 0;
157  for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
158       I != E; ++I)
159    if (I->isCtrl())
160      NumberDeps++;
161
162  return NumberDeps;
163}
164
165///
166/// Initialize nodes.
167///
168void ResourcePriorityQueue::initNodes(std::vector<SUnit> &sunits) {
169  SUnits = &sunits;
170  NumNodesSolelyBlocking.resize(SUnits->size(), 0);
171
172  for (unsigned i = 0, e = SUnits->size(); i != e; ++i) {
173    SUnit *SU = &(*SUnits)[i];
174    initNumRegDefsLeft(SU);
175    SU->NodeQueueId = 0;
176  }
177}
178
179/// This heuristic is used if DFA scheduling is not desired
180/// for some VLIW platform.
181bool resource_sort::operator()(const SUnit *LHS, const SUnit *RHS) const {
182  // The isScheduleHigh flag allows nodes with wraparound dependencies that
183  // cannot easily be modeled as edges with latencies to be scheduled as
184  // soon as possible in a top-down schedule.
185  if (LHS->isScheduleHigh && !RHS->isScheduleHigh)
186    return false;
187
188  if (!LHS->isScheduleHigh && RHS->isScheduleHigh)
189    return true;
190
191  unsigned LHSNum = LHS->NodeNum;
192  unsigned RHSNum = RHS->NodeNum;
193
194  // The most important heuristic is scheduling the critical path.
195  unsigned LHSLatency = PQ->getLatency(LHSNum);
196  unsigned RHSLatency = PQ->getLatency(RHSNum);
197  if (LHSLatency < RHSLatency) return true;
198  if (LHSLatency > RHSLatency) return false;
199
200  // After that, if two nodes have identical latencies, look to see if one will
201  // unblock more other nodes than the other.
202  unsigned LHSBlocked = PQ->getNumSolelyBlockNodes(LHSNum);
203  unsigned RHSBlocked = PQ->getNumSolelyBlockNodes(RHSNum);
204  if (LHSBlocked < RHSBlocked) return true;
205  if (LHSBlocked > RHSBlocked) return false;
206
207  // Finally, just to provide a stable ordering, use the node number as a
208  // deciding factor.
209  return LHSNum < RHSNum;
210}
211
212
213/// getSingleUnscheduledPred - If there is exactly one unscheduled predecessor
214/// of SU, return it, otherwise return null.
215SUnit *ResourcePriorityQueue::getSingleUnscheduledPred(SUnit *SU) {
216  SUnit *OnlyAvailablePred = nullptr;
217  for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
218       I != E; ++I) {
219    SUnit &Pred = *I->getSUnit();
220    if (!Pred.isScheduled) {
221      // We found an available, but not scheduled, predecessor.  If it's the
222      // only one we have found, keep track of it... otherwise give up.
223      if (OnlyAvailablePred && OnlyAvailablePred != &Pred)
224        return nullptr;
225      OnlyAvailablePred = &Pred;
226    }
227  }
228  return OnlyAvailablePred;
229}
230
231void ResourcePriorityQueue::push(SUnit *SU) {
232  // Look at all of the successors of this node.  Count the number of nodes that
233  // this node is the sole unscheduled node for.
234  unsigned NumNodesBlocking = 0;
235  for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
236       I != E; ++I)
237    if (getSingleUnscheduledPred(I->getSUnit()) == SU)
238      ++NumNodesBlocking;
239
240  NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking;
241  Queue.push_back(SU);
242}
243
244/// Check if scheduling of this SU is possible
245/// in the current packet.
246bool ResourcePriorityQueue::isResourceAvailable(SUnit *SU) {
247  if (!SU || !SU->getNode())
248    return false;
249
250  // If this is a compound instruction,
251  // it is likely to be a call. Do not delay it.
252  if (SU->getNode()->getGluedNode())
253    return true;
254
255  // First see if the pipeline could receive this instruction
256  // in the current cycle.
257  if (SU->getNode()->isMachineOpcode())
258    switch (SU->getNode()->getMachineOpcode()) {
259    default:
260      if (!ResourcesModel->canReserveResources(&TII->get(
261          SU->getNode()->getMachineOpcode())))
262           return false;
263    case TargetOpcode::EXTRACT_SUBREG:
264    case TargetOpcode::INSERT_SUBREG:
265    case TargetOpcode::SUBREG_TO_REG:
266    case TargetOpcode::REG_SEQUENCE:
267    case TargetOpcode::IMPLICIT_DEF:
268        break;
269    }
270
271  // Now see if there are no other dependencies
272  // to instructions already in the packet.
273  for (unsigned i = 0, e = Packet.size(); i != e; ++i)
274    for (SUnit::const_succ_iterator I = Packet[i]->Succs.begin(),
275         E = Packet[i]->Succs.end(); I != E; ++I) {
276      // Since we do not add pseudos to packets, might as well
277      // ignore order deps.
278      if (I->isCtrl())
279        continue;
280
281      if (I->getSUnit() == SU)
282        return false;
283    }
284
285  return true;
286}
287
288/// Keep track of available resources.
289void ResourcePriorityQueue::reserveResources(SUnit *SU) {
290  // If this SU does not fit in the packet
291  // start a new one.
292  if (!isResourceAvailable(SU) || SU->getNode()->getGluedNode()) {
293    ResourcesModel->clearResources();
294    Packet.clear();
295  }
296
297  if (SU->getNode() && SU->getNode()->isMachineOpcode()) {
298    switch (SU->getNode()->getMachineOpcode()) {
299    default:
300      ResourcesModel->reserveResources(&TII->get(
301        SU->getNode()->getMachineOpcode()));
302      break;
303    case TargetOpcode::EXTRACT_SUBREG:
304    case TargetOpcode::INSERT_SUBREG:
305    case TargetOpcode::SUBREG_TO_REG:
306    case TargetOpcode::REG_SEQUENCE:
307    case TargetOpcode::IMPLICIT_DEF:
308      break;
309    }
310    Packet.push_back(SU);
311  }
312  // Forcefully end packet for PseudoOps.
313  else {
314    ResourcesModel->clearResources();
315    Packet.clear();
316  }
317
318  // If packet is now full, reset the state so in the next cycle
319  // we start fresh.
320  if (Packet.size() >= InstrItins->SchedModel.IssueWidth) {
321    ResourcesModel->clearResources();
322    Packet.clear();
323  }
324}
325
326signed ResourcePriorityQueue::rawRegPressureDelta(SUnit *SU, unsigned RCId) {
327  signed RegBalance    = 0;
328
329  if (!SU || !SU->getNode() || !SU->getNode()->isMachineOpcode())
330    return RegBalance;
331
332  // Gen estimate.
333  for (unsigned i = 0, e = SU->getNode()->getNumValues(); i != e; ++i) {
334      MVT VT = SU->getNode()->getSimpleValueType(i);
335      if (TLI->isTypeLegal(VT)
336          && TLI->getRegClassFor(VT)
337          && TLI->getRegClassFor(VT)->getID() == RCId)
338        RegBalance += numberRCValSuccInSU(SU, RCId);
339  }
340  // Kill estimate.
341  for (unsigned i = 0, e = SU->getNode()->getNumOperands(); i != e; ++i) {
342      const SDValue &Op = SU->getNode()->getOperand(i);
343      MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
344      if (isa<ConstantSDNode>(Op.getNode()))
345        continue;
346
347      if (TLI->isTypeLegal(VT) && TLI->getRegClassFor(VT)
348          && TLI->getRegClassFor(VT)->getID() == RCId)
349        RegBalance -= numberRCValPredInSU(SU, RCId);
350  }
351  return RegBalance;
352}
353
354/// Estimates change in reg pressure from this SU.
355/// It is achieved by trivial tracking of defined
356/// and used vregs in dependent instructions.
357/// The RawPressure flag makes this function to ignore
358/// existing reg file sizes, and report raw def/use
359/// balance.
360signed ResourcePriorityQueue::regPressureDelta(SUnit *SU, bool RawPressure) {
361  signed RegBalance    = 0;
362
363  if (!SU || !SU->getNode() || !SU->getNode()->isMachineOpcode())
364    return RegBalance;
365
366  if (RawPressure) {
367    for (TargetRegisterInfo::regclass_iterator I = TRI->regclass_begin(),
368             E = TRI->regclass_end(); I != E; ++I) {
369      const TargetRegisterClass *RC = *I;
370      RegBalance += rawRegPressureDelta(SU, RC->getID());
371    }
372  }
373  else {
374    for (TargetRegisterInfo::regclass_iterator I = TRI->regclass_begin(),
375         E = TRI->regclass_end(); I != E; ++I) {
376      const TargetRegisterClass *RC = *I;
377      if ((RegPressure[RC->getID()] +
378           rawRegPressureDelta(SU, RC->getID()) > 0) &&
379          (RegPressure[RC->getID()] +
380           rawRegPressureDelta(SU, RC->getID())  >= RegLimit[RC->getID()]))
381        RegBalance += rawRegPressureDelta(SU, RC->getID());
382    }
383  }
384
385  return RegBalance;
386}
387
388// Constants used to denote relative importance of
389// heuristic components for cost computation.
390static const unsigned PriorityOne = 200;
391static const unsigned PriorityTwo = 50;
392static const unsigned PriorityThree = 15;
393static const unsigned PriorityFour = 5;
394static const unsigned ScaleOne = 20;
395static const unsigned ScaleTwo = 10;
396static const unsigned ScaleThree = 5;
397static const unsigned FactorOne = 2;
398
399/// Returns single number reflecting benefit of scheduling SU
400/// in the current cycle.
401signed ResourcePriorityQueue::SUSchedulingCost(SUnit *SU) {
402  // Initial trivial priority.
403  signed ResCount = 1;
404
405  // Do not waste time on a node that is already scheduled.
406  if (SU->isScheduled)
407    return ResCount;
408
409  // Forced priority is high.
410  if (SU->isScheduleHigh)
411    ResCount += PriorityOne;
412
413  // Adaptable scheduling
414  // A small, but very parallel
415  // region, where reg pressure is an issue.
416  if (HorizontalVerticalBalance > RegPressureThreshold) {
417    // Critical path first
418    ResCount += (SU->getHeight() * ScaleTwo);
419    // If resources are available for it, multiply the
420    // chance of scheduling.
421    if (isResourceAvailable(SU))
422      ResCount <<= FactorOne;
423
424    // Consider change to reg pressure from scheduling
425    // this SU.
426    ResCount -= (regPressureDelta(SU,true) * ScaleOne);
427  }
428  // Default heuristic, greeady and
429  // critical path driven.
430  else {
431    // Critical path first.
432    ResCount += (SU->getHeight() * ScaleTwo);
433    // Now see how many instructions is blocked by this SU.
434    ResCount += (NumNodesSolelyBlocking[SU->NodeNum] * ScaleTwo);
435    // If resources are available for it, multiply the
436    // chance of scheduling.
437    if (isResourceAvailable(SU))
438      ResCount <<= FactorOne;
439
440    ResCount -= (regPressureDelta(SU) * ScaleTwo);
441  }
442
443  // These are platform-specific things.
444  // Will need to go into the back end
445  // and accessed from here via a hook.
446  for (SDNode *N = SU->getNode(); N; N = N->getGluedNode()) {
447    if (N->isMachineOpcode()) {
448      const MCInstrDesc &TID = TII->get(N->getMachineOpcode());
449      if (TID.isCall())
450        ResCount += (PriorityTwo + (ScaleThree*N->getNumValues()));
451    }
452    else
453      switch (N->getOpcode()) {
454      default:  break;
455      case ISD::TokenFactor:
456      case ISD::CopyFromReg:
457      case ISD::CopyToReg:
458        ResCount += PriorityFour;
459        break;
460
461      case ISD::INLINEASM:
462        ResCount += PriorityThree;
463        break;
464      }
465  }
466  return ResCount;
467}
468
469
470/// Main resource tracking point.
471void ResourcePriorityQueue::scheduledNode(SUnit *SU) {
472  // Use NULL entry as an event marker to reset
473  // the DFA state.
474  if (!SU) {
475    ResourcesModel->clearResources();
476    Packet.clear();
477    return;
478  }
479
480  const SDNode *ScegN = SU->getNode();
481  // Update reg pressure tracking.
482  // First update current node.
483  if (ScegN->isMachineOpcode()) {
484    // Estimate generated regs.
485    for (unsigned i = 0, e = ScegN->getNumValues(); i != e; ++i) {
486      MVT VT = ScegN->getSimpleValueType(i);
487
488      if (TLI->isTypeLegal(VT)) {
489        const TargetRegisterClass *RC = TLI->getRegClassFor(VT);
490        if (RC)
491          RegPressure[RC->getID()] += numberRCValSuccInSU(SU, RC->getID());
492      }
493    }
494    // Estimate killed regs.
495    for (unsigned i = 0, e = ScegN->getNumOperands(); i != e; ++i) {
496      const SDValue &Op = ScegN->getOperand(i);
497      MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
498
499      if (TLI->isTypeLegal(VT)) {
500        const TargetRegisterClass *RC = TLI->getRegClassFor(VT);
501        if (RC) {
502          if (RegPressure[RC->getID()] >
503            (numberRCValPredInSU(SU, RC->getID())))
504            RegPressure[RC->getID()] -= numberRCValPredInSU(SU, RC->getID());
505          else RegPressure[RC->getID()] = 0;
506        }
507      }
508    }
509    for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
510                              I != E; ++I) {
511      if (I->isCtrl() || (I->getSUnit()->NumRegDefsLeft == 0))
512        continue;
513      --I->getSUnit()->NumRegDefsLeft;
514    }
515  }
516
517  // Reserve resources for this SU.
518  reserveResources(SU);
519
520  // Adjust number of parallel live ranges.
521  // Heuristic is simple - node with no data successors reduces
522  // number of live ranges. All others, increase it.
523  unsigned NumberNonControlDeps = 0;
524
525  for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
526                                  I != E; ++I) {
527    adjustPriorityOfUnscheduledPreds(I->getSUnit());
528    if (!I->isCtrl())
529      NumberNonControlDeps++;
530  }
531
532  if (!NumberNonControlDeps) {
533    if (ParallelLiveRanges >= SU->NumPreds)
534      ParallelLiveRanges -= SU->NumPreds;
535    else
536      ParallelLiveRanges = 0;
537
538  }
539  else
540    ParallelLiveRanges += SU->NumRegDefsLeft;
541
542  // Track parallel live chains.
543  HorizontalVerticalBalance += (SU->Succs.size() - numberCtrlDepsInSU(SU));
544  HorizontalVerticalBalance -= (SU->Preds.size() - numberCtrlPredInSU(SU));
545}
546
547void ResourcePriorityQueue::initNumRegDefsLeft(SUnit *SU) {
548  unsigned  NodeNumDefs = 0;
549  for (SDNode *N = SU->getNode(); N; N = N->getGluedNode())
550    if (N->isMachineOpcode()) {
551      const MCInstrDesc &TID = TII->get(N->getMachineOpcode());
552      // No register need be allocated for this.
553      if (N->getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) {
554        NodeNumDefs = 0;
555        break;
556      }
557      NodeNumDefs = std::min(N->getNumValues(), TID.getNumDefs());
558    }
559    else
560      switch(N->getOpcode()) {
561        default:     break;
562        case ISD::CopyFromReg:
563          NodeNumDefs++;
564          break;
565        case ISD::INLINEASM:
566          NodeNumDefs++;
567          break;
568      }
569
570  SU->NumRegDefsLeft = NodeNumDefs;
571}
572
573/// adjustPriorityOfUnscheduledPreds - One of the predecessors of SU was just
574/// scheduled.  If SU is not itself available, then there is at least one
575/// predecessor node that has not been scheduled yet.  If SU has exactly ONE
576/// unscheduled predecessor, we want to increase its priority: it getting
577/// scheduled will make this node available, so it is better than some other
578/// node of the same priority that will not make a node available.
579void ResourcePriorityQueue::adjustPriorityOfUnscheduledPreds(SUnit *SU) {
580  if (SU->isAvailable) return;  // All preds scheduled.
581
582  SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU);
583  if (!OnlyAvailablePred || !OnlyAvailablePred->isAvailable)
584    return;
585
586  // Okay, we found a single predecessor that is available, but not scheduled.
587  // Since it is available, it must be in the priority queue.  First remove it.
588  remove(OnlyAvailablePred);
589
590  // Reinsert the node into the priority queue, which recomputes its
591  // NumNodesSolelyBlocking value.
592  push(OnlyAvailablePred);
593}
594
595
596/// Main access point - returns next instructions
597/// to be placed in scheduling sequence.
598SUnit *ResourcePriorityQueue::pop() {
599  if (empty())
600    return nullptr;
601
602  std::vector<SUnit *>::iterator Best = Queue.begin();
603  if (!DisableDFASched) {
604    signed BestCost = SUSchedulingCost(*Best);
605    for (std::vector<SUnit *>::iterator I = std::next(Queue.begin()),
606           E = Queue.end(); I != E; ++I) {
607
608      if (SUSchedulingCost(*I) > BestCost) {
609        BestCost = SUSchedulingCost(*I);
610        Best = I;
611      }
612    }
613  }
614  // Use default TD scheduling mechanism.
615  else {
616    for (std::vector<SUnit *>::iterator I = std::next(Queue.begin()),
617       E = Queue.end(); I != E; ++I)
618      if (Picker(*Best, *I))
619        Best = I;
620  }
621
622  SUnit *V = *Best;
623  if (Best != std::prev(Queue.end()))
624    std::swap(*Best, Queue.back());
625
626  Queue.pop_back();
627
628  return V;
629}
630
631
632void ResourcePriorityQueue::remove(SUnit *SU) {
633  assert(!Queue.empty() && "Queue is empty!");
634  std::vector<SUnit *>::iterator I = std::find(Queue.begin(), Queue.end(), SU);
635  if (I != std::prev(Queue.end()))
636    std::swap(*I, Queue.back());
637
638  Queue.pop_back();
639}
640