OpenASIP  2.0
Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
CycleLookBackSoftwareBypasser Class Reference

#include <CycleLookBackSoftwareBypasser.hh>

Inheritance diagram for CycleLookBackSoftwareBypasser:
Inheritance graph
Collaboration diagram for CycleLookBackSoftwareBypasser:
Collaboration graph

Public Member Functions

 CycleLookBackSoftwareBypasser ()
 
virtual ~CycleLookBackSoftwareBypasser ()
 
virtual int bypass (MoveNodeGroup &candidates, DataDependenceGraph &ddg, ResourceManager &rm, bool bypassTrigger)
 
virtual void removeBypass (MoveNodeGroup &candidates, DataDependenceGraph &ddg, ResourceManager &rm)
 
virtual void removeBypass (MoveNode &moveNode, DataDependenceGraph &ddg, ResourceManager &rm, bool restoreSource=true)
 
virtual int removeDeadResults (MoveNodeGroup &candidates, DataDependenceGraph &ddg, ResourceManager &rm, std::set< std::pair< TTAProgram::Move *, int > > &removedMoves)
 
void setSelector (MoveNodeSelector *selector)
 
virtual void clearCaches (DataDependenceGraph &ddg, bool removeDeadResults)
 
- Public Member Functions inherited from SoftwareBypasser
 SoftwareBypasser ()
 
virtual ~SoftwareBypasser ()
 
int bypassCount ()
 
int deadResultCount ()
 

Static Public Member Functions

static void printStats ()
 

Private Member Functions

int bypassNode (MoveNode &nodeToBypass, int &lastOperandCycle, DataDependenceGraph &ddg, ResourceManager &rm)
 

Private Attributes

int cyclesToLookBack_
 count of cycles before the operand write to look for the producer of the read value More...
 
int cyclesToLookBackNoDRE_
 count of cycles before the operand write to look for the producer of the read value when cannot kill result More...
 
bool killDeadResults_
 
bool bypassFromRegs_
 
bool bypassToRegs_
 
std::map< MoveNode *, MoveNode *, MoveNode::ComparatorstoredSources_
 Stores sources and bypassed moves in case they have to be unassigned (case when operands are scheduled and bypassed but result can not be scheduled with such operands. More...
 
std::map< MoveNode *, int > sourceCycles_
 
std::map< MoveNode *, const TTAMachine::Bus * > sourceBuses_
 
std::map< MoveNode *, MoveNode *, MoveNode::ComparatorremovedStoredSources_
 
DataDependenceGraph::NodeSet removedNodes_
 
MoveNodeSelectorselector_
 

Static Private Attributes

static int bypassCount_ = 0
 
static int deadResultCount_ = 0
 
static int triggerAbortCount_ = 0
 

Additional Inherited Members

- Protected Attributes inherited from SoftwareBypasser
int bypassCount_
 
int deadResultCount_
 

Detailed Description

A simple implementation of software bypassing that reschedules operand writes as bypassed moves in case the result has been produced in n previous cycles.

Definition at line 52 of file CycleLookBackSoftwareBypasser.hh.

Constructor & Destructor Documentation

◆ CycleLookBackSoftwareBypasser()

CycleLookBackSoftwareBypasser::CycleLookBackSoftwareBypasser ( )

Constructor.

Definition at line 62 of file CycleLookBackSoftwareBypasser.cc.

62  :
64  killDeadResults_(true), bypassFromRegs_(true), bypassToRegs_(true),
65  selector_(NULL) {
66 
69  if (opts != NULL) {
70  if (opts->bypassDistance() > -1) {
72  }
73  if (opts->noDreBypassDistance() > -1) {
75  }
77  }
78 }

References SchedulerCmdLineOptions::bypassDistance(), Application::cmdLineOptions(), cyclesToLookBack_, cyclesToLookBackNoDRE_, SchedulerCmdLineOptions::killDeadResults(), killDeadResults_, and SchedulerCmdLineOptions::noDreBypassDistance().

Here is the call graph for this function:

◆ ~CycleLookBackSoftwareBypasser()

CycleLookBackSoftwareBypasser::~CycleLookBackSoftwareBypasser ( )
virtual

Empty destructor.

Definition at line 83 of file CycleLookBackSoftwareBypasser.cc.

83  {
84 }

Member Function Documentation

◆ bypass()

int CycleLookBackSoftwareBypasser::bypass ( MoveNodeGroup candidates,
DataDependenceGraph ddg,
ResourceManager rm,
bool  bypassTrigger 
)
virtual

Apply software bypassing to as many moves in the given MoveNodeGroup as possible.

This implementation works only if all operand writes have been scheduled. It tries to bypass all the operand write moves.

Parameters
candidatesThe moves to which apply software bypassing, if possible.
ddgThe data dependence graph in which the movenodes belong to.
rmThe resource manager which is used to check for resource availability.
Returns
The count of bypassed moves.

Implements SoftwareBypasser.

Definition at line 353 of file CycleLookBackSoftwareBypasser.cc.

357  {
358 
359  // bypassing disabled with 0
360  if (cyclesToLookBack_ <= 0) {
361  return 0;
362  }
363 #ifdef MOVE_BYPASSER
364  cyclesToLookBack_ = 1;
365 #endif
366  int bypassCounter = 0;
367 
368  MoveNode* trigger = NULL;
369  int lastOperandCycle = 0;
370 
371  for (int i = 0; i < candidates.nodeCount(); i++) {
372  MoveNode& moveNode = candidates.node(i);
373 
374  // result value or already bypassed - don't bypass this
375  if (moveNode.isSourceOperation()) {
376  continue;
377  }
378 
379  // find the trigger, will try to bypass it as the last one
380  if (moveNode.move().isTriggering()) {
381  trigger = &moveNode;
382  continue;
383  }
384 
385  // bypass this node.
386  int rv = bypassNode(moveNode, lastOperandCycle, ddg, rm);
387  if (rv == -1) {
388  return -1; // failed, need cleanup
389  } else {
390  bypassCounter += rv;
391  }
392  }
393  // Try to bypass triggering move, if possible ok, if not
394  // it will be rescheduled at the end after all not bypassed
395  // moves are tried to be rescheduled
396  bool triggerWasBypassed = false;
397  if (trigger != NULL && !trigger->move().isControlFlowMove() &&
398  !trigger->isSourceOperation() && bypassTrigger) {
399  int rv = bypassNode(*trigger, lastOperandCycle, ddg, rm);
400  if (rv == -1) {
401  return -1; // failed, need cleanup
402  } else {
403  bypassCounter += rv;
404  if (rv == 1) {
405  triggerWasBypassed = true;
406  }
407  }
408  }
409  // at this point the schedule might be broken in case we
410  // managed to bypass the trigger and it got pushed above
411  // an operand move
412 
413  // try to reschedule the moves that were not bypassed because
414  // earlier operand moves might allow scheduling also the trigger
415  // earlier thus shorten the schedule
416 
417  // this might fix the schedule in case the previous loop
418  // managed to push trigger above an operand move
419  // if not, the last loop fixes the situation
420 
421  for (int i = 0; i < candidates.nodeCount(); i++) {
422  MoveNode& moveNode = candidates.node(i);
423  if (!moveNode.isDestinationOperation() ||
424  moveNode.move().isControlFlowMove()) {
425  continue;
426  }
427  // Bypassed moves and bypassed trigger are not rescheduled here
428  if (moveNode.isBypass() ||
429  (trigger == &moveNode && triggerWasBypassed)) {
430  lastOperandCycle =
431  std::max(lastOperandCycle, moveNode.cycle());
432  continue;
433  }
434  int oldCycle = moveNode.cycle();
435  int earliestCycleDDG = ddg.earliestCycle(moveNode);
436 
437  if (earliestCycleDDG >= oldCycle) {
438  continue;
439  }
440  rm.unassign(moveNode);
441  int earliestCycle = earliestCycleDDG;
442 
443  if (!moveNode.move().isUnconditional()) {
444  earliestCycle =
445  std::max(earliestCycleDDG, moveNode.guardLatency() - 1);
446  }
447  earliestCycle = rm.earliestCycle(earliestCycle, moveNode);
448  if ((oldCycle > earliestCycle && earliestCycle != -1) ||
449  (trigger == &moveNode && earliestCycle != -1)){
450  try {
451  rm.assign(earliestCycle, moveNode);
452  } catch (const Exception& e) {
453  throw ModuleRunTimeError(__FILE__, __LINE__, __func__,
454  e.errorMessageStack());
455  }
456  } else {
457  try {
458  if (!rm.canAssign(oldCycle, moveNode)) {
459  return -1;
460  }
461  rm.assign(oldCycle, moveNode);
462  } catch (const Exception& e) {
463  throw ModuleRunTimeError(__FILE__, __LINE__, __func__,
464  e.errorMessageStack());
465  }
466  }
467  lastOperandCycle =
468  std::max(lastOperandCycle, moveNode.cycle());
469  if (!moveNode.isScheduled()){
470  throw InvalidData(
471  __FILE__, __LINE__, __func__, "Move assignment failed");
472  }
473 
474  }
475  // Traditional test if trigger is not earlier then some operand,
476  // could happen due to bypass of trigger
477  // todo: this could be optimized by trying to uxchange cycles of
478  // trigger and operand in this case.
479  if (trigger != NULL) {
480  try{
481  if (trigger->cycle() < lastOperandCycle) {
482  rm.unassign(*trigger);
483  int newCycle = rm.earliestCycle(lastOperandCycle, *trigger);
484  int latestDDG = ddg.latestCycle(*trigger);
485  if (newCycle == -1 || newCycle > latestDDG) {
487  // BBScheduler will call removeBypass
488  return -1;
489  }
490  rm.assign(newCycle, *trigger);
491  if (!trigger->isScheduled()){
492  throw InvalidData(
493  __FILE__, __LINE__, __func__,"Trigger assignment failed");
494  }
495  }
496  } catch (const Exception& e) {
497  throw ModuleRunTimeError(
498  __FILE__, __LINE__, __func__,e.errorMessageStack());
499  }
500  }
501  return bypassCounter;
502 }

References __func__, ResourceManager::assign(), bypassNode(), ResourceManager::canAssign(), MoveNode::cycle(), cyclesToLookBack_, ResourceManager::earliestCycle(), DataDependenceGraph::earliestCycle(), Exception::errorMessageStack(), MoveNode::guardLatency(), MoveNode::isBypass(), TTAProgram::Move::isControlFlowMove(), MoveNode::isDestinationOperation(), MoveNode::isScheduled(), MoveNode::isSourceOperation(), TTAProgram::Move::isTriggering(), TTAProgram::Move::isUnconditional(), DataDependenceGraph::latestCycle(), MoveNode::move(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), triggerAbortCount_, and ResourceManager::unassign().

Here is the call graph for this function:

◆ bypassNode()

int CycleLookBackSoftwareBypasser::bypassNode ( MoveNode moveNode,
int &  lastOperandCycle,
DataDependenceGraph ddg,
ResourceManager rm 
)
privatevirtual

Tries to bypass a MoveNode.

Parameters
moveNodeMoveNode to bypass.
lastOperandCyclein which contains last cycle of operands of the operation
ddgThe data dependence graph in which the movenodes belong to.
rmThe resource manager which is used to check for resource availability.
Returns
-1 if failed and need fixup, 1 is succeeded, 0 if did not bypass.

Implements SoftwareBypasser.

Definition at line 98 of file CycleLookBackSoftwareBypasser.cc.

102  {
103 
104  int cyclesToLookBack = cyclesToLookBack_;
105  if (moveNode.isDestinationVariable() && !bypassToRegs_) {
106  return 0;
107  }
108 
109  int originalCycle = moveNode.cycle();
110  int latestCycle = originalCycle;
111 
112  DataDependenceGraph::EdgeSet edges = ddg.inEdges(moveNode);
113  DataDependenceGraph::EdgeSet::iterator edgeIter = edges.begin();
114  DataDependenceEdge* bypassEdge = NULL;
115 
116  // find one incoming raw edge. if multiple, cannot bypass.
117  while (edgeIter != edges.end()) {
118 
119  DataDependenceEdge& edge = *(*edgeIter);
120  // if the edge is not a real reg/ra raw edge, skip to next edge
123  edge.guardUse() || edge.headPseudo()) {
124  edgeIter++;
125  continue;
126  }
127 
128  if (bypassEdge == NULL) {
129  bypassEdge = &edge;
130  } else {
131  // cannot bypass if multiple inputs
132  return 0;
133  }
134  edgeIter++;
135  }
136 
137  // if no bypassable edge found, cannot bypass
138  if (bypassEdge == NULL || bypassEdge->isBackEdge()) {
139  return 0;
140  }
141 
142  MoveNode& source = ddg.tailNode(*bypassEdge);
143 
144  if (!source.isScheduled()) {
145  return 0;
146  }
147 
148  // don't bypass from incoming tempregcopies of immediates
149  if (source.isSourceConstant() &&
150  source.move().hasAnnotations(
152  return 0;
153  }
154 
155  // if cannot kill dead result, divide bypass dist by 2
156  if (source.isSourceOperation() &&
157  moveNode.isDestinationOperation() &&
158  cyclesToLookBack != INT_MAX &&
159  cyclesToLookBack > cyclesToLookBackNoDRE_ &&
160  (ddg.regRawSuccessorCount(source, true) > 1 ||
161  ddg.regRawSuccessorCount(source, false) <
162  static_cast<DataDependenceGraph*>(ddg.rootGraph())->
163  regRawSuccessorCount(source, false))) {
164  cyclesToLookBack = cyclesToLookBackNoDRE_;
165  }
166 
167  // source node is too far for our purposes
168  // do not bypass this operand
169  if (cyclesToLookBack != INT_MAX &&
170  source.cycle() + cyclesToLookBack < moveNode.cycle()) {
171  return 0;
172  }
173 
174  if (!ddg.guardsAllowBypass(source, moveNode)) {
175  return 0;
176  }
177 
178  // if dest register, only allow input from reg or imm.
179  // and limit the read to same as original read
180  // in order to not make live ranges longer, limiting schdule
181  if (!moveNode.isDestinationOperation()) {
182  latestCycle = source.cycle();
183  }
184  if (!(source.isSourceOperation() || source.isSourceConstant())) {
185  if (!bypassFromRegs_) {
186  return 0;
187  }
188  // handle antidependencies from reg-reg moves.
190  ddg.regWarSuccessors(source);
191  for (DataDependenceGraph::NodeSet::iterator i = warSuccs.begin();
192  i != warSuccs.end();i++) {
193  MoveNode& mn = **i;
194  if (mn.isScheduled()) {
195  if (mn.cycle() < latestCycle) {
196  latestCycle = std::min(latestCycle, mn.cycle());
197  }
198  }
199  }
200 
201  // redundant latest check to prevent loops in ddg.
202  for (edgeIter = edges.begin(); edgeIter != edges.end(); edgeIter++) {
203  DataDependenceEdge& edge = **edgeIter;
204  if (&edge != bypassEdge) {
205  MoveNode& tail = ddg.tailNode(edge);
206  if (!tail.isScheduled()) {
207  return 0;
208  }
210  if (tail.cycle() > latestCycle) {
211  return 0;
212  }
213  } else {
214  if (tail.cycle() > latestCycle-1) {
215  return 0;
216  }
217  }
218  }
219  }
220  }
221  rm.unassign(moveNode);
222  storedSources_.insert(
223  std::pair<MoveNode*, MoveNode*>(&moveNode, &source));
224 
225  // if mergeandkeep fails, undo bypass and return 0
226  if (!ddg.mergeAndKeepUser(source, moveNode)) {
227  rm.assign(originalCycle, moveNode);
228  assert(moveNode.isScheduled());
229  storedSources_.erase(&moveNode);
230  return 0;
231  }
232 
233  if (moveNode.move().source().isImmediateRegister()) {
234  moveNode.move().setSource(
235  static_cast<SimpleResourceManager&>(rm).immediateValue(source)->copy());
236  }
237 
238  // then try to assign the bypassed node..
239  int ddgCycle = ddg.earliestCycle(moveNode);
240  if (!moveNode.move().isUnconditional()) {
241  ddgCycle = std::max(ddgCycle, moveNode.guardLatency() - 1);
242  }
243  if (ddgCycle != INT_MAX) {
244 #ifdef MOVE_BYPASSER
245  ddgCycle = originalCycle;
246 #endif
247  // remove dead results now?
248  int sourceCycle = source.cycle();
249  bool sourceRemoved = false;
250  // Check if machine is forcing disabling DRE,
251  // if so disable when first move is bypassed.
252  if (killDeadResults_ &&
253  source.move().bus().machine()->alwaysWriteResults()) {
254  killDeadResults_ = false;
255  }
256  // disable DRE if ii != 0
257  // only kill if dest is op
258 
259  // >8058 fails
260  // >8059 works
261  if (killDeadResults_ && !ddg.resultUsed(source)) { // && source.nodeID() > 8058) {
262  // if restoring lated
263  sourceCycles_[&source] = sourceCycle;
264  sourceRemoved = true;
265  // results that has no "use" later and are overwritten are
266  // dead if there are some other edges we don't do anything
267  // Resuls is positively death
268  // we need to properly get rid of it
269  sourceBuses_[&source] = &source.move().bus();
270  rm.unassign(source);
271  }
272 
273  int cycle = rm.earliestCycle(ddgCycle, moveNode);
274  if (cycle != -1 && cycle <= latestCycle) {
275  rm.assign(cycle, moveNode);
276  if (!moveNode.isScheduled()){
277  throw InvalidData(
278  __FILE__, __LINE__, __func__,
279  "Move assignment failed");
280  }
281  lastOperandCycle = std::max(lastOperandCycle, cycle);
282  // only one bypass per operand is possible, no point to
283  // test other edges of same moveNode
284  if (sourceRemoved) {
285  ddg.copyDepsOver(source, true, false);
286  }
287  bypassCount_++;
288  return 1;
289  } else {
290  // undo only this bypass.
291  // allow other moves of same po to be bypassed.
292  ddg.unMergeUser(source, moveNode);
293  if (!rm.canAssign(originalCycle, moveNode)) {
294  // Cannot return to original position. getting problematic.
295  // return source to it's position
296  if (sourceRemoved) {
297  assert(sourceBuses_[&source] != NULL);
298  source.move().setBus(*sourceBuses_[&source]);
299  assert(rm.canAssign(sourceCycle, source));
300  rm.assign(sourceCycle, source);
301  sourceCycles_.erase(&source);
302  sourceBuses_.erase(&source);
303  }
304  // Try if we can assign it to some earlier place.
305  ddgCycle = ddg.earliestCycle(moveNode);
306  if (!moveNode.move().isUnconditional()) {
307  ddgCycle = std::max(ddgCycle, moveNode.guardLatency()-1);
308  }
309  int ec = rm.earliestCycle(ddgCycle, moveNode);
310  if (ec != -1 && ec < originalCycle) {
311  rm.assign(ec, moveNode);
312  return 0;
313  } else {
314  // Need to abort bypassing.
315  return -1;
316  }
317  }
318  rm.assign(originalCycle, moveNode);
319  assert(moveNode.isScheduled());
320  storedSources_.erase(&moveNode);
321 
322  // return source to it's position
323  if (sourceRemoved) {
324  assert(sourceBuses_[&source] != NULL);
325  source.move().setBus(*sourceBuses_[&source]);
326  assert(rm.canAssign(sourceCycle, source));
327  rm.assign(sourceCycle, source);
328  sourceCycles_.erase(&source);
329  sourceBuses_.erase(&source);
330  }
331  return 0;
332  }
333  }
334  // if node could not be bypassed, we return -1 and let
335  // BBScheduler call removeBypass
336  return -1;
337 }

References __func__, TTAMachine::Machine::alwaysWriteResults(), TTAProgram::ProgramAnnotation::ANN_CONNECTIVITY_MOVE, assert, ResourceManager::assign(), TTAProgram::Move::bus(), bypassCount_, bypassFromRegs_, bypassToRegs_, ResourceManager::canAssign(), DataDependenceGraph::copyDepsOver(), MoveNode::cycle(), cyclesToLookBack_, cyclesToLookBackNoDRE_, DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::dependenceType(), ResourceManager::earliestCycle(), DataDependenceGraph::earliestCycle(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), MoveNode::guardLatency(), DataDependenceGraph::guardsAllowBypass(), DataDependenceEdge::guardUse(), TTAProgram::AnnotatedInstructionElement::hasAnnotations(), DataDependenceEdge::headPseudo(), BoostGraph< GraphNode, GraphEdge >::inEdges(), DataDependenceEdge::isBackEdge(), MoveNode::isDestinationOperation(), MoveNode::isDestinationVariable(), TTAProgram::Terminal::isImmediateRegister(), MoveNode::isScheduled(), MoveNode::isSourceConstant(), MoveNode::isSourceOperation(), TTAProgram::Move::isUnconditional(), killDeadResults_, TTAMachine::Component::machine(), DataDependenceGraph::mergeAndKeepUser(), MoveNode::move(), DataDependenceGraph::regRawSuccessorCount(), DataDependenceGraph::regWarSuccessors(), DataDependenceGraph::resultUsed(), BoostGraph< GraphNode, GraphEdge >::rootGraph(), TTAProgram::Move::setBus(), TTAProgram::Move::setSource(), TTAProgram::Move::source(), sourceBuses_, sourceCycles_, storedSources_, BoostGraph< GraphNode, GraphEdge >::tailNode(), ResourceManager::unassign(), and DataDependenceGraph::unMergeUser().

Referenced by bypass().

Here is the call graph for this function:

◆ clearCaches()

void CycleLookBackSoftwareBypasser::clearCaches ( DataDependenceGraph ddg,
bool  removeDeletedResults 
)
virtual

Clears the storedSources data structure, when the old values in it are not needed anymore, allowing them to be deleted by the objects who own them.

Delete node from sourceCycles structure, as thesse are not deleted elsewhere.

Implements SoftwareBypasser.

Definition at line 769 of file CycleLookBackSoftwareBypasser.cc.

770  {
771  storedSources_.clear();
772  sourceBuses_.clear();
773  if (removeDeletedResults) {
774  // TODO: somebody should also delete these
775  for (DataDependenceGraph::NodeSet::iterator i = removedNodes_.begin();
776  i != removedNodes_.end(); i++) {
777  if (ddg.rootGraph() != &ddg) {
778  ddg.rootGraph()->removeNode(**i);
779  }
780  delete *i;
781  }
782  }
783  removedNodes_.clear();
784  removedStoredSources_.clear();
785 }

References removedNodes_, removedStoredSources_, BoostGraph< GraphNode, GraphEdge >::removeNode(), BoostGraph< GraphNode, GraphEdge >::rootGraph(), sourceBuses_, and storedSources_.

Here is the call graph for this function:

◆ printStats()

void CycleLookBackSoftwareBypasser::printStats ( )
static

Definition at line 788 of file CycleLookBackSoftwareBypasser.cc.

788  {
789  std::cerr << "Bypasser statistics: " << std::endl
790  << "\tBypasses: " << bypassCount_ << std::endl
791  << "\tKilled results: " << deadResultCount_ << std::endl
792  << "\tTrigger too early aborts: " << triggerAbortCount_ << std::endl;
793 }

References bypassCount_, deadResultCount_, and triggerAbortCount_.

◆ removeBypass() [1/2]

void CycleLookBackSoftwareBypasser::removeBypass ( MoveNode moveNode,
DataDependenceGraph ddg,
ResourceManager rm,
bool  restoreSource = true 
)
virtual

Implements SoftwareBypasser.

Definition at line 543 of file CycleLookBackSoftwareBypasser.cc.

546  {
547 
548  // bypassing disabled
549  if (cyclesToLookBack_ <= 0) {
550  return;
551  }
552 
553  if (MapTools::containsKey(storedSources_, &moveNode)) {
554  // if node was bypassed, find a original source
555  // and restore it, also unassign if bypass was
556  // assigned
557  MoveNode* tempSource =
558  MapTools::valueForKey<MoveNode*>(storedSources_, &moveNode);
559  assert(tempSource != NULL);
560  storedSources_.erase(&moveNode);
561  // if it was bypass and was scheduled we
562  // need to unassign and restore, should allways be a case
563  if (moveNode.isScheduled()) {
564  rm.unassign(moveNode);
565  }
566 
567  // if we unassigned the source of the bypass, restore it.
568  if (!tempSource->isScheduled()) {
569  std::map<MoveNode*, int>::iterator cycleIter =
570  sourceCycles_.find(tempSource);
571  if (cycleIter != sourceCycles_.end()) {
572  if (restoreSource) {
573  assert(sourceBuses_[tempSource] != NULL);
574  tempSource->move().setBus(*sourceBuses_[tempSource]);
575  assert(rm.canAssign(cycleIter->second, *tempSource));
576  rm.assign(cycleIter->second, *tempSource); // fails here. somebody else uses the bus?
577  }
578  sourceCycles_.erase(cycleIter);
579  sourceBuses_.erase(tempSource);
580  }
581  }
582  ddg.unMergeUser(*tempSource, moveNode);
583  bypassCount_--;
584  }
585  // this is only for afterwards cleanup.
587  MoveNode* tempSource =
588  MapTools::valueForKey<MoveNode*>(removedStoredSources_, &moveNode);
589  assert(tempSource != NULL);
590  removedStoredSources_.erase(&moveNode);
591 
592  if (moveNode.isScheduled()) {
593  rm.unassign(moveNode);
594  }
595  ddg.unMergeUser(*tempSource, moveNode);
596  }
597 }

References assert, ResourceManager::assign(), bypassCount_, ResourceManager::canAssign(), MapTools::containsKey(), cyclesToLookBack_, MoveNode::isScheduled(), MoveNode::move(), removedStoredSources_, TTAProgram::Move::setBus(), sourceBuses_, sourceCycles_, storedSources_, ResourceManager::unassign(), and DataDependenceGraph::unMergeUser().

Here is the call graph for this function:

◆ removeBypass() [2/2]

void CycleLookBackSoftwareBypasser::removeBypass ( MoveNodeGroup candidates,
DataDependenceGraph ddg,
ResourceManager rm 
)
virtual

Remove software bypassing from all moves in the given MoveNodeGroup if possible.

Parameters
candidatesThe moves from which to remove software bypassing, if possible.
ddgThe data dependence grap in which the movenodes belong to.
rmThe resource manager which is used to check for resource availability.

Implements SoftwareBypasser.

Definition at line 515 of file CycleLookBackSoftwareBypasser.cc.

518  {
519 
520  // bypassing disabled
521  if (cyclesToLookBack_ <= 0) {
522  return;
523  }
524 
525  // Some of operand bypassing attempts failed
526  // Unschedule all operands, unassign them also since in BBSched
527  // this is followed by another attempt to schedule operands
528 
529  for (int i = 0; i < candidates.nodeCount(); i++) {
530  MoveNode& moveNode = candidates.node(i);
531  if (moveNode.isScheduled()) {
532  rm.unassign(moveNode);
533  }
534  }
535 
536  for (int k = 0; k < candidates.nodeCount(); k++) {
537  MoveNode& moveNode = candidates.node(k);
538  removeBypass(moveNode, ddg, rm);
539  }
540 }

References cyclesToLookBack_, MoveNode::isScheduled(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), and ResourceManager::unassign().

Here is the call graph for this function:

◆ removeDeadResults()

int CycleLookBackSoftwareBypasser::removeDeadResults ( MoveNodeGroup candidates,
DataDependenceGraph ddg,
ResourceManager rm,
std::set< std::pair< TTAProgram::Move *, int > > &  removedMoves 
)
virtual

Remove dead result moves for each bypassed move of given MoveNodeGroup if possible. That is, no other result reads of result exists. This assumes that result moves in MoveNodeGroup are also scheduled.

Parameters
candidatesThe moves for which remove dead result writes
ddgThe data dependence grap in which the movenodes belong to.
rmThe resource manager which is used to check for resource availability.
removedMovesThe dead result eliminated moves and their original cycles, to allow rescheduling of moves that were previously resource (RF write port usually) constrained by the removed moves.
Returns
number of dead results killed

Implements SoftwareBypasser.

Definition at line 600 of file CycleLookBackSoftwareBypasser.cc.

604  {
605 
606  for (int i = 0; i < candidates.nodeCount(); i++) {
607  // For now, this version is called after operands AND results
608  // were scheduled
609  if (!candidates.node(i).isScheduled()) {
610  return 0;
611  }
612  }
613 
614  // For each of bypassed moves, look for its original source and
615  // if that one has no more outgoing RAW edges and will be
616  // overwritten in same basic block (WAW edge) remove it
617 
618  int resultsRemoved = 0;
619  for (int i = 0; i < candidates.nodeCount(); i++) {
620  MoveNode& moveNode = candidates.node(i);
621  // Results in candidates are freshly scheduled so they have no
622  // bypasses so far
623  if (!MapTools::containsKey(storedSources_, &moveNode)) {
624  // In case the result was already removed by other move from same
625  // candidates set (both operands were bypassed from same result
626  // move) we continue
627  continue;
628  }
629 
630  // the original result move for the bypassed move
631  MoveNode& resultMove =
632  *MapTools::valueForKey<MoveNode*>(storedSources_, &moveNode);
633 
634  // if killed this one, finish the kill
635 
636  // try to get the original cycle of the result move
637  std::map<MoveNode*, int>::iterator srcIter =
638  sourceCycles_.find(&resultMove);
639  if (srcIter != sourceCycles_.end()) {
640 
641  // we lose edges so our notifyScheduled does not notify
642  // some antidependencies, store them for notification.
643  DataDependenceGraph::NodeSet successors =
644  ddg.successors(resultMove);
645 
646  successors.erase(&resultMove); // if WaW to itself, remove it.
647 
648  ddg.dropNode(resultMove);
649  removedNodes_.insert(&resultMove);
650 
651  // remove dead result also from map of sources and bypassed
652  // moves, it should not by tried to get removed second time
653  // by some other bypassed move from same candidate set
654  for (std::map<MoveNode*, MoveNode*, MoveNode::Comparator>::
655  iterator j = storedSources_.begin();
656  j != storedSources_.end();) {
657  if (j->second == &resultMove) {
658  removedStoredSources_[j->first] = &resultMove;
659  storedSources_.erase(j++);
660  } else {
661  j++;
662  }
663  }
664 
665  removedMoves.insert(
666  std::make_pair(&resultMove.move(), (*srcIter).second));
667 
668  sourceCycles_.erase(srcIter);
669  resultsRemoved++;
671 
672  // we lost edges so our notifyScheduled does not notify
673  // some antidependencies. notify them.
674  if (selector_ != NULL) {
675  for (DataDependenceGraph::NodeSet::iterator iter =
676  successors.begin();
677  iter != successors.end(); iter++) {
678  // don't notify other dead results
679  if (sourceCycles_.find(*iter) == sourceCycles_.end()) {
680  selector_->mightBeReady(**iter);
681  }
682  }
683  }
684  } else {
685  // we might have some orhpan nodes because some antideps have moved
686  // from user node to source node,
687  // so make sure notify the scheduler about them.
688  if (ddg.hasNode(resultMove)) {
689  DataDependenceGraph::NodeSet successors =
690  ddg.regWawSuccessors(resultMove);
691  if (selector_ != NULL) {
692  for (DataDependenceGraph::NodeSet::iterator iter =
693  successors.begin();
694  iter != successors.end(); iter++) {
695  // don't notify other dead results
696  if (sourceCycles_.find(*iter) == sourceCycles_.end()) {
697  selector_->mightBeReady(**iter);
698  }
699  }
700  }
701  }
702  }
703 
704  // also remove dummy move to itself moves, as the bypassed move.
705  if (moveNode.move().source().equals(
706  moveNode.move().destination())) {
707 
708  // we lost edges so our notifyScheduled does not notify
709  // some antidependencies. store them for notification.
710  DataDependenceGraph::NodeSet successors =
711  ddg.successors(moveNode);
712 
713  successors.erase(&moveNode); // if WaW to itself, rremove it.
714 
715  rm.unassign(moveNode);
716 
717  // this may lead to extra raw edges.
718  static_cast<DataDependenceGraph*>(ddg.rootGraph())->
719  copyDepsOver(moveNode, true, true);
720 
721  ddg.dropNode(moveNode);
722  removedNodes_.insert(&moveNode);
723 
724  // we lost edges so our notifyScheduled does not notify
725  // some antidependencies. notify them.
726  if (selector_ != NULL) {
727  for (DataDependenceGraph::NodeSet::iterator iter =
728  successors.begin();
729  iter != successors.end(); iter++) {
730  // don't notify other dead results
731  if (sourceCycles_.find(*iter) == sourceCycles_.end()) {
732  selector_->mightBeReady(**iter);
733  }
734  }
735  }
736  }
737  }
738 
739 
740  assert(sourceCycles_.empty());
741 
742  return resultsRemoved;
743 }

References assert, MapTools::containsKey(), deadResultCount_, TTAProgram::Move::destination(), BoostGraph< GraphNode, GraphEdge >::dropNode(), TTAProgram::Terminal::equals(), BoostGraph< GraphNode, GraphEdge >::hasNode(), MoveNode::isScheduled(), MoveNodeSelector::mightBeReady(), MoveNode::move(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), DataDependenceGraph::regWawSuccessors(), removedNodes_, removedStoredSources_, BoostGraph< GraphNode, GraphEdge >::rootGraph(), selector_, TTAProgram::Move::source(), sourceCycles_, storedSources_, BoostGraph< GraphNode, GraphEdge >::successors(), and ResourceManager::unassign().

Here is the call graph for this function:

◆ setSelector()

void CycleLookBackSoftwareBypasser::setSelector ( MoveNodeSelector selector)
virtual

Reimplemented from SoftwareBypasser.

Definition at line 756 of file CycleLookBackSoftwareBypasser.cc.

756  {
757  selector_ = selector;
758 }

References selector_.

Member Data Documentation

◆ bypassCount_

int CycleLookBackSoftwareBypasser::bypassCount_ = 0
staticprivate

Definition at line 125 of file CycleLookBackSoftwareBypasser.hh.

Referenced by bypassNode(), printStats(), and removeBypass().

◆ bypassFromRegs_

bool CycleLookBackSoftwareBypasser::bypassFromRegs_
private

Definition at line 96 of file CycleLookBackSoftwareBypasser.hh.

Referenced by bypassNode().

◆ bypassToRegs_

bool CycleLookBackSoftwareBypasser::bypassToRegs_
private

Definition at line 99 of file CycleLookBackSoftwareBypasser.hh.

Referenced by bypassNode().

◆ cyclesToLookBack_

int CycleLookBackSoftwareBypasser::cyclesToLookBack_
private

count of cycles before the operand write to look for the producer of the read value

Definition at line 86 of file CycleLookBackSoftwareBypasser.hh.

Referenced by bypass(), bypassNode(), CycleLookBackSoftwareBypasser(), and removeBypass().

◆ cyclesToLookBackNoDRE_

int CycleLookBackSoftwareBypasser::cyclesToLookBackNoDRE_
private

count of cycles before the operand write to look for the producer of the read value when cannot kill result

Definition at line 90 of file CycleLookBackSoftwareBypasser.hh.

Referenced by bypassNode(), and CycleLookBackSoftwareBypasser().

◆ deadResultCount_

int CycleLookBackSoftwareBypasser::deadResultCount_ = 0
staticprivate

Definition at line 126 of file CycleLookBackSoftwareBypasser.hh.

Referenced by printStats(), and removeDeadResults().

◆ killDeadResults_

bool CycleLookBackSoftwareBypasser::killDeadResults_
private

Definition at line 93 of file CycleLookBackSoftwareBypasser.hh.

Referenced by bypassNode(), and CycleLookBackSoftwareBypasser().

◆ removedNodes_

DataDependenceGraph::NodeSet CycleLookBackSoftwareBypasser::removedNodes_
private

Definition at line 121 of file CycleLookBackSoftwareBypasser.hh.

Referenced by clearCaches(), and removeDeadResults().

◆ removedStoredSources_

std::map<MoveNode*, MoveNode*, MoveNode::Comparator> CycleLookBackSoftwareBypasser::removedStoredSources_
private

Definition at line 117 of file CycleLookBackSoftwareBypasser.hh.

Referenced by clearCaches(), removeBypass(), and removeDeadResults().

◆ selector_

MoveNodeSelector* CycleLookBackSoftwareBypasser::selector_
private

Definition at line 123 of file CycleLookBackSoftwareBypasser.hh.

Referenced by removeDeadResults(), and setSelector().

◆ sourceBuses_

std::map<MoveNode*, const TTAMachine::Bus*> CycleLookBackSoftwareBypasser::sourceBuses_
private

Definition at line 115 of file CycleLookBackSoftwareBypasser.hh.

Referenced by bypassNode(), clearCaches(), and removeBypass().

◆ sourceCycles_

std::map<MoveNode*, int> CycleLookBackSoftwareBypasser::sourceCycles_
private

Definition at line 114 of file CycleLookBackSoftwareBypasser.hh.

Referenced by bypassNode(), removeBypass(), and removeDeadResults().

◆ storedSources_

std::map<MoveNode*, MoveNode*, MoveNode::Comparator> CycleLookBackSoftwareBypasser::storedSources_
private

Stores sources and bypassed moves in case they have to be unassigned (case when operands are scheduled and bypassed but result can not be scheduled with such operands.

Definition at line 111 of file CycleLookBackSoftwareBypasser.hh.

Referenced by bypassNode(), clearCaches(), removeBypass(), and removeDeadResults().

◆ triggerAbortCount_

int CycleLookBackSoftwareBypasser::triggerAbortCount_ = 0
staticprivate

Definition at line 127 of file CycleLookBackSoftwareBypasser.hh.

Referenced by bypass(), and printStats().


The documentation for this class was generated from the following files:
CycleLookBackSoftwareBypasser::deadResultCount_
static int deadResultCount_
Definition: CycleLookBackSoftwareBypasser.hh:126
TTAProgram::Move::isTriggering
bool isTriggering() const
Definition: Move.cc:284
MoveNode::isDestinationVariable
bool isDestinationVariable() const
Definition: MoveNode.cc:264
BoostGraph::tailNode
virtual Node & tailNode(const Edge &edge) const
MoveNodeGroup::node
MoveNode & node(int index) const
Definition: MoveNodeGroup.cc:152
CycleLookBackSoftwareBypasser::triggerAbortCount_
static int triggerAbortCount_
Definition: CycleLookBackSoftwareBypasser.hh:127
DataDependenceEdge::isBackEdge
bool isBackEdge() const
Definition: DataDependenceEdge.hh:118
DataDependenceGraph::resultUsed
bool resultUsed(MoveNode &resultNode)
Definition: DataDependenceGraph.cc:2348
MoveNode::isDestinationOperation
bool isDestinationOperation() const
ResourceManager::unassign
virtual void unassign(MoveNode &node)=0
BoostGraph< MoveNode, DataDependenceEdge >::NodeSet
std::set< MoveNode *, typename MoveNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
CycleLookBackSoftwareBypasser::sourceBuses_
std::map< MoveNode *, const TTAMachine::Bus * > sourceBuses_
Definition: CycleLookBackSoftwareBypasser.hh:115
SchedulerCmdLineOptions::killDeadResults
virtual bool killDeadResults() const
Definition: SchedulerCmdLineOptions.cc:361
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
CycleLookBackSoftwareBypasser::sourceCycles_
std::map< MoveNode *, int > sourceCycles_
Definition: CycleLookBackSoftwareBypasser.hh:114
CycleLookBackSoftwareBypasser::killDeadResults_
bool killDeadResults_
Definition: CycleLookBackSoftwareBypasser.hh:93
CycleLookBackSoftwareBypasser::storedSources_
std::map< MoveNode *, MoveNode *, MoveNode::Comparator > storedSources_
Stores sources and bypassed moves in case they have to be unassigned (case when operands are schedule...
Definition: CycleLookBackSoftwareBypasser.hh:111
TTAProgram::Move::bus
const TTAMachine::Bus & bus() const
Definition: Move.cc:373
MoveNode
Definition: MoveNode.hh:65
MoveNode::isSourceConstant
bool isSourceConstant() const
Definition: MoveNode.cc:238
CycleLookBackSoftwareBypasser::bypassNode
int bypassNode(MoveNode &nodeToBypass, int &lastOperandCycle, DataDependenceGraph &ddg, ResourceManager &rm)
Definition: CycleLookBackSoftwareBypasser.cc:98
DataDependenceEdge::EDGE_REGISTER
@ EDGE_REGISTER
Definition: DataDependenceEdge.hh:53
CycleLookBackSoftwareBypasser::removeBypass
virtual void removeBypass(MoveNodeGroup &candidates, DataDependenceGraph &ddg, ResourceManager &rm)
Definition: CycleLookBackSoftwareBypasser.cc:515
MoveNodeGroup::nodeCount
int nodeCount() const
Definition: MoveNodeGroup.cc:140
DataDependenceEdge::dependenceType
DependenceType dependenceType() const
Definition: DataDependenceEdge.hh:88
BoostGraph::dropNode
virtual void dropNode(Node &node)
SchedulerCmdLineOptions
Definition: SchedulerCmdLineOptions.hh:45
DataDependenceGraph::mergeAndKeepUser
bool mergeAndKeepUser(MoveNode &resultNode, MoveNode &userNode, bool force=false)
Definition: DataDependenceGraph.cc:2079
CycleLookBackSoftwareBypasser::cyclesToLookBackNoDRE_
int cyclesToLookBackNoDRE_
count of cycles before the operand write to look for the producer of the read value when cannot kill ...
Definition: CycleLookBackSoftwareBypasser.hh:90
TTAMachine::Machine::alwaysWriteResults
bool alwaysWriteResults() const
Definition: Machine.cc:954
assert
#define assert(condition)
Definition: Application.hh:86
DataDependenceGraph::regWarSuccessors
NodeSet regWarSuccessors(const MoveNode &node) const
Definition: DataDependenceGraph.cc:4239
TTAProgram::Terminal::isImmediateRegister
virtual bool isImmediateRegister() const
Definition: Terminal.cc:97
DataDependenceGraph::regWawSuccessors
NodeSet regWawSuccessors(const MoveNode &node) const
Definition: DataDependenceGraph.cc:4347
MoveNode::isBypass
bool isBypass() const
Definition: MoveNode.cc:280
MoveNode::cycle
int cycle() const
Definition: MoveNode.cc:421
MoveNode::guardLatency
int guardLatency() const
Definition: MoveNode.cc:779
TTAProgram::Move::isControlFlowMove
bool isControlFlowMove() const
Definition: Move.cc:233
BoostGraph::rootGraph
BoostGraph * rootGraph()
InvalidData
Definition: Exception.hh:149
BoostGraph< MoveNode, DataDependenceEdge >::EdgeSet
std::set< DataDependenceEdge *, typename DataDependenceEdge ::Comparator > EdgeSet
Definition: BoostGraph.hh:87
BoostGraph::removeNode
virtual void removeNode(Node &node)
CycleLookBackSoftwareBypasser::selector_
MoveNodeSelector * selector_
Definition: CycleLookBackSoftwareBypasser.hh:123
DataDependenceEdge::DEP_RAW
@ DEP_RAW
Definition: DataDependenceEdge.hh:47
CycleLookBackSoftwareBypasser::removedNodes_
DataDependenceGraph::NodeSet removedNodes_
Definition: CycleLookBackSoftwareBypasser.hh:121
Application::cmdLineOptions
static CmdLineOptions * cmdLineOptions()
Definition: Application.cc:397
__func__
#define __func__
Definition: Application.hh:67
Exception::errorMessageStack
std::string errorMessageStack(bool messagesOnly=false) const
Definition: Exception.cc:138
MoveNode::isSourceOperation
bool isSourceOperation() const
Definition: MoveNode.cc:168
ResourceManager::canAssign
virtual bool canAssign(int cycle, MoveNode &node, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) const =0
CycleLookBackSoftwareBypasser::bypassCount_
static int bypassCount_
Definition: CycleLookBackSoftwareBypasser.hh:125
Exception
Definition: Exception.hh:54
ModuleRunTimeError
Definition: Exception.hh:1043
DataDependenceGraph::unMergeUser
void unMergeUser(MoveNode &resultNode, MoveNode &mergedNode, bool loopBypass=false)
Definition: DataDependenceGraph.cc:2240
MoveNodeSelector::mightBeReady
virtual void mightBeReady(MoveNode &node)=0
Definition: MoveNodeSelector.cc:82
BoostGraph::hasNode
bool hasNode(const Node &) const
TTAProgram::AnnotatedInstructionElement::hasAnnotations
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:165
BoostGraph::inEdges
virtual EdgeSet inEdges(const Node &node) const
CycleLookBackSoftwareBypasser::bypassToRegs_
bool bypassToRegs_
Definition: CycleLookBackSoftwareBypasser.hh:99
DataDependenceGraph::earliestCycle
int earliestCycle(const MoveNode &moveNode, unsigned int ii=UINT_MAX, bool ignoreRegWaRs=false, bool ignoreRegWaWs=false, bool ignoreGuards=false, bool ignoreFUDeps=false, bool ignoreSameOperationEdges=false, bool assumeBypassing=false) const
Definition: DataDependenceGraph.cc:388
DataDependenceEdge::guardUse
bool guardUse() const
Definition: DataDependenceEdge.hh:100
MoveNode::move
TTAProgram::Move & move()
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
TTAMachine::Component::machine
virtual Machine * machine() const
CycleLookBackSoftwareBypasser::bypassFromRegs_
bool bypassFromRegs_
Definition: CycleLookBackSoftwareBypasser.hh:96
ResourceManager::assign
virtual void assign(int cycle, MoveNode &node, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1)=0
DataDependenceGraph::guardsAllowBypass
bool guardsAllowBypass(const MoveNode &defNode, const MoveNode &useNode, bool loopBypass=false)
Definition: DataDependenceGraph.cc:4543
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
TTAProgram::Terminal::equals
virtual bool equals(const Terminal &other) const =0
DataDependenceEdge
Definition: DataDependenceEdge.hh:43
MoveNode::isScheduled
bool isScheduled() const
Definition: MoveNode.cc:409
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
SimpleResourceManager
Definition: SimpleResourceManager.hh:58
TTAProgram::ProgramAnnotation::ANN_CONNECTIVITY_MOVE
@ ANN_CONNECTIVITY_MOVE
A reg to reg move that was added because of missing connectivity between the original target and dest...
Definition: ProgramAnnotation.hh:123
CycleLookBackSoftwareBypasser::removedStoredSources_
std::map< MoveNode *, MoveNode *, MoveNode::Comparator > removedStoredSources_
Definition: CycleLookBackSoftwareBypasser.hh:117
SchedulerCmdLineOptions::noDreBypassDistance
virtual int noDreBypassDistance() const
Definition: SchedulerCmdLineOptions.cc:352
SchedulerCmdLineOptions::bypassDistance
virtual int bypassDistance() const
Definition: SchedulerCmdLineOptions.cc:327
DataDependenceEdge::headPseudo
bool headPseudo() const
Definition: DataDependenceEdge.hh:115
DataDependenceEdge::DEP_WAR
@ DEP_WAR
Definition: DataDependenceEdge.hh:48
DataDependenceGraph::copyDepsOver
EdgeSet copyDepsOver(MoveNode &node, bool anti, bool raw)
Definition: DataDependenceGraph.cc:2422
ResourceManager::earliestCycle
virtual int earliestCycle(MoveNode &node, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) const =0
DataDependenceGraph::regRawSuccessorCount
int regRawSuccessorCount(const MoveNode &mn, bool onlyScheduled)
Definition: DataDependenceGraph.cc:3952
TTAProgram::Move::setBus
void setBus(const TTAMachine::Bus &bus)
Definition: Move.cc:383
CycleLookBackSoftwareBypasser::cyclesToLookBack_
int cyclesToLookBack_
count of cycles before the operand write to look for the producer of the read value
Definition: CycleLookBackSoftwareBypasser.hh:86
BoostGraph::successors
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
DataDependenceEdge::edgeReason
EdgeReason edgeReason() const
Definition: DataDependenceEdge.hh:91
TTAProgram::Move::setSource
void setSource(Terminal *src)
Definition: Move.cc:312
DataDependenceGraph::latestCycle
int latestCycle(const MoveNode &moveNode, unsigned int ii=UINT_MAX, bool ignoreRegAntideps=false, bool ignoreUnscheduledSuccessors=true, bool ignoreGuards=false, bool ignoreFUDeps=false, bool ignoreSameOperationEdges=false) const
Definition: DataDependenceGraph.cc:543