OpenASIP 2.2
Loading...
Searching...
No Matches
Classes | Public Types | Static Public Member Functions | Static Private Member Functions | List of all members
LoopAnalyzer Class Reference

#include <LoopAnalyzer.hh>

Collaboration diagram for LoopAnalyzer:
Collaboration graph

Classes

struct  InitAndUpdate
 
struct  LoopAnalysisResult
 

Public Types

typedef std::pair< int, MoveNode * > EndCondition
 

Static Public Member Functions

static LoopAnalysisResultanalyze (BasicBlockNode &bbn, DataDependenceGraph &ddg)
 

Static Private Member Functions

static InitAndUpdatefindInitAndUpdate (DataDependenceGraph &ddg, MoveNode &cmpVal)
 
static EndConditionfindEndCond (DataDependenceGraph &ddg, MoveNode &cmpVal, bool allowVariable)
 
static EndConditiontryTrackCommonAncestor (DataDependenceGraph &ddg, MoveNode &init, MoveNode &endCond)
 

Detailed Description

Definition at line 6 of file LoopAnalyzer.hh.

Member Typedef Documentation

◆ EndCondition

typedef std::pair<int, MoveNode*> LoopAnalyzer::EndCondition

Definition at line 20 of file LoopAnalyzer.hh.

Member Function Documentation

◆ analyze()

LoopAnalyzer::LoopAnalysisResult * LoopAnalyzer::analyze ( BasicBlockNode bbn,
DataDependenceGraph ddg 
)
static

Definition at line 14 of file LoopAnalyzer.cc.

14 {
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}
static int verboseLevel()
TTAProgram::BasicBlock & basicBlock()
virtual const TCEString & name() const
MoveNode * onlyGuardDefOfMove(MoveNode &moveNode)
MoveNode * onlyRegisterRawSource(const MoveNode &mn, int allowGuardEdges=2, int backEdges=0) const
MoveNode & nodeOfMove(const TTAProgram::Move &move)
virtual void writeToDotFile(const TCEString &fileName) const
static InitAndUpdate * findInitAndUpdate(DataDependenceGraph &ddg, MoveNode &cmpVal)
static EndCondition * findEndCond(DataDependenceGraph &ddg, MoveNode &cmpVal, bool allowVariable)
static EndCondition * tryTrackCommonAncestor(DataDependenceGraph &ddg, MoveNode &init, MoveNode &endCond)
std::pair< int, MoveNode * > EndCondition
int count() const
MoveNode & at(int index)
bool isSourceVariable() const
Definition MoveNode.cc:196
ProgramOperation & sourceOperation() const
Definition MoveNode.cc:453
TTAProgram::Move & move()
bool isSourceOperation() const
Definition MoveNode.cc:168
virtual TCEString name() const
Definition Operation.cc:93
const Operation & operation() const
MoveNodeSet & inputNode(int in) const
std::string toString() const
int intValue() const
Definition SimValue.cc:895
virtual int instructionCount() const
Move & move(int i) const
bool isInverted() const
Definition MoveGuard.cc:76
MoveGuard & guard() const
Definition Move.cc:345
Terminal & source() const
Definition Move.cc:302
bool isJump() const
Definition Move.cc:164
virtual SimValue value() const
Definition Terminal.cc:178
virtual bool isGPR() const
Definition Terminal.cc:107
virtual bool isImmediateRegister() const
Definition Terminal.cc:97
virtual bool isImmediate() const
Definition Terminal.cc:63

References MoveNodeSet::at(), BasicBlockNode::basicBlock(), MoveNodeSet::count(), findEndCond(), findInitAndUpdate(), TTAProgram::Move::guard(), LoopAnalyzer::InitAndUpdate::initNode, LoopAnalyzer::InitAndUpdate::initVal, ProgramOperation::inputNode(), TTAProgram::CodeSnippet::instructionCount(), SimValue::intValue(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediate(), TTAProgram::Terminal::isImmediateRegister(), TTAProgram::MoveGuard::isInverted(), TTAProgram::Move::isJump(), MoveNode::isSourceOperation(), MoveNode::isSourceVariable(), LoopAnalyzer::InitAndUpdate::loopEdge, MoveNode::move(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), BoostGraph< GraphNode, GraphEdge >::name(), Operation::name(), DataDependenceGraph::nodeOfMove(), DataDependenceGraph::onlyGuardDefOfMove(), DataDependenceGraph::onlyRegisterRawSource(), ProgramOperation::operation(), TTAProgram::Move::source(), MoveNode::sourceOperation(), ProgramOperation::toString(), tryTrackCommonAncestor(), LoopAnalyzer::InitAndUpdate::update, TTAProgram::Terminal::value(), Application::verboseLevel(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by BBSchedulerController::handleBasicBlock().

Here is the call graph for this function:

◆ findEndCond()

LoopAnalyzer::EndCondition * LoopAnalyzer::findEndCond ( DataDependenceGraph ddg,
MoveNode cmpVal,
bool  allowVariable 
)
staticprivate

Definition at line 357 of file LoopAnalyzer.cc.

357 {
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}
#define assert(condition)
const BasicBlockNode & getBasicBlockNode(const MoveNode &mn) const
std::string toString() const
Definition MoveNode.cc:576
bool isSourceConstant() const
Definition MoveNode.cc:238

References assert, MoveNodeSet::at(), MoveNodeSet::count(), findEndCond(), DataDependenceGraph::getBasicBlockNode(), ProgramOperation::inputNode(), SimValue::intValue(), TTAProgram::Terminal::isGPR(), MoveNode::isSourceConstant(), MoveNode::isSourceOperation(), MoveNode::isSourceVariable(), MoveNode::move(), Operation::name(), DataDependenceGraph::onlyRegisterRawSource(), ProgramOperation::operation(), TTAProgram::Move::source(), MoveNode::sourceOperation(), MoveNode::toString(), and TTAProgram::Terminal::value().

Referenced by analyze(), and findEndCond().

Here is the call graph for this function:

◆ findInitAndUpdate()

LoopAnalyzer::InitAndUpdate * LoopAnalyzer::findInitAndUpdate ( DataDependenceGraph ddg,
MoveNode cmpVal 
)
staticprivate

Definition at line 471 of file LoopAnalyzer.cc.

471 {
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
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}
NodeSet regRawPredecessors(const MoveNode &node, int backedges=0) const
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
Definition Graph.hh:53

References MoveNodeSet::at(), MoveNodeSet::count(), ProgramOperation::inputNode(), SimValue::intValue(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediate(), MoveNode::isSourceConstant(), MoveNode::isSourceOperation(), MoveNode::isSourceVariable(), MoveNode::move(), Operation::name(), DataDependenceGraph::onlyRegisterRawSource(), ProgramOperation::operation(), DataDependenceGraph::regRawPredecessors(), TTAProgram::Move::source(), MoveNode::sourceOperation(), MoveNode::toString(), TTAProgram::Terminal::value(), and Application::verboseLevel().

Referenced by analyze().

Here is the call graph for this function:

◆ tryTrackCommonAncestor()

LoopAnalyzer::EndCondition * LoopAnalyzer::tryTrackCommonAncestor ( DataDependenceGraph ddg,
MoveNode init,
MoveNode endCond 
)
staticprivate

Definition at line 649 of file LoopAnalyzer.cc.

650 {
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}

References MoveNodeSet::at(), MoveNodeSet::count(), ProgramOperation::inputNode(), SimValue::intValue(), TTAProgram::Terminal::isImmediate(), MoveNode::isSourceOperation(), MoveNode::move(), Operation::name(), DataDependenceGraph::onlyRegisterRawSource(), ProgramOperation::operation(), TTAProgram::Move::source(), MoveNode::sourceOperation(), and TTAProgram::Terminal::value().

Referenced by analyze().

Here is the call graph for this function:

The documentation for this class was generated from the following files: