OpenASIP  2.0
Public Member Functions | Static Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | List of all members
BasicBlockScheduler Class Reference

#include <BasicBlockScheduler.hh>

Inheritance diagram for BasicBlockScheduler:
Inheritance graph
Collaboration diagram for BasicBlockScheduler:
Collaboration graph

Public Member Functions

 BasicBlockScheduler (InterPassData &data, SoftwareBypasser *bypasser=NULL, RegisterRenamer *renamer=NULL)
 
virtual ~BasicBlockScheduler ()
 
virtual int handleDDG (DataDependenceGraph &ddg, SimpleResourceManager &rm, const TTAMachine::Machine &targetMachine, int minCycle=0, bool testOnly=false) override
 
virtual int handleLoopDDG (DataDependenceGraph &ddg, SimpleResourceManager &rm, const TTAMachine::Machine &targetMachine, int tripCount, SimpleResourceManager *prologRM, bool testOnly=false) override
 
virtual std::string shortDescription () const
 
virtual std::string longDescription () const
 
virtual void printStats () const
 
virtual DataDependenceGraphBuilderddgBuilder ()
 
- Public Member Functions inherited from DDGPass
 DDGPass (InterPassData &data)
 
virtual ~DDGPass ()
 
- Public Member Functions inherited from SchedulerPass
 SchedulerPass (InterPassData &data)
 
virtual ~SchedulerPass ()
 
InterPassDatainterPassData ()
 
- Public Member Functions inherited from BasicBlockPass
 BasicBlockPass (InterPassData &data)
 
virtual ~BasicBlockPass ()
 
virtual void handleBasicBlock (TTAProgram::BasicBlock &basicBlock, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, BasicBlockNode *bbn=NULL)
 
virtual void executeDDGPass (TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, std::vector< DDGPass * > ddgPasses, BasicBlockNode *bbn=NULL)
 
virtual bool executeLoopPass (TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, std::vector< DDGPass * > ddgPasses, BasicBlockNode *bbn=NULL)
 
virtual DataDependenceGraphBuilderddgBuilder ()
 

Static Public Member Functions

static MoveNodefindTrigger (const ProgramOperation &po, const TTAMachine::Machine &mach)
 
- Static Public Member Functions inherited from BasicBlockPass
static void copyRMToBB (SimpleResourceManager &rm, TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, int lastCycle=-1)
 

Protected Member Functions

void scheduleRRMove (MoveNode &moveNode)
 
void scheduleOperation (MoveNodeGroup &moves)
 
int scheduleOperandWrites (int &cycle, MoveNodeGroup &moves)
 
bool scheduleResultReads (MoveNodeGroup &moves)
 
void scheduleMove (MoveNode &move, int earliestCycle, bool allowPredicationAndRenaming)
 
void scheduleRRTempMoves (MoveNode &regToRegMove, MoveNode &firstMove, int lastUse)
 
void scheduleInputOperandTempMoves (MoveNode &operandMove, MoveNode &operandWrite)
 
void unschedule (MoveNode &moveNode)
 
void unscheduleAllNodes ()
 
void unscheduleInputOperandTempMoves (MoveNode &operandMove)
 
void scheduleResultReadTempMoves (MoveNode &resultMove, MoveNode &resultRead, int lastUse)
 
void unscheduleResultReadTempMoves (MoveNode &resultMove)
 
void notifyScheduled (MoveNodeGroup &moves, MoveNodeSelector &selector)
 
void ddgSnapshot (DataDependenceGraph &ddg, const std::string &name, DataDependenceGraph::DumpFileFormat format, bool final, bool resetCounter=false) const
 
MoveNodesucceedingTempMove (MoveNode &current)
 
int getTriggerOperand (const Operation &operation, const TTAMachine::Machine &machine)
 
bool tryToSwitchInputs (ProgramOperation &op)
 
void handleRemovedResultMoves (std::set< std::pair< TTAProgram::Move *, int > > removedMoves)
 
bool tryToOptimizeWaw (const MoveNode &moveNode)
 
void tryToDelayOperands (MoveNodeGroup &moves)
 
- Protected Member Functions inherited from BasicBlockPass
void ddgSnapshot (DataDependenceGraph *ddg, std::string &name, DataDependenceGraph::DumpFileFormat format, bool final)
 
virtual DataDependenceGraphcreateDDGFromBB (TTAProgram::BasicBlock &bb, const TTAMachine::Machine &mach)
 

Static Protected Member Functions

static MoveNodefindTriggerFromUnit (const ProgramOperation &po, const TTAMachine::Unit &unit)
 

Protected Attributes

const TTAMachine::MachinetargetMachine_
 The target machine we are scheduling the program against. More...
 
DataDependenceGraphddg_
 DDG of the currently scheduled BB. More...
 
SimpleResourceManagerrm_
 Resource Manager of the currently scheduled BB. More...
 
std::map< const MoveNode *, DataDependenceGraph::NodeSetscheduledTempMoves_
 Stores the MoveNodes that were scheduled as temp moves during scheduling of the operand move. More...
 
SoftwareBypassersoftwareBypasser_
 The software bypasser to use to bypass registers when possible. More...
 
RegisterRenamerrenamer_
 
int minCycle_
 The earliest cycle to schedule moves in. Used to leave room for sched_yield() by the sched_yield() emitter. More...
 
MoveNodeSelectorselector_
 
boost::timer schedulingTime_
 Time for getting the scheduling time for current basic block. More...
 
int bypassedCount_
 
int deadResults_
 
LLVMTCECmdLineOptionsoptions_
 
MoveNodejumpNode_
 
int tripCount_
 

Detailed Description

A class that implements the functionality of a basic block scheduler.

Schedules the program one basic block at a time. Does not fill delay slots if they couldn't be filled with the basic block's contents itself (no instruction importing).

Definition at line 66 of file BasicBlockScheduler.hh.

Constructor & Destructor Documentation

◆ BasicBlockScheduler()

BasicBlockScheduler::BasicBlockScheduler ( InterPassData data,
SoftwareBypasser bypasser = NULL,
RegisterRenamer renamer = NULL 
)

Constructs the basic block scheduler.

Parameters
dataInterpass data
bypasserHelper module implementing software bypassing
delaySlotFillerHelper module implementing jump delay slot filling

Definition at line 85 of file BasicBlockScheduler.cc.

87  :
88  DDGPass(data), BasicBlockPass(data), ddg_(NULL), rm_(NULL),
89  softwareBypasser_(bypasser), renamer_(renamer), minCycle_(0),
90  jumpNode_(NULL) {
91  CmdLineOptions *cmdLineOptions = Application::cmdLineOptions();
92  options_ = dynamic_cast<LLVMTCECmdLineOptions*>(cmdLineOptions);
93 }

References Application::cmdLineOptions(), and options_.

Here is the call graph for this function:

◆ ~BasicBlockScheduler()

BasicBlockScheduler::~BasicBlockScheduler ( )
virtual

Definition at line 95 of file BasicBlockScheduler.cc.

95  {
96 }

Member Function Documentation

◆ ddgBuilder()

virtual DataDependenceGraphBuilder& BasicBlockPass::ddgBuilder
inline

Definition at line 86 of file BasicBlockPass.hh.

86 { return ddgBuilder_; }

◆ ddgSnapshot()

void BasicBlockScheduler::ddgSnapshot ( DataDependenceGraph ddg,
const std::string &  name,
DataDependenceGraph::DumpFileFormat  format,
bool  final,
bool  resetCounter = false 
) const
protected

Prints DDG to a dot file before and after scheudling

Parameters
ddgto print
nameoperation name for ddg
finalspecify if ddg is after scheduling
resetCounter
formatformat of the file
Returns
number of cycles/instructions copied.

Definition at line 1633 of file BasicBlockScheduler.cc.

1638  {
1639 
1640  static int bbCounter = 0;
1641 
1642  if (resetCounter) {
1643  bbCounter = 0;
1644  }
1645 
1646  if (final) {
1647  if (format == DataDependenceGraph::DUMP_DOT) {
1648  ddg.writeToDotFile(
1649  (boost::format("bb_%s_%s_after_scheduling.dot") %
1650  ddg_->name() % name).str());
1651  } else {
1652  ddg.writeToXMLFile(
1653  (boost::format("bb_%s_%s_after_scheduling.xml") %
1654  ddg_->name() % name).str());
1655  }
1656 
1657  } else {
1658  if (format == DataDependenceGraph::DUMP_DOT) {
1659  ddg.writeToDotFile(
1660  (boost::format("bb_%s_%d_%s_before_scheduling.dot")
1661  % ddg.name() % bbCounter % name).str());
1662  DataDependenceGraph* criticalPath = ddg.criticalPathGraph();
1663  criticalPath->writeToDotFile(
1664  (boost::format(
1665  "bb_%s_%d_%s_before_scheduling_critical_path.dot")
1666  % ddg.name() % bbCounter % name).str());
1667  delete criticalPath;
1668  } else {
1669  ddg.writeToXMLFile(
1670  (boost::format("bb_%s_%d_%s_before_scheduling.xml")
1671  % ddg.name() % bbCounter % name).str());
1672  }
1673  }
1674  ++bbCounter;
1675 }

References DataDependenceGraph::criticalPathGraph(), ddg_, DataDependenceGraph::DUMP_DOT, BoostGraph< GraphNode, GraphEdge >::name(), GraphBase< GraphNode, GraphEdge >::writeToDotFile(), and DataDependenceGraph::writeToXMLFile().

Referenced by BUBasicBlockScheduler::handleDDG(), handleDDG(), BUBasicBlockScheduler::handleLoopDDG(), handleLoopDDG(), and scheduleOperation().

Here is the call graph for this function:

◆ findTrigger()

MoveNode * BasicBlockScheduler::findTrigger ( const ProgramOperation po,
const TTAMachine::Machine mach 
)
static

Definition at line 2094 of file BasicBlockScheduler.cc.

2095  {
2096 
2097  MoveNode* triggerFromPO = po.triggeringMove();
2098  if (triggerFromPO) {
2099  return triggerFromPO;
2100  }
2101 
2102  // no scheduled moves. getting harder.
2103 
2105  mach.functionUnitNavigator();
2106  MoveNode* candidate = NULL;
2107  for (int i = 0; i < nav.count(); i++) {
2108  TTAMachine::FunctionUnit* fu = nav.item(i);
2109  if (fu->hasOperation(po.operation().name())) {
2110  if (candidate == NULL) {
2111  candidate = findTriggerFromUnit(po, *fu);
2112  } else {
2113  // make sure two different FU's don't have different
2114  // trigger ports.
2115  if (findTriggerFromUnit(po, *fu) != candidate) {
2116  return NULL;
2117  }
2118  }
2119  }
2120  }
2121 
2122  if (mach.controlUnit()->hasOperation(po.operation().name())) {
2123  return findTriggerFromUnit(po, *mach.controlUnit());
2124  }
2125  return candidate;
2126 
2127 }

References TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), findTriggerFromUnit(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::FunctionUnit::hasOperation(), TTAMachine::Machine::Navigator< ComponentType >::item(), Operation::name(), ProgramOperation::operation(), and ProgramOperation::triggeringMove().

Referenced by BFOptimization::getSisterTrigger(), BF2Scheduler::mustBeTrigger(), and BUBasicBlockScheduler::scheduleOperandWrites().

Here is the call graph for this function:

◆ findTriggerFromUnit()

MoveNode * BasicBlockScheduler::findTriggerFromUnit ( const ProgramOperation po,
const TTAMachine::Unit unit 
)
staticprotected

Definition at line 2130 of file BasicBlockScheduler.cc.

2131  {
2132  const TTAMachine::FunctionUnit* fu =
2133  dynamic_cast<const TTAMachine::FunctionUnit*>(&unit);
2134  int ioIndex = -1;
2135 
2136  int portC = fu->portCount();
2137  for (int i = 0; i < portC; i++) {
2138  auto p = fu->port(i);
2139  const TTAMachine::FUPort* port = dynamic_cast<const TTAMachine::FUPort*>(p);
2140  if (port != nullptr && port->isTriggering()) {
2141  const TTAMachine::HWOperation* hwop =
2142  fu->operation(po.operation().name());
2143  ioIndex = hwop->io(*port);
2144  return &po.inputNode(ioIndex).at(0);
2145  }
2146  }
2147  return NULL;
2148 }

References MoveNodeSet::at(), ProgramOperation::inputNode(), TTAMachine::HWOperation::io(), TTAMachine::FUPort::isTriggering(), Operation::name(), TTAMachine::FunctionUnit::operation(), ProgramOperation::operation(), TTAMachine::FunctionUnit::port(), and TTAMachine::Unit::portCount().

Referenced by findTrigger().

Here is the call graph for this function:

◆ getTriggerOperand()

int BasicBlockScheduler::getTriggerOperand ( const Operation operation,
const TTAMachine::Machine machine 
)
protected

Returns the operand which is triggering in all FU's which support the operation. If operation not found, is not gcu or multiple FU's have different triggers, returns 0

Definition at line 1684 of file BasicBlockScheduler.cc.

1686  {
1687 
1688  const TCEString& opName = operation.name();
1691 
1692  int trigger = 0;
1693  for (int i = 0; i < fuNav.count(); i++) {
1694  TTAMachine::FunctionUnit& fu = *fuNav.item(i);
1695  if (fu.hasOperation(opName)) {
1696  TTAMachine::HWOperation& hwop = *fu.operation(opName);
1697  for (int j = 1; j <= operation.numberOfInputs(); j++) {
1698  TTAMachine::FUPort& port = *hwop.port(j);
1699  if (port.isTriggering()) {
1700  if (trigger == 0) {
1701  trigger = j;
1702  } else {
1703  if (trigger != j) {
1704  return 0;
1705  }
1706  }
1707  }
1708  }
1709  }
1710  }
1711  return trigger;
1712 }

References TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::FunctionUnit::hasOperation(), TTAMachine::FUPort::isTriggering(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine, Operation::name(), Operation::numberOfInputs(), TTAMachine::FunctionUnit::operation(), and TTAMachine::HWOperation::port().

Referenced by BUBasicBlockScheduler::tryToSwitchInputs(), and tryToSwitchInputs().

Here is the call graph for this function:

◆ handleDDG()

int BasicBlockScheduler::handleDDG ( DataDependenceGraph ddg,
SimpleResourceManager rm,
const TTAMachine::Machine targetMachine,
int  minCycle = 0,
bool  test = false 
)
overridevirtual

Schedules a piece of code in a DDG

Parameters
ddgThe ddg containing the code
rmResource manager that is to be used.
targetMachineThe target machine.
Returns
size of the produces schedule.
Exceptions
Exceptionseveral TCE exceptions can be thrown in case of a scheduling error.

Reimplemented from DDGPass.

Reimplemented in BUBasicBlockScheduler.

Definition at line 109 of file BasicBlockScheduler.cc.

111  {
112  tripCount_ = 0;
113  ddg_ = &ddg;
114  targetMachine_ = &targetMachine;
115  minCycle_ = minCycle;
116  schedulingTime_.restart();
117 
118  if (renamer_ != NULL) {
119  renamer_->initialize(ddg);
120  }
121 
122  if (options_ != NULL && options_->dumpDDGsDot()) {
123  ddgSnapshot(
124  ddg, std::string("0"), DataDependenceGraph::DUMP_DOT, false);
125  }
126 
127  if (options_ != NULL && options_->dumpDDGsXML()) {
128  ddgSnapshot(
129  ddg, std::string("0"), DataDependenceGraph::DUMP_XML, false);
130  }
131 
132  scheduledTempMoves_.clear();
133 
134  // empty DDGs can be ignored
135  if (ddg.nodeCount() == 0 ||
136  (ddg.nodeCount() == 1 && !ddg.node(0).isMove())) {
137  return 0;
138  }
139 
140  CriticalPathBBMoveNodeSelector selector(ddg, targetMachine);
141  selector_ = &selector;
142 
143  rm_ = &rm;
144 
145 
146  // register selector to bypasser for notfications.
147  if (softwareBypasser_ != NULL) {
148  softwareBypasser_->setSelector(&selector);
149  }
150 
151  if (renamer_ != NULL) {
152  renamer_->setSelector(&selector);
153  }
154 
155  MoveNodeGroup moves = selector.candidates();
156  while (moves.nodeCount() > 0) {
157  bool movesRemoved = false;
158  MoveNode& firstMove = moves.node(0);
159  if (firstMove.isOperationMove()) {
160  scheduleOperation(moves);
161  } else {
162  if (firstMove.move().destination().isRA()) {
163  scheduleMove(firstMove,0, true);
164  } else {
165  scheduleRRMove(firstMove);
166  int lastOperandFake = 0;
167  if (softwareBypasser_ != NULL) {
168  int rv =
170  firstMove, lastOperandFake, ddg, rm);
171  if (rv < 0) {
173  firstMove, ddg, rm, true);
174  scheduleRRMove(firstMove);
175  }
176 
177  // did the bypass cause a reg-to-itself copy?
178  // if it did, let's kill it.
179  if (firstMove.move().source().equals(
180  firstMove.move().destination())) {
181  movesRemoved = true;
182  }
183 
184  if (rv > 0) {
185  std::set<std::pair<TTAProgram::Move*, int> >
186  removedMoves;
188  moves, ddg, rm, removedMoves);
189  // TODO: disabled becaused may be problematic
190  // when rescheduled to different buses
191 // handleRemovedResultMoves(removedMoves);
192  }
193  }
194  }
195  }
196 
197  if (!movesRemoved) {
198  if (!moves.isScheduled()) {
199  std::string message = " Move(s) did not get scheduled: ";
200  for (int i = 0; i < moves.nodeCount(); i++) {
201  message += moves.node(i).toString() + " ";
202  }
203 
205 
206  throw ModuleRunTimeError(__FILE__,__LINE__,__func__,message);
207  }
208 
209  // notifies successors of the scheduled moves.
210  notifyScheduled(moves, selector);
211  }
212 
213  moves = selector.candidates();
214  }
215  int size = rm.largestCycle();
216  if (test) {
218  return size;
219  }
220  if (softwareBypasser_ != NULL) {
221  softwareBypasser_->clearCaches(ddg, true);
222  }
223 
224  if (ddg.nodeCount() !=
225  ddg.scheduledNodeCount()) {
226  ddg.writeToDotFile("failed_bb.dot");
227  std::cerr << ddg.nodeCount() << ", " << ddg.scheduledNodeCount()
228  << std::endl;
229  throw ModuleRunTimeError(__FILE__, __LINE__, __func__,
230  "All moves in the DDG didn't get scheduled.");
231  }
232 
233  if (options_ != NULL && options_->dumpDDGsDot()) {
234  ddgSnapshot(ddg, std::string("0"), DataDependenceGraph::DUMP_DOT, true);
235  }
236 
237  if (options_ != NULL && options_->dumpDDGsXML()) {
238  ddgSnapshot(ddg, std::string("0"), DataDependenceGraph::DUMP_XML, true);
239  }
240  return size;
241 }

References __func__, SoftwareBypasser::bypassNode(), CriticalPathBBMoveNodeSelector::candidates(), SoftwareBypasser::clearCaches(), ddg_, ddgSnapshot(), TTAProgram::Move::destination(), DataDependenceGraph::DUMP_DOT, DataDependenceGraph::DUMP_XML, LLVMTCECmdLineOptions::dumpDDGsDot(), LLVMTCECmdLineOptions::dumpDDGsXML(), TTAProgram::Terminal::equals(), RegisterRenamer::initialize(), MoveNode::isMove(), MoveNode::isOperationMove(), TTAProgram::Terminal::isRA(), MoveNodeGroup::isScheduled(), SimpleResourceManager::largestCycle(), minCycle_, MoveNode::move(), MoveNodeGroup::node(), BoostGraph< GraphNode, GraphEdge >::node(), MoveNodeGroup::nodeCount(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), notifyScheduled(), options_, SoftwareBypasser::removeBypass(), SoftwareBypasser::removeDeadResults(), renamer_, rm_, DataDependenceGraph::scheduledNodeCount(), scheduledTempMoves_, scheduleMove(), scheduleOperation(), scheduleRRMove(), schedulingTime_, selector_, RegisterRenamer::setSelector(), SoftwareBypasser::setSelector(), softwareBypasser_, TTAProgram::Move::source(), targetMachine_, MoveNode::toString(), tripCount_, unscheduleAllNodes(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Here is the call graph for this function:

◆ handleLoopDDG()

int BasicBlockScheduler::handleLoopDDG ( DataDependenceGraph ddg,
SimpleResourceManager rm,
const TTAMachine::Machine targetMachine,
int  tripCount,
SimpleResourceManager prologRM,
bool  testOnly = false 
)
overridevirtual

Schedules loop in a DDG

Parameters
ddgThe ddg containing the loop
rmResource manager that is to be used.
targetMachineThe target machine.
Exceptions
Exceptionseveral TCE exceptions can be thrown in case of a scheduling error.
Returns
negative if failed, else overlapcount.

Reimplemented from DDGPass.

Reimplemented in BUBasicBlockScheduler.

Definition at line 254 of file BasicBlockScheduler.cc.

257  {
258  tripCount_ = tripCount;
259  ddg_ = &ddg;
260  targetMachine_ = &targetMachine;
261  minCycle_ = 0;
262  schedulingTime_.restart();
263 
264  if (renamer_ != NULL) {
265  renamer_->initialize(ddg);
266  }
267 
268  if (options_ != NULL && options_->dumpDDGsDot()) {
269  ddgSnapshot(
270  ddg, std::string("0"), DataDependenceGraph::DUMP_DOT, false, true);
271  }
272 
273  if (options_ != NULL && options_->dumpDDGsXML()) {
274  ddgSnapshot(
275  ddg, std::string("0"), DataDependenceGraph::DUMP_XML, false, true);
276  }
277 
278  scheduledTempMoves_.clear();
279 
280  // empty DDGs can be ignored
281  if (ddg.nodeCount() == 0 ||
282  (ddg.nodeCount() == 1 && !ddg.node(0).isMove())) {
283  return 0;
284  }
285 
286  CriticalPathBBMoveNodeSelector selector(ddg, targetMachine);
287 
288  rm_ = &rm;
289 
290  // register selector to bypasser for notfications.
291  if (softwareBypasser_ != NULL) {
292  softwareBypasser_->setSelector(&selector);
293  }
294 
295  if (renamer_ != NULL) {
296  renamer_->setSelector(&selector);
297  }
298 
299  for (int i = ddg.nodeCount()-1; i>= 0 ; i--) {
300  MoveNode& node = ddg.node(i);
301  if (node.move().isControlFlowMove()) {
302  jumpNode_ = &node;
303  MoveNodeGroup mng;
304  mng.addNode(node);
305  scheduleOperation(mng);
306  }
307  }
308 
309  MoveNodeGroup moves = selector.candidates();
310  while (moves.nodeCount() > 0) {
311 
312  MoveNode& firstMove = moves.node(0);
313  if (firstMove.isOperationMove()) {
314  scheduleOperation(moves);
315  } else {
316  if (firstMove.move().destination().isRA()) {
317  scheduleMove(firstMove,0, true);
318  } else {
319  scheduleRRMove(firstMove);
320  }
321  }
322 
323  if (!moves.isScheduled()) {
325  std::string("ii_") +
327  std::string("_dag.dot"));
328 
330 
331  return -1;
332  }
333 
334  // notifies successors of the scheduled moves.
335  notifyScheduled(moves, selector);
336 
337  moves = selector.candidates();
338  }
339 
340  if (ddg.nodeCount() !=
341  ddg.scheduledNodeCount()) {
342  debugLog("All moves in the DDG didn't get scheduled.");
343 // debugLog("Disassembly of the situation:");
344 // Application::logStream() << bb.disassemble() << std::endl;
345  ddg.writeToDotFile("failed_bb.dot");
346  abortWithError("Should not happen!");
347  }
348 
349  // loop schedulign did not help.
350  if (static_cast<unsigned>(ddg.largestCycle()) < rm.initiationInterval()
351  || testOnly) {
352  if (static_cast<unsigned>(ddg.largestCycle()) <
353  rm.initiationInterval()) {
355  << "No overlapping instructions."
356  << "Should Revert to ordinary scheduler."
357  << std::endl;
358  }
359  // this have to be calculated before unscheduling.
360  int rv = ddg.largestCycle() / rm.initiationInterval();
362  return rv;
363  }
364 
365  // test that ext-cond jump not in prolog (where it is skipped)
366  int overlap_count = ddg.largestCycle() / rm.initiationInterval();
367  if (overlap_count >= tripCount) {
369  return -1;
370  }
371 
372  if (softwareBypasser_ != NULL) {
373  softwareBypasser_->clearCaches(ddg, true);
374  }
375 
376  if (options_ != NULL && options_->dumpDDGsDot()) {
377  ddgSnapshot(ddg, std::string("0"), DataDependenceGraph::DUMP_DOT, true);
378  }
379 
380  if (options_ != NULL && options_->dumpDDGsXML()) {
381  ddgSnapshot(ddg, std::string("0"), DataDependenceGraph::DUMP_XML, true);
382  }
383 
384  return ddg.largestCycle() / rm.initiationInterval();
385 }

References abortWithError, MoveNodeGroup::addNode(), CriticalPathBBMoveNodeSelector::candidates(), SoftwareBypasser::clearCaches(), ddg_, ddgSnapshot(), debugLog, TTAProgram::Move::destination(), DataDependenceGraph::DUMP_DOT, DataDependenceGraph::DUMP_XML, LLVMTCECmdLineOptions::dumpDDGsDot(), LLVMTCECmdLineOptions::dumpDDGsXML(), RegisterRenamer::initialize(), SimpleResourceManager::initiationInterval(), TTAProgram::Move::isControlFlowMove(), MoveNode::isMove(), MoveNode::isOperationMove(), TTAProgram::Terminal::isRA(), MoveNodeGroup::isScheduled(), jumpNode_, DataDependenceGraph::largestCycle(), Application::logStream(), minCycle_, MoveNode::move(), MoveNodeGroup::node(), BoostGraph< GraphNode, GraphEdge >::node(), MoveNodeGroup::nodeCount(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), notifyScheduled(), options_, renamer_, rm_, DataDependenceGraph::scheduledNodeCount(), scheduledTempMoves_, scheduleMove(), scheduleOperation(), scheduleRRMove(), schedulingTime_, RegisterRenamer::setSelector(), SoftwareBypasser::setSelector(), softwareBypasser_, targetMachine_, Conversion::toString(), tripCount_, unscheduleAllNodes(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Here is the call graph for this function:

◆ handleRemovedResultMoves()

void BasicBlockScheduler::handleRemovedResultMoves ( std::set< std::pair< TTAProgram::Move *, int > >  removedMoves)
protected

Checks if the result moves that were removed might remove some resource bottleneck of already scheduled moves.

This situation happens at least when a result move used the last RF write port for a cycle and limited the earliest cycle of a previously scheduled move. Thus, after the last use of that result was scheduled and bypassed, the RF write port is freed as the result move becomes unnecessary, thus the move that was scheduled before could be scheduled earlier. Same thing can happen for bus (move slot) contrained moves and also moves that were restricted by a WaR edge due to the result move, etc.

Todo:
: reschedule also the moves dependent from the rescheduled ones that got earlier

Definition at line 1807 of file BasicBlockScheduler.cc.

1808  {
1809 
1810  if (removedMoves.size() == 0)
1811  return;
1812 
1813 #ifndef RESCHEDULE_NEXT_CYCLE_AFTER_DRE
1814  return;
1815 #endif
1816 
1817  const bool DEBUG_PRINT = false; //Application::verboseLevel() > 0;
1818 
1819  if (DEBUG_PRINT) {
1821  << removedMoves.size() << " dead results eliminated: "
1822  << std::endl;
1823  }
1824 
1825  for (std::set<std::pair<TTAProgram::Move*, int> >::
1826  const_iterator i = removedMoves.begin();
1827  i != removedMoves.end(); ++i) {
1828 
1829  TTAProgram::Move& eliminatedMove = *(*i).first;
1830  int cycle = (*i).second;
1831 
1832  if (DEBUG_PRINT) {
1834  << eliminatedMove.toString() << " (cycle " << cycle << ") ";
1835  }
1836 
1837  int oldCycle = cycle + 1;
1838  // look for already scheduled moves that were scheduled after
1839  // the cycle of the result move, thus potentially were limited by
1840  // the result move earlier
1841  DataDependenceGraph::NodeSet nextCycleMoves =
1842  ddg_->movesAtCycle(oldCycle);
1843 
1844  // if true, try to reschedule all moves at the next cycle (slower,
1845  // but handles the case when the cycle was bus constrained previously),
1846  // if false, tries to schedule only potentially RF write port
1847  // constrained moves (faster)
1848  bool rescheduleAllSucceedingMoves = false;
1849  for (DataDependenceGraph::NodeSet::const_iterator m =
1850  nextCycleMoves.begin(); m != nextCycleMoves.end(); ++m) {
1851  MoveNode& moveNode = **m;
1852 
1853  if (rescheduleAllSucceedingMoves ||
1854  (moveNode.move().destination().isGPR() &&
1855  &eliminatedMove.destination().registerFile() ==
1856  &moveNode.move().destination().registerFile())) {
1857 
1858  if (DEBUG_PRINT) {
1860  << "Trying to reschedule "
1861  << moveNode.toString() << " " << std::endl;
1862  }
1863 
1864  assert(moveNode.isScheduled() && moveNode.cycle() == oldCycle);
1865 
1866  unschedule(moveNode);
1867  // because a pontially removed WaR, we might be able to
1868  // schedule this move (write to the same reg) even earlier
1869  // than the dead result move cycle
1870  scheduleMove(moveNode, std::max(oldCycle - 10, 0), false);
1871 
1872  if (!moveNode.isScheduled()) {
1873  for (int c = 4; c >= 0; --c) {
1875  << "\t\t" << oldCycle - c << ": "
1876  << rm_->instruction(
1877  std::max(oldCycle - c, 0))->toString()
1878  << std::endl;
1879  }
1880  assert(moveNode.isScheduled());
1881  }
1882 
1883  if (moveNode.cycle() < oldCycle) {
1884  if (DEBUG_PRINT) {
1886  << " OK at cycle " << moveNode.cycle() << ". " << std::endl;
1887  }
1888  } else {
1889  // should not get worse schedule!
1890  assert(moveNode.cycle() == oldCycle);
1891  if (DEBUG_PRINT) {
1892  Application::logStream() << " NO change. " << std::endl;
1893  }
1894  }
1895 
1896  }
1897  /// @todo: reschedule also the moves dependent from the
1898  /// rescheduled ones that got earlier
1899  }
1900 
1901  if (DEBUG_PRINT) {
1902  Application::logStream() << std::endl;
1903  }
1904  }
1905 }

References assert, MoveNode::cycle(), ddg_, TTAProgram::Move::destination(), SimpleResourceManager::instruction(), TTAProgram::Terminal::isGPR(), MoveNode::isScheduled(), Application::logStream(), MoveNode::move(), DataDependenceGraph::movesAtCycle(), TTAProgram::Terminal::registerFile(), rm_, scheduleMove(), TTAProgram::Move::toString(), TTAProgram::Instruction::toString(), MoveNode::toString(), and unschedule().

Referenced by scheduleOperation().

Here is the call graph for this function:

◆ longDescription()

std::string BasicBlockScheduler::longDescription ( ) const
virtual

Optional longer description of the pass.

This description can include usage instructions, details of choice of algorithmic details, etc.

Returns
The description as a string.

Reimplemented from SchedulerPass.

Reimplemented in BUBasicBlockScheduler.

Definition at line 1587 of file BasicBlockScheduler.cc.

1587  {
1588  return
1589  "Basic block scheduler that uses the longest path information of "
1590  "data dependency graph to prioritize the ready list. Assumes that "
1591  "the input has registers allocated and no connectivity missing.";
1592 }

◆ notifyScheduled()

void BasicBlockScheduler::notifyScheduled ( MoveNodeGroup moves,
MoveNodeSelector selector 
)
protected

Notifies to the selector that given nodes and their temp reg copies are scheduled .

Parameters
nodesnodes which are scheduled.
selectorselector which to notify.

Definition at line 1602 of file BasicBlockScheduler.cc.

1603  {
1604 
1605  for (int moveIndex = 0; moveIndex < moves.nodeCount(); ++moveIndex) {
1606  MoveNode& moveNode = moves.node(moveIndex);
1607  selector.notifyScheduled(moveNode);
1608  std::map<const MoveNode*, DataDependenceGraph::NodeSet>::
1609  iterator tmIter = scheduledTempMoves_.find(&moveNode);
1610  if (tmIter != scheduledTempMoves_.end()) {
1611  DataDependenceGraph::NodeSet& tempMoves = tmIter->second;
1612  for (DataDependenceGraph::NodeSet::iterator i =
1613  tempMoves.begin(); i != tempMoves.end(); i++) {
1614  if ((**i).isScheduled()) {
1615  selector.notifyScheduled(**i);
1616  }
1617  }
1618  }
1619  }
1620 }

References MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), MoveNodeSelector::notifyScheduled(), and scheduledTempMoves_.

Referenced by handleDDG(), BUBasicBlockScheduler::handleLoopDDG(), and handleLoopDDG().

Here is the call graph for this function:

◆ printStats()

void BasicBlockScheduler::printStats ( ) const
virtual

Definition at line 1908 of file BasicBlockScheduler.cc.

1908  {
1909  if (Application::verboseLevel() > 0) {
1910  }
1911 }

References Application::verboseLevel().

Here is the call graph for this function:

◆ scheduleInputOperandTempMoves()

void BasicBlockScheduler::scheduleInputOperandTempMoves ( MoveNode operandMove,
MoveNode operandWrite 
)
protected

Schedules the (possible) temporary register copy moves (due to missing connectivity) preceeding the given input move.

The function recursively goes through all the temporary moves added to the given input move.

Parameters
operandMoveA temp move whose predecessor has to be scheduled.
operandWriteThe original move of which temp moves to schedule.

Definition at line 1344 of file BasicBlockScheduler.cc.

1345  {
1346  /* Because temporary register moves do not have WaR dependency edges
1347  between the other possible uses of the same temp register in
1348  the same operation, we have to limit the scheduling of the new
1349  temp reg move to the last use of the same temp register so
1350  we don't overwrite the temp registers of other operands. */
1351 
1352  /* <pekka> TODO: this could be improved by allowing to schedule also
1353  *before* the previous use, in the "holes" where it's unused. Now in effect
1354  the copies serialize the code quite badly. */
1355  int lastUse = 0;
1356 
1357  // find all unscheduled preceeding temp moves of the operand move
1358  DataDependenceGraph::EdgeSet inEdges = ddg_->inEdges(operandMove);
1359  MoveNode* tempMove = NULL;
1360  for (DataDependenceGraph::EdgeSet::iterator i = inEdges.begin();
1361  i != inEdges.end(); ++i) {
1362  if ((**i).edgeReason() != DataDependenceEdge::EDGE_REGISTER ||
1363  (**i).guardUse() ||
1364  (**i).dependenceType() != DataDependenceEdge::DEP_RAW) {
1365  continue;
1366  }
1367 
1368  MoveNode& m = ddg_->tailNode(**i);
1369  if (m.isScheduled() ||
1370  !m.move().hasAnnotations(
1372  continue;
1373  }
1374 
1375  assert(tempMove == NULL &&
1376  "Multiple unscheduled moves for the operand move, should have "
1377  "max. one (the temporary move)!");
1378  tempMove = &m;
1379  MoveNode* lastRead =
1381  tempMove->move().destination().registerFile(),
1382  tempMove->move().destination().index());
1383  if (lastRead != NULL)
1384  lastUse = lastRead->cycle();
1385  }
1386 
1387  if (tempMove == NULL)
1388  return; // no temp moves found
1389 
1390  // the temp move should have maximum of one unscheduled
1391  // preceeding reg to reg copy (in case of an additional temp reg copy),
1392  // schedule it first if found, calling recursively this function
1393  scheduleInputOperandTempMoves(*tempMove, operandWrite);
1394 
1395  // TODO: is the true correct here?
1396  scheduleMove(*tempMove, lastUse, true);
1397  assert(tempMove->isScheduled());
1398  scheduledTempMoves_[&operandWrite].insert(tempMove);
1399 }

References TTAProgram::ProgramAnnotation::ANN_CONNECTIVITY_MOVE, assert, MoveNode::cycle(), ddg_, DataDependenceEdge::DEP_RAW, TTAProgram::Move::destination(), DataDependenceEdge::EDGE_REGISTER, TTAProgram::AnnotatedInstructionElement::hasAnnotations(), TTAProgram::Terminal::index(), BoostGraph< GraphNode, GraphEdge >::inEdges(), MoveNode::isScheduled(), DataDependenceGraph::lastScheduledRegisterRead(), MoveNode::move(), TTAProgram::Terminal::registerFile(), scheduledTempMoves_, scheduleMove(), and BoostGraph< GraphNode, GraphEdge >::tailNode().

Referenced by scheduleOperandWrites().

Here is the call graph for this function:

◆ scheduleMove()

void BasicBlockScheduler::scheduleMove ( MoveNode moveNode,
int  earliestCycle,
bool  allowPredicationAndRenaming 
)
protected

Schedules a single move to the earliest possible cycle, taking in account the DDG, resource constraints, and latencies in producing source values.

This method assumes the move is possible to schedule with regards to connectivity and resources. Short immediates are converted to long immediates when needed.

Parameters
moveThe move to schedule.
earliestCycleThe earliest cycle to try.
allowPredicationAndRenamingWhether allowed to remove guard from the move being scheduled. Checks again side-effects are still made, this can be done only to operand moves and triggers without mem write or side-effects.

Definition at line 950 of file BasicBlockScheduler.cc.

951  {
952  if (moveNode.isScheduled()) {
953  throw InvalidData(
954  __FILE__, __LINE__, __func__,
955  (boost::format("Move '%s' is already scheduled!")
956  % moveNode.toString()).str());
957  }
958 
959  int sourceReadyCycle = 0;
960  if (moveNode.isSourceOperation()) {
961  sourceReadyCycle = moveNode.earliestResultReadCycle();
962  }
963 
964  int ddgCycle = 0;
965 
966  unsigned int ii = rm_->initiationInterval();
967 
968  // schedule jumps and calls...
969  if (moveNode.move().isControlFlowMove()) {
970 
971  // the branch should get scheduled last, so the DDG should have
972  // only the branch move(s) at hand unscheduled. For software
973  // pipelining (ii > 0), branches might be scheduled earlier.
974  if (ii == 0 && ddg_->nodeCount() != ddg_->scheduledNodeCount() + 1) {
975  // in rare case the branch moves can have 2 parameters (SPU)
976  // and therefore 2 nodes unscheduled. Check if the unscheduled
977  // moves are all control flow moves.
978  DataDependenceGraph::NodeSet unscheduledMoves =
980  for (DataDependenceGraph::NodeSet::iterator i = unscheduledMoves.begin();
981  i != unscheduledMoves.end(); ++i) {
982  if (!(*i)->move().isControlFlowMove()) {
983  TCEString msg =
984  "Control Flow Move is not last of the unscheduled moves! ";
985  msg += "Scheduled count=" +
987  msg += " Node count=" +
989  throw InvalidData(__FILE__, __LINE__, __func__, msg);
990  }
991  }
992  }
993 
994  // try to fill the delay slots with moves within the same basic
995  // block
996  // @TODO: ignore argument/rv register deps in case of call as they
997  // are not really used by the call instruction but by the called
998  // procedure, thus we can schedule them at the delay slots
999 
1000  // largest cycle of DDG is the highest cycle where something
1001  // was scheduled, however such a move can have pipeline
1002  // that spans more cycles and we should not change
1003  // the control flow while something is still in pipeline
1004  int largest = std::max(rm_->largestCycle(), ddg_->largestCycle());
1005  if (ii == 0) {
1006  ddgCycle =
1007  std::max(
1008  ddg_->earliestCycle(moveNode),
1009  largest - targetMachine_->controlUnit()->delaySlots());
1010  } else {
1011  unsigned int delaySlots =
1013  // is the jump in first or later iteration?
1014  MoveNode* jumpLimit = ddg_->findLoopLimitAndIndex(moveNode).first;
1015 
1016  ddgCycle = (((ddg_->earliestCycle(moveNode, ii) +
1017  delaySlots) / ii) + 1)*ii - 1 - delaySlots;
1018  if ((unsigned)ddgCycle >= ii - delaySlots) {
1019 
1020  int jumpOverlapCount = (ddgCycle + delaySlots) / ii;
1021  if (jumpLimit == NULL) {
1022  // allow jump only in first iteration if we could
1023  // not find the limit
1024  return;
1025  } else {
1026  // update loop limit counter.
1027  TTAProgram::TerminalImmediate& ti = dynamic_cast<
1028  TTAProgram::TerminalImmediate&>(jumpLimit->move().source());
1029  int jumpLimitValue = ti.value().unsignedValue();
1030  int loopCounterStep = 1;
1031  if (jumpLimitValue != tripCount_) {
1032  if (jumpLimitValue == 2 * tripCount_) {
1033  loopCounterStep = 2;
1034  } else {
1035  if (jumpLimitValue == 4 * tripCount_) {
1036  loopCounterStep = 4;
1037  } else {
1038  // don't know how much to decr. counter.
1039  return;
1040  }
1041  }
1042  }
1043 
1044  if (tripCount_ > jumpOverlapCount) {
1045  jumpLimit->move().setSource(
1047  SimValue(
1048  jumpLimitValue -
1049  (jumpOverlapCount * loopCounterStep),
1050  ti.value().width())));
1051  } else {
1052  // loop limit is too short.
1053  // would be always executed too many times.
1054  return;
1055  }
1056  }
1057  }
1058  }
1059  } else { // not a control flow move:
1060  ddgCycle = ddg_->earliestCycle(moveNode, ii);
1061 
1062  // <pekka> This is now always called even though renaming is disabled?
1063  int minRenamedEC = std::max(
1064  sourceReadyCycle, ddg_->earliestCycle(moveNode, ii, true, true));
1065 
1066  // rename if can and may alow scheuduling earlier.
1067  if (renamer_ != NULL && minRenamedEC < ddgCycle &&
1068  allowPredicationAndRenaming) {
1069  minRenamedEC = rm_->earliestCycle(minRenamedEC, moveNode);
1070  if (minRenamedEC < ddgCycle) {
1071 
1073  moveNode, ii != 0, true, true, minRenamedEC)) {
1074  ddgCycle = ddg_->earliestCycle(moveNode, ii);
1075  } else {
1076 #ifdef THIS_IS_BUGGY_WITH_REGCOPY_ADDER
1077  // renaming already scheduled ones may fail if
1078  // loop scheudling.
1079  if (rm_->initiationInterval() == 0) {
1080  MoveNode *limitingAdep =
1082  if (limitingAdep != NULL) {
1083  // don't try to rename is same operation.
1084  // as it would not help at all.
1085  if (!moveNode.isSourceOperation() ||
1086  !limitingAdep->isDestinationOperation() ||
1087  &moveNode.sourceOperation() !=
1088  &limitingAdep->destinationOperation()) {
1090  *limitingAdep, false, true, true)) {
1091  ddgCycle = ddg_->earliestCycle(
1092  moveNode);
1093  }
1094  }
1095  }
1096  }
1097 #endif
1098  }
1099  }
1100  }
1101  }
1102 
1103  // if it's a conditional move then we have to be sure that the guard
1104  // is defined before executing the move.
1105  // this is already handled by DDGs earliestCycle, except cases
1106  // where the guard is defined in a previous BB.
1107  // So this prevents scheduling unconditional moves at the beginning
1108  // of a BB.
1109 
1110  if (!moveNode.move().isUnconditional()) {
1111  ddgCycle = std::max(ddgCycle, moveNode.guardLatency()-1);
1112 
1113  if (allowPredicationAndRenaming) {
1114  // try to get rid of the guard if it gives earlier earliestcycle.
1115  if (ddg_->earliestCycle(moveNode, ii, false, false, true)
1116  < ddgCycle) {
1117  bool guardNeeded = false;
1118  if (moveNode.move().destination().isGPR() ||
1119  moveNode.move().isControlFlowMove()) {
1120  guardNeeded = true;
1121  } else {
1122  // this would be needed only for trigger,
1123  // but trigger may change during scheduling.
1124  // so lets just limit all operands, it seems
1125  // this does not make the schedule any worse.
1126  if (moveNode.isDestinationOperation()) {
1127  const Operation& o =
1128  moveNode.destinationOperation().operation();
1129  if (o.writesMemory() || o.hasSideEffects() ||
1130  o.affectsCount() != 0) {
1131  guardNeeded = true;
1132  }
1133  }
1134  }
1135  if (!guardNeeded) {
1136  moveNode.move().setGuard(NULL);
1137  ddg_->removeIncomingGuardEdges(moveNode);
1138  ddgCycle = ddg_->earliestCycle(moveNode, ii);
1139  assert(moveNode.move().isUnconditional());
1140  }
1141  }
1142 
1143  if (ii == 0 && tryToOptimizeWaw(moveNode)) {
1144  ddgCycle = std::max(ddg_->earliestCycle(moveNode, ii),
1145  moveNode.guardLatency()-1);
1146  }
1147 
1148  }
1149  }
1150 
1151  // Earliest cycle from which to start, could depend on result ready
1152  // for result moves.
1153  int minCycle = std::max(std::max(earliestCycle, ddgCycle), minCycle_);
1154  minCycle = std::max(minCycle, sourceReadyCycle);
1155 
1156  // RM hasConnection takes MoveNodeSet, however is called only for one
1157  // moveNode here.
1158  MoveNodeSet tempSet;
1159  tempSet.addMoveNode(moveNode);
1160  if (moveNode.isSourceConstant() &&
1161  !moveNode.move().hasAnnotations(
1163  // If source is constant and node does not have annotation already,
1164  // we add it if constant can not be transported so IU broker and
1165  // OutputPSocket brokers will add Immediate
1166  // Example : 999999 -> integer0.2
1167  if (!rm_->canTransportImmediate(moveNode)){
1168  TTAProgram::ProgramAnnotation annotation(
1170  moveNode.move().setAnnotation(annotation);
1171 
1172  } else if (!moveNode.isDestinationOperation() &&
1173  rm_->earliestCycle(rm_->largestCycle() + 1, moveNode) == -1
1174  && rm_->initiationInterval() == 0) {
1175 
1176  // If source is constant and node does not have annotation already,
1177  // we add it if node has no connection, so IU broker and
1178  // OutputPSocket brokers will add Immediate
1179  // Example: 27 -> integer0.2
1180  // With bus capable of transporting 27 as short immediate but
1181  // no connection from that bus to integer0 unit
1182  // this may mess up modulo scheduling.
1183  // TODO: do this more cleanly, this is a kludge.
1184  TTAProgram::ProgramAnnotation annotation(
1186  moveNode.move().setAnnotation(annotation);
1187  }
1188  }
1189  // annotate the return move otherwise it might get undetected in the
1190  // simulator after the short to long immediate conversion and thus
1191  // stopping simulation automatically might not work
1192  if (moveNode.isSourceConstant() &&
1193  moveNode.move().isReturn() &&
1194  !rm_->canTransportImmediate(moveNode)) {
1195  TTAProgram::ProgramAnnotation annotation(
1197  moveNode.move().setAnnotation(annotation);
1198  }
1199 
1200  minCycle = rm_->earliestCycle(minCycle, moveNode);
1201  if (minCycle == -1 || minCycle == INT_MAX) {
1202  if (moveNode.isSourceConstant() &&
1203  !moveNode.isDestinationOperation() &&
1204  moveNode.move().hasAnnotations(
1206  // If earliest cycle returns -1 and source is constant and moveNode
1207  // needs long immediate there is most likely missing long immediate
1208  // unit
1209  std::string msg = "Assignment of MoveNode " + moveNode.toString();
1210  msg += " failed! Most likely missing Long Immediate Unit";
1211  msg += " or Instruction Template!";
1212  if (rm_->initiationInterval() == 0) {
1213  ddg_->writeToDotFile("illegalmach.dot");
1214  throw IllegalMachine(
1215  __FILE__, __LINE__, __func__, msg);
1216  } else {
1218  std::string("ii_") +
1220  std::string("_dag.dot"));
1221 
1223  throw ModuleRunTimeError(
1224  __FILE__, __LINE__, __func__, msg);
1225  }
1226  }
1227  return;
1228  }
1229 
1230  int latestDDG = ddg_->latestCycle(moveNode, ii);
1231 
1232  if (ii != 0 && (minCycle > latestDDG)) {
1233 
1234  if (ddg_->latestCycle(moveNode, ii, true) > latestDDG) {
1235 
1236  if (renamer_ != NULL && allowPredicationAndRenaming) {
1237  // todo: do also otherway
1238  if (renamer_->renameSourceRegister(moveNode,true, true, true)) {
1239  latestDDG = ddg_->latestCycle(moveNode, ii);
1240  }
1241  }
1242  }
1243  }
1244 
1245  // test again after renaming?
1246 
1247  if (ii != 0 && (minCycle > latestDDG)) {
1248 
1249  // if we pre-scheduled jump, unschedule it and try to schdule
1250  // the node again.
1251  if (jumpNode_ != NULL) {
1252  ddg_->writeToDotFile("unschedJump.dot");
1254  jumpNode_ = NULL;
1255  scheduleMove(moveNode, earliestCycle, allowPredicationAndRenaming);
1256  return;
1257  }
1258 
1260  std::string("ii_") + Conversion::toString(ii) +
1261  std::string("_dag.dot"));
1262 
1264  throw ModuleRunTimeError(
1265  __FILE__, __LINE__, __func__, "Schedule failed try bigger ii.");
1266  }
1267 
1268  try {
1269  rm_->assign(minCycle, moveNode);
1270  } catch (const Exception& e) {
1271  throw ModuleRunTimeError(
1272  __FILE__, __LINE__, __func__, e.errorMessageStack());
1273  }
1274 
1275  if (!moveNode.isScheduled()) {
1276  throw ModuleRunTimeError(
1277  __FILE__, __LINE__, __func__,
1278  (boost::format("Assignment of MoveNode '%s' failed!")
1279  % moveNode.toString()).str());
1280  }
1281  assert(moveNode.cycle() >= minCycle_);
1282 }

References __func__, MoveNodeSet::addMoveNode(), Operation::affectsCount(), TTAProgram::ProgramAnnotation::ANN_REQUIRES_LIMM, TTAProgram::ProgramAnnotation::ANN_STACKFRAME_PROCEDURE_RETURN, assert, SimpleResourceManager::assign(), SimpleResourceManager::canTransportImmediate(), TTAMachine::Machine::controlUnit(), MoveNode::cycle(), ddg_, TTAMachine::ControlUnit::delaySlots(), TTAProgram::Move::destination(), MoveNode::destinationOperation(), SimpleResourceManager::earliestCycle(), DataDependenceGraph::earliestCycle(), MoveNode::earliestResultReadCycle(), Exception::errorMessageStack(), DataDependenceGraph::findLimitingAntidependenceSource(), DataDependenceGraph::findLoopLimitAndIndex(), MoveNode::guardLatency(), TTAProgram::AnnotatedInstructionElement::hasAnnotations(), Operation::hasSideEffects(), SimpleResourceManager::initiationInterval(), TTAProgram::Move::isControlFlowMove(), MoveNode::isDestinationOperation(), TTAProgram::Terminal::isGPR(), TTAProgram::Move::isReturn(), MoveNode::isScheduled(), MoveNode::isSourceConstant(), MoveNode::isSourceOperation(), TTAProgram::Move::isUnconditional(), jumpNode_, SimpleResourceManager::largestCycle(), DataDependenceGraph::largestCycle(), DataDependenceGraph::latestCycle(), minCycle_, MoveNode::move(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), ProgramOperation::operation(), DataDependenceGraph::removeIncomingGuardEdges(), RegisterRenamer::renameDestinationRegister(), renamer_, RegisterRenamer::renameSourceRegister(), rm_, DataDependenceGraph::scheduledNodeCount(), TTAProgram::AnnotatedInstructionElement::setAnnotation(), TTAProgram::Move::setGuard(), TTAProgram::Move::setSource(), TTAProgram::Move::source(), MoveNode::sourceOperation(), targetMachine_, Conversion::toString(), MoveNode::toString(), tripCount_, tryToOptimizeWaw(), unschedule(), unscheduleAllNodes(), DataDependenceGraph::unscheduledMoves(), SimValue::unsignedValue(), TTAProgram::TerminalImmediate::value(), SimValue::width(), Operation::writesMemory(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by handleDDG(), handleLoopDDG(), handleRemovedResultMoves(), scheduleInputOperandTempMoves(), scheduleOperandWrites(), scheduleResultReads(), scheduleResultReadTempMoves(), scheduleRRMove(), scheduleRRTempMoves(), and tryToOptimizeWaw().

◆ scheduleOperandWrites()

int BasicBlockScheduler::scheduleOperandWrites ( int &  cycle,
MoveNodeGroup moves 
)
protected

Schedules operand moves of an operation execution.

Assumes the given MoveNodeGroup contains all moves in the operation execution. Also assumes that all inputs to the MoveNodeGroup have been scheduled. Exception to this are the possible temporary register copies inserted before the operand move due to missing connectivity. If found, the temp moves are scheduled atomically with the operand move. Assumes top-down scheduling.

Parameters
cycleEarliest cycle for starting scheduling of operands. This parameter is modified to the highest cycle one should try next in case scheduling starting from the given cycle failed.
movesMoves of the operation execution.
Returns
The cycle the earliest of the operands got scheduled

Definition at line 633 of file BasicBlockScheduler.cc.

633  {
634  const int MAX_OPERAND_CYCLE_DIFFERENCE = 15;
635 
636  const int MAX_OPERATION_START_BEFORE_EARLIEST_READ = 50;
637 
638  int lastOperandCycle = 0;
639  int earliestScheduledOperand = INT_MAX;
640  int startCycle = 0;
641  MoveNode* trigger = NULL;
642  MoveNode* firstToSchedule = NULL;
643 
644  // find the movenode which has highest DDG->earliestCycle and limit
645  // the starting cycle of all operands close to that.
646  // this should prevent trying to schedule immediate writes very early
647  // and having lots of retries until the cycle has risen to the level of
648  // other moves.
649  // this might make SCHEDULING_WINDOW or SimpleBrokerDirector unnecessary /
650  // allow groving it much smaller without scheduler slowdown.
651  for (int i = 0; i < moves.nodeCount(); i++) {
652  int limit = 0;
653  if (moves.node(i).isDestinationOperation()) {
654  limit = ddg_->earliestCycle(
655  moves.node(i), rm_->initiationInterval()) -
656  MAX_OPERAND_CYCLE_DIFFERENCE;
657  } else if (moves.node(i).isSourceOperation()) {
658  limit = ddg_->earliestCycle(
659  moves.node(i), rm_->initiationInterval()) -
660  MAX_OPERATION_START_BEFORE_EARLIEST_READ;
661  } else {
662  continue;
663  }
664  if (limit < 0) {
665  limit = 0;
666  }
667  if (limit > cycle) {
668  cycle = limit;
669  }
670  }
671 
672  // Find and schedule moveNode which has highest "earliest Cycle"
673  // other moveNodes could be scheduled in earlier cycle but this
674  // makes sure there will be no problems with operands overwritting
675  // and assignment failures. At least it reduced a count of such.
676  // Also find smallest of all earliest cycles,
677  // make no sense to start from 0
678  for (int i = 0; i < moves.nodeCount(); i++) {
679  if (!moves.node(i).isDestinationOperation()) {
680  continue;
681  }
682 
683  // Temporary moves needs to be scheduled so DDG can find
684  // earliest cycle
685  // TODO: this should also have cycle limit?
686  scheduleInputOperandTempMoves(moves.node(i), moves.node(i));
687  int earliestDDG = ddg_->earliestCycle(
688  moves.node(i), rm_->initiationInterval());
689 
690  if (earliestDDG == INT_MAX) {
691  ddg_->writeToDotFile("failed_bb.dot");
693  throw InvalidData(
694  __FILE__, __LINE__, __func__,
695  (boost::format("InputTempMoves failed to schedule "
696  "successfully for '%s' ") % moves.node(i).toString()).str());
697  }
698 
699  // passed argument could be larger than what DDG thinks is earliest
700  earliestDDG = std::max(earliestDDG, cycle);
701  int earliest = rm_->earliestCycle(earliestDDG, moves.node(i));
702  if (earliest == -1) {
704  continue;
705  }
706  if (earliest >= startCycle) {
707  // Find first moveNode that will be scheduled
708  startCycle = earliest;
709  firstToSchedule = &moves.node(i);
710  }
712 
713  // Find also smallest of earliestCycles
714  cycle = std::min(cycle, earliest);
715  }
716 
717  if (firstToSchedule != NULL) {
718  // start cycle could be null if there was problem scheduling
719  // all input temp operands
720  scheduleInputOperandTempMoves(*firstToSchedule, *firstToSchedule);
721  // earliestCycle gave us the startCycle so this must pass
722  scheduleMove(*firstToSchedule, startCycle, true);
723  if (!firstToSchedule->isScheduled()) {
725  std::string("ii_") +
727  std::string("_dag.dot"));
728 
730  throw ModuleRunTimeError(
731  __FILE__, __LINE__, __func__,
732  (boost::format("Move '%s' failed to schedule")
733  % firstToSchedule->toString()).str());
734  }
735  startCycle = firstToSchedule->cycle();
736  if (firstToSchedule->move().destination().isTriggering()) {
737  trigger = firstToSchedule;
738  } else {
739  lastOperandCycle = std::max(lastOperandCycle, startCycle);
740  }
741  } else {
743  std::string("ii_") +
745  std::string("_dag.dot"));
746 
748  throw ModuleRunTimeError(
749  __FILE__, __LINE__, __func__,
750  (boost::format(
751  "Unable to schedule '%s' is there enough resources?")
752  % moves.toString()).str());
753  }
754 
755  // try to schedule all input moveNodes, except trigger
756  for (int moveIndex = 0; moveIndex < moves.nodeCount(); ++moveIndex) {
757  MoveNode& moveNode = moves.node(moveIndex);
758  // skip the result reads
759  if (!moveNode.isDestinationOperation()) {
760  continue;
761  }
762 
763  if (moveNode.isScheduled()) {
764  earliestScheduledOperand =
765  std::min(earliestScheduledOperand, moveNode.cycle());
766  if (moveNode.move().destination().isTriggering()) {
767  trigger = &moveNode;
768  }
769  continue;
770  }
771 
772  // in case the operand move requires register copies due to
773  // missing connectivity, schedule them first
774  scheduleInputOperandTempMoves(moveNode, moveNode);
775  scheduleMove(moveNode, cycle, true);
776 
777  if (moveNode.isScheduled()) {
778  earliestScheduledOperand =
779  std::min(earliestScheduledOperand, moveNode.cycle());
780  if (moveNode.move().destination().isTriggering()) {
781  trigger = &moveNode;
782  earliestScheduledOperand =
783  std::min(earliestScheduledOperand, moveNode.cycle());
784  } else {
785  lastOperandCycle =
786  std::max(lastOperandCycle, moveNode.cycle());
787  }
788  } else {
789  // Movenode scheduling failed.
791  // try to unschedule trigger and then schedule this operand.
792  if (trigger != NULL && trigger->isScheduled()) {
793  unschedule(*trigger);
795  scheduleInputOperandTempMoves(moveNode, moveNode);
796  scheduleMove(moveNode, cycle, true);
797  if (!moveNode.isScheduled()) {
798  // if still failed return -1
800  // but make sure high-level loop advances some more cycles
801  if (earliestScheduledOperand != INT_MAX) {
802  cycle = earliestScheduledOperand;
803  }
804  return -1;
805  }
806  earliestScheduledOperand =
807  std::min(earliestScheduledOperand, moveNode.cycle());
808  lastOperandCycle =
809  std::max(lastOperandCycle, moveNode.cycle());
810  } else {
811  // failed even though no trigger scheduled.
812  // but make sure high-level loop advances some more cycles
813  if (earliestScheduledOperand != INT_MAX) {
814  cycle = earliestScheduledOperand;
815  }
816  return -1;
817  }
818  }
819  }
820 
821  // if trigger unscheduled, schedule it again.
822  assert(trigger != NULL);
823  if (!trigger->isScheduled()) {
824  scheduleInputOperandTempMoves(*trigger, *trigger);
825  scheduleMove(*trigger, lastOperandCycle, true);
826 
827  if (!trigger->isScheduled()) {
828  // trigger scheduling failed.
830  return -1;
831  }
832  earliestScheduledOperand =
833  std::min(earliestScheduledOperand, trigger->cycle());
834  }
835 
836  return earliestScheduledOperand;
837 }

References __func__, assert, MoveNode::cycle(), ddg_, TTAProgram::Move::destination(), SimpleResourceManager::earliestCycle(), DataDependenceGraph::earliestCycle(), SimpleResourceManager::initiationInterval(), MoveNode::isDestinationOperation(), MoveNode::isScheduled(), MoveNode::isSourceOperation(), TTAProgram::Terminal::isTriggering(), MoveNode::move(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), rm_, scheduleInputOperandTempMoves(), scheduleMove(), Conversion::toString(), MoveNodeGroup::toString(), MoveNode::toString(), unschedule(), unscheduleAllNodes(), unscheduleInputOperandTempMoves(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by scheduleOperation().

Here is the call graph for this function:

◆ scheduleOperation()

void BasicBlockScheduler::scheduleOperation ( MoveNodeGroup moves)
protected

Schedules moves in a single operation execution.

Assumes the given MoveNodeGroup contains all moves in the operation execution. Also assumes that all inputs to the MoveNodeGroup have been scheduled.

Parameters
movesMoves of the operation execution.

Definition at line 401 of file BasicBlockScheduler.cc.

401  {
402  ProgramOperation& po =
403  (moves.node(0).isSourceOperation())?
404  (moves.node(0).sourceOperation()):
405  (moves.node(0).destinationOperation());
406 
407  // may switch operands of commutative operations. Do it before
408  // regcopyadder because it's easier here.
409  // cooperation with regcopyadder might make it perform better though.
410  tryToSwitchInputs(po);
411 
412 #ifdef DEBUG_REG_COPY_ADDER
413  ddg_->setCycleGrouping(true);
415  (boost::format("%s_before_ddg.dot") % ddg_->name()).str());
416 #endif
417 
418  RegisterCopyAdder regCopyAdder(
421  regCopyAdder.addMinimumRegisterCopies(po, *targetMachine_, ddg_);
422 #ifdef DEBUG_REG_COPY_ADDER
423  const int tempsAdded = copies.count_;
424 #endif
425 
426 #ifdef DEBUG_REG_COPY_ADDER
427  if (tempsAdded > 0) {
429  (boost::format("%s_after_regcopy_ddg.dot") % ddg_->name()).str());
430  }
431  ddg_->sanityCheck();
432 #endif
433 
434  MoveNodeSet tempSet;
435  for (int i = 0; i < moves.nodeCount(); i++) {
436  // MoveNodeGroup relates to DDG so we copy it to
437  // a simpler MoveNodeSet container
438  tempSet.addMoveNode(moves.node(i));
439  }
440 
441  bool operandsFailed = true;
442  bool resultsFailed = true;
443  int operandsStartCycle = 0;
444 
445  int maxFromRm = rm_->largestCycle();
446 
447  // Magic number defining how many times we should try to schedule
448  // operands and results. Should not be needed in final version of
449  // scheduler
450  const int retryCount = 20;
451  int minOperand = operandsStartCycle;
452 
453  bool tryBypassing = softwareBypasser_ != NULL;
454  bool bypassTrigger = true;
455 
456  while ((operandsFailed || resultsFailed) &&
457  operandsStartCycle < maxFromRm + retryCount) {
458 
459  minOperand = scheduleOperandWrites(operandsStartCycle, moves);
460  if (minOperand != -1) {
461  operandsFailed = false;
462  } else {
463  // Scheduling some operand failed, unschedule and try later cycle
464  for (int i = 0; i < moves.nodeCount(); i++){
465  MoveNode& moveNode = moves.node(i);
466  if (moveNode.isScheduled() &&
467  moveNode.isDestinationOperation()) {
468  unschedule(moveNode);
470  }
471  }
472  operandsFailed = true;
473  operandsStartCycle++;
474  continue;
475  }
476 
477  regCopyAdder.operandsScheduled(copies, *ddg_);
478 
479  int bypassedMoves = -1;
480  if (tryBypassing) {
481  bypassedMoves = softwareBypasser_->bypass(
482  moves, *ddg_, *rm_, bypassTrigger);
483  if (bypassedMoves == -1){
484  // bypassing failed try again without attempt to bypass
485  // this restores the original schedule of operands
486  // and disable bypassing
487  operandsFailed = true;
488  if (bypassTrigger == false) {
489  tryBypassing = false;
490  } else {
491  bypassTrigger = false;
492  }
494  continue;
495  }
496  // bypass was success
497  }
498 
499  // TODO: disabled because may cause fail if rescheduled
500  // to different bus.
501 // tryToDelayOperands(moves);
502 
503  if (scheduleResultReads(moves)) {
504  resultsFailed = false;
505  // Results were scheduled, we are not going to change schedule
506  // of this program operation. Lets check if some of the
507  // bypassed operands did not produce dead result moves
508  if (tryBypassing) {
509  try {
510  std::set<std::pair<TTAProgram::Move*, int> >
511  removedMoves;
513  moves, *ddg_, *rm_, removedMoves);
514  handleRemovedResultMoves(removedMoves);
515  } catch (const Exception& e) {
516  throw ModuleRunTimeError(
517  __FILE__, __LINE__, __func__, e.errorMessageStack());
518  }
519  }
520  } else {
521  // Scheduling results failed, most likely due to large distance
522  // between trigger and earliest result cycle
523  // Some other operation is overwritting result on same FU
524  for (int i = 0; i < moves.nodeCount(); i++){
525  MoveNode& moveNode = moves.node(i);
526  if (moveNode.isScheduled()) {
527  // Operands were scheduled successfully but result can
528  // not be, we unschedule everything
529  unschedule(moveNode);
530  if (moveNode.isDestinationOperation()) {
532  }
533  if (moveNode.isSourceOperation()) {
535  }
536  }
537  }
538  resultsFailed = true;
539  // If some operands were bypassed, we need to remove bypassing
540  if (tryBypassing) {
542  tryBypassing = false;
543  continue;
544  }
545  // We will try to schedule operands in later cycle
546  // taking larger strides
547  operandsStartCycle++;
548  minOperand++;
549  operandsStartCycle = std::max(minOperand, operandsStartCycle);
550  }
551  }
552  // This fails if there is "timeout" on retry count.
553  // Should not be needed in final version.
554 
555  if (operandsFailed) {
557  std::string("ii_") +
559  std::string("_dag.dot"));
560 
562  throw ModuleRunTimeError(
563  __FILE__, __LINE__, __func__,
564  "Operands scheduling failed for \'" + moves.toString());
565  }
566  if (resultsFailed) {
568  std::string("ii_") +
570  std::string("_dag.dot"));
571 
573  throw ModuleRunTimeError(
574  __FILE__, __LINE__, __func__,
575  "Results scheduling failed for \'" + moves.toString());
576  }
577 
578  if (options_ != NULL &&
580  (resultsFailed || operandsFailed)) {
581 
582  //static int failedCounter = 0;
583  if (options_->dumpDDGsDot()) {
584  ddgSnapshot(*ddg_, std::string("2_failed.dot"),
586  } else {
587  ddgSnapshot(*ddg_, std::string("2_failed.xml"),
589  }
590 
592  throw ModuleRunTimeError(
593  __FILE__, __LINE__, __func__,
594  (boost::format("Bad BB %s") % ddg_->name()).str());
595  }
596 
597  regCopyAdder.resultsScheduled(copies, *ddg_);
598 
599 #ifdef DEBUG_REG_COPY_ADDER
600  if (tempsAdded > 0) {
602  (boost::format("%s_after_scheduler_ddg.dot") %
603  ddg_->name()).str());
605  << "(operation fix #" << ddg_->name() << ")" << std::endl
606  << std::endl;
607 
608  ++graphCount;
609  }
610 #endif
611 }

References __func__, RegisterCopyAdder::addMinimumRegisterCopies(), MoveNodeSet::addMoveNode(), SoftwareBypasser::bypass(), RegisterCopyAdder::AddedRegisterCopies::count_, ddg_, ddgSnapshot(), MoveNode::destinationOperation(), DataDependenceGraph::DUMP_DOT, DataDependenceGraph::DUMP_XML, LLVMTCECmdLineOptions::dumpDDGsDot(), Exception::errorMessageStack(), handleRemovedResultMoves(), SimpleResourceManager::initiationInterval(), SchedulerPass::interPassData(), MoveNode::isDestinationOperation(), MoveNode::isScheduled(), MoveNode::isSourceOperation(), SimpleResourceManager::largestCycle(), Application::logStream(), BoostGraph< GraphNode, GraphEdge >::name(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), RegisterCopyAdder::operandsScheduled(), options_, SoftwareBypasser::removeBypass(), SoftwareBypasser::removeDeadResults(), RegisterCopyAdder::resultsScheduled(), rm_, DataDependenceGraph::sanityCheck(), scheduleOperandWrites(), scheduleResultReads(), selector_, DataDependenceGraph::setCycleGrouping(), softwareBypasser_, MoveNode::sourceOperation(), targetMachine_, Conversion::toString(), MoveNodeGroup::toString(), tryToSwitchInputs(), unschedule(), unscheduleAllNodes(), unscheduleInputOperandTempMoves(), unscheduleResultReadTempMoves(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by handleDDG(), and handleLoopDDG().

Here is the call graph for this function:

◆ scheduleResultReads()

bool BasicBlockScheduler::scheduleResultReads ( MoveNodeGroup moves)
protected

Schedules the result read moves of an operation execution.

Assumes the given MoveNodeGroup contains all moves in the operation execution. Also assumes that all operand moves have been scheduled.

Parameters
movesMoves of the operation execution.

Definition at line 847 of file BasicBlockScheduler.cc.

847  {
848  int tempRegLimitCycle = 0;
849 
850  for (int moveIndex = 0; moveIndex < moves.nodeCount(); ++moveIndex) {
851  MoveNode& moveNode = moves.node(moveIndex);
852 
853  if (!moveNode.isScheduled()) {
854  if (!moveNode.isSourceOperation()) {
855  throw InvalidData(
856  __FILE__, __LINE__, __func__,
857  (boost::format("Move to schedule '%s' is not "
858  "result move!") % moveNode.toString()).str());
859  }
860  if (succeedingTempMove(moveNode) != NULL) {
861 
862  MoveNode* lastRead =
864  moveNode.move().destination().registerFile(),
865  moveNode.move().destination().index());
866  if (lastRead != NULL) {
867  tempRegLimitCycle = lastRead->cycle();
868  }
869  }
870 
871  scheduleMove(moveNode, tempRegLimitCycle, true);
872  if (!moveNode.isScheduled()) {
873  // Result can not be scheduled even when operands were,
874  // usually caused by operands too early (data dependencies
875  // ok) and result forced to be scheduled much later
876  // because of data dependencies (WA{R,W} dependence with
877  // target register in most cases)
878  return false;
879  }
880  scheduleResultReadTempMoves(moveNode, moveNode, 0);
881  if (!moveNode.isScheduled()) {
882  throw InvalidData(
883  __FILE__, __LINE__, __func__,
884  (boost::format("Move '%s' did not get scheduled!")
885  % moveNode.toString()).str());
886  }
887  }
888  }
889  return true;
890 }

References __func__, MoveNode::cycle(), ddg_, TTAProgram::Move::destination(), TTAProgram::Terminal::index(), MoveNode::isScheduled(), MoveNode::isSourceOperation(), DataDependenceGraph::lastScheduledRegisterRead(), MoveNode::move(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), TTAProgram::Terminal::registerFile(), scheduleMove(), scheduleResultReadTempMoves(), succeedingTempMove(), and MoveNode::toString().

Referenced by scheduleOperation().

Here is the call graph for this function:

◆ scheduleResultReadTempMoves()

void BasicBlockScheduler::scheduleResultReadTempMoves ( MoveNode resultMove,
MoveNode resultRead,
int  lastUse 
)
protected

Schedules the (possible) temporary register copy moves (due to missing connectivity) succeeding the given result read move.

The function recursively goes through all the temporary moves added to the given input move.

Parameters
resultMoveA temp move whose successor has to be scheduled.
resultReadThe original move of which temp moves to schedule.
lastUseRecursive function parameter, it should be set as 0 for the first function call.

Definition at line 1442 of file BasicBlockScheduler.cc.

1443  {
1444  /* Because temporary register moves do not have WaR/WaW dependency edges
1445  between the other possible uses of the same temp register in
1446  the same operation, we have to limit the scheduling of the new
1447  temp reg move to the last use of the same temp register so
1448  we don't overwrite the temp registers of the other operands. */
1449 
1450 
1451  // find all unscheduled succeeding moves of the result read move
1452  // there should be only only one with the only dependence edge (RaW) to
1453  // the result move
1454 
1455  MoveNode* tempMove1 = succeedingTempMove(resultMove);
1456  if (tempMove1 == NULL)
1457  return; // no temp moves found
1458 
1459  MoveNode* tempMove2 = succeedingTempMove(*tempMove1);
1460  if (tempMove2 != NULL) {
1461  MoveNode* lastRead =
1463  tempMove1->move().destination().registerFile(),
1464  tempMove1->move().destination().index());
1465  if (lastRead != NULL)
1466  lastUse = lastRead->cycle();
1467  }
1468 
1469  scheduleMove(*tempMove1, lastUse, true);
1470  assert(tempMove1->isScheduled());
1471  scheduledTempMoves_[&resultRead].insert(tempMove1);
1472 
1473  // the temp move should have maximum of one unscheduled
1474  // succeeding additional reg to reg copy (in case of two temp reg copies),
1475  // schedule it also if found
1476  scheduleResultReadTempMoves(*tempMove1, resultRead, lastUse+1);
1477 }

References assert, MoveNode::cycle(), ddg_, TTAProgram::Move::destination(), TTAProgram::Terminal::index(), MoveNode::isScheduled(), DataDependenceGraph::lastScheduledRegisterRead(), MoveNode::move(), TTAProgram::Terminal::registerFile(), scheduledTempMoves_, scheduleMove(), and succeedingTempMove().

Referenced by scheduleResultReads(), and scheduleRRTempMoves().

Here is the call graph for this function:

◆ scheduleRRMove()

void BasicBlockScheduler::scheduleRRMove ( MoveNode moveNode)
protected

Schedules moves in a single operation execution.

Assumes the given MoveNodeGroup contains all moves in the operation execution. Also assumes that all inputs to the MoveNodeGroup have been scheduled.

Parameters
moveNodeR-R Move to schedule.

Definition at line 902 of file BasicBlockScheduler.cc.

902  {
903 #ifdef DEBUG_REG_COPY_ADDER
904  ddg_->setCycleGrouping(true);
906  (boost::format("%s_before_ddg.dot") % ddg_->name()).str());
907 #endif
908 
909  RegisterCopyAdder regCopyAdder(
911 
912 #ifdef DEBUG_REG_COPY_ADDER
913  const int tempsAdded =
914 #endif
915 
916  regCopyAdder.addRegisterCopiesToRRMove(moveNode, ddg_)
917 #ifdef DEBUG_REG_COPY_ADDER
918  .count_
919 #endif
920  ;
921 #ifdef DEBUG_REG_COPY_ADDER
922  if (tempsAdded > 0) {
924  (boost::format("%s_after_regcopy_ddg.dot") % ddg_->name()).str());
925  }
926  ddg_->sanityCheck();
927 #endif
928 
929  scheduleMove(moveNode, 0, true);
930  scheduleRRTempMoves(moveNode, moveNode, 0); //Fabio: 0 or more?!?
931 }

References RegisterCopyAdder::addRegisterCopiesToRRMove(), RegisterCopyAdder::AddedRegisterCopies::count_, ddg_, SchedulerPass::interPassData(), BoostGraph< GraphNode, GraphEdge >::name(), rm_, DataDependenceGraph::sanityCheck(), scheduleMove(), scheduleRRTempMoves(), selector_, DataDependenceGraph::setCycleGrouping(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by handleDDG(), and handleLoopDDG().

Here is the call graph for this function:

◆ scheduleRRTempMoves()

void BasicBlockScheduler::scheduleRRTempMoves ( MoveNode regToRegMove,
MoveNode firstMove,
int  lastUse 
)
protected

Schedules the (possible) temporary register copy moves (due to missing connectivity) succeeding the given RR move.

The function recursively goes through all the temporary moves added to the given RR move.

Parameters
regToRegMoveA temp move whose successor has to be scheduled.
firstMoveThe original move of which temp moves to schedule.
lastUseRecursive function parameter, it should be set as 0 for the first function call.

Definition at line 1297 of file BasicBlockScheduler.cc.

1298  {
1299  /* Because temporary register moves do not have WaR/WaW dependency edges
1300  between the other possible uses of the same temp register in
1301  the same operation, we have to limit the scheduling of the new
1302  temp reg move to the last use of the same temp register so
1303  we don't overwrite the temp registers of the other operands. */
1304 
1305  // find all unscheduled succeeding moves of the result read move
1306  // there should be only only one with the only dependence edge (RaW) to
1307  // the result move
1308 
1309  MoveNode* tempMove1 = succeedingTempMove(regToRegMove);
1310  if (tempMove1 == NULL)
1311  return; // no temp moves found
1312 
1313  MoveNode* tempMove2 = succeedingTempMove(*tempMove1);
1314  if (tempMove2 != NULL) {
1315  MoveNode* lastRead =
1317  tempMove1->move().destination().registerFile(),
1318  tempMove1->move().destination().index());
1319  if (lastRead != NULL)
1320  lastUse = lastRead->cycle();
1321  }
1322 
1323  scheduleMove(*tempMove1, lastUse, true);
1324  assert(tempMove1->isScheduled());
1325  scheduledTempMoves_[&firstMove].insert(tempMove1);
1326 
1327  // the temp move should have maximum of one unscheduled
1328  // succeeding additional reg to reg copy (in case of two temp reg copies),
1329  // schedule it also if found
1330  scheduleResultReadTempMoves(*tempMove1, firstMove, lastUse+1);
1331 }

References assert, MoveNode::cycle(), ddg_, TTAProgram::Move::destination(), TTAProgram::Terminal::index(), MoveNode::isScheduled(), DataDependenceGraph::lastScheduledRegisterRead(), MoveNode::move(), TTAProgram::Terminal::registerFile(), scheduledTempMoves_, scheduleMove(), scheduleResultReadTempMoves(), and succeedingTempMove().

Referenced by scheduleRRMove().

Here is the call graph for this function:

◆ shortDescription()

std::string BasicBlockScheduler::shortDescription ( ) const
virtual

A short description of the pass, usually the optimization name, such as "basic block scheduler".

Returns
The description as a string.

Implements SchedulerPass.

Reimplemented in BUBasicBlockScheduler.

Definition at line 1574 of file BasicBlockScheduler.cc.

1574  {
1575  return "Instruction scheduler with a basic block scope.";
1576 }

◆ succeedingTempMove()

MoveNode * BasicBlockScheduler::succeedingTempMove ( MoveNode current)
protected

Finds the temp move succeeding the given movenode.

If it does not have one , returns null.

Parameters
currentMoveNode whose tempmoves we are searching
Returns
tempMove succeeding given node, or null if does not exist.

Definition at line 1410 of file BasicBlockScheduler.cc.

1410  {
1411 
1412  DataDependenceGraph::NodeSet succ = ddg_->successors(current);
1413  MoveNode* result = NULL;
1414  for (DataDependenceGraph::NodeSet::iterator i = succ.begin();
1415  i != succ.end(); ++i) {
1416  MoveNode& m = **i;
1417  if (m.isScheduled() ||
1418  !m.move().hasAnnotations(
1420  continue;
1421 
1422  assert(result == NULL &&
1423  "Multiple candidates for the temp move of result read.");
1424  result = &m;
1425  }
1426  return result;
1427 }

References TTAProgram::ProgramAnnotation::ANN_CONNECTIVITY_MOVE, assert, ddg_, TTAProgram::AnnotatedInstructionElement::hasAnnotations(), MoveNode::isScheduled(), MoveNode::move(), and BoostGraph< GraphNode, GraphEdge >::successors().

Referenced by BUBasicBlockScheduler::bypassNode(), scheduleResultReads(), BUBasicBlockScheduler::scheduleResultReads(), BUBasicBlockScheduler::scheduleResultReadTempMoves(), scheduleResultReadTempMoves(), scheduleRRTempMoves(), and BUBasicBlockScheduler::scheduleRRTempMoves().

Here is the call graph for this function:

◆ tryToDelayOperands()

void BasicBlockScheduler::tryToDelayOperands ( MoveNodeGroup moves)
protected

Definition at line 2021 of file BasicBlockScheduler.cc.

2021  {
2022 
2023  // try to then push non-triggers back
2024  // to as close as possible to tirggers.
2025  // this frees up the FU to be used fr other operations before
2026  // this operation.
2027  // first search first cycle when this FU is used.
2028 
2029  int ec = INT_MAX;
2030  MoveNode* trigger = NULL;
2031  for (int i = 0; i < moves.nodeCount(); i++) {
2032  MoveNode& moveNode = moves.node(i);
2033  if (!moveNode.isDestinationOperation()) {
2034  continue;
2035  }
2036  if (moveNode.move().isTriggering()) {
2037  trigger = &moveNode;
2038  } else {
2039  int oldCycle = moveNode.cycle();
2040  if (oldCycle < ec) {
2041  ec = oldCycle;
2042  }
2043  }
2044  }
2045 
2046  int triggerCycle = trigger->cycle();
2047 
2048  bool failed = false;
2049  while (ec < triggerCycle && !failed) {
2050  for (int i = 0; i < moves.nodeCount(); i++) {
2051  MoveNode& moveNode = moves.node(i);
2052  if (!moveNode.isDestinationOperation()) {
2053  continue;
2054  }
2055  if (&moveNode != trigger) {
2056  int oldCycle = moveNode.cycle();
2057  if (oldCycle == ec) {
2058  int latest = ddg_->latestCycle(moveNode);
2059  if (latest > oldCycle) {
2060  latest = std::min(latest, triggerCycle);
2061  assert(latest >= ec);
2062  rm_->unassign(moveNode);
2063  int latestrm = rm_->latestCycle(latest, moveNode);
2064  if (latestrm == ec) {
2065  failed = true;
2066  }
2067  assert(latestrm >= ec);
2068  rm_->assign(latestrm, moveNode);
2069  } else {
2070  failed = true;
2071  }
2072  }
2073  }
2074  }
2075  ec = INT_MAX;
2076  // first earliest scheduled operands.
2077  for (int i = 0; i < moves.nodeCount(); i++) {
2078  MoveNode& moveNode = moves.node(i);
2079  if (!moveNode.isDestinationOperation()) {
2080  continue;
2081  }
2082  if (&moveNode != trigger) {
2083  int oldCycle = moveNode.cycle();
2084  if (oldCycle < ec) {
2085  ec = oldCycle;
2086  }
2087  }
2088  }
2089  }
2090 }

References assert, SimpleResourceManager::assign(), MoveNode::cycle(), ddg_, MoveNode::isDestinationOperation(), TTAProgram::Move::isTriggering(), SimpleResourceManager::latestCycle(), DataDependenceGraph::latestCycle(), MoveNode::move(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), rm_, and SimpleResourceManager::unassign().

Here is the call graph for this function:

◆ tryToOptimizeWaw()

bool BasicBlockScheduler::tryToOptimizeWaw ( const MoveNode moveNode)
protected

Tries to get rid of WaW dependence from unconditional to conditional.

if the conditional move's result is overwritten by the cond for all users, make the unconditional move conditional, with opposite guard.

Definition at line 1920 of file BasicBlockScheduler.cc.

1920  {
1921 
1922  if (ddg_->earliestCycle(moveNode, 0 , false, true) >=
1923  ddg_->earliestCycle(moveNode)) {
1924  return false;
1925  }
1926 
1927  MoveNode* wawPred = NULL;
1928  DataDependenceEdge* wawEdge = NULL;
1929 
1930  DataDependenceGraph::EdgeSet inEdges = ddg_->inEdges(moveNode);
1931  for (DataDependenceGraph::EdgeSet::iterator i = inEdges.begin();
1932  i != inEdges.end(); i++) {
1933  DataDependenceEdge* e = *i;
1934 
1937  !e->tailPseudo()) {
1938  if (wawPred == NULL) {
1939  wawPred = &ddg_->tailNode(**i);
1940  wawEdge = e;
1941  } else {
1942  return false;
1943  }
1944  }
1945  }
1946  if (wawPred == NULL) {
1947  return false;
1948  }
1949 
1950  assert(wawPred->isScheduled());
1951  int wawPredCycle = wawPred->cycle();
1952 
1953  if (!wawPred->move().isUnconditional()) {
1954  return false;
1955  }
1956 
1957  DataDependenceGraph::NodeSet gdMoves = ddg_->guardDefMoves(moveNode);
1958  for (DataDependenceGraph::NodeSet::iterator i = gdMoves.begin();
1959  i != gdMoves.end(); i++) {
1960  MoveNode& mn = **i;
1961  assert(mn.isScheduled());
1962  if (mn.cycle() + moveNode.guardLatency() > wawPredCycle) {
1963  return false;
1964  }
1965  }
1966 
1967  // check that no other usage of the data.
1968  DataDependenceGraph::NodeSet consumers = ddg_->regRawSuccessors(*wawPred);
1969  DataDependenceGraph::NodeSet consumers2 = ddg_->regRawSuccessors(moveNode);
1970  for (DataDependenceGraph::NodeSet::iterator i = consumers.begin();
1971  i != consumers.end(); i++) {
1972  MoveNode* mn = *i;
1973  if (consumers2.find(mn) == consumers2.end() &&
1974  (mn->move().isUnconditional() ||
1975  !ddg_->exclusingGuards(*mn, moveNode))) {
1976  return false;
1977  }
1978  }
1979 
1980  unschedule(*wawPred);
1981 
1983  wawPred->move().setGuard(cg.createInverseGuard(moveNode.move().guard()));
1984 
1985  ddg_->copyDepsOver(*wawPred, true, false);
1986 
1987  ddg_->copyIncomingGuardEdges(moveNode, *wawPred);
1988  ddg_->copyOutgoingGuardWarEdges(moveNode, *wawPred);
1989 
1990  ddg_->removeEdge(*wawEdge);
1991 
1992  bool revert = false;
1993 
1994  try {
1995  scheduleMove(*wawPred, wawPredCycle, false);
1996 
1997  if (!wawPred->isScheduled()) {
1998  revert = true;
1999  }
2000  if (wawPred->isScheduled() && wawPred->cycle() > wawPredCycle) {
2001  unschedule(*wawPred);
2002  revert = true;
2003  }
2004  } catch (Exception&e) {
2005  revert = true;
2006  }
2007 
2008  if (revert) {
2009  wawPred->move().setGuard(NULL);
2010  ddg_->removeIncomingGuardEdges(*wawPred);
2011  ddg_->removeOutgoingGuardWarEdges(*wawPred);
2012  scheduleMove(*wawPred, wawPredCycle, false);
2013  ddg_->connectNodes(*wawPred, moveNode, *wawEdge);
2014  return false;
2015  }
2016 
2017  return true;
2018 }

References assert, BoostGraph< GraphNode, GraphEdge >::connectNodes(), DataDependenceGraph::copyDepsOver(), DataDependenceGraph::copyIncomingGuardEdges(), DataDependenceGraph::copyOutgoingGuardWarEdges(), TTAProgram::CodeGenerator::createInverseGuard(), MoveNode::cycle(), ddg_, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), DataDependenceGraph::earliestCycle(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceGraph::exclusingGuards(), TTAProgram::Move::guard(), DataDependenceGraph::guardDefMoves(), MoveNode::guardLatency(), BoostGraph< GraphNode, GraphEdge >::inEdges(), MoveNode::isScheduled(), TTAProgram::Move::isUnconditional(), MoveNode::move(), DataDependenceGraph::regRawSuccessors(), BoostGraph< GraphNode, GraphEdge >::removeEdge(), DataDependenceGraph::removeIncomingGuardEdges(), DataDependenceGraph::removeOutgoingGuardWarEdges(), scheduleMove(), TTAProgram::Move::setGuard(), BoostGraph< GraphNode, GraphEdge >::tailNode(), DataDependenceEdge::tailPseudo(), targetMachine_, and unschedule().

Referenced by scheduleMove().

Here is the call graph for this function:

◆ tryToSwitchInputs()

bool BasicBlockScheduler::tryToSwitchInputs ( ProgramOperation po)
protected

If the operation is commutative, tries to change the operands so that the scheduler can schedule it better.

If the operation is not commutative, does nothing.

Which is better depends lots on the code being compiled and architecture which we are compiling for.

Current implementation tries to make constants triggers, and if there are no constant inputs, try to also change inputs so that last ready operand becomes trigger if it's near, but first ready operand becomes trigger if it's further (allows better bypassing of other operands) This seems to work in practice

Parameters
poprogramoperation whose inputs to switch
Returns
true if changed inputs, false if not.

Definition at line 1734 of file BasicBlockScheduler.cc.

1734  {
1735  const Operation& op = po.operation();
1736  if (op.numberOfInputs() == 2 && op.canSwap(1, 2)) {
1737 
1738  int triggerOperand = getTriggerOperand(op, *targetMachine_);
1739 
1740  if (triggerOperand != 0) {
1741  MoveNode* latest = NULL;
1742  int latestMinCycle = -1;
1743  int firstMinCycle = INT_MAX;
1744 
1745  //check all input moves.
1746  for (int i = 0; i < po.inputMoveCount(); i++) {
1747  MoveNode& node = po.inputMove(i);
1748  // always make constants triggers.
1749  // todo: shoudl do this only with short imms?
1750  if (node.isSourceConstant()) {
1751  int operandIndex =
1752  node.move().destination().operationIndex();
1753  if (operandIndex != triggerOperand) {
1754  po.switchInputs();
1755  return true;
1756  } else {
1757  return false;
1758  }
1759  }
1760 
1761  int minCycle = ddg_->earliestCycle(
1762  node, rm_->initiationInterval(), false, false, true, true);
1763  if (minCycle > latestMinCycle) {
1764  latest = &node;
1765  latestMinCycle = minCycle;
1766  }
1767  if (minCycle < firstMinCycle) {
1768  firstMinCycle = minCycle;
1769  }
1770  }
1771 
1772  int lastOperand = latest->move().destination().operationIndex();
1773 
1774  // don't change if min cycles of first and alst are equal.
1775  if (latestMinCycle == firstMinCycle) {
1776  return false;
1777  }
1778  if (latestMinCycle - firstMinCycle > 1) { // reverse logic if far.
1779  if (lastOperand == triggerOperand) {
1780  po.switchInputs();
1781  return true;
1782  }
1783  } else {
1784  if (lastOperand != triggerOperand) {
1785  po.switchInputs();
1786  return true;
1787  }
1788  }
1789  }
1790  }
1791  return false;
1792 }

References Operation::canSwap(), ddg_, TTAProgram::Move::destination(), DataDependenceGraph::earliestCycle(), getTriggerOperand(), SimpleResourceManager::initiationInterval(), ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), MoveNode::isSourceConstant(), MoveNode::move(), Operation::numberOfInputs(), ProgramOperation::operation(), TTAProgram::Terminal::operationIndex(), rm_, ProgramOperation::switchInputs(), and targetMachine_.

Referenced by scheduleOperation().

Here is the call graph for this function:

◆ unschedule()

void BasicBlockScheduler::unschedule ( MoveNode moveNode)
protected

Unschedules the given move.

Also restores a possible short immediate source in case it was converted to a long immediate register read during scheduling.

Parameters
moveNodeMove to unschedule.

Definition at line 1488 of file BasicBlockScheduler.cc.

1488  {
1489  if (moveNode.isScheduled()) {
1490  rm_->unassign(moveNode);
1491  }
1492 
1493  if (moveNode.move().hasAnnotations(
1495  // If we added annotation during scheduleMove delete it
1496  moveNode.move().removeAnnotations(
1498  }
1499  if (moveNode.isScheduled() || moveNode.isPlaced()) {
1500  throw InvalidData(
1501  __FILE__, __LINE__, __func__,
1502  (boost::format("Unscheduling of move '%s' failed!")
1503  % moveNode.toString()).str());
1504  }
1505 }

References __func__, TTAProgram::ProgramAnnotation::ANN_REQUIRES_LIMM, TTAProgram::AnnotatedInstructionElement::hasAnnotations(), MoveNode::isPlaced(), MoveNode::isScheduled(), MoveNode::move(), TTAProgram::AnnotatedInstructionElement::removeAnnotations(), rm_, MoveNode::toString(), and SimpleResourceManager::unassign().

Referenced by BUBasicBlockScheduler::bypassNode(), handleRemovedResultMoves(), scheduleMove(), scheduleOperandWrites(), BUBasicBlockScheduler::scheduleOperandWrites(), scheduleOperation(), BUBasicBlockScheduler::scheduleOperation(), BUBasicBlockScheduler::scheduleResultReads(), BUBasicBlockScheduler::tryToOptimizeWaw(), tryToOptimizeWaw(), BUBasicBlockScheduler::undoBypass(), unscheduleAllNodes(), BUBasicBlockScheduler::unscheduleAllNodes(), unscheduleInputOperandTempMoves(), and unscheduleResultReadTempMoves().

Here is the call graph for this function:

◆ unscheduleAllNodes()

void BasicBlockScheduler::unscheduleAllNodes ( )
protected

Calls unschedule() for all ddg nodes, which are scheduled.

Definition at line 1511 of file BasicBlockScheduler.cc.

1511  {
1513  for (DataDependenceGraph::NodeSet::iterator i = scheduled.begin();
1514  i != scheduled.end(); ++i) {
1515  if (softwareBypasser_ != NULL) {
1516  softwareBypasser_->removeBypass(**i, *ddg_, *rm_, false);
1517  }
1518  unschedule(**i);
1519  }
1520  if (softwareBypasser_ != NULL) {
1522  }
1523 }

References SoftwareBypasser::clearCaches(), ddg_, SoftwareBypasser::removeBypass(), rm_, DataDependenceGraph::scheduledMoves(), softwareBypasser_, and unschedule().

Referenced by handleDDG(), handleLoopDDG(), scheduleMove(), scheduleOperandWrites(), and scheduleOperation().

Here is the call graph for this function:

◆ unscheduleInputOperandTempMoves()

void BasicBlockScheduler::unscheduleInputOperandTempMoves ( MoveNode operandMove)
protected

Unschedules the (possible) temporary register copy moves (due to missing connectivity) preceeding the given move.

Parameters
operandMoveThe move of which temp moves to unschedule.

Definition at line 1532 of file BasicBlockScheduler.cc.

1532  {
1533 
1534  if (!MapTools::containsKey(scheduledTempMoves_, &operandMove))
1535  return; // nothing to unschedule
1536 
1537  DataDependenceGraph::NodeSet tempMoves = scheduledTempMoves_[&operandMove];
1538 
1539  for (DataDependenceGraph::NodeSet::iterator i = tempMoves.begin();
1540  i != tempMoves.end(); ++i) {
1541  unschedule(**i);
1542  }
1543  scheduledTempMoves_.erase(&operandMove);
1544 }

References MapTools::containsKey(), scheduledTempMoves_, and unschedule().

Referenced by scheduleOperandWrites(), BUBasicBlockScheduler::scheduleOperandWrites(), scheduleOperation(), and BUBasicBlockScheduler::scheduleOperation().

Here is the call graph for this function:

◆ unscheduleResultReadTempMoves()

void BasicBlockScheduler::unscheduleResultReadTempMoves ( MoveNode resultMove)
protected

Unschedules the (possible) temporary register copy moves (due to missing connectivity) succeeding the given result read move.

Parameters
resultMoveThe move of which temp moves to unschedule.

Definition at line 1553 of file BasicBlockScheduler.cc.

1553  {
1554 
1555  if (!MapTools::containsKey(scheduledTempMoves_, &resultMove))
1556  return; // nothing to unschedule
1557 
1558  DataDependenceGraph::NodeSet tempMoves = scheduledTempMoves_[&resultMove];
1559 
1560  for (DataDependenceGraph::NodeSet::iterator i = tempMoves.begin();
1561  i != tempMoves.end(); ++i) {
1562  unschedule(**i);
1563  }
1564  scheduledTempMoves_.erase(&resultMove);
1565 }

References MapTools::containsKey(), scheduledTempMoves_, and unschedule().

Referenced by scheduleOperation(), and BUBasicBlockScheduler::scheduleOperation().

Here is the call graph for this function:

Member Data Documentation

◆ bypassedCount_

int BasicBlockScheduler::bypassedCount_
protected

Definition at line 170 of file BasicBlockScheduler.hh.

◆ ddg_

DataDependenceGraph* BasicBlockScheduler::ddg_
protected

◆ deadResults_

int BasicBlockScheduler::deadResults_
protected

Definition at line 171 of file BasicBlockScheduler.hh.

◆ jumpNode_

MoveNode* BasicBlockScheduler::jumpNode_
protected

Definition at line 175 of file BasicBlockScheduler.hh.

Referenced by handleLoopDDG(), and scheduleMove().

◆ minCycle_

int BasicBlockScheduler::minCycle_
protected

The earliest cycle to schedule moves in. Used to leave room for sched_yield() by the sched_yield() emitter.

Definition at line 165 of file BasicBlockScheduler.hh.

Referenced by handleDDG(), BUBasicBlockScheduler::handleLoopDDG(), handleLoopDDG(), and scheduleMove().

◆ options_

LLVMTCECmdLineOptions* BasicBlockScheduler::options_
protected

◆ renamer_

RegisterRenamer* BasicBlockScheduler::renamer_
protected

◆ rm_

SimpleResourceManager* BasicBlockScheduler::rm_
protected

◆ scheduledTempMoves_

std::map<const MoveNode*, DataDependenceGraph::NodeSet> BasicBlockScheduler::scheduledTempMoves_
protected

◆ schedulingTime_

boost::timer BasicBlockScheduler::schedulingTime_
protected

Time for getting the scheduling time for current basic block.

Definition at line 169 of file BasicBlockScheduler.hh.

Referenced by handleDDG(), BUBasicBlockScheduler::handleLoopDDG(), and handleLoopDDG().

◆ selector_

MoveNodeSelector* BasicBlockScheduler::selector_
protected

◆ softwareBypasser_

SoftwareBypasser* BasicBlockScheduler::softwareBypasser_
protected

The software bypasser to use to bypass registers when possible.

Definition at line 159 of file BasicBlockScheduler.hh.

Referenced by handleDDG(), handleLoopDDG(), scheduleOperation(), and unscheduleAllNodes().

◆ targetMachine_

const TTAMachine::Machine* BasicBlockScheduler::targetMachine_
protected

◆ tripCount_

int BasicBlockScheduler::tripCount_
protected

The documentation for this class was generated from the following files:
ProgramOperation::operation
const Operation & operation() const
Definition: ProgramOperation.cc:590
CriticalPathBBMoveNodeSelector
Definition: CriticalPathBBMoveNodeSelector.hh:70
DataDependenceGraph::lastScheduledRegisterRead
MoveNode * lastScheduledRegisterRead(const TTAMachine::BaseRegisterFile &rf, int registerIndex, int lastCycleToTest=INT_MAX) const
Definition: DataDependenceGraph.cc:766
RegisterCopyAdder::AddedRegisterCopies
Definition: RegisterCopyAdder.hh:104
TTAProgram::Terminal::isTriggering
virtual bool isTriggering() const
Definition: Terminal.cc:298
BasicBlockScheduler::ddg_
DataDependenceGraph * ddg_
DDG of the currently scheduled BB.
Definition: BasicBlockScheduler.hh:152
SoftwareBypasser::setSelector
virtual void setSelector(MoveNodeSelector *selector)
Definition: SoftwareBypasser.cc:143
BoostGraph::connectNodes
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
Operation::writesMemory
virtual bool writesMemory() const
Definition: Operation.cc:252
TTAProgram::Move::isTriggering
bool isTriggering() const
Definition: Move.cc:284
DataDependenceGraph::removeIncomingGuardEdges
void removeIncomingGuardEdges(MoveNode &node)
Definition: DataDependenceGraph.cc:5466
BasicBlockScheduler::unschedule
void unschedule(MoveNode &moveNode)
Definition: BasicBlockScheduler.cc:1488
BoostGraph::removeEdge
virtual void removeEdge(Edge &e)
DataDependenceGraph::regRawSuccessors
NodeSet regRawSuccessors(const MoveNode &node) const
Definition: DataDependenceGraph.cc:4272
BoostGraph::tailNode
virtual Node & tailNode(const Edge &edge) const
SimpleResourceManager::largestCycle
virtual int largestCycle() const override
Definition: SimpleResourceManager.cc:463
DataDependenceGraph::scheduledNodeCount
int scheduledNodeCount() const
Definition: DataDependenceGraph.cc:1859
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
Operation::hasSideEffects
virtual bool hasSideEffects() const
Definition: Operation.cc:272
MoveNodeGroup::node
MoveNode & node(int index) const
Definition: MoveNodeGroup.cc:152
TTAProgram::Terminal::index
virtual int index() const
Definition: Terminal.cc:274
BasicBlockScheduler::succeedingTempMove
MoveNode * succeedingTempMove(MoveNode &current)
Definition: BasicBlockScheduler.cc:1410
RegisterCopyAdder
Definition: RegisterCopyAdder.hh:91
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
TTAMachine::HWOperation
Definition: HWOperation.hh:52
BoostGraph::node
Node & node(const int index) const
BasicBlockPass::ddgBuilder_
DataDependenceGraphBuilder ddgBuilder_
Definition: BasicBlockPass.hh:100
TTAProgram::Terminal::registerFile
virtual const TTAMachine::RegisterFile & registerFile() const
Definition: Terminal.cc:225
MoveNode::isDestinationOperation
bool isDestinationOperation() const
TTAProgram::Move::isReturn
bool isReturn() const
Definition: Move.cc:259
DataDependenceGraph::findLimitingAntidependenceSource
MoveNode * findLimitingAntidependenceSource(MoveNode &mn)
Definition: DataDependenceGraph.cc:5272
DataDependenceGraph::findLoopLimitAndIndex
std::pair< MoveNode *, MoveNode * > findLoopLimitAndIndex(MoveNode &jumpMove)
Definition: DataDependenceGraph.cc:4618
BoostGraph< MoveNode, DataDependenceEdge >::NodeSet
std::set< MoveNode *, typename MoveNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
BasicBlockScheduler::selector_
MoveNodeSelector * selector_
Definition: BasicBlockScheduler.hh:167
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
TTAProgram::AnnotatedInstructionElement::setAnnotation
void setAnnotation(const ProgramAnnotation &annotation)
Definition: AnnotatedInstructionElement.cc:79
BasicBlockScheduler::scheduleResultReadTempMoves
void scheduleResultReadTempMoves(MoveNode &resultMove, MoveNode &resultRead, int lastUse)
Definition: BasicBlockScheduler.cc:1442
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
DataDependenceGraph::scheduledMoves
NodeSet scheduledMoves() const
Definition: DataDependenceGraph.cc:1375
Operation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:192
TTAProgram::Instruction::toString
std::string toString() const
Definition: Instruction.cc:576
ProgramOperation::switchInputs
void switchInputs(int idx1=1, int idx2=2)
Definition: ProgramOperation.cc:795
ProgramOperation
Definition: ProgramOperation.hh:70
TTAProgram::Move::setGuard
void setGuard(MoveGuard *guard)
Definition: Move.cc:360
TTAProgram::Move::toString
std::string toString() const
Definition: Move.cc:436
MoveNode
Definition: MoveNode.hh:65
MoveNode::isSourceConstant
bool isSourceConstant() const
Definition: MoveNode.cc:238
BasicBlockScheduler::unscheduleResultReadTempMoves
void unscheduleResultReadTempMoves(MoveNode &resultMove)
Definition: BasicBlockScheduler.cc:1553
MoveNodeSelector::notifyScheduled
virtual void notifyScheduled(MoveNode &node)=0
Definition: MoveNodeSelector.cc:70
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
BasicBlockScheduler::options_
LLVMTCECmdLineOptions * options_
Definition: BasicBlockScheduler.hh:173
SimpleResourceManager::assign
virtual void assign(int cycle, MoveNode &node, const TTAMachine::Bus *bus=NULL, const TTAMachine::FunctionUnit *srcFU=NULL, const TTAMachine::FunctionUnit *dstFU=NULL, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) override
Definition: SimpleResourceManager.cc:221
DataDependenceEdge::EDGE_REGISTER
@ EDGE_REGISTER
Definition: DataDependenceEdge.hh:53
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
TTAMachine::Machine::Navigator::count
int count() const
MoveNodeGroup::nodeCount
int nodeCount() const
Definition: MoveNodeGroup.cc:140
DataDependenceGraph::sanityCheck
void sanityCheck() const
Definition: DataDependenceGraph.cc:1399
SimpleResourceManager::initiationInterval
virtual unsigned initiationInterval() const
Definition: SimpleResourceManager.hh:135
TTAMachine::FUPort::isTriggering
virtual bool isTriggering() const
Definition: FUPort.cc:182
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
DataDependenceEdge::dependenceType
DependenceType dependenceType() const
Definition: DataDependenceEdge.hh:88
SimpleResourceManager::unassign
virtual void unassign(MoveNode &node) override
Definition: SimpleResourceManager.cc:252
LLVMTCECmdLineOptions::dumpDDGsDot
virtual bool dumpDDGsDot() const
Definition: LLVMTCECmdLineOptions.cc:359
BasicBlockScheduler::findTriggerFromUnit
static MoveNode * findTriggerFromUnit(const ProgramOperation &po, const TTAMachine::Unit &unit)
Definition: BasicBlockScheduler.cc:2130
Conversion::toString
static std::string toString(const T &source)
DataDependenceEdge::tailPseudo
bool tailPseudo() const
Definition: DataDependenceEdge.hh:109
ProgramOperation::triggeringMove
MoveNode * triggeringMove() const
Definition: ProgramOperation.cc:643
BasicBlockScheduler::scheduleMove
void scheduleMove(MoveNode &move, int earliestCycle, bool allowPredicationAndRenaming)
Definition: BasicBlockScheduler.cc:950
BasicBlockScheduler::minCycle_
int minCycle_
The earliest cycle to schedule moves in. Used to leave room for sched_yield() by the sched_yield() em...
Definition: BasicBlockScheduler.hh:165
BasicBlockScheduler::tripCount_
int tripCount_
Definition: BasicBlockScheduler.hh:177
BasicBlockScheduler::scheduleOperandWrites
int scheduleOperandWrites(int &cycle, MoveNodeGroup &moves)
Definition: BasicBlockScheduler.cc:633
DataDependenceGraph::guardDefMoves
NodeSet guardDefMoves(const MoveNode &moveNode)
Definition: DataDependenceGraph.cc:743
SoftwareBypasser::bypassNode
virtual int bypassNode(MoveNode &moveNode, int &lastOperandCycle, DataDependenceGraph &ddg, ResourceManager &rm)=0
SimValue
Definition: SimValue.hh:96
SoftwareBypasser::removeBypass
virtual void removeBypass(MoveNodeGroup &candidates, DataDependenceGraph &ddg, ResourceManager &rm)=0
Definition: SoftwareBypasser.cc:89
DataDependenceGraph::setCycleGrouping
virtual void setCycleGrouping(bool flag)
Definition: DataDependenceGraph.cc:1738
Operation::canSwap
virtual bool canSwap(int id1, int id2) const
Definition: Operation.cc:470
MoveNode::isPlaced
bool isPlaced() const
Definition: MoveNode.cc:352
BasicBlockScheduler::scheduleRRMove
void scheduleRRMove(MoveNode &moveNode)
Definition: BasicBlockScheduler.cc:902
BasicBlockScheduler::targetMachine_
const TTAMachine::Machine * targetMachine_
The target machine we are scheduling the program against.
Definition: BasicBlockScheduler.hh:150
MoveNode::sourceOperation
ProgramOperation & sourceOperation() const
Definition: MoveNode.cc:453
assert
#define assert(condition)
Definition: Application.hh:86
TTAProgram::TerminalImmediate::value
virtual SimValue value() const
Definition: TerminalImmediate.cc:75
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAMachine::HWOperation::port
virtual FUPort * port(int operand) const
Definition: HWOperation.cc:320
TTAMachine::FUPort
Definition: FUPort.hh:46
MoveNode::isMove
bool isMove() const
DataDependenceGraph::writeToXMLFile
void writeToXMLFile(std::string fileName) const
Definition: DataDependenceGraph.cc:1747
BasicBlockScheduler::ddgSnapshot
void ddgSnapshot(DataDependenceGraph &ddg, const std::string &name, DataDependenceGraph::DumpFileFormat format, bool final, bool resetCounter=false) const
Definition: BasicBlockScheduler.cc:1633
MoveNode::earliestResultReadCycle
int earliestResultReadCycle() const
Definition: MoveNode.cc:652
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
TTAProgram::Terminal::operationIndex
virtual int operationIndex() const
Definition: Terminal.cc:364
TTAMachine::HWOperation::io
int io(const FUPort &port) const
Definition: HWOperation.cc:364
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
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
DataDependenceGraph::largestCycle
int largestCycle() const
Definition: DataDependenceGraph.cc:1838
InvalidData
Definition: Exception.hh:149
BoostGraph< MoveNode, DataDependenceEdge >::EdgeSet
std::set< DataDependenceEdge *, typename DataDependenceEdge ::Comparator > EdgeSet
Definition: BoostGraph.hh:87
MoveNodeSet::at
MoveNode & at(int index)
DataDependenceEdge::DEP_RAW
@ DEP_RAW
Definition: DataDependenceEdge.hh:47
DDGPass::DDGPass
DDGPass(InterPassData &data)
Definition: DDGPass.cc:42
RegisterRenamer::initialize
void initialize(DataDependenceGraph &ddg)
Definition: RegisterRenamer.cc:81
BasicBlockScheduler::handleRemovedResultMoves
void handleRemovedResultMoves(std::set< std::pair< TTAProgram::Move *, int > > removedMoves)
Definition: BasicBlockScheduler.cc:1807
DataDependenceGraph::DUMP_XML
@ DUMP_XML
Definition: DataDependenceGraph.hh:87
CmdLineOptions
Definition: CmdLineOptions.hh:54
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
Application::cmdLineOptions
static CmdLineOptions * cmdLineOptions()
Definition: Application.cc:397
__func__
#define __func__
Definition: Application.hh:67
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
RegisterRenamer::renameSourceRegister
bool renameSourceRegister(MoveNode &node, bool loopScheduling, bool allowSameRf, bool differentRfOnlyDirectlyReachable, int latestCycle=INT_MAX)
Definition: RegisterRenamer.cc:617
RegisterCopyAdder::AddedRegisterCopies::count_
int count_
Definition: RegisterCopyAdder.hh:107
SimpleResourceManager::earliestCycle
virtual int earliestCycle(MoveNode &node, const TTAMachine::Bus *bus=NULL, const TTAMachine::FunctionUnit *srcFU=NULL, const TTAMachine::FunctionUnit *dstFU=NULL, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) const override
Definition: SimpleResourceManager.cc:278
TTAProgram::Terminal::isGPR
virtual bool isGPR() const
Definition: Terminal.cc:107
Exception::errorMessageStack
std::string errorMessageStack(bool messagesOnly=false) const
Definition: Exception.cc:138
MoveNode::isSourceOperation
bool isSourceOperation() const
Definition: MoveNode.cc:168
BasicBlockPass::BasicBlockPass
BasicBlockPass(InterPassData &data)
Definition: BasicBlockPass.cc:51
DataDependenceGraph::copyIncomingGuardEdges
void copyIncomingGuardEdges(const MoveNode &src, MoveNode &dst)
Definition: DataDependenceGraph.cc:3865
TTAProgram::ProgramAnnotation::ANN_REQUIRES_LIMM
@ ANN_REQUIRES_LIMM
Definition: ProgramAnnotation.hh:125
DataDependenceGraph::DUMP_DOT
@ DUMP_DOT
Definition: DataDependenceGraph.hh:86
BasicBlockScheduler::unscheduleInputOperandTempMoves
void unscheduleInputOperandTempMoves(MoveNode &operandMove)
Definition: BasicBlockScheduler.cc:1532
BasicBlockScheduler::scheduleRRTempMoves
void scheduleRRTempMoves(MoveNode &regToRegMove, MoveNode &firstMove, int lastUse)
Definition: BasicBlockScheduler.cc:1297
TTAProgram::Move
Definition: Move.hh:55
BasicBlockScheduler::unscheduleAllNodes
void unscheduleAllNodes()
Definition: BasicBlockScheduler.cc:1511
TTAMachine::ControlUnit::delaySlots
int delaySlots() const
SoftwareBypasser::bypass
virtual int bypass(MoveNodeGroup &candidates, DataDependenceGraph &ddg, ResourceManager &rm, bool bypassTrigger)=0
Definition: SoftwareBypasser.cc:65
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
Exception
Definition: Exception.hh:54
ModuleRunTimeError
Definition: Exception.hh:1043
SoftwareBypasser::removeDeadResults
virtual int removeDeadResults(MoveNodeGroup &candidates, DataDependenceGraph &ddg, ResourceManager &rm, std::set< std::pair< TTAProgram::Move *, int > > &removedMoves)=0
Definition: SoftwareBypasser.cc:116
MoveNodeSet
Definition: MoveNodeSet.hh:41
BasicBlockScheduler::scheduleInputOperandTempMoves
void scheduleInputOperandTempMoves(MoveNode &operandMove, MoveNode &operandWrite)
Definition: BasicBlockScheduler.cc:1344
LLVMTCECmdLineOptions
Definition: LLVMTCECmdLineOptions.hh:48
ProgramOperation::inputMoveCount
int inputMoveCount() const
Definition: ProgramOperation.cc:600
LLVMTCECmdLineOptions::dumpDDGsXML
virtual bool dumpDDGsXML() const
Definition: LLVMTCECmdLineOptions.cc:364
DataDependenceEdge::DEP_WAW
@ DEP_WAW
Definition: DataDependenceEdge.hh:49
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
Operation
Definition: Operation.hh:59
TTAProgram::AnnotatedInstructionElement::hasAnnotations
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:165
MoveNodeGroup::toString
std::string toString() const
Definition: MoveNodeGroup.cc:248
BoostGraph::inEdges
virtual EdgeSet inEdges(const Node &node) const
GraphBase::writeToDotFile
virtual void writeToDotFile(const TCEString &fileName) const
BasicBlockScheduler::renamer_
RegisterRenamer * renamer_
Definition: BasicBlockScheduler.hh:161
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
DataDependenceGraph::movesAtCycle
NodeSet movesAtCycle(int cycle) const
Definition: DataDependenceGraph.cc:699
MoveNodeGroup::addNode
void addNode(MoveNode &node)
Definition: MoveNodeGroup.cc:70
SimValue::unsignedValue
unsigned int unsignedValue() const
Definition: SimValue.cc:919
BasicBlockScheduler::rm_
SimpleResourceManager * rm_
Resource Manager of the currently scheduled BB.
Definition: BasicBlockScheduler.hh:154
TTAProgram::TerminalImmediate
Definition: TerminalImmediate.hh:44
MoveNode::destinationOperation
ProgramOperation & destinationOperation(unsigned int index=0) const
MoveNode::move
TTAProgram::Move & move()
SchedulerPass::interPassData
InterPassData & interPassData()
Definition: SchedulerPass.cc:53
SimValue::width
int width() const
Definition: SimValue.cc:103
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
TTAProgram::ProgramAnnotation::ANN_STACKFRAME_PROCEDURE_RETURN
@ ANN_STACKFRAME_PROCEDURE_RETURN
precedure return jmp
Definition: ProgramAnnotation.hh:76
IllegalMachine
Definition: Exception.hh:878
BasicBlockScheduler::getTriggerOperand
int getTriggerOperand(const Operation &operation, const TTAMachine::Machine &machine)
Definition: BasicBlockScheduler.cc:1684
MoveNodeSet::addMoveNode
void addMoveNode(MoveNode &)
Definition: MoveNodeSet.cc:62
SimpleResourceManager::canTransportImmediate
virtual bool canTransportImmediate(const MoveNode &node, const TTAMachine::Bus *preAssignedBus=NULL) const
Definition: SimpleResourceManager.cc:411
DataDependenceGraph::exclusingGuards
bool exclusingGuards(const MoveNode &mn1, const MoveNode &mn2) const
Definition: DataDependenceGraph.cc:4480
RegisterRenamer::renameDestinationRegister
bool renameDestinationRegister(MoveNode &node, bool loopScheduling, bool allowSameRf, bool differentRfOnlyDirectlyReachable, int earliestCycle=-1)
Definition: RegisterRenamer.cc:458
TCEString
Definition: TCEString.hh:53
BasicBlockScheduler::softwareBypasser_
SoftwareBypasser * softwareBypasser_
The software bypasser to use to bypass registers when possible.
Definition: BasicBlockScheduler.hh:159
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
RegisterRenamer::setSelector
void setSelector(MoveNodeSelector *selector)
Definition: RegisterRenamer.cc:1126
DataDependenceGraph::copyOutgoingGuardWarEdges
void copyOutgoingGuardWarEdges(const MoveNode &src, MoveNode &dst)
Definition: DataDependenceGraph.cc:3897
SimpleResourceManager::latestCycle
virtual int latestCycle(MoveNode &node, const TTAMachine::Bus *bus=NULL, const TTAMachine::FunctionUnit *srcFU=NULL, const TTAMachine::FunctionUnit *dstFU=NULL, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) const override
Definition: SimpleResourceManager.cc:349
DataDependenceGraph::criticalPathGraph
DataDependenceGraph * criticalPathGraph()
Definition: DataDependenceGraph.cc:3458
BasicBlockScheduler::scheduledTempMoves_
std::map< const MoveNode *, DataDependenceGraph::NodeSet > scheduledTempMoves_
Stores the MoveNodes that were scheduled as temp moves during scheduling of the operand move.
Definition: BasicBlockScheduler.hh:157
MoveNode::isOperationMove
bool isOperationMove() const
Definition: MoveNode.cc:253
TTAProgram::CodeGenerator
Definition: CodeGenerator.hh:53
ProgramOperation::inputNode
MoveNodeSet & inputNode(int in) const
Definition: ProgramOperation.cc:513
BasicBlockScheduler::scheduleResultReads
bool scheduleResultReads(MoveNodeGroup &moves)
Definition: BasicBlockScheduler.cc:847
TTAProgram::Terminal::equals
virtual bool equals(const Terminal &other) const =0
MoveNodeGroup::isScheduled
bool isScheduled() const
Definition: MoveNodeGroup.cc:164
DataDependenceEdge
Definition: DataDependenceEdge.hh:43
MoveNode::isScheduled
bool isScheduled() const
Definition: MoveNode.cc:409
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
BasicBlockScheduler::tryToSwitchInputs
bool tryToSwitchInputs(ProgramOperation &op)
Definition: BasicBlockScheduler.cc:1734
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
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
BasicBlockScheduler::tryToOptimizeWaw
bool tryToOptimizeWaw(const MoveNode &moveNode)
Definition: BasicBlockScheduler.cc:1920
DataDependenceGraph::removeOutgoingGuardWarEdges
void removeOutgoingGuardWarEdges(MoveNode &node)
Definition: DataDependenceGraph.cc:5496
TTAProgram::ProgramAnnotation
Definition: ProgramAnnotation.hh:49
MoveNodeGroup
Definition: MoveNodeGroup.hh:48
TTAProgram::AnnotatedInstructionElement::removeAnnotations
void removeAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID)
Definition: AnnotatedInstructionElement.cc:146
SoftwareBypasser::clearCaches
virtual void clearCaches(DataDependenceGraph &ddg, bool removeDeadResults)=0
TTAProgram::Terminal::isRA
virtual bool isRA() const
Definition: Terminal.cc:129
BoostGraph::name
virtual const TCEString & name() const
debugLog
#define debugLog(text)
Definition: Application.hh:95
DataDependenceGraph::copyDepsOver
EdgeSet copyDepsOver(MoveNode &node, bool anti, bool raw)
Definition: DataDependenceGraph.cc:2422
BoostGraph::nodeCount
int nodeCount() const
DataDependenceGraph::unscheduledMoves
NodeSet unscheduledMoves() const
Definition: DataDependenceGraph.cc:1355
BoostGraph::successors
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
Operation::affectsCount
virtual int affectsCount() const
Definition: Operation.cc:402
DataDependenceEdge::edgeReason
EdgeReason edgeReason() const
Definition: DataDependenceEdge.hh:91
BasicBlockScheduler::notifyScheduled
void notifyScheduled(MoveNodeGroup &moves, MoveNodeSelector &selector)
Definition: BasicBlockScheduler.cc:1602
TTAProgram::Move::setSource
void setSource(Terminal *src)
Definition: Move.cc:312
ProgramOperation::inputMove
MoveNode & inputMove(int index) const
Definition: ProgramOperation.cc:621
BasicBlockScheduler::scheduleOperation
void scheduleOperation(MoveNodeGroup &moves)
Definition: BasicBlockScheduler.cc:401
BasicBlockScheduler::schedulingTime_
boost::timer schedulingTime_
Time for getting the scheduling time for current basic block.
Definition: BasicBlockScheduler.hh:169
SimpleResourceManager::instruction
virtual TTAProgram::Instruction * instruction(int cycle) const override
Definition: SimpleResourceManager.cc:442
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
BasicBlockScheduler::jumpNode_
MoveNode * jumpNode_
Definition: BasicBlockScheduler.hh:175