OpenASIP  2.0
Public Member Functions | Private Member Functions | List of all members
LoopPrologAndEpilogBuilder Class Reference

#include <LoopPrologAndEpilogBuilder.hh>

Collaboration diagram for LoopPrologAndEpilogBuilder:
Collaboration graph

Public Member Functions

 LoopPrologAndEpilogBuilder ()
 
virtual ~LoopPrologAndEpilogBuilder ()
 
virtual int build (DataDependenceGraph &ddg, SimpleResourceManager &rm, ControlFlowGraph &cfg, BasicBlockNode &loopBBN, int endCycle=-1, bool createEpilog=true)
 
BasicBlockNodeaddPrologFromRM (SimpleResourceManager &prologRM, SimpleResourceManager &loopRM, ControlFlowGraph &cfg, BasicBlockNode &loopBBN)
 
BasicBlockNodeaddEpilogFromRM (SimpleResourceManager &prologEpilogRM, int ii, ControlFlowGraph &cfg, BasicBlockNode &loopBBN)
 

Private Member Functions

void moveJumpDestination (TTAProgram::InstructionReferenceManager &irm, BasicBlockNode &tail, BasicBlockNode &dst, ControlFlowEdge &jumpEdge)
 
void addPrologIntoCfg (ControlFlowGraph &cfg, BasicBlockNode &prologBBN, BasicBlockNode &loopBBN)
 
void addEpilogIntoCfg (ControlFlowGraph &cfg, BasicBlockNode &epilogBBN, BasicBlockNode &loopBBN)
 
bool optimizeProlog (TTAProgram::BasicBlock &prolog)
 
bool optimizeEpilog (TTAProgram::BasicBlock &epilog)
 

Detailed Description

Classes that implement this interface are able to software bypass moves.

Definition at line 54 of file LoopPrologAndEpilogBuilder.hh.

Constructor & Destructor Documentation

◆ LoopPrologAndEpilogBuilder()

LoopPrologAndEpilogBuilder::LoopPrologAndEpilogBuilder ( )

Definition at line 56 of file LoopPrologAndEpilogBuilder.cc.

56  {
57 }

◆ ~LoopPrologAndEpilogBuilder()

LoopPrologAndEpilogBuilder::~LoopPrologAndEpilogBuilder ( )
virtual

Definition at line 59 of file LoopPrologAndEpilogBuilder.cc.

59  {
60 }

Member Function Documentation

◆ addEpilogFromRM()

BasicBlockNode * LoopPrologAndEpilogBuilder::addEpilogFromRM ( SimpleResourceManager prologEpilogRM,
int  ii,
ControlFlowGraph cfg,
BasicBlockNode loopBBN 
)

Definition at line 448 of file LoopPrologAndEpilogBuilder.cc.

450  {
451 
453  BasicBlockNode* epilogNode = new BasicBlockNode(*epilogBB);
454 
455  if (Application::verboseLevel() > 1) {
457  << "Copying epilog rm to bb" << epilogNode->toString()
458  << std::endl;
459  }
460 
461  for (int i = BF2Scheduler::PROLOG_CYCLE_BIAS + ii;
462  i <= prologEpilogRM.largestCycle(); i++) {
463  TTAProgram::Instruction* newInstruction =
464  prologEpilogRM.instruction(i);
465  prologEpilogRM.loseInstructionOwnership(i);
466  epilogBB->add(newInstruction);
467  }
468  if (optimizeEpilog(*epilogBB)) {
469  addEpilogIntoCfg(cfg, *epilogNode, loopBBN);
470  epilogNode->setScheduled();
471  if (Application::verboseLevel() > 1) {
473  << "epilog added to cfg" << epilogNode->toString() << std::endl;
474 
476  << "Disassembly of epilog" << std::endl <<
477  epilogBB->disassembly() << std::endl;
478  }
479  } else {
480  if (Application::verboseLevel() > 1) {
482  << "epilog empty, not added to cfg." << std::endl;
483  }
484  delete epilogNode;
485  }
486 
487  return epilogNode;
488 
489 }

References TTAProgram::CodeSnippet::add(), addEpilogIntoCfg(), TTAProgram::CodeSnippet::disassembly(), SimpleResourceManager::instruction(), SimpleResourceManager::largestCycle(), Application::logStream(), SimpleResourceManager::loseInstructionOwnership(), optimizeEpilog(), BF2Scheduler::PROLOG_CYCLE_BIAS, BasicBlockNode::setScheduled(), BasicBlockNode::toString(), and Application::verboseLevel().

Here is the call graph for this function:

◆ addEpilogIntoCfg()

void LoopPrologAndEpilogBuilder::addEpilogIntoCfg ( ControlFlowGraph cfg,
BasicBlockNode epilogBBN,
BasicBlockNode loopBBN 
)
private

Adds an epilog into control flow graph.

Creates the node and fixed edges.

Parameters
cfgcfg where to add the epilog
prologBBbb which contains the epilog
loopBBNnode of cfg which contains the loop

Definition at line 166 of file LoopPrologAndEpilogBuilder.cc.

168  {
169 
170  cfg.addNode(epilogBBN);
171  assert(cfg.outDegree(loopBBN) == 2);
172 
173  for (int i = 0; i < cfg.outDegree(loopBBN); i++) {
174  ControlFlowEdge& loopExitEdge = cfg.outEdge(loopBBN,i);
175  if (!loopExitEdge.isFallThroughEdge()) {
176  continue;
177  }
178  BasicBlockNode& succNode = cfg.headNode(loopExitEdge);
179  cfg.moveInEdge(succNode, epilogBBN, loopExitEdge);
180  cfg.connectNodes(
181  epilogBBN, succNode, *(new ControlFlowEdge(
184  )));
185 
186  return;
187  }
188  assert(false&&"Loop exit fall-thru not in ddg!");
189 }

References BoostGraph< GraphNode, GraphEdge >::addNode(), assert, ControlFlowEdge::CFLOW_EDGE_FALLTHROUGH, ControlFlowEdge::CFLOW_EDGE_NORMAL, BoostGraph< GraphNode, GraphEdge >::connectNodes(), BoostGraph< GraphNode, GraphEdge >::headNode(), ControlFlowEdge::isFallThroughEdge(), BoostGraph< GraphNode, GraphEdge >::moveInEdge(), BoostGraph< GraphNode, GraphEdge >::outDegree(), and BoostGraph< GraphNode, GraphEdge >::outEdge().

Referenced by addEpilogFromRM(), and build().

Here is the call graph for this function:

◆ addPrologFromRM()

BasicBlockNode * LoopPrologAndEpilogBuilder::addPrologFromRM ( SimpleResourceManager prologRM,
SimpleResourceManager loopRM,
ControlFlowGraph cfg,
BasicBlockNode loopBBN 
)

Stupid immediates still have to be copied from the main loop :(

Definition at line 408 of file LoopPrologAndEpilogBuilder.cc.

411  {
412 
413  int startCycle = prologRM.smallestCycle();
414 
416  BasicBlockNode* prologNode = new BasicBlockNode(*prologBB);
417 
418  if (Application::verboseLevel() > 1) {
420  << "Copying prolog rm to bb" << prologNode->toString()
421  << " Start cycle: " << startCycle << std::endl;
422  }
423  BasicBlockPass::copyRMToBB(prologRM, *prologBB, prologRM.machine(),
425  loopRM.initiationInterval()-1
427 
428  if (optimizeProlog(*prologBB)) {
429  addPrologIntoCfg(cfg, *prologNode, loopBBN);
430  prologNode->setScheduled();
431 
432  if (Application::verboseLevel() > 1) {
434  << "Prolog added to cfg" << prologNode->toString() << std::endl
435  << "Disassembly of prolog" << std::endl <<
436  prologBB->disassembly() << std::endl;
437  }
438  } else {
439  if (Application::verboseLevel() > 1) {
441  << "Empty prolog, not added to cfg" << std::endl;
442  }
443  delete prologNode;
444  }
445  return prologNode;
446 }

References addPrologIntoCfg(), BasicBlockPass::copyRMToBB(), TTAProgram::CodeSnippet::disassembly(), SimpleResourceManager::initiationInterval(), ControlFlowGraph::instructionReferenceManager(), Application::logStream(), ResourceManager::machine(), optimizeProlog(), BF2Scheduler::PROLOG_CYCLE_BIAS, BasicBlockNode::setScheduled(), SimpleResourceManager::smallestCycle(), BasicBlockNode::toString(), and Application::verboseLevel().

Here is the call graph for this function:

◆ addPrologIntoCfg()

void LoopPrologAndEpilogBuilder::addPrologIntoCfg ( ControlFlowGraph cfg,
BasicBlockNode prologBBN,
BasicBlockNode loopBBN 
)
private

Adds a prolog into control flow graph.

Creates the node and fixed edges and instruction references.

Parameters
cfgcfg where to add the prolog
prologBBbb which contains the prolog
loopBBNnode of cfg which contains the loop

Definition at line 120 of file LoopPrologAndEpilogBuilder.cc.

122  {
123 
124  if (Application::verboseLevel() > 1) {
125  std::cerr << "adding prolog into cfg" << std::endl;
126  }
127  cfg.addNode(prologBBN);
128 
129  // update incoming cfg edges to point into prolog
130  for (int i = 0; i < cfg.inDegree(loopBBN); i++) {
131  ControlFlowEdge&e = cfg.inEdge(loopBBN,i);
132  BasicBlockNode& tail = cfg.tailNode(e);
133  if (&tail != &loopBBN) {
134  cfg.moveInEdge(loopBBN, prologBBN,e);
135  i--;
136  if (e.isJumpEdge()) {
137  if (Application::verboseLevel() > 1) {
138  std::cerr << "\tmoving jump into loop into prolog"
139  << std::endl;
140  }
142  tail, prologBBN, e);
143  }
144  }
145  }
146 
147  // connect prolog and loop
148  cfg.connectNodes(
149  prologBBN, loopBBN, *(new ControlFlowEdge(
152 
153 }

References BoostGraph< GraphNode, GraphEdge >::addNode(), ControlFlowEdge::CFLOW_EDGE_FALLTHROUGH, ControlFlowEdge::CFLOW_EDGE_NORMAL, BoostGraph< GraphNode, GraphEdge >::connectNodes(), BoostGraph< GraphNode, GraphEdge >::inDegree(), BoostGraph< GraphNode, GraphEdge >::inEdge(), ControlFlowGraph::instructionReferenceManager(), ControlFlowEdge::isJumpEdge(), BoostGraph< GraphNode, GraphEdge >::moveInEdge(), moveJumpDestination(), BoostGraph< GraphNode, GraphEdge >::tailNode(), and Application::verboseLevel().

Referenced by addPrologFromRM(), and build().

Here is the call graph for this function:

◆ build()

int LoopPrologAndEpilogBuilder::build ( DataDependenceGraph ddg,
SimpleResourceManager rm,
ControlFlowGraph cfg,
BasicBlockNode loopBBN,
int  endCycle = -1,
bool  createEpilog = true 
)
virtual

Definition at line 192 of file LoopPrologAndEpilogBuilder.cc.

195  {
196 
197  if (Application::verboseLevel() > 1) {
198  Application::logStream() << "Building epilog and prolog for the loop."
199  << std::endl;
200  std::cerr << "rm.smallestCycle: " << rm.smallestCycle() << std::endl;
201  std::cerr << "end cycle: " << endCycle << std::endl;
202  }
203 
204  int ii = rm.initiationInterval();
205  if (Application::verboseLevel() > 1) {
206  Application::logStream() << "Investigate nodes. ii: " << ii
207  << std::endl;
208  }
209 
210  // resolve how many times loop overlaps
211  int overlap_count;
212  if (endCycle != -1) {
213  overlap_count = ((endCycle - rm.smallestCycle()) / ii);
214  } else {
215  overlap_count = ddg.largestCycle() / ii;
216  }
217 
218  TTAProgram::Move* jumpMove = NULL;
219  if (overlap_count > 0) {
220  if (Application::verboseLevel() > 1) {
222  << "Building prolog and epilog..... "
223  << " Overlapcount: " << overlap_count << std::endl;
224  }
225 
226  DataDependenceGraph* rootDDG = static_cast<DataDependenceGraph*>(
227  ddg.rootGraph());
228 
229  // make room for moves of prolog and epilog
230  TTAProgram::BasicBlock *prolog =
232  BasicBlockNode *prologNode = new BasicBlockNode(*prolog, true, true,
233  loopBBN.originalStartAddress(), false);
234 
235  TTAProgram::BasicBlock *epilog = NULL;
236  BasicBlockNode* epilogNode = NULL;
237  if (createEpilog) {
238  epilog =
240  epilogNode = new BasicBlockNode(
241  *epilog, true, true, loopBBN.originalStartAddress(), false);
242  }
243  for (int i = 0; i < overlap_count * ii; i++) {
244  prolog->add(new TTAProgram::Instruction());
245  if (createEpilog) {
246  epilog->add(new TTAProgram::Instruction());
247  }
248  }
249 
250  // scan for long immediates. these can be copied to both
251  // prolog and epilog.
252  for (int j = 0; j < overlap_count; j++) {
253  for (int i = 0; i < ii; i++) {
255  for (int k = 0; k < ins->immediateCount(); k++) {
256  auto newImm = ins->immediate(k).copy();
257  auto newImm2 = ins->immediate(k).copy();
258  prolog->instructionAtIndex(i+j*ii).addImmediate(newImm);
259  if (createEpilog) {
260  epilog->instructionAtIndex(i+j*ii).addImmediate(newImm2);
261  }
262  }
263  }
264  }
265  int newZero = endCycle + 1 - (ii * (1 + overlap_count));
266  for (int i = 0 ; i < overlap_count; i++) {
267  for (int j = 0; j < ddg.nodeCount(); j++) {
268  MoveNode& n = ddg.node(j);
269 
270  // ignore jump
271  if (n.move().isControlFlowMove()) {
272  jumpMove = &n.move();
273  continue;
274  }
275 
276  int cycle;
277  if (endCycle != -1) {
278  cycle = n.cycle() - newZero;
279  } else {
280  cycle = n.cycle();
281  }
282  int round = cycle / ii;
283  int place = cycle % ii;
284 
285  MoveNode* nodeCopy;
286  if (createEpilog || round == 0) {
287  nodeCopy = n.copy();
288  nodeCopy->move().setGuard(NULL);
289 
290  if (endCycle != -1) {
291  nodeCopy->setCycle(place + newZero);
292  } else {
293  nodeCopy->setCycle(place);
294  }
295 
296  if (Application::verboseLevel() > 1) {
298  << "Node cycle: " << cycle
299  << " round: " << round
300  << " place: " << place << " "
301  << n.toString()<< "\t" ;
302  }
303  } else {
304  continue;
305  }
306 /*
307  if (createEpilog) {
308  if (n.move().isControlFlowMove()) {
309  assert(!n.move().isUnconditional());
310  if (Application::verboseLevel() > 1) {
311  std::cerr << "jumpmove reversing guard at address: "
312  << &nodeCopy->move()<< std::endl;
313  }
314  nodeCopy->move().setGuard(
315  TTAProgram::CodeGenerator::createInverseGuard(
316  n.move().guard(), &n.move().bus()));
317  // TODO: set jump target to first of epilog
318  nodeCopy->move().setSource(
319  new TTAProgram::TerminalInstructionReference(
320  cfg.instructionReferenceManager().createReference(
321  epilog->instructionAtIndex(0))));
322  }
323  }
324 */
325  // select if node should go to prolog or epilog
326  if (round <= i) {
327  prolog->instructionAtIndex(
328  (i*ii)+place).addMove(nodeCopy->movePtr());
329  if (Application::verboseLevel() > 1) {
330  Application::logStream() << " to prolog" << std::endl;
331  }
332  rootDDG->addNode(*nodeCopy, *prologNode);
333  rootDDG->copyExternalInEdges(*nodeCopy, n);
334  rootDDG->copyExternalOutEdges(*nodeCopy, n);
335 
336  } else {
337  if (createEpilog) {
338  epilog->instructionAtIndex(
339  (i*ii)+place).addMove(nodeCopy->movePtr());
340  if (Application::verboseLevel() > 1) {
341  Application::logStream() << " to epilog" << std::endl;
342  }
343  rootDDG->addNode(*nodeCopy, *epilogNode);
344  rootDDG->copyExternalInEdges(*nodeCopy, n);
345  rootDDG->copyExternalOutEdges(*nodeCopy, n);
346  }
347  }
348  }
349  }
350  assert(jumpMove != NULL);
351 
352  if (Application::verboseLevel() > 1) {
354  << "Disassembly of prolog" << std::endl <<
355  prolog->disassembly() << std::endl;
356  if (createEpilog) {
358  << "Disassembly of epilog" << std::endl <<
359  epilog->disassembly() << std::endl;
360  }
361  }
362 
363  if (optimizeProlog(*prolog)) {
364  if (Application::verboseLevel() > 1) {
366  << "Disassembly of optimized prolog" << std::endl <<
367  prolog->disassembly() << std::endl;
368  }
369  addPrologIntoCfg(cfg, *prologNode, loopBBN);
370  } else {
371  delete prologNode;
372  }
373  if (Application::verboseLevel() > 1) {
375  << "Prolog optimized."
376  << std::endl;
377  }
378  if (createEpilog) {
379  if (optimizeEpilog(*epilog)) {
380  if (Application::verboseLevel() > 1) {
382  << "Disassembly of optimized epilog" << std::endl <<
383  epilog->disassembly() << std::endl;
384  }
385  addEpilogIntoCfg(cfg, *epilogNode, loopBBN);
386  } else {
387  delete epilogNode; // TODO: what about the BB?
388  }
389  if (Application::verboseLevel() > 1) {
391  << "Epilog optimized."
392  << std::endl;
393  }
394  }
395  } else {
396  if (Application::verboseLevel() > 1) {
398  << "No overlapping instructions.No need for prolog or epilog."
399  << "Should have used normal scheduler."
400  << std::endl;
401  }
402  }
403 
404  return overlap_count;
405 }

References TTAProgram::CodeSnippet::add(), addEpilogIntoCfg(), TTAProgram::Instruction::addImmediate(), TTAProgram::Instruction::addMove(), DataDependenceGraph::addNode(), addPrologIntoCfg(), assert, TTAProgram::Immediate::copy(), MoveNode::copy(), DataDependenceGraph::copyExternalInEdges(), DataDependenceGraph::copyExternalOutEdges(), MoveNode::cycle(), TTAProgram::CodeSnippet::disassembly(), TTAProgram::Instruction::immediate(), TTAProgram::Instruction::immediateCount(), SimpleResourceManager::initiationInterval(), SimpleResourceManager::instruction(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::Move::isControlFlowMove(), DataDependenceGraph::largestCycle(), Application::logStream(), MoveNode::move(), MoveNode::movePtr(), BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), optimizeEpilog(), optimizeProlog(), BasicBlockNode::originalStartAddress(), BoostGraph< GraphNode, GraphEdge >::rootGraph(), MoveNode::setCycle(), TTAProgram::Move::setGuard(), SimpleResourceManager::smallestCycle(), MoveNode::toString(), and Application::verboseLevel().

Here is the call graph for this function:

◆ moveJumpDestination()

void LoopPrologAndEpilogBuilder::moveJumpDestination ( TTAProgram::InstructionReferenceManager irm,
BasicBlockNode tail,
BasicBlockNode dst,
ControlFlowEdge jumpEdge 
)
private

Definition at line 63 of file LoopPrologAndEpilogBuilder.cc.

66  {
67  TTAProgram::BasicBlock& tailBB = tail.basicBlock();
68 
69  auto predicate = jumpEdge.edgePredicate();
70  std::pair<int, TTAProgram::Move*> jumpData =
71  CopyingDelaySlotFiller::findJump(tailBB, &predicate);
72 
73  std::pair<TTAProgram::Move*, std::shared_ptr<TTAProgram::Immediate> >
74  jumpAddressData;
75 
76  // should be the same
77  int jumpIndex = jumpData.first;
78  TTAProgram::Move* jumpMove = jumpData.second;
79  if (jumpMove == NULL) {
80  abortWithError("incoming jump not found");
81  }
82 
86 
87  if (!jumpMove->source().isInstructionAddress()) {
88  // address comes from LIMM, search the write to limm reg.
89  jumpAddressData =
91  jumpIndex, *jumpMove, irm);
92  if (jumpAddressData.first == NULL &&
93  jumpAddressData.second == NULL) {
94  //Imm source not found, aborting
95  abortWithError("Unknown immediate contains jump address");
96  return;
97  }
98  if (jumpAddressData.first != NULL) {
99  jumpAddressData.first->setSource(
101  } else {
102  jumpAddressData.second->setValue(
104  }
105  } else {
106  jumpMove->source().setInstructionReference(ir);
107  }
108 }

References abortWithError, BasicBlockNode::basicBlock(), TTAProgram::InstructionReferenceManager::createReference(), ControlFlowEdge::edgePredicate(), CopyingDelaySlotFiller::findJump(), CopyingDelaySlotFiller::findJumpImmediate(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::Terminal::isInstructionAddress(), TTAProgram::Terminal::setInstructionReference(), TTAProgram::BasicBlock::skippedFirstInstructions(), and TTAProgram::Move::source().

Referenced by addPrologIntoCfg().

Here is the call graph for this function:

◆ optimizeEpilog()

bool LoopPrologAndEpilogBuilder::optimizeEpilog ( TTAProgram::BasicBlock epilog)
private

Definition at line 575 of file LoopPrologAndEpilogBuilder.cc.

575  {
576 
577  if (epilog.instructionCount() == 0) {
578  return false;
579  }
580 
581  for (int i = epilog.instructionCount() -1 ; i >= 0 ; i--) {
583  // check for moves is enough. no imms after moves.
584  if (ins.moveCount() > 0) {
585  break;
586  } else {
587  // empty? leave one ins behind just for
588  if (i == 0) {
589  return false;
590  }
591  assert(i!= 0);
592  epilog.remove(ins);
593  delete &ins;
594  }
595  }
596  return true;
597 }

References assert, TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Instruction::moveCount(), and TTAProgram::CodeSnippet::remove().

Referenced by addEpilogFromRM(), and build().

Here is the call graph for this function:

◆ optimizeProlog()

bool LoopPrologAndEpilogBuilder::optimizeProlog ( TTAProgram::BasicBlock prolog)
private

Definition at line 492 of file LoopPrologAndEpilogBuilder.cc.

492  {
493 
494  if (prolog.instructionCount() == 0) {
495  return false;
496  }
497  // optimize away immediate values not used
498  for (int i = 0; i < prolog.instructionCount() ;i++) {
500  for (int j = 0; j < ins.immediateCount(); j++) {
501  bool used = false;
502  bool overwritten = false;
503  TTAProgram::Immediate& imm = ins.immediate(j);
504  const TTAProgram::Terminal& t = imm.destination();
505  const TTAProgram::Terminal& dst = imm.destination();
506  const TTAMachine::ImmediateUnit& immu = dst.immediateUnit();
507  for (int k = i + immu.latency() ;
508  k < prolog.instructionCount() &&
509  !used && !overwritten; k++) {
510 
512  // if immu has latency 0, check immediate before moves.
513  if (immu.latency() == 0 && k > i) {
514  for (int l = 0; l < ins2.immediateCount(); l++) {
515  const TTAProgram::Immediate& imm2 = ins2.immediate(l);
516  const TTAProgram::Terminal& t2 = imm2.destination();
517  if (&t2.immediateUnit() == & t.immediateUnit() &&
518  t2.index() == t.index()) {
519  overwritten = true;
520  break;
521  }
522  }
523  }
524 
525  for (int l = 0; l < ins2.moveCount(); l++) {
526  const TTAProgram::Move& m = ins2.move(l);
527  const TTAProgram::Terminal& t2 = m.source();
528  if (t2.isImmediateRegister() &&
529  &t2.immediateUnit() == &dst.immediateUnit() &&
530  t2.index() == dst.index()) {
531  used = true;
532  break;
533  }
534  }
535  // if immu has latency 1, check moves before imms
536  if (immu.latency() == 1) {
537  for (int l = 0; l < ins2.immediateCount(); l++) {
538  const TTAProgram::Immediate& imm2 = ins2.immediate(l);
539  const TTAProgram::Terminal& t2 = imm2.destination();
540  if (&t2.immediateUnit() == & t.immediateUnit() &&
541  t2.index() == t.index()) {
542  overwritten = true;
543  break;
544  }
545  }
546  }
547  }
548  if (!used && overwritten) {
549  ins.removeImmediate(imm);
550  }
551  }
552  }
553  for (int i = 0; i <= prolog.instructionCount() -1 ;i++) {
555  // check for moves is enough. no imms after moves.
556  if (ins.moveCount() > 0 || ins.immediateCount() > 0) {
557  break;
558  } else {
559  // empty? leave one ins behind just for
560  if (i == prolog.instructionCount() - 1) {
561  return false;
562  }
563  prolog.remove(ins);
564  delete &ins;
565  // We removed current instruction, there shell be new current
566  // instruction once we increse i at beginning of the loop.
567  i--;
568  }
569  }
570  return true;
571 }

References TTAProgram::Immediate::destination(), TTAProgram::Instruction::immediate(), TTAProgram::Instruction::immediateCount(), TTAProgram::Terminal::immediateUnit(), TTAProgram::Terminal::index(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Terminal::isImmediateRegister(), TTAMachine::ImmediateUnit::latency(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), TTAProgram::CodeSnippet::remove(), TTAProgram::Instruction::removeImmediate(), and TTAProgram::Move::source().

Referenced by addPrologFromRM(), and build().

Here is the call graph for this function:

The documentation for this class was generated from the following files:
BoostGraph::connectNodes
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
BoostGraph::outEdge
virtual Edge & outEdge(const Node &node, const int index) const
TTAProgram::Instruction::addMove
void addMove(std::shared_ptr< Move > move)
Definition: Instruction.cc:147
BoostGraph::tailNode
virtual Node & tailNode(const Edge &edge) const
SimpleResourceManager::largestCycle
virtual int largestCycle() const override
Definition: SimpleResourceManager.cc:463
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
TTAProgram::Instruction::move
Move & move(int i) const
Definition: Instruction.cc:193
TTAProgram::Terminal::index
virtual int index() const
Definition: Terminal.cc:274
TTAProgram::Terminal::isInstructionAddress
virtual bool isInstructionAddress() const
Definition: Terminal.cc:87
BoostGraph::headNode
virtual Node & headNode(const Edge &edge) const
BoostGraph::node
Node & node(const int index) const
MoveNode::movePtr
std::shared_ptr< TTAProgram::Move > movePtr()
ControlFlowEdge::isJumpEdge
bool isJumpEdge() const
Definition: ControlFlowEdge.cc:148
TTAProgram::Instruction
Definition: Instruction.hh:57
SimpleResourceManager::smallestCycle
virtual int smallestCycle() const override
Definition: SimpleResourceManager.cc:480
CopyingDelaySlotFiller::findJump
static std::pair< int, TTAProgram::Move * > findJump(TTAProgram::BasicBlock &bb, ControlFlowEdge::CFGEdgePredicate *pred=nullptr)
Definition: CopyingDelaySlotFiller.cc:1751
TTAProgram::CodeSnippet::remove
virtual void remove(Instruction &ins)
Definition: CodeSnippet.cc:558
TTAProgram::InstructionReferenceManager::createReference
InstructionReference createReference(Instruction &ins)
Definition: InstructionReferenceManager.cc:73
TTAProgram::Instruction::removeImmediate
void removeImmediate(Immediate &imm)
Definition: Instruction.cc:560
TTAProgram::Move::setGuard
void setGuard(MoveGuard *guard)
Definition: Move.cc:360
MoveNode
Definition: MoveNode.hh:65
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
BoostGraph::addNode
virtual void addNode(Node &node)
LoopPrologAndEpilogBuilder::moveJumpDestination
void moveJumpDestination(TTAProgram::InstructionReferenceManager &irm, BasicBlockNode &tail, BasicBlockNode &dst, ControlFlowEdge &jumpEdge)
Definition: LoopPrologAndEpilogBuilder.cc:63
TTAProgram::Immediate::copy
std::shared_ptr< Immediate > copy() const
Definition: Immediate.cc:131
SimpleResourceManager::initiationInterval
virtual unsigned initiationInterval() const
Definition: SimpleResourceManager.hh:135
ControlFlowGraph::instructionReferenceManager
TTAProgram::InstructionReferenceManager & instructionReferenceManager()
Definition: ControlFlowGraph.cc:2401
TTAProgram::CodeSnippet::disassembly
virtual std::string disassembly() const
Definition: CodeSnippet.cc:820
TTAMachine::ImmediateUnit::latency
virtual int latency() const
Definition: ImmediateUnit.cc:155
ControlFlowEdge
Definition: ControlFlowEdge.hh:50
BoostGraph::outDegree
virtual int outDegree(const Node &node) const
ControlFlowEdge::CFLOW_EDGE_NORMAL
@ CFLOW_EDGE_NORMAL
Definition: ControlFlowEdge.hh:53
BoostGraph::moveInEdge
virtual void moveInEdge(const Node &source, const Node &destination, Edge &edge, const Node *tail=NULL, bool childs=false)
BasicBlockNode::basicBlock
TTAProgram::BasicBlock & basicBlock()
Definition: BasicBlockNode.cc:126
TTAProgram::Immediate::destination
const Terminal & destination() const
Definition: Immediate.cc:92
assert
#define assert(condition)
Definition: Application.hh:86
TTAProgram::Terminal::isImmediateRegister
virtual bool isImmediateRegister() const
Definition: Terminal.cc:97
TTAProgram::Immediate
Definition: Immediate.hh:54
TTAProgram::BasicBlock::skippedFirstInstructions
int skippedFirstInstructions() const
Definition: BasicBlock.cc:88
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
MoveNode::cycle
int cycle() const
Definition: MoveNode.cc:421
TTAProgram::Move::isControlFlowMove
bool isControlFlowMove() const
Definition: Move.cc:233
DataDependenceGraph::largestCycle
int largestCycle() const
Definition: DataDependenceGraph.cc:1838
BoostGraph::rootGraph
BoostGraph * rootGraph()
LoopPrologAndEpilogBuilder::optimizeEpilog
bool optimizeEpilog(TTAProgram::BasicBlock &epilog)
Definition: LoopPrologAndEpilogBuilder.cc:575
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
TTAProgram::CodeSnippet::add
virtual void add(Instruction *ins)
Definition: CodeSnippet.cc:432
DataDependenceGraph::copyExternalOutEdges
void copyExternalOutEdges(MoveNode &nodeCopy, const MoveNode &source)
Definition: DataDependenceGraph.cc:5346
LoopPrologAndEpilogBuilder::addPrologIntoCfg
void addPrologIntoCfg(ControlFlowGraph &cfg, BasicBlockNode &prologBBN, BasicBlockNode &loopBBN)
Definition: LoopPrologAndEpilogBuilder.cc:120
BoostGraph::inEdge
virtual Edge & inEdge(const Node &node, const int index) const
LoopPrologAndEpilogBuilder::optimizeProlog
bool optimizeProlog(TTAProgram::BasicBlock &prolog)
Definition: LoopPrologAndEpilogBuilder.cc:492
BasicBlockNode
Definition: BasicBlockNode.hh:64
TTAProgram::TerminalInstructionReference
Definition: TerminalInstructionReference.hh:48
TTAProgram::Terminal::immediateUnit
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
Definition: Terminal.cc:240
LoopPrologAndEpilogBuilder::addEpilogIntoCfg
void addEpilogIntoCfg(ControlFlowGraph &cfg, BasicBlockNode &epilogBBN, BasicBlockNode &loopBBN)
Definition: LoopPrologAndEpilogBuilder.cc:166
TTAProgram::Move
Definition: Move.hh:55
ControlFlowEdge::isFallThroughEdge
bool isFallThroughEdge() const
Definition: ControlFlowEdge.cc:158
BoostGraph::inDegree
virtual int inDegree(const Node &node) const
CopyingDelaySlotFiller::findJumpImmediate
static std::pair< TTAProgram::Move *, std::shared_ptr< TTAProgram::Immediate > > findJumpImmediate(int jumpIndex, TTAProgram::Move &jumpMove, TTAProgram::InstructionReferenceManager &irm)
Definition: CopyingDelaySlotFiller.cc:705
BasicBlockPass::copyRMToBB
static void copyRMToBB(SimpleResourceManager &rm, TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, int lastCycle=-1)
Definition: BasicBlockPass.cc:213
TTAProgram::Instruction::immediate
Immediate & immediate(int i) const
Definition: Instruction.cc:285
BF2Scheduler::PROLOG_CYCLE_BIAS
static const int PROLOG_CYCLE_BIAS
Definition: BF2Scheduler.hh:209
ControlFlowEdge::edgePredicate
CFGEdgePredicate edgePredicate() const
Definition: ControlFlowEdge.hh:83
DataDependenceGraph::addNode
void addNode(MoveNode &moveNode)
Definition: DataDependenceGraph.cc:144
BasicBlockNode::setScheduled
void setScheduled(bool state=true)
Definition: BasicBlockNode.hh:94
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
MoveNode::move
TTAProgram::Move & move()
MoveNode::setCycle
void setCycle(const int newcycle)
Definition: MoveNode.cc:503
ResourceManager::machine
const TTAMachine::Machine & machine() const
Definition: ResourceManager.cc:56
TTAProgram::Instruction::immediateCount
int immediateCount() const
Definition: Instruction.cc:267
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
SimpleResourceManager::loseInstructionOwnership
virtual void loseInstructionOwnership(int cycle)
Definition: SimpleResourceManager.cc:498
TTAProgram::Terminal
Definition: Terminal.hh:60
TTAProgram::CodeSnippet::instructionAtIndex
virtual Instruction & instructionAtIndex(int index) const
Definition: CodeSnippet.cc:285
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
TTAProgram::Terminal::setInstructionReference
virtual void setInstructionReference(InstructionReference ref)
Definition: Terminal.cc:404
MoveNode::copy
MoveNode * copy()
Definition: MoveNode.cc:135
ControlFlowEdge::CFLOW_EDGE_FALLTHROUGH
@ CFLOW_EDGE_FALLTHROUGH
Definition: ControlFlowEdge.hh:62
BoostGraph::nodeCount
int nodeCount() const
DataDependenceGraph::copyExternalInEdges
void copyExternalInEdges(MoveNode &nodeCopy, const MoveNode &source)
Definition: DataDependenceGraph.cc:5323
TTAProgram::InstructionReference
Definition: InstructionReference.hh:49
BasicBlockNode::originalStartAddress
InstructionAddress originalStartAddress() const
Definition: BasicBlockNode.cc:162
TTAProgram::Instruction::moveCount
int moveCount() const
Definition: Instruction.cc:176
TTAProgram::Instruction::addImmediate
void addImmediate(std::shared_ptr< Immediate > imm)
Definition: Instruction.cc:234
BasicBlockNode::toString
std::string toString() const
Definition: BasicBlockNode.cc:185
SimpleResourceManager::instruction
virtual TTAProgram::Instruction * instruction(int cycle) const override
Definition: SimpleResourceManager.cc:442
TTAMachine::ImmediateUnit
Definition: ImmediateUnit.hh:50