OpenASIP  2.0
LoopAnalyzer.cc
Go to the documentation of this file.
1 #include "LoopAnalyzer.hh"
2 #include "Move.hh"
3 #include "MoveNodeSet.hh"
4 #include "Operation.hh"
5 #include "Terminal.hh"
6 #include "Instruction.hh"
7 #include "BasicBlock.hh"
8 #include "BasicBlockNode.hh"
9 #include "MoveGuard.hh"
10 
11 //#define DEBUG_LOOP_ANALYZER
12 
15  MoveNode* jumpMove = NULL;
16 
17 #ifdef DEBUG_LOOP_ANALYZER
18  TCEString dotName("loop_analyzis");
19  dotName << ddg.name();
20  dotName << ".dot";
21  ddg.writeToDotFile(dotName);
22 #endif
23 
25  for (int i = bb.instructionCount()-1; i >= 0;i--) {
26  TTAProgram::Instruction& ins = bb[i];
27  for (int j = 0; j < ins.moveCount(); j++) {
28  TTAProgram::Move& move = ins.move(j);
29  if (move.isJump()) {
30  jumpMove = &ddg.nodeOfMove(move);
31  }
32  }
33  }
34  if (jumpMove == NULL) {
35  return NULL;
36  }
37 
38  MoveNode* guardDef = ddg.onlyGuardDefOfMove(*jumpMove);
39  if (guardDef == NULL) {
40  return NULL;
41  }
42  while (guardDef->isSourceVariable()) {
43  guardDef = ddg.onlyRegisterRawSource(*guardDef);
44  if (guardDef == NULL) {
45  return NULL;
46  }
47  }
48  // find guard def op.
49  if (!guardDef->isSourceOperation()) {
50  return NULL;
51  }
52  ProgramOperation* gdpo = &guardDef->sourceOperation();
53  bool inverted = jumpMove->move().guard().isInverted();
54 
55  // machine does not have ne operation so eq + xor used.
56  if (gdpo->operation().name() == "XOR") {
57  MoveNodeSet& input1Set = gdpo->inputNode(1);
58  MoveNodeSet& input2Set = gdpo->inputNode(2);
59  if (input1Set.count() != 1 || input2Set.count() != 1) {
60  return NULL;
61  }
62  MoveNode& input1 = input1Set.at(0);
63  MoveNode& input2 = input2Set.at(0);
64 
65  MoveNode *regMove = NULL;
66  if (input1.move().source().isGPR() &&
67  input2.move().source().isImmediate()) {
68  regMove = &input1;
69  }
70 
71  if (input2.move().source().isGPR() &&
72  input1.move().source().isImmediate()) {
73  regMove = &input2;
74  }
75 
76  // bypassed directly from eq?
77  if (input1.isSourceOperation() &&
78  input2.move().source().isImmediate()) {
79  gdpo = &input1.sourceOperation();
80  } else {
81  if (input2.isSourceOperation() &&
82  input1.move().source().isImmediate()) {
83  gdpo = &input2.sourceOperation();
84  } else { // not bypassed.
85  if (regMove == NULL) {
86  return NULL;
87  }
88  MoveNode* xorSrc = ddg.onlyRegisterRawSource(*regMove);
89  if (xorSrc != NULL && xorSrc->isSourceOperation()) {
90  inverted = !inverted;
91  gdpo = &xorSrc->sourceOperation();
92  } else {
93  return NULL;
94  }
95  }
96  }
97  }
98  // now we should have the comparison op.
99  // supported comparisons:
100 
101  // 0 -> N: x ne N -> jump
102  // 0 -> N: x lt N -> jump
103  // 0 -> N: N gt x -> jump
104  // and same with inverted. (eq, geu, leu)
105 
106  // N -> 0: x ne 0 -> jump
107  // N -> 0: x gt 0 -> jump
108  // N -> 0: 0 lt x -> jump
109  // and same with inverted (eq, ltu, geu)
110  bool gtu = false;
111  bool ltu = false;
112 
113 #ifndef DEBUG_LOOP_ANALYZER
114  if (Application::verboseLevel() > 1) {
115 #endif
116  std::cerr << "\tLoop comparison op is: " <<gdpo->toString()<< std::endl;
117 #ifndef DEBUG_LOOP_ANALYZER
118  }
119 #endif
120 
121  if (!((gdpo->operation().name() == "NE" && !inverted) ||
122  (gdpo->operation().name() == "EQ" && inverted))) {
123  if ((gdpo->operation().name() == "GTU" && !inverted) ||
124  (gdpo->operation().name() == "LEU" && inverted)) {
125  gtu = true;
126  } else {
127  if ((gdpo->operation().name() == "LTU" && !inverted) ||
128  (gdpo->operation().name() == "GEU" && inverted)) {
129  ltu = true;
130  } else {
131  // unsupported comparison operation.
132 #ifndef DEBUG_LOOP_ANALYZER
133  if (Application::verboseLevel() > 1) {
134 #endif
135  std::cerr <<
136  "Unsupported comparison op for loop analyzer." <<
137  std::endl;
138 #ifndef DEBUG_LOOP_ANALYZER
139  }
140 #endif
141  return NULL;
142  }
143  }
144  }
145 
146  MoveNode* constCmp = NULL;
147  MoveNode* regCmp1 = NULL;
148  MoveNode* regCmp2 = NULL;
149  MoveNode* onlyRegCmp = NULL;
150 
151  MoveNodeSet& input1Set = gdpo->inputNode(1);
152  MoveNodeSet& input2Set = gdpo->inputNode(2);
153  if (input1Set.count() != 1 || input2Set.count() != 1) {
154  return NULL;
155  }
156  MoveNode& input1 = input1Set.at(0);
157  MoveNode& input2 = input2Set.at(0);
158  if (input1.move().source().isGPR()) {
159  onlyRegCmp = regCmp1 = &input1;
160  } else if (input1.move().source().isImmediate() ||
161  input1.move().source().isImmediateRegister()) {
162  constCmp = &input1;
163  }
164 
165  if (input2.move().source().isGPR()) {
166  regCmp2 = &input2;
167  if (onlyRegCmp == NULL) {
168  onlyRegCmp = regCmp2;
169  } else {
170  onlyRegCmp = NULL;
171  }
172  } else if (input2.move().source().isImmediate() ||
173  input2.move().source().isImmediateRegister()) {
174  if (constCmp != NULL) {
175  return NULL;
176  }
177  constCmp = &input2;
178  }
179 
180  int endVal;
181  // case 1: Either one is constant.
182  if (constCmp) {
183  if (constCmp == &input1) {
184  // operand 1 of comparison is limit. this means
185  // comparison operands are "swapped".
186  if (gtu) {
187  ltu = true;
188  gtu = false;
189  } else if (ltu) {
190  ltu = false;
191  gtu = true;
192  }
193  }
194 
195  TTAProgram::Terminal& src = constCmp->move().source();
196  if (src.isImmediateRegister()) {
197  return NULL; // not yet supported
198  }
199  endVal = src.value().intValue();
200  InitAndUpdate* initAndUpdate = findInitAndUpdate(ddg, *onlyRegCmp);
201  if (initAndUpdate == NULL) {
202  return NULL;
203  }
204  int update = initAndUpdate->update;
205  if (initAndUpdate->initNode != NULL) {
206  // goes from X to zero.
207  if (update <0 && endVal == 0) {
208  if (ltu) return NULL;
209  return new LoopAnalysisResult(
210  initAndUpdate->loopEdge, initAndUpdate->initNode,-update);
211  } else {
212  if (update < 0 && abs(endVal) < -update) {
213  if (ltu) return NULL;
214  return new LoopAnalysisResult(
215  initAndUpdate->loopEdge,
216  initAndUpdate->initNode, -update);
217  } else {
218  if (ltu) return NULL;
219  if (endVal < 0) {
220  return new LoopAnalysisResult(
221  initAndUpdate->loopEdge + (endVal/update),
222  initAndUpdate->initNode, -update);
223  }
224  }
225  return NULL;
226  }
227  }
228  int diff = endVal - initAndUpdate->initVal;
229  if (diff % update != 0) {
230  return NULL;
231  }
232  if (update < 0 && gtu) return NULL;
233  if (update > 0 && ltu) return NULL;
234  return new LoopAnalysisResult(
235  (diff / update) + initAndUpdate->loopEdge, NULL);
236 
237  } else { // case 2: both are registers.
238  InitAndUpdate* initAndUpdate = findInitAndUpdate(ddg, *regCmp1);
239  EndCondition* endCond = NULL;
240  if (initAndUpdate == NULL) {
241  initAndUpdate = findInitAndUpdate(ddg, *regCmp2);
242  if (initAndUpdate == NULL) {
243  return NULL;
244  }
245  // operand 1 of comparison is limit. this means
246  // comparison operand are "swapped".
247  if (gtu) {
248  ltu = true;
249  gtu = false;
250  } else if (ltu) {
251  ltu = false;
252  gtu = true;
253  }
254 
255  endCond = findEndCond(ddg, *regCmp1, false);
256  if (endCond == NULL) {
257  endCond = findEndCond(ddg, *regCmp1, true);
258  }
259  } else {
260  endCond = findEndCond(ddg, *regCmp2, false);
261  if (endCond == NULL) {
262  endCond = findEndCond(ddg, *regCmp2, true);
263  }
264  }
265  if (endCond == NULL) {
266 #ifndef DEBUG_LOOP_ANALYZER
267  if (Application::verboseLevel() > 1) {
268 #endif
269  std::cerr << "Could not analyze end condition" << std::endl;
270 #ifndef DEBUG_LOOP_ANALYZER
271  }
272 #endif
273  // Could not analyze endcond
274  return NULL;
275  }
276 
277  // init from variable.
278  if (initAndUpdate->initNode != NULL) {
279  int update = initAndUpdate->update;
280  // go down from variable to 0.
281  if (endCond->first == 0 && endCond->second == NULL) {
282  // no update value of wrong comparison
283  if (ltu || update >= 0 ) return NULL;
284  if (update == -1 || gtu) {
285  return new LoopAnalysisResult(
286  initAndUpdate->loopEdge,
287  initAndUpdate->initNode, -update);
288  }
289  }
290  // both variables, but calculated from same source
291  // with add or sub operation.
292  if (endCond->second && initAndUpdate->initNode) {
293  EndCondition* commonAncestor =
295  ddg, *initAndUpdate->initNode, *endCond->second);
296  if (commonAncestor != NULL) {
297  if (commonAncestor->second == NULL) {
298  if (update < 0 && ltu) return NULL;
299  if (update > 0 && gtu) return NULL;
300  return new LoopAnalysisResult(
301  commonAncestor->first/update +
302  initAndUpdate->loopEdge);
303  }
304  }
305  }
306  return NULL;
307  }
308 
309  if (endCond->second == NULL) {
310 #ifndef DEBUG_LOOP_ANALYZER
311  if (Application::verboseLevel() > 1) {
312 #endif
313  std::cerr << "End condition is constant:" << endCond->first << std::endl;
314 #ifndef DEBUG_LOOP_ANALYZER
315  }
316 #endif
317  int diff = endCond->first - initAndUpdate->initVal;
318  int update = initAndUpdate->update;
319  if (diff % update != 0) {
320  return NULL;
321  }
322  if (update < 0 && ltu) return NULL;
323  if (update > 0 && gtu) return NULL;
324  return new LoopAnalysisResult((diff / update) + initAndUpdate->loopEdge, NULL);
325  } else {
326 
327 #ifndef DEBUG_LOOP_ANALYZER
328  if (Application::verboseLevel() > 1) {
329 #endif
330  std::cerr << "\tLoop end register might be: " << endCond->second->toString() << std::endl;
331  std::cerr << "\tEnd cond first is: " << endCond->first << std::endl;
332  std::cerr << "\t init is: " << initAndUpdate->initVal
333  << " and update is: " << initAndUpdate->update << std::endl;
334 #ifndef DEBUG_LOOP_ANALYZER
335  }
336 #endif
337  if (initAndUpdate->initVal != 0) {
338 #ifndef DEBUG_LOOP_ANALYZER
339  if (Application::verboseLevel() > 1) {
340 #endif
341  std::cerr << "Variable loop counts with init !=0 not yet supported" << std::endl;
342 #ifndef DEBUG_LOOP_ANALYZER
343  }
344 #endif
345  return NULL;
346  }
347  return new LoopAnalysisResult(initAndUpdate->loopEdge, endCond->second, initAndUpdate->update);
348  }
349 
350  }
351 
352  return NULL;
353 }
354 
355 
357 LoopAnalyzer::findEndCond(DataDependenceGraph& ddg, MoveNode& cmpVal, bool allowVariable) {
358 #ifdef DEBUG_LOOP_ANALYZER
359  std::cerr << "\tSearching end cond, allow var: " << allowVariable
360  << " from: " << cmpVal.toString() << std::endl;
361 #endif
362  if (cmpVal.isSourceConstant()) {
363  return new EndCondition(
364  cmpVal.move().source().value().intValue(), NULL);
365  }
366  MoveNode* cmpSrc = ddg.onlyRegisterRawSource(cmpVal);
367  if (cmpSrc == NULL) {
368 #ifdef DEBUG_LOOP_ANALYZER
369  std::cerr << "\t\tNo only RRAW source found, returning this or NULL"
370  << std::endl;
371 #endif
372  if (cmpVal.move().source().isGPR() && allowVariable) {
373  return new EndCondition(0, &cmpVal);
374  } else {
375  return NULL;
376  }
377  }
378 
379  if (cmpSrc->isSourceConstant()) {
380  return new EndCondition(
381  cmpSrc->move().source().value().intValue(), NULL);
382  }
383 
384  if (&ddg.getBasicBlockNode(cmpVal) != &ddg.getBasicBlockNode(*cmpSrc)
385  && allowVariable) {
386 #ifdef DEBUG_LOOP_ANALYZER
387  std::cerr << "cmp val" << cmpVal.toString() << " and cmpsrc "
388  << cmpSrc->toString() << " has different BB, ret cmpval"
389  << std::endl;
390 #endif
391  return new EndCondition(0, &cmpVal);
392  }
393 
394  if (cmpSrc->isSourceVariable()) {
395  return findEndCond(ddg, *cmpSrc, allowVariable);
396  }
397 
398  if (!cmpSrc->isSourceOperation()) {
399  if (allowVariable) {
400  return new EndCondition(0, &cmpVal);
401  } else {
402  return NULL;
403  }
404  }
405 
406  ProgramOperation& po = cmpSrc->sourceOperation();
407  bool isSub = po.operation().name() == "SUB";
408  bool isAdd = po.operation().name() == "ADD";
409  if (!isSub && !isAdd) {
410 #ifdef DEBUG_LOOP_ANALYZER
411  std::cerr << "\t\tFind End Cond unknown op, returning NULL" << std::endl;
412 #endif
413  return NULL;
414  }
415 
416  MoveNodeSet& input1Set = po.inputNode(1);
417  MoveNodeSet& input2Set = po.inputNode(2);
418  if (input1Set.count() != 1 || input2Set.count() != 1) {
419  if (allowVariable) { // TODO: is this also borken?
420  return new EndCondition(0, &cmpVal);
421  } else {
422  return NULL;
423  }
424  }
425  MoveNode& input1 = input1Set.at(0);
426  MoveNode& input2 = input2Set.at(0);
427 
428  EndCondition* tmpRes2 = findEndCond(ddg, input2, allowVariable);
429  if (tmpRes2 == NULL) {
430  return NULL;
431  }
432  if (tmpRes2->second == NULL) {
433  int value = tmpRes2->first;
434  if (isSub) {
435  value *= -1;
436  }
437 
438  EndCondition* tmpRes1 = findEndCond(ddg, input1, allowVariable);
439  if (tmpRes1 == NULL) {
440  return NULL;
441  }
442  tmpRes1->first += value;
443  return tmpRes1;
444  } else { // 2 comes from a reg.
445  // sub by register getting too cmplex, giving up.
446  if (isSub) {
447  if (allowVariable) {
448  return new EndCondition(0, &cmpVal);
449  } else {
450  return NULL;
451  }
452  }
453  EndCondition* tmpRes1 = findEndCond(ddg, input1, allowVariable);
454  if (tmpRes1 == NULL) {
455  return NULL;
456  }
457  if (tmpRes1->second == NULL) {
458  tmpRes2->first += tmpRes1->first;
459  return tmpRes2;
460  } else { // both from reg.. return me.
461  return new EndCondition(0, &cmpVal);
462  }
463  }
464  // should never be here
465  assert(false);
466 }
467 
468 
469 
472  // TODO: looping and non-looping update
473 #ifndef DEBUG_LOOP_ANALYZER
474  if (Application::verboseLevel() > 1) {
475 #endif
476  std::cerr << "\tSearching init and update from cmpval: "
477  << cmpVal.toString() << std::endl;
478 #ifndef DEBUG_LOOP_ANALYZER
479  }
480 #endif
481 
482  MoveNode* cmpSrc = ddg.onlyRegisterRawSource(cmpVal,0);
483  MoveNode* backCmpSrc = ddg.onlyRegisterRawSource(cmpVal,1);
484 
485  if (cmpSrc == NULL) {
486  MoveNode* fwdCmpSrc = ddg.onlyRegisterRawSource(cmpVal,2);
487  if (backCmpSrc && fwdCmpSrc) {
488  // update happens after comparison, this means
489  // iteration count is one more.
490  cmpSrc = backCmpSrc;
491  } else {
492  return NULL;
493  }
494  }
495 
496  MoveNode* originalCmpSrc = cmpSrc;
497 
498  if (!cmpSrc->isSourceOperation()) {
499  MoveNode* cmpSrcSrc = ddg.onlyRegisterRawSource(*cmpSrc);
500  if (cmpSrcSrc == NULL) {
501  return NULL;
502  } else {
503  if (!cmpSrcSrc->isSourceOperation()) {
504  return NULL;
505  } else {
506  cmpSrc = cmpSrcSrc;
507  }
508  }
509  }
510 
511  ProgramOperation& po = cmpSrc->sourceOperation();
512  bool isSub = po.operation().name() == "SUB";
513  bool isAdd = po.operation().name() == "ADD";
514  if (!isSub && !isAdd) {
515  return NULL;
516  }
517 
518  // is add or sub
519  MoveNodeSet& input1Set = po.inputNode(1);
520  MoveNodeSet& input2Set = po.inputNode(2);
521  if (input1Set.count() != 1 || input2Set.count() != 1) {
522  return NULL;
523  }
524  MoveNode& input1 = input1Set.at(0);
525  MoveNode& input2 = input2Set.at(0);
526 
527  MoveNode *regMove = NULL;
528  MoveNode *immMove = NULL;
529  if (input1.move().source().isGPR() &&
530  input2.move().source().isImmediate()) {
531  regMove = &input1;
532  immMove = &input2;
533  } else if (input2.move().source().isGPR() &&
534  input1.move().source().isImmediate()) {
535  // no sub by variable
536  if (isSub) {
537  return NULL;
538  }
539  regMove = &input2;
540  immMove = &input1;
541  } else { // not yet supported.
542  return NULL;
543  }
544 
545  int updateVal = immMove->move().source().value().intValue();
546  if (isSub) {
547  updateVal *=-1;
548  }
549 
550 
551  MoveNode* updateSource = ddg.onlyRegisterRawSource(*regMove, 2, 1);
552  if (updateSource == NULL ||
553  (updateSource != cmpSrc && updateSource != originalCmpSrc)) {
554  return NULL;
555  }
556 
557  DataDependenceGraph::NodeSet initNodes =
558  ddg.regRawPredecessors(*regMove, 2);
559  MoveNode* counterInit = NULL;
560  if (initNodes.size() == 1) {
561  counterInit = *initNodes.begin();
562  } else if (initNodes.size() > 1) {
563 #ifdef DEBUG_LOOP_ANALYZER
564  std::cerr << "multiple init nodes, must be dynamic " << std::endl;
565 #endif
566  for (auto i = initNodes.begin(); i != initNodes.end(); i++) {
567  std::cerr << "\t\t" << (**i).toString() << std::endl;
568  }
569  return new InitAndUpdate(*regMove, updateVal, backCmpSrc != 0);
570  }
571 
572  if (counterInit == NULL) {
573  return NULL;
574  }
575  int counterOffset = 0;
576  while (true) {
577  if (counterInit->isSourceVariable()) {
578  counterInit = ddg.onlyRegisterRawSource(*counterInit);
579  if (counterInit == NULL) {
580  return new InitAndUpdate(*regMove, updateVal, backCmpSrc !=0);
581  }
582  } else { // not variable
583 #ifdef DEBUG_LOOP_ANALYZER
584  std::cerr << "Coutner init src not var: " << counterInit->toString() << std::endl;
585 #endif
586  if (counterInit->isSourceOperation()) {
587 #ifdef DEBUG_LOOP_ANALYZER
588  std::cerr << "Coutner init src op: " << counterInit->toString() << std::endl;
589 #endif
590  ProgramOperation& po = counterInit->sourceOperation();
591  bool isSub = po.operation().name() == "SUB";
592  bool isAdd = po.operation().name() == "ADD";
593  if (!isSub && !isAdd) {
594  break;
595  }
596 
597  // is add or sub
598  MoveNodeSet& input1Set = po.inputNode(1);
599  MoveNodeSet& input2Set = po.inputNode(2);
600  if (input1Set.count() != 1 || input2Set.count() != 1) {
601  break;
602  }
603  MoveNode& input1 = input1Set.at(0);
604  MoveNode& input2 = input2Set.at(0);
605 #ifdef DEBUG_LOOP_ANALYZER
606  std::cerr << "inputs: " << input1.toString() << " and "
607  << input2.toString() << std::endl;
608 #endif
609  if (input2.isSourceConstant()) {
610 #ifdef DEBUG_LOOP_ANALYZER
611  std::cerr << "input2 imm" << input2.toString() << std::endl;
612 #endif
613  if (isAdd) {
614  counterOffset += input2.move().source().value().intValue();
615  } else {// sisSub
616  counterOffset -= input2.move().source().value().intValue();
617  }
618  if (input1.isSourceConstant()) {
619  return new InitAndUpdate(input1.move().source().value().intValue()
620  + counterOffset, updateVal, backCmpSrc != 0);
621  } else {
622  counterInit = &input1;
623  }
624  } else { // 2nd input not const, cannot track..
625  break;
626  }
627  } else {
628  break;
629  }
630  }
631  }
632 
633  if (counterInit->isSourceConstant()) {
634  return new InitAndUpdate(
635  counterInit->move().source().value().intValue()+counterOffset,
636  updateVal, backCmpSrc != 0);
637  }
638 #ifndef DEBUG_LOOP_ANALYZER
639  if (Application::verboseLevel() > 1) {
640 #endif
641  std::cerr << "\t\tCounter init variable: " << counterInit->toString() << std::endl;
642 #ifndef DEBUG_LOOP_ANALYZER
643  }
644 #endif
645  return new InitAndUpdate(*counterInit, counterOffset, updateVal, backCmpSrc != 0);
646 }
647 
648 
650  DataDependenceGraph& ddg,MoveNode& init, MoveNode& endCond) {
651 
652  MoveNode* i = &init;
653  MoveNode* initSrc = ddg.onlyRegisterRawSource(*i);
654  while (initSrc != NULL) {
655  i = initSrc;
656  initSrc = ddg.onlyRegisterRawSource(*i);
657  }
658 
659  MoveNode* e = &endCond;
660  MoveNode* eSrc = ddg.onlyRegisterRawSource(*e);
661  while (eSrc != NULL) {
662  e = eSrc;
663  eSrc = ddg.onlyRegisterRawSource(*e);
664  }
665 
666  if (e == NULL || i == NULL) {
667  return NULL;
668  }
669  if (!e->isSourceOperation() ||
670  (e->sourceOperation().operation().name() != "ADD" &&
671  (e->sourceOperation().operation().name() != "SUB"))) {
672  return NULL;
673  }
675  MoveNodeSet& input1Set = po.inputNode(1);
676  MoveNodeSet& input2Set = po.inputNode(2);
677  if (input1Set.count() != 1 || input2Set.count() != 1) {
678  return NULL;
679  }
680  MoveNode& input1 = input1Set.at(0);
681  MoveNode& input2 = input2Set.at(0);
682 
683  if (!i->isSourceOperation()) {
684  return NULL;
685  }
686 
687  if (input1.isSourceOperation() && &input1.sourceOperation() ==
688  &i->sourceOperation() && input1.move().source()==i->move().source()) {
689  if (input2.move().source().isImmediate()) {
690  int updateVal = input2.move().source().value().intValue();
691  return new EndCondition(updateVal, NULL);
692  }
693  }
694 
695  if (input2.isSourceOperation() && &input2.sourceOperation() ==
696  &i->sourceOperation() && input2.move().source()==i->move().source()) {
697  if (input1.move().source().isImmediate()) {
698  int updateVal = input1.move().source().value().intValue();
699  return new EndCondition(updateVal, NULL);
700  }
701 
702  }
703 
704 
705  return NULL;
706 }
ProgramOperation::operation
const Operation & operation() const
Definition: ProgramOperation.cc:590
SimValue::intValue
int intValue() const
Definition: SimValue.cc:895
LoopAnalyzer::InitAndUpdate::initNode
MoveNode * initNode
Definition: LoopAnalyzer.hh:23
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
TTAProgram::Instruction::move
Move & move(int i) const
Definition: Instruction.cc:193
LoopAnalyzer::InitAndUpdate
Definition: LoopAnalyzer.hh:22
TTAProgram::MoveGuard::isInverted
bool isInverted() const
Definition: MoveGuard.cc:76
BoostGraph< MoveNode, DataDependenceEdge >::NodeSet
std::set< MoveNode *, typename MoveNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
TTAProgram::Instruction
Definition: Instruction.hh:57
BasicBlockNode.hh
ProgramOperation
Definition: ProgramOperation.hh:70
MoveNode
Definition: MoveNode.hh:65
DataDependenceGraph::regRawPredecessors
NodeSet regRawPredecessors(const MoveNode &node, int backedges=0) const
Definition: DataDependenceGraph.cc:4310
MoveNode::isSourceConstant
bool isSourceConstant() const
Definition: MoveNode.cc:238
LoopAnalyzer::InitAndUpdate::initVal
int initVal
Definition: LoopAnalyzer.hh:24
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
Terminal.hh
LoopAnalyzer::findInitAndUpdate
static InitAndUpdate * findInitAndUpdate(DataDependenceGraph &ddg, MoveNode &cmpVal)
Definition: LoopAnalyzer.cc:471
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
LoopAnalyzer::analyze
static LoopAnalysisResult * analyze(BasicBlockNode &bbn, DataDependenceGraph &ddg)
Definition: LoopAnalyzer.cc:14
DataDependenceGraph::onlyRegisterRawSource
MoveNode * onlyRegisterRawSource(const MoveNode &mn, int allowGuardEdges=2, int backEdges=0) const
Definition: DataDependenceGraph.cc:4083
LoopAnalyzer::tryTrackCommonAncestor
static EndCondition * tryTrackCommonAncestor(DataDependenceGraph &ddg, MoveNode &init, MoveNode &endCond)
Definition: LoopAnalyzer.cc:649
BasicBlockNode::basicBlock
TTAProgram::BasicBlock & basicBlock()
Definition: BasicBlockNode.cc:126
MoveNode::sourceOperation
ProgramOperation & sourceOperation() const
Definition: MoveNode.cc:453
assert
#define assert(condition)
Definition: Application.hh:86
TTAProgram::Terminal::isImmediateRegister
virtual bool isImmediateRegister() const
Definition: Terminal.cc:97
Instruction.hh
MoveNodeSet::at
MoveNode & at(int index)
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
DataDependenceGraph::nodeOfMove
MoveNode & nodeOfMove(const TTAProgram::Move &move)
Definition: DataDependenceGraph.cc:3600
BasicBlockNode
Definition: BasicBlockNode.hh:64
TTAProgram::Terminal::isGPR
virtual bool isGPR() const
Definition: Terminal.cc:107
DataDependenceGraph::onlyGuardDefOfMove
MoveNode * onlyGuardDefOfMove(MoveNode &moveNode)
Definition: DataDependenceGraph.cc:4581
Operation.hh
MoveNode::isSourceOperation
bool isSourceOperation() const
Definition: MoveNode.cc:168
TTAProgram::Terminal::value
virtual SimValue value() const
Definition: Terminal.cc:178
TTAProgram::Move
Definition: Move.hh:55
MoveNodeSet
Definition: MoveNodeSet.hh:41
GraphBase::writeToDotFile
virtual void writeToDotFile(const TCEString &fileName) const
MoveNodeSet::count
int count() const
MoveNode::isSourceVariable
bool isSourceVariable() const
Definition: MoveNode.cc:196
LoopAnalyzer::LoopAnalysisResult
Definition: LoopAnalyzer.hh:13
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
MoveNode::move
TTAProgram::Move & move()
ProgramOperation::toString
std::string toString() const
Definition: ProgramOperation.cc:746
LoopAnalyzer::EndCondition
std::pair< int, MoveNode * > EndCondition
Definition: LoopAnalyzer.hh:20
MoveNodeSet.hh
TCEString
Definition: TCEString.hh:53
BasicBlock.hh
LoopAnalyzer::InitAndUpdate::loopEdge
int loopEdge
Definition: LoopAnalyzer.hh:26
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
ProgramOperation::inputNode
MoveNodeSet & inputNode(int in) const
Definition: ProgramOperation.cc:513
TTAProgram::Terminal
Definition: Terminal.hh:60
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
TTAProgram::Move::isJump
bool isJump() const
Definition: Move.cc:164
Move.hh
LoopAnalyzer.hh
TTAProgram::Terminal::isImmediate
virtual bool isImmediate() const
Definition: Terminal.cc:63
LoopAnalyzer::findEndCond
static EndCondition * findEndCond(DataDependenceGraph &ddg, MoveNode &cmpVal, bool allowVariable)
Definition: LoopAnalyzer.cc:357
BoostGraph::name
virtual const TCEString & name() const
TTAProgram::Instruction::moveCount
int moveCount() const
Definition: Instruction.cc:176
DataDependenceGraph::getBasicBlockNode
const BasicBlockNode & getBasicBlockNode(const MoveNode &mn) const
Definition: DataDependenceGraph.cc:186
LoopAnalyzer::InitAndUpdate::update
int update
Definition: LoopAnalyzer.hh:25
MoveGuard.hh