OpenASIP  2.0
RegisterRenamer.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file RegisterRenamer.cc
26  *
27  * Definition of RegisterRenamer class.
28  *
29  * @todo rename the file to match the class name
30  *
31  * @author Heikki Kultala 2009-2011 (hkultala-no.spam-cs.tut.fi)
32  * @note rating: red
33  */
34 
35 #include "MapTools.hh"
36 
37 #include "RegisterRenamer.hh"
38 
39 #include "RegisterFile.hh"
40 #include "Guard.hh"
41 #include "Machine.hh"
43 #include "BasicBlock.hh"
44 #include "DataDependenceGraph.hh"
45 #include "MoveNode.hh"
46 #include "Terminal.hh"
47 #include "DisassemblyRegister.hh"
48 #include "LiveRangeData.hh"
49 #include "TerminalRegister.hh"
50 #include "MoveNodeSelector.hh"
51 #include "Move.hh"
52 #include "MoveGuard.hh"
53 #include "LiveRange.hh"
54 
55 // #define DEBUG_REG_RENAMER
56 #include "tce_config.h"
57 
58 /**
59  * Constructor.
60  *
61  * @param machine machine for which we are scheudling
62 
63 RegisterRenamer::RegisterRenamer(const TTAMachine::Machine& machine) :
64  machine_(machine) {
65  initialize();
66 }
67 */
68 
69 /**
70  * Constructor.
71 *
72  * @param machine machine for which we are scheudling
73  */
76  machine_(machine), bb_(bb), ddg_(NULL){
77  initialize();
78 }
79 
80 void
82  ddg_ = &ddg;
84 }
85 
86 void
88  auto regNav = machine_.registerFileNavigator();
89 
90  auto trCacheIter = tempRegFileCache_.find(&machine_);
91 
92  if (trCacheIter == tempRegFileCache_.end()) {
96  } else {
97  tempRegFiles_ = trCacheIter->second;
98  }
99 
100  for (int i = 0; i < regNav.count(); i++) {
101  bool isTempRf = false;
102  TTAMachine::RegisterFile* rf = regNav.item(i);
104  isTempRf = true;
105  }
106  unsigned int regCount = isTempRf ? rf->size()-1 : rf->size();
107  for (unsigned int j = 0; j < regCount; j++ ) {
109  }
110  }
111 }
112 
113 void
115 
116  assert(ddg_ != NULL);
121 
122  std::map<TCEString,int> lastUses;
123 
124  // find regs inside this BB.
125  for (int i = 0; i < ddg_->nodeCount(); i++) {
126  MoveNode& node = ddg_->node(i);
127 
128  // any write to a reg means it's not alive.
129  TTAProgram::Terminal& dest = node.move().destination();
130  if (dest.isGPR()) {
132  dest.registerFile(), dest.index());
133  onlyMidPartiallyUsedRegs_.insert(regName);
134  }
135  TTAProgram::Terminal& src = node.move().source();
136  if (src.isGPR()) {
138  src.registerFile(), src.index());
139  onlyMidPartiallyUsedRegs_.insert(regName);
140  }
141  }
142 
143  // then loop for deps outside or inside this bb.
144  for (std::set<TCEString>::iterator allIter = freeGPRs_.begin();
145  allIter != freeGPRs_.end();) {
146  bool aliveOver = false;
147  bool aliveAtBeginning = false;
148  bool aliveAtEnd = false;
149  bool aliveAtMid = false;
150  // defined before and used here or after?
151  if (bb_.liveRangeData_->regDefReaches_.find(*allIter) !=
153  if (bb_.liveRangeData_->registersUsedAfter_.find(*allIter)
155  aliveOver = true;
156  }
157  if (bb_.liveRangeData_->regFirstUses_.find(*allIter) !=
159  aliveAtBeginning = true;
160  LiveRangeData::MoveNodeUseMapSet::iterator i =
161  bb_.liveRangeData_->regLastUses_.find(*allIter);
162  if (i != bb_.liveRangeData_->regLastUses_.end()) {
163  LiveRangeData::MoveNodeUseSet& lastUses = i->second;
164  for (LiveRangeData::MoveNodeUseSet::iterator j =
165  lastUses.begin(); j != lastUses.end(); j++) {
166  if (j->pseudo()) {
167  aliveOver = true;
168  }
169  }
170  }
171  }
172  aliveAtBeginning = true;
173  }
174  // used after this?
175  if (bb_.liveRangeData_->registersUsedAfter_.find(*allIter) !=
177  // defined here?
178  if (bb_.liveRangeData_->regDefines_.find(*allIter) !=
179  bb_.liveRangeData_->regDefines_.end()) {
180  aliveAtEnd = true;
181  }
182  }
183 
184  if (aliveAtEnd && aliveAtBeginning) {
185  aliveOver = true;
186  }
187 
188  // TODO: why was this here?
189  if (onlyMidPartiallyUsedRegs_.find(*allIter) !=
191  aliveAtMid = true;
192  }
193 
194  if (aliveOver) {
195  // can not be used for renaming.
196  onlyMidPartiallyUsedRegs_.erase(*allIter);
197  freeGPRs_.erase(allIter++);
198  } else {
199  if (aliveAtBeginning) {
200  onlyBeginPartiallyUsedRegs_.insert(*allIter);
201 
202  onlyMidPartiallyUsedRegs_.erase(*allIter);
203  freeGPRs_.erase(allIter++);
204  } else {
205  if (aliveAtEnd) {
206  onlyEndPartiallyUsedRegs_.insert(*allIter);
207 
208  onlyMidPartiallyUsedRegs_.erase(*allIter);
209  freeGPRs_.erase(allIter++);
210  } else { // only mid if has reads of writes?
211  if (aliveAtMid) {
212  freeGPRs_.erase(allIter++);
213  } else {
214  allIter++;
215  }
216  }
217  }
218  }
219  }
220 }
221 
222 std::set<TCEString>
224  const RegisterRenamer::RegisterFileSet& rfs) const {
225 
226  std::set<TCEString> allowedGprs = registersOfRFs(rfs);
227  std::set<TCEString> regs;
228  SetTools::intersection(allowedGprs, freeGPRs_, regs);
229  return regs;
230 }
231 
232 std::set<TCEString>
234  const RegisterFileSet& rfs) const {
235 
236  std::set<TCEString> gprs;
237  for (std::set<const TTAMachine::RegisterFile*,
238  TTAMachine::MachinePart::Comparator>::iterator i = rfs.begin();
239  i != rfs.end(); i++) {
240  bool isTempRF = false;
241  const TTAMachine::RegisterFile* rf = *i;
243  isTempRF = true;
244  }
245  int lowestFreeIndex = 0;
246  if (rf->zeroRegister()) {
247  lowestFreeIndex = 1;
248  }
249  for (int j = lowestFreeIndex;
250  j < (isTempRF ? rf->size() - 1 : rf->size()); j++) {
251  gprs.insert(DisassemblyRegister::registerName(*rf, j));
252  }
253  }
254  return gprs;
255 }
256 /**
257  * Finds registers which are used but only before given earliestCycle.
258  */
259 std::set<TCEString>
261  const RegisterFileSet& rfs, int earliestCycle,
262  const DataDependenceGraph::NodeSet& guardMoves) const {
263 
264  std::set<TCEString> availableRegs;
265  // nothing can be scheduled earlier than cycle 0.
266  // in that case we have empty set, no need to check.
267  if (earliestCycle < 1) {
268  return availableRegs;
269  }
270 
271  std::set<TCEString> allowedGprs = registersOfRFs(rfs);
272  std::set<TCEString> regs = usedGPRs_;
275  std::set<TCEString> regs2;
276  SetTools::intersection(allowedGprs, regs, regs2);
277 
278 
279  // find from used gprs.
280  // todo: this is too conservative? leaves one cycle netween war?
281  for (std::set<TCEString>::iterator i = regs2.begin();
282  i != regs2.end(); i++) {
283  TCEString rfName = i->substr(0, i->find('.'));
286 
287  unsigned int regIndex = atoi(i->substr(i->find('.')+1).c_str());
288  if (ddg_->lastRegisterCycle(*rf, regIndex) < earliestCycle) {
289  availableRegs.insert(*i);
290  }
291  }
292 
293  // if need to have guards?
294  if (guardMoves.empty()) {
295  return availableRegs;
296  } else {
297  std::set<TCEString> guardedRegs =
298  findGuardRegisters(guardMoves, rfs);
299  std::set<TCEString> guardedAvailableRegs;
301  availableRegs, guardedRegs, guardedAvailableRegs);
302  return guardedAvailableRegs;
303  }
304 }
305 
306 /**
307  * Finds registers which are used but only after given earliestCycle.
308  */
309 std::set<TCEString>
311  const RegisterRenamer::RegisterFileSet& rfs, int latestCycle) const {
312 
313  std::set<TCEString> availableRegs;
314  // nothing can be scheduled earlier than cycle 0.
315  // in that case we have empty set, no need to check.
316 
317  std::set<TCEString> allowedGprs = registersOfRFs(rfs);
318  std::set<TCEString> regs = usedGPRs_;
321  std::set<TCEString> regs2;
322  SetTools::intersection(allowedGprs, regs, regs2);
323 
324  // find from used gprs.
325  // todo: this is too conservative? leaves one cycle netween war?
326  for (std::set<TCEString>::iterator i = regs2.begin();
327  i != regs2.end(); i++) {
328  TCEString rfName = i->substr(0, i->find('.'));
331 
332  unsigned int regIndex = atoi(i->substr(i->find('.')+1).c_str());
333  if (ddg_->firstRegisterCycle(*rf, regIndex) > latestCycle) {
334  availableRegs.insert(*i);
335  }
336  }
337  return availableRegs;
338 }
339 
340 std::set<TCEString>
342  int bitWidth, int earliestCycle,
343  const DataDependenceGraph::NodeSet& guardMoves) const {
344  std::set<TCEString> availableRegs;
345  // nothing can be scheduled earlier than cycle 0.
346  // in that case we have empty set, no need to check.
347  if (earliestCycle < 1) {
348  return availableRegs;
349  }
350 
351  std::set<TCEString> regs = onlyMidPartiallyUsedRegs_;
354 
355  for (std::set<TCEString>::iterator i = regs.begin();
356  i != regs.end(); i++) {
357 
358  TCEString rfName = i->substr(0, i->find('.'));
361  unsigned int regIndex = atoi(i->substr(i->find('.')+1).c_str());
362  if (ddg_->lastRegisterCycle(*rf, regIndex) < earliestCycle &&
363  rf->width() == bitWidth) {
364  availableRegs.insert(*i);
365  }
366  }
367  // if need to have guards?
368  if (guardMoves.empty()) {
369  return availableRegs;
370  } else {
371 #ifdef DEBUG_REGISTER_RENAMER
372  if (!liveRange->guards.empty()) {
373  std::cerr << "\t\t\t\tpartiallyusedregs: ";
374  for (std::set<TCEString>::iterator i =
375  regs.begin();
376  i != regs.end(); i++) {
377  std::cerr << *i << " ";
378  }
379  std::cerr << std::endl;
380  }
381 #endif
382 
383  RegisterFileSet rfs; // empty, all rf's
384  std::set<TCEString> guardedRegs =
385  findGuardRegisters(guardMoves, rfs);
386  std::set<TCEString> guardedAvailableRegs;
388  availableRegs, guardedRegs, guardedAvailableRegs);
389  return guardedAvailableRegs;
390  }
391 }
392 
393 std::set<TCEString>
395  int bitWidth, int latestCycle) const {
396  std::set<TCEString> availableRegs;
397 
398  std::set<TCEString> regs = onlyMidPartiallyUsedRegs_;
401 
402  for (std::set<TCEString>::iterator i = regs.begin();
403  i != regs.end(); i++) {
404 
405  TCEString rfName = i->substr(0, i->find('.'));
408  unsigned int regIndex = atoi(i->substr(i->find('.')+1).c_str());
409  if (ddg_->firstRegisterCycle(*rf, regIndex) > latestCycle &&
410  rf->width() == bitWidth) {
411  availableRegs.insert(*i);
412  }
413  }
414  return availableRegs;
415 }
416 
417 std::set<TCEString>
419  int bitWidth) const {
420 
421  std::set<TCEString> availableRegs;
422 
423  for (std::set<TCEString>::iterator i = freeGPRs_.begin();
424  i != freeGPRs_.end(); i++) {
425 
426  TCEString rfName = i->substr(0, i->find('.'));
429  if (rf->width() == bitWidth) {
430  availableRegs.insert(*i);
431  }
432  }
433  return availableRegs;
434 }
435 
436 std::set<TCEString>
438  const DataDependenceGraph::NodeSet& guardUseNodes,
439  int bitWidth, const RegisterFileSet& rfs) const {
440  std::set<TCEString> availableRegs;
441 
443  (rfs.empty() ?
444  findFreeRegisters(bitWidth) :
445  findFreeRegistersInRF(rfs)),
446  findGuardRegisters(guardUseNodes, rfs),
447  availableRegs);
448 
449  return availableRegs;
450 }
451 
452 
453 /**
454  * Renames destination register of a move (from the move itself and
455  * from all other moves in same liverange)
456  */
457 bool
459  MoveNode& node, bool loopScheduling,
460  bool allowSameRf, bool differentRfOnlyDirectlyReachable,
461  int earliestCycle) {
462 
463  if (!node.isMove() || !node.move().destination().isGPR()) {
464  return false;
465  }
466  const TTAMachine::RegisterFile& rf =
467  node.move().destination().registerFile();
468 
469  // don't allow using same reg multiple times if loop scheduling.
470  // unscheudling would cause problems, missing war edges.
471  if (loopScheduling) {
472  earliestCycle = -1;
473  }
474  // first find used fully scheduled ones!
475  bool reused = true;
476 
477  std::unique_ptr<LiveRange> liveRange(
478  ddg_->findLiveRange(node, true, false));
479 
480  if (liveRange->writes.empty()) {
481  return false;
482  }
483  std::set<TCEString> availableRegisters;
484 
485  if (!liveRange->noneScheduled()) {
486  // not yet allow guards rename when some movenodes of lr
487  // already sched
488  if (!allowSameRf) {
489  return false;
490  }
491  RegisterFileSet rfs;
492  rfs.insert(&rf);
493  earliestCycle = std::min(earliestCycle, liveRange->firstCycle());
494  availableRegisters =
496  liveRange->guards);
497  } else { // none scheduled.
498  if (tempRegFiles_.empty()) {
499 
500 #ifdef DEBUG_REG_RENAMER
501  if (!liveRange->guards.empty()) {
502  std::cerr<<"\t\tSearching for avail guard regs before cycle:"
503  << earliestCycle << std::endl;
504  }
505 #endif
506 
507  availableRegisters =
509  rf.width(), earliestCycle, liveRange->guards);
510 
511 #ifdef DEBUG_REG_RENAMER
512  if (!liveRange->guards.empty()) {
513  std::cerr << "\t\t\tfound free gaurd regs: ";
514  for (std::set<TCEString>::iterator i =
515  availableRegisters.begin();
516  i != availableRegisters.end(); i++) {
517  std::cerr << *i << " ";
518  }
519  std::cerr << std::endl;
520  }
521 #endif
522 
523  } else {
524  if (!differentRfOnlyDirectlyReachable) {
525  // only connected RFs
526  RegisterFileSet rfs = findConnectedRFs(*liveRange, false);
527  availableRegisters =
529  rfs, earliestCycle, liveRange->guards);
530  if (availableRegisters.empty()) {
531  // allow usasge of limm.
532  rfs = findConnectedRFs(*liveRange, true);
533  availableRegisters =
535  rfs, earliestCycle, liveRange->guards);
536  }
537  }
538  }
539  } // if not guards - after this can be guards
540  if (availableRegisters.empty()) {
541  reused = false;
542 
543  if (!liveRange->noneScheduled()) {
544  if (liveRange->guards.empty()) {
545  RegisterFileSet rfs;
546  rfs.insert(&rf);
547  availableRegisters =
549  }
550  } else {
551  if (tempRegFiles_.empty()) {
552  if (liveRange->guards.empty()) {
553  availableRegisters =
554  findFreeRegisters(rf.width());
555  } else { // guards use..
556 #ifdef DEBUG_REG_RENAMER
557  std::cerr << "\t\tSearching for avail guard regs" << std::endl;
558 #endif
559  RegisterFileSet rfs; // empty, use all RF's
560  availableRegisters =
562  liveRange->guards, rf.width(), rfs);
563 #ifdef DEBUG_REG_RENAMER
564  std::cerr << "\t\t\tfound free gaurd regs: ";
565  for (std::set<TCEString>::iterator i =
566  availableRegisters.begin();
567  i != availableRegisters.end(); i++) {
568  std::cerr << *i << " ";
569  }
570  std::cerr << std::endl;
571 #endif
572  }
573 
574  } else {
575  // TODO: this disables guard renaming with regcopyadder
576  if (liveRange->guards.empty()) {
577  if (!differentRfOnlyDirectlyReachable) {
578  // only connected RFs
579  RegisterFileSet rfs =
580  findConnectedRFs(*liveRange, false);
581  availableRegisters =
583  if (availableRegisters.empty()) {
584  // allow usage of LIMM
585  rfs = findConnectedRFs(*liveRange, true);
586  availableRegisters =
588  }
589  }
590  } else {
591  // guards. use only same rf for now.
592  // TODO: update findconnectedRF's to work with guards
593  RegisterFileSet rfs;
594  rfs.insert(&rf);
595  availableRegisters =
597  liveRange->guards, rf.width(), rfs);
598  }
599  }
600  }
601  if (availableRegisters.empty()) {
602  return false;
603  }
604  }
605 
606  // then actually do it.
607  return renameLiveRange(
608  *liveRange, *availableRegisters.begin(),
609  reused, false, loopScheduling);
610 }
611 
612 /**
613  * Renames source register of a move (from the move itself and
614  * from all other moves in same liverange)
615  */
616 bool
618  MoveNode& node, bool loopScheduling,
619  bool allowSameRf, bool differentRfOnlyDirectlyReachable, int latestCycle) {
620 
621  if (!node.isMove() || !node.move().source().isGPR()) {
622  return false;
623  }
624  const TTAMachine::RegisterFile& rf =
625  node.move().source().registerFile();
626 
627  if (loopScheduling) {
628  latestCycle = -1;
629  }
630 
631  // first find used fully scheduled ones!
632  bool reused = true;
633 
634  std::unique_ptr<LiveRange> liveRange(
635  ddg_->findLiveRange(node, false, false));
636 
637  if (liveRange->writes.empty()) {
638  return false;
639  }
640  std::set<TCEString> availableRegisters;
641 
642  if (!liveRange->noneScheduled()) {
643  if (!allowSameRf) {
644  return false;
645  }
646  std::set<const TTAMachine::RegisterFile*,
648  rfs.insert(&rf);
649  latestCycle = std::max(latestCycle, liveRange->lastCycle());
650 
651  availableRegisters =
653  } else {
654  if (tempRegFiles_.empty()) {
655  availableRegisters =
656  findPartiallyUsedRegistersAfterCycle(rf.width(), latestCycle);
657  } else {
658  if (!differentRfOnlyDirectlyReachable) {
659  // only connected RFs
660  std::set<const TTAMachine::RegisterFile*,
662  rfs = findConnectedRFs(*liveRange, false);
663  availableRegisters =
665  if (availableRegisters.empty()) {
666  rfs = findConnectedRFs(*liveRange, true);
667  availableRegisters =
669  rfs, latestCycle);
670  }
671  }
672  }
673  }
674 
675  if (availableRegisters.empty()) {
676  reused = false;
677 
678  if (!liveRange->noneScheduled()) {
679  std::set<const TTAMachine::RegisterFile*,
681  rfs.insert(&rf);
682  availableRegisters =
684  } else {
685  if (tempRegFiles_.empty()) {
686  availableRegisters =
687  findFreeRegisters(rf.width());
688  } else {
689  if (!differentRfOnlyDirectlyReachable) {
690  // only connected RFs
691  std::set<const TTAMachine::RegisterFile*,
693  rfs = findConnectedRFs(*liveRange, false);
694  availableRegisters = findFreeRegistersInRF(rfs);
695  if (availableRegisters.empty()) {
696  rfs = findConnectedRFs(*liveRange, true);
697  availableRegisters = findFreeRegistersInRF(rfs);
698  }
699  }
700  }
701  }
702  if (availableRegisters.empty()) {
703  return false;
704  }
705  }
706 
707  return
709  *liveRange, *availableRegisters.begin(), false, reused,
710  loopScheduling);
711 }
712 
713 bool
715  LiveRange& liveRange, const TCEString& newReg, bool usedBefore,
716  bool usedAfter, bool loopScheduling) {
717 
718  if (liveRange.writes.size() <1) {
719  return false;
720  }
721 
722  if (liveRange.reads.size() == 0 && liveRange.guards.size() == 0) {
723  return false;
724  }
725 
726  assert(newReg.length() > 2);
727  TCEString rfName = newReg.substr(0, newReg.find('.'));
730 
731  int newRegIndex =
732  atoi(newReg.substr(newReg.find('.')+1).c_str());
733 
734  if (usedBefore) {
735  // create antidependencies from the previous use of this temp reg.
736 
737  //todo: if in a loop, create antidependencies to first ones in the BB.
738  DataDependenceGraph::NodeSet lastReads =
740  *rf, newRegIndex);
741 
742  DataDependenceGraph::NodeSet lastWrites =
744  *rf, newRegIndex);
745 
746  DataDependenceGraph::NodeSet lastGuards =
748  *rf, newRegIndex);
749 
750  // create the deps.
751  for (DataDependenceGraph::NodeSet::iterator i =
752  liveRange.writes.begin(); i != liveRange.writes.end(); i++) {
753 
754  // create WAR's from previous reads
755  for (DataDependenceGraph::NodeSet::iterator
756  j = lastReads.begin(); j != lastReads.end(); j++) {
757 
761 
762  ddg_->connectNodes(**j, **i, *edge);
763  }
764 
765  // create WAR's from previous guard uses
766  for (DataDependenceGraph::NodeSet::iterator
767  j = lastGuards.begin(); j != lastGuards.end(); j++) {
768 
771  DataDependenceEdge::DEP_WAR, newReg, true);
772 
773  ddg_->connectNodes(**j, **i, *edge);
774  }
775 
776  // create WAW's from previous writes.
777  for (DataDependenceGraph::NodeSet::iterator
778  j = lastWrites.begin(); j != lastWrites.end(); j++) {
779 
783 
784  ddg_->connectNodes(**j, **i, *edge);
785  }
786  }
787  } else {
788  // this is not used before.
789 
790  // update bookkeeping about first use of this reg
791  if (!usedAfter)
792  assert(bb_.liveRangeData_->regFirstUses_[newReg].empty());
793 
794  // killing write.
795  if (liveRange.writes.size() == 1 &&
796  (*liveRange.writes.begin())->move().isUnconditional()) {
797  bb_.liveRangeData_->regKills_[newReg].first =
798  MoveNodeUse(**liveRange.writes.begin());
799  bb_.liveRangeData_->regFirstDefines_[newReg].clear();
800  bb_.liveRangeData_->regFirstUses_[newReg].clear();
801  }
802 
803  // for writing.
804  for (DataDependenceGraph::NodeSet::iterator i =
805  liveRange.writes.begin(); i != liveRange.writes.end(); i++) {
806 
807  MoveNodeUse mnd(**i);
808  bb_.liveRangeData_->regFirstDefines_[newReg].insert(mnd);
809  // TODO: only if intra-bb-antideps enabled?
810  static_cast<DataDependenceGraph*>(ddg_->rootGraph())->
811  updateRegWrite(mnd, newReg, bb_);
812  }
813 
814  // for reading.
815  for (DataDependenceGraph::NodeSet::iterator i =
816  liveRange.reads.begin(); i != liveRange.reads.end(); i++) {
817 
818  MoveNodeUse mnd(**i);
819  bb_.liveRangeData_->regFirstUses_[newReg].insert(mnd);
820  // no need to create raw deps here
821  }
822 
823  // for guards.
824  for (DataDependenceGraph::NodeSet::iterator i =
825  liveRange.guards.begin(); i != liveRange.guards.end(); i++) {
826 
827  MoveNodeUse mnd(**i);
828  bb_.liveRangeData_->regFirstUses_[newReg].insert(mnd);
829  // no need to create raw deps here
830  }
831 
832  }
833 
834  if (usedAfter) {
835 
836  DataDependenceGraph::NodeSet firstWrites =
838  *rf, newRegIndex);
839 
840  // make sure no circular antidep path
841  for (DataDependenceGraph::NodeSet::iterator
842  j = firstWrites.begin(); j != firstWrites.end(); j++) {
843 
844  for (DataDependenceGraph::NodeSet::iterator i =
845  liveRange.reads.begin(); i != liveRange.reads.end();
846  i++) {
847  if (ddg_->hasPath(**j, **i)) {
848  return false;
849  }
850  }
851 
852  for (DataDependenceGraph::NodeSet::iterator i =
853  liveRange.writes.begin(); i != liveRange.writes.end();
854  i++) {
855  if (ddg_->hasPath(**j, **i)) {
856  return false;
857  }
858  }
859  }
860 
861 
862  // create the antidep deps.
863 
864  for (DataDependenceGraph::NodeSet::iterator
865  j = firstWrites.begin(); j != firstWrites.end(); j++) {
866 
867  // WaW's
868  for (DataDependenceGraph::NodeSet::iterator i =
869  liveRange.writes.begin(); i != liveRange.writes.end();
870  i++) {
871 
875 
876  ddg_->connectNodes(**i,**j, *edge);
877  }
878 
879  // WaR's
880  for (DataDependenceGraph::NodeSet::iterator i =
881  liveRange.reads.begin(); i != liveRange.reads.end();
882  i++) {
886 
887  ddg_->connectNodes(**i,**j, *edge);
888  }
889  }
890 
891  } else {
892 
893  // killing write.
894  if (liveRange.writes.size() == 1 &&
895  (*liveRange.writes.begin())->move().isUnconditional()) {
896  bb_.liveRangeData_->regLastKills_[newReg].first =
897  MoveNodeUse(**liveRange.writes.begin());
898  bb_.liveRangeData_->regDefines_[newReg].clear();
899  }
900 
901  // for writing.
902  for (DataDependenceGraph::NodeSet::iterator i =
903  liveRange.writes.begin(); i != liveRange.writes.end(); i++) {
904 
905  MoveNodeUse mnd(**i);
906  bb_.liveRangeData_->regDefines_[newReg].insert(mnd);
907  }
908 
909  // for reading.
910  for (DataDependenceGraph::NodeSet::iterator i =
911  liveRange.reads.begin(); i != liveRange.reads.end(); i++) {
912 
913  MoveNodeUse mnd(**i);
914  bb_.liveRangeData_->regLastUses_[newReg].insert(mnd);
915  }
916 
917  // need to create backedges to first if we are loop scheduling.
918  if (loopScheduling) {
919  updateAntiEdgesFromLRTo(liveRange, newReg, bb_, 1);
920  }
921  }
922 
923  // first update the movenodes.
924 
925  // for writes.
926  for (DataDependenceGraph::NodeSet::iterator i = liveRange.writes.begin();
927  i != liveRange.writes.end(); i++) {
928  TTAProgram::Move& move = (**i).move();
929  const TTAMachine::Port& oldPort = move.destination().port();
930  if (oldPort.parentUnit() == rf) {
932  oldPort, newRegIndex));
933  } else {
935  *rf->firstWritePort(), newRegIndex));
936  }
937 
938  }
939 
940  // for reads.
941  for (DataDependenceGraph::NodeSet::iterator i = liveRange.reads.begin();
942  i != liveRange.reads.end(); i++) {
943  TTAProgram::Move& move = (**i).move();
944  const TTAMachine::Port& oldPort = move.source().port();
945  if (oldPort.parentUnit() == rf) {
947  oldPort, newRegIndex));
948  } else {
950  *rf->firstReadPort(), newRegIndex));
951  }
952  }
953 
954 
955  // for reads.
956  for (DataDependenceGraph::NodeSet::iterator i = liveRange.guards.begin();
957  i != liveRange.guards.end(); i++) {
958  MoveNode& mn = **i;
959  TTAProgram::Move& move = mn.move();
960  const TTAMachine::Guard& guard = move.guard().guard();
961  // TODO: update the guard here
962 
963 #ifdef DEBUG_REG_RENAMER
964 
965  TTAMachine::Bus& bus = move.bus();
966 
967  std::cerr << "We should be updating guard here for: "
968  << mn.toString()
969  << std::endl;
970  std::cerr << "\tnew guard reg: " << rf->name() << "." << newRegIndex
971  << std::endl;
972 
973  std::cerr << "\tBus: " << bus.name() << std::endl;
974 
975 #endif
976  TTAMachine::Bus* guardBus = guard.parentBus();
977 #ifdef DEBUG_REG_RENAMER
978  std::cerr << "\tGuard bus: " << guardBus->name() << std::endl;
979 #endif
980  for (int j = 0 ; j < guardBus->guardCount(); j++) {
981  TTAMachine::Guard *g = guardBus->guard(j);
983  dynamic_cast<TTAMachine::RegisterGuard*>(g);
984  if (rg) {
985  if (rg->registerFile() == rf &&
986  rg->registerIndex() == newRegIndex &&
987  rg->isInverted() == guard.isInverted()) {
988  move.setGuard(new TTAProgram::MoveGuard(*g));
989 #ifdef DEBUG_REG_RENAMER
990  std::cerr << "\tset new guard: " << mn.toString()
991  << std::endl;
992 #endif
993  }
994  }
995  }
996 
997  }
998 
999 
1000 
1001 
1002 
1003 
1004 
1005 
1006 
1007 
1008  // then update ddg and notify selector.
1009 
1010  // for writes.
1011  for (DataDependenceGraph::NodeSet::iterator i = liveRange.writes.begin();
1012  i != liveRange.writes.end(); i++) {
1013 
1014  DataDependenceGraph::NodeSet writeSuccessors =
1015  ddg_->successors(**i);
1016 
1017  DataDependenceGraph::NodeSet writePredecessors =
1018  ddg_->predecessors(**i);
1019 
1020  ddg_->destRenamed(**i);
1021 
1022  // notify successors of write to prevent orphan nodes.
1023  for (DataDependenceGraph::NodeSet::iterator iter =
1024  writeSuccessors.begin();
1025  iter != writeSuccessors.end(); iter++) {
1026  selector_->mightBeReady(**iter);
1027  }
1028 
1029  // notify successors of write to prevent orphan nodes.
1030  for (DataDependenceGraph::NodeSet::iterator iter =
1031  writePredecessors.begin();
1032  iter != writePredecessors.end(); iter++) {
1033  selector_->mightBeReady(**iter);
1034  }
1035 
1036  }
1037 
1038  // for reads
1039  for (DataDependenceGraph::NodeSet::iterator i = liveRange.reads.begin();
1040  i != liveRange.reads.end(); i++) {
1041  DataDependenceGraph::NodeSet successors =
1042  ddg_->successors(**i);
1043 
1044  ddg_->sourceRenamed(**i);
1045 
1046  DataDependenceGraph::NodeSet predecessors =
1047  ddg_->predecessors(**i);
1048 
1049  // notify successors to prevent orphan nodes.
1050  for (DataDependenceGraph::NodeSet::iterator iter =
1051  successors.begin();
1052  iter != successors.end(); iter++) {
1053  selector_->mightBeReady(**iter);
1054  }
1055 
1056  // notify successors to prevent orphan nodes.
1057  for (DataDependenceGraph::NodeSet::iterator iter =
1058  predecessors.begin();
1059  iter != predecessors.end(); iter++) {
1060  selector_->mightBeReady(**iter);
1061  }
1062  }
1063 
1064  // for guards
1065  for (DataDependenceGraph::NodeSet::iterator i = liveRange.guards.begin();
1066  i != liveRange.guards.end(); i++) {
1067  DataDependenceGraph::NodeSet successors =
1068  ddg_->successors(**i);
1069 
1070  ddg_->guardRenamed(**i);
1071 
1072  DataDependenceGraph::NodeSet predecessors =
1073  ddg_->predecessors(**i);
1074 
1075  // notify successors to prevent orphan nodes.
1076  for (DataDependenceGraph::NodeSet::iterator iter =
1077  successors.begin();
1078  iter != successors.end(); iter++) {
1079  selector_->mightBeReady(**iter);
1080  }
1081 
1082  // notify successors to prevent orphan nodes.
1083  for (DataDependenceGraph::NodeSet::iterator iter =
1084  predecessors.begin();
1085  iter != predecessors.end(); iter++) {
1086  selector_->mightBeReady(**iter);
1087  }
1088  }
1089 
1090  renamedToRegister(newReg);
1091  return true;
1092 }
1093 
1095 
1096  freeGPRs_.erase(newReg);
1097 
1098  onlyBeginPartiallyUsedRegs_.erase(newReg);
1099  onlyEndPartiallyUsedRegs_.erase(newReg);
1100  onlyMidPartiallyUsedRegs_.erase(newReg);
1101 
1102  usedGPRs_.insert(newReg);
1103 
1104 }
1105 
1107  if (bb_.liveRangeData_->regFirstUses_[reg].empty() &&
1108  bb_.liveRangeData_->regLastUses_[reg].empty() &&
1109  bb_.liveRangeData_->regDefines_[reg].empty() &&
1110  bb_.liveRangeData_->regFirstDefines_[reg].empty()) {
1111  freeGPRs_.insert(reg);
1112  }
1113 }
1114 
1115 /**
1116  * Registers the selector being used to the bypasser.
1117  *
1118  * If the bypasser has been registered to the selector,
1119  * bypasses can notify the selector about dependence changes.
1120  * Currently it notifies the successors of a node being removed due
1121  * dead result elimination.
1122  *
1123  * @param selector selector which bypasser notifies on some dependence changes.
1124  */
1125 void
1127  selector_ = selector;
1128 }
1129 
1130 /**
1131  * Updates antidep edges from this liverange to first def of some other bb.
1132  *
1133  * @param liveRange liverange which is the origin of the deps
1134  * @param newReg name of the new register
1135  * @param bb destination BB where to draw the edges to
1136  * @loopDepth loop depth of added edges.
1137  */
1138 void
1140  LiveRange& liveRange, const TCEString& newReg, TTAProgram::BasicBlock& bb,
1141  int loopDepth) const {
1142  std::set<MoveNodeUse>& firstDefs =
1144 
1145  for (std::set<MoveNodeUse>::iterator i = firstDefs.begin();
1146  i != firstDefs.end(); i++) {
1147 
1148  const MoveNodeUse& destination = *i;
1149  if (ddg_->hasNode(*destination.mn())) {
1150 
1151  //WaW's of writes.
1152  for (DataDependenceGraph::NodeSet::iterator j =
1153  liveRange.writes.begin();
1154  j != liveRange.writes.end(); j++) {
1155 
1156  // create dependency edge
1157  DataDependenceEdge* dde =
1158  new DataDependenceEdge(
1160  DataDependenceEdge::DEP_WAW, newReg,
1161  false, false, false, destination.pseudo(), loopDepth);
1162 
1163  // and connect.
1165  **j, *destination.mn(), dde);
1166  }
1167 
1168  //War's of reads.
1169  for (DataDependenceGraph::NodeSet::iterator j =
1170  liveRange.reads.begin();
1171  j != liveRange.reads.end(); j++) {
1172 
1173  // create dependency edge
1174  DataDependenceEdge* dde =
1175  new DataDependenceEdge(
1177  DataDependenceEdge::DEP_WAR, newReg,
1178  false, false, false, destination.pseudo(), 1);
1179 
1180  // and connect.
1182  **j, *destination.mn(), dde);
1183  }
1184 
1185  //War's of guards.
1186  for (DataDependenceGraph::NodeSet::iterator j =
1187  liveRange.guards.begin();
1188  j != liveRange.guards.end(); j++) {
1189 
1190  // create dependency edge
1191  DataDependenceEdge* dde =
1192  new DataDependenceEdge(
1194  DataDependenceEdge::DEP_WAR, newReg,
1195  true, false, false, destination.pseudo(), 1);
1196 
1197  // and connect.
1199  **j, *destination.mn(), dde);
1200  }
1201  }
1202  }
1203 }
1204 
1207 
1208  assert(!lr.writes.empty());
1209  TTAMachine::RegisterFile* originalRF =
1210  dynamic_cast<TTAMachine::RegisterFile*>(
1211  (*lr.writes.begin())->move().destination().port().parentUnit());
1212  assert(originalRF != 0);
1213  int bitwidth = originalRF->width();
1214  std::set<const TTAMachine::RegisterFile*,
1216 
1217  // TODO: loop over movenoeds or RF's? this routine could be made faster.
1220  for (int i = 0; i < rfNav.count(); i++) {
1221  TTAMachine::RegisterFile* rf = rfNav.item(i);
1222  if (rf->width() != bitwidth) {
1223  continue;
1224  }
1225  MachineConnectivityCheck::PortSet writePorts =
1227  bool connected = true;
1228 
1229  for (DataDependenceGraph::NodeSet::iterator j = lr.writes.begin();
1230  j != lr.writes.end() && connected; j++) {
1231  const MoveNode& write = **j;
1233  write, writePorts)) {
1234  case -1:
1235  connected = allowLimm;
1236  break;
1237  case 0:
1238  connected = false;
1239  default:
1240  break;
1241  }
1242  }
1243  if (!connected) {
1244  continue;
1245  }
1246 
1249 
1250  for (DataDependenceGraph::NodeSet::iterator j = lr.reads.begin();
1251  j != lr.reads.end() && connected; j++) {
1252  const MoveNode& read = **j;
1254  readPorts, read)) {
1255  connected = false;
1256  }
1257  }
1258  if (connected) {
1259  rv.insert(rf);
1260  }
1261  }
1262  return rv;
1263 }
1264 
1265 
1266 
1267 
1268 
1269 std::set<TCEString>
1271  const DataDependenceGraph::NodeSet& guardMoves,
1272  const RegisterFileSet& rfs) const {
1273 
1274 
1275  TTAMachine::Bus* bus = NULL;
1276  for (DataDependenceGraph::NodeSet::iterator i = guardMoves.begin();
1277  i != guardMoves.end(); i++) {
1278  const MoveNode& mn = **i;
1279  const TTAProgram::Move& move = mn.move();
1280  assert(!move.isUnconditional());
1281  if (bus == NULL) {
1282  bus = move.guard().guard().parentBus();
1283  } else {
1284  TTAMachine::Bus* bus2 = move.guard().guard().parentBus();
1285  if (bus != bus2) {
1286  return std::set<TCEString>();
1287  }
1288  }
1289  }
1290 
1291  if (bus != NULL) {
1292  return findGuardRegisters(*bus, rfs);
1293  } else {
1294  return std::set<TCEString>();
1295  }
1296 }
1297 
1298 /**
1299  * Finds registers which can guard moves from the given bus.
1300  */
1301 std::set<TCEString>
1303  const TTAMachine::Bus& bus, const RegisterFileSet& rfs) const {
1304 
1305  std::set<TCEString> trueGuards;
1306  std::set<TCEString> falseGuards;
1307 
1308  // find guard
1309  for (int i = 0 ; i < bus.guardCount(); i++) {
1310  TTAMachine::Guard *g = bus.guard(i);
1312  dynamic_cast<TTAMachine::RegisterGuard*>(g);
1313  if (rg) {
1314  bool rfOk = true;
1315  if (!rfs.empty()) {
1316  if (rfs.find(rg->registerFile()) == rfs.end()) {
1317  rfOk = false;
1318  continue;
1319  }
1320  }
1321 
1322  if (rfOk) {
1323  if (rg->isInverted()) {
1324  falseGuards.insert(
1326  *rg->registerFile(), rg->registerIndex()));
1327  } else {
1328  trueGuards.insert(
1330  *rg->registerFile(), rg->registerIndex()));
1331  }
1332  }
1333  }
1334  }
1335 
1336  for (std::set<TCEString>::iterator i = trueGuards.begin();
1337  i != trueGuards.end(); i++) {
1338  if (falseGuards.find(*i) == falseGuards.end()) {
1339  trueGuards.erase(i);
1340  i = trueGuards.begin();
1341  }
1342  }
1343  return trueGuards;
1344 }
1345 
1346 
1347 
1348 /// To avoid reanalysing machine every time hen new rr created.
1349 std::map<const TTAMachine::Machine*,
1350  std::set <const TTAMachine::RegisterFile*,
TTAMachine::RegisterFile::firstReadPort
Port * firstReadPort() const
Definition: RegisterFile.cc:607
TTAMachine::Guard
Definition: Guard.hh:55
RegisterRenamer::freeGPRs_
std::set< TCEString > freeGPRs_
Definition: RegisterRenamer.hh:141
LiveRangeData::regLastKills_
MoveNodeUseMapPair regLastKills_
Definition: LiveRangeData.hh:80
BoostGraph::predecessors
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
BoostGraph::connectNodes
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
RegisterRenamer::onlyEndPartiallyUsedRegs_
std::set< TCEString > onlyEndPartiallyUsedRegs_
Definition: RegisterRenamer.hh:151
DataDependenceGraph::firstRegisterCycle
int firstRegisterCycle(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
Definition: DataDependenceGraph.cc:981
DataDependenceGraph::lastScheduledRegisterWrites
NodeSet lastScheduledRegisterWrites(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
Definition: DataDependenceGraph.cc:1206
MoveNodeUse::mn
const MoveNode * mn() const
Definition: MoveNodeUse.hh:39
RegisterRenamer::RegisterFileSet
std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > RegisterFileSet
Definition: RegisterRenamer.hh:62
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
RegisterRenamer::renamedToRegister
void renamedToRegister(const TCEString &newReg)
Definition: RegisterRenamer.cc:1094
RegisterRenamer::updateAntiEdgesFromLRTo
void updateAntiEdgesFromLRTo(LiveRange &liveRange, const TCEString &newReg, TTAProgram::BasicBlock &bb, int loopDepth) const
Definition: RegisterRenamer.cc:1139
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
MachineConnectivityCheck.hh
TTAProgram::Terminal::index
virtual int index() const
Definition: Terminal.cc:274
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
RegisterRenamer::allNormalGPRs_
std::set< TCEString > allNormalGPRs_
Definition: RegisterRenamer.hh:140
BoostGraph::node
Node & node(const int index) const
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
BoostGraph::hasPath
bool hasPath(GraphNode &src, const GraphNode &dest) const
LiveRangeData::MoveNodeUseSet
std::set< MoveNodeUse > MoveNodeUseSet
Definition: LiveRangeData.hh:51
TTAProgram::Terminal::registerFile
virtual const TTAMachine::RegisterFile & registerFile() const
Definition: Terminal.cc:225
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
BoostGraph< MoveNode, DataDependenceEdge >::NodeSet
std::set< MoveNode *, typename MoveNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
MoveNodeUse::pseudo
bool pseudo() const
Definition: MoveNodeUse.hh:42
MoveNodeUse
Definition: MoveNodeUse.hh:20
MapTools.hh
TTAMachine::Bus
Definition: Bus.hh:53
RegisterRenamer::findConnectedRFs
RegisterFileSet findConnectedRFs(LiveRange &lr, bool allowLimm)
Definition: RegisterRenamer.cc:1206
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
LiveRangeData::regDefines_
MoveNodeUseMapSet regDefines_
Definition: LiveRangeData.hh:78
DataDependenceGraph::guardRenamed
DataDependenceGraph::UndoData guardRenamed(MoveNode &mn)
Definition: DataDependenceGraph.cc:5006
RegisterRenamer::findPartiallyUsedRegistersAfterCycle
std::set< TCEString > findPartiallyUsedRegistersAfterCycle(int bitWidth, int latestCycle) const
Definition: RegisterRenamer.cc:394
DataDependenceGraph::lastScheduledRegisterGuardReads
NodeSet lastScheduledRegisterGuardReads(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
Definition: DataDependenceGraph.cc:1163
RegisterRenamer::tempRegFiles_
std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegFiles_
Definition: RegisterRenamer.hh:159
TTAProgram::Move::bus
const TTAMachine::Bus & bus() const
Definition: Move.cc:373
DataDependenceGraph.hh
TTAProgram::Move::setGuard
void setGuard(MoveGuard *guard)
Definition: Move.cc:360
MoveNode
Definition: MoveNode.hh:65
DataDependenceGraph::findLiveRange
LiveRange * findLiveRange(MoveNode &lrNode, bool writingNode, bool guardUseNode) const
Definition: DataDependenceGraph.cc:4827
LiveRangeData::regKills_
MoveNodeUseMapPair regKills_
Definition: LiveRangeData.hh:85
Terminal.hh
DataDependenceEdge::EDGE_REGISTER
@ EDGE_REGISTER
Definition: DataDependenceEdge.hh:53
TTAMachine::Machine::Navigator::count
int count() const
RegisterRenamer::usedGPRs_
std::set< TCEString > usedGPRs_
Definition: RegisterRenamer.hh:145
LiveRangeData::regDefReaches_
MoveNodeUseMapSet regDefReaches_
Definition: LiveRangeData.hh:90
MachineConnectivityCheck::findWritePorts
static PortSet findWritePorts(const TTAMachine::Unit &rf)
Definition: MachineConnectivityCheck.cc:1589
TerminalRegister.hh
MoveNodeSelector.hh
RegisterRenamer::onlyBeginPartiallyUsedRegs_
std::set< TCEString > onlyBeginPartiallyUsedRegs_
Definition: RegisterRenamer.hh:149
assert
#define assert(condition)
Definition: Application.hh:86
LiveRange::lastCycle
int lastCycle() const
Definition: LiveRange.cc:103
MoveNode::isMove
bool isMove() const
TTAProgram::Move::setDestination
void setDestination(Terminal *dst)
Definition: Move.cc:333
RegisterRenamer::bb
TTAProgram::BasicBlock & bb()
Definition: RegisterRenamer.hh:102
TTAMachine::RegisterFile::firstWritePort
Port * firstWritePort() const
Definition: RegisterFile.cc:618
BoostGraph::rootGraph
BoostGraph * rootGraph()
TTAProgram::BasicBlock::liveRangeData_
LiveRangeData * liveRangeData_
Definition: BasicBlock.hh:111
RegisterRenamer::findFreeGuardRegisters
std::set< TCEString > findFreeGuardRegisters(const DataDependenceGraph::NodeSet &guardUseNodes, int bitWidth, const RegisterFileSet &rfs) const
Definition: RegisterRenamer.cc:437
RegisterRenamer::bb_
TTAProgram::BasicBlock & bb_
Definition: RegisterRenamer.hh:162
TTAMachine::RegisterGuard
Definition: Guard.hh:137
TTAMachine::Port
Definition: Port.hh:54
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
LiveRangeData::regFirstDefines_
MoveNodeUseMapSet regFirstDefines_
Definition: LiveRangeData.hh:87
MachineConnectivityCheck::canSourceWriteToAnyDestinationPort
static int canSourceWriteToAnyDestinationPort(const MoveNode &src, PortSet &ports, bool ignoreGuard=false)
Definition: MachineConnectivityCheck.cc:1754
LiveRange::noneScheduled
bool noneScheduled() const
Definition: LiveRange.cc:36
RegisterRenamer::findGuardRegisters
std::set< TCEString > findGuardRegisters(const DataDependenceGraph::NodeSet &guardMoves, const RegisterFileSet &rfs) const
Definition: RegisterRenamer.cc:1270
RegisterRenamer::initializeFreeRegisters
void initializeFreeRegisters()
Definition: RegisterRenamer.cc:114
RegisterRenamer::renameSourceRegister
bool renameSourceRegister(MoveNode &node, bool loopScheduling, bool allowSameRf, bool differentRfOnlyDirectlyReachable, int latestCycle=INT_MAX)
Definition: RegisterRenamer.cc:617
LiveRangeData::regLastUses_
MoveNodeUseMapSet regLastUses_
Definition: LiveRangeData.hh:79
TTAProgram::Terminal::isGPR
virtual bool isGPR() const
Definition: Terminal.cc:107
Guard.hh
DataDependenceGraph::connectOrDeleteEdge
bool connectOrDeleteEdge(const MoveNode &tailNode, const MoveNode &headNode, DataDependenceEdge *edge)
Definition: DataDependenceGraph.cc:3355
RegisterRenamer::tempRegFileCache_
static std::map< const TTAMachine::Machine *, std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > > tempRegFileCache_
To avoid reanalysing machine every time hen new rr created.
Definition: RegisterRenamer.hh:157
MachineConnectivityCheck::findReadPorts
static PortSet findReadPorts(const TTAMachine::Unit &rf)
Definition: MachineConnectivityCheck.cc:1601
LiveRange::writes
DataDependenceGraph::NodeSet writes
Definition: LiveRange.hh:39
TTAProgram::Move
Definition: Move.hh:55
MoveNodeSelector
Definition: MoveNodeSelector.hh:45
Machine.hh
RegisterRenamer::findPartiallyUsedRegistersInRFBeforeCycle
std::set< TCEString > findPartiallyUsedRegistersInRFBeforeCycle(const RegisterFileSet &rfs, int earliestCycle, const DataDependenceGraph::NodeSet &guardMoves) const
Definition: RegisterRenamer.cc:260
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
MoveNodeSelector::mightBeReady
virtual void mightBeReady(MoveNode &node)=0
Definition: MoveNodeSelector.cc:82
BoostGraph::hasNode
bool hasNode(const Node &) const
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
DataDependenceEdge::DEP_WAW
@ DEP_WAW
Definition: DataDependenceEdge.hh:49
RegisterRenamer::RegisterRenamer
RegisterRenamer(const TTAMachine::Machine &machine, TTAProgram::BasicBlock &bb)
Definition: RegisterRenamer.cc:74
LiveRange::reads
DataDependenceGraph::NodeSet reads
Definition: LiveRange.hh:40
MachineConnectivityCheck::tempRegisterFiles
static std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegisterFiles(const TTAMachine::Machine &machine)
Definition: MachineConnectivityCheck.cc:1038
LiveRange::guards
DataDependenceGraph::NodeSet guards
Definition: LiveRange.hh:41
SetTools::intersection
static void intersection(const std::set< ValueType > &firstContainer, const std::set< ValueType > &secondContainer, std::set< ValueType > &intersection)
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
TTAMachine::Guard::parentBus
virtual Bus * parentBus() const
RegisterRenamer::initialize
void initialize()
Definition: RegisterRenamer.cc:87
DataDependenceGraph::lastRegisterCycle
int lastRegisterCycle(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
Definition: DataDependenceGraph.cc:882
MoveNode::move
TTAProgram::Move & move()
LiveRangeData::registersUsedAfter_
std::set< TCEString > registersUsedAfter_
Definition: LiveRangeData.hh:121
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
DisassemblyRegister.hh
LiveRangeData.hh
TTAMachine::Guard::isInverted
virtual bool isInverted() const
DataDependenceGraph::destRenamed
DataDependenceGraph::UndoData destRenamed(MoveNode &mn)
Definition: DataDependenceGraph.cc:5055
AssocTools::append
static void append(const ContainerType &src, ContainerType &dest)
RegisterFile.hh
RegisterRenamer::renameDestinationRegister
bool renameDestinationRegister(MoveNode &node, bool loopScheduling, bool allowSameRf, bool differentRfOnlyDirectlyReachable, int earliestCycle=-1)
Definition: RegisterRenamer.cc:458
TCEString
Definition: TCEString.hh:53
BasicBlock.hh
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
RegisterRenamer::setSelector
void setSelector(MoveNodeSelector *selector)
Definition: RegisterRenamer.cc:1126
RegisterRenamer::ddg_
DataDependenceGraph * ddg_
Definition: RegisterRenamer.hh:163
LiveRange::firstCycle
int firstCycle() const
Definition: LiveRange.cc:77
DataDependenceGraph::firstScheduledRegisterWrites
NodeSet firstScheduledRegisterWrites(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
Definition: DataDependenceGraph.cc:1245
TTAProgram::Terminal
Definition: Terminal.hh:60
DataDependenceEdge
Definition: DataDependenceEdge.hh:43
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
RegisterRenamer::renameLiveRange
bool renameLiveRange(LiveRange &liveRange, const TCEString &newReg, bool usedBefore, bool usedAfter, bool loopScheduling)
Definition: RegisterRenamer.cc:714
RegisterRenamer::findPartiallyUsedRegistersBeforeCycle
std::set< TCEString > findPartiallyUsedRegistersBeforeCycle(int bitWidth, int earliestCycle, const DataDependenceGraph::NodeSet &guardMoves) const
Definition: RegisterRenamer.cc:341
RegisterRenamer::findFreeRegistersInRF
std::set< TCEString > findFreeRegistersInRF(const RegisterFileSet &rfs) const
Definition: RegisterRenamer.cc:223
TTAProgram::Terminal::port
virtual const TTAMachine::Port & port() const
Definition: Terminal.cc:378
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
DisassemblyRegister::registerName
static TCEString registerName(const TTAMachine::RegisterFile &rf, int index, char delim='.')
Definition: DisassemblyRegister.cc:95
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
TTAProgram::MoveGuard::guard
const TTAMachine::Guard & guard() const
Definition: MoveGuard.cc:86
RegisterRenamer::machine_
const TTAMachine::Machine & machine_
Definition: RegisterRenamer.hh:161
MachineConnectivityCheck::canAnyPortWriteToDestination
static bool canAnyPortWriteToDestination(PortSet &ports, const MoveNode &dest)
Definition: MachineConnectivityCheck.cc:1830
RegisterRenamer::revertedRenameToRegister
void revertedRenameToRegister(const TCEString &reg)
Definition: RegisterRenamer.cc:1106
Move.hh
TTAMachine::BaseRegisterFile::size
virtual int size() const
DataDependenceEdge::DEP_WAR
@ DEP_WAR
Definition: DataDependenceEdge.hh:48
MoveNode.hh
TTAMachine::MachinePart::Comparator
Definition: MachinePart.hh:59
TTAProgram::MoveGuard
Definition: MoveGuard.hh:47
TTAMachine::BaseRegisterFile::width
virtual int width() const
DataDependenceGraph::lastScheduledRegisterReads
NodeSet lastScheduledRegisterReads(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
Definition: DataDependenceGraph.cc:1080
RegisterRenamer::onlyMidPartiallyUsedRegs_
std::set< TCEString > onlyMidPartiallyUsedRegs_
Definition: RegisterRenamer.hh:152
BoostGraph::nodeCount
int nodeCount() const
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
LiveRange
Definition: LiveRange.hh:38
BoostGraph::successors
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
RegisterRenamer.hh
RegisterRenamer::findPartiallyUsedRegistersInRFAfterCycle
std::set< TCEString > findPartiallyUsedRegistersInRFAfterCycle(const RegisterFileSet &rfs, int latestCycle) const
Definition: RegisterRenamer.cc:310
MachineConnectivityCheck::PortSet
std::set< const TTAMachine::Port *, const TTAMachine::MachinePart::Comparator > PortSet
Definition: MachineConnectivityCheck.hh:72
LiveRange.hh
TTAProgram::TerminalRegister
Definition: TerminalRegister.hh:53
RegisterRenamer::registersOfRFs
std::set< TCEString > registersOfRFs(const RegisterFileSet &rfs) const
Definition: RegisterRenamer.cc:233
LiveRangeData::regFirstUses_
MoveNodeUseMapSet regFirstUses_
Definition: LiveRangeData.hh:86
RegisterRenamer::findFreeRegisters
std::set< TCEString > findFreeRegisters(int bitWidth) const
Definition: RegisterRenamer.cc:418
TTAMachine::RegisterFile::zeroRegister
virtual bool zeroRegister() const
Definition: RegisterFile.cc:629
TTAProgram::Move::setSource
void setSource(Terminal *src)
Definition: Move.cc:312
TTAMachine::Machine
Definition: Machine.hh:73
DataDependenceGraph::sourceRenamed
DataDependenceGraph::UndoData sourceRenamed(MoveNode &mn)
Definition: DataDependenceGraph.cc:4970
RegisterRenamer::selector_
MoveNodeSelector * selector_
Definition: RegisterRenamer.hh:165
MoveGuard.hh
TTAMachine::Port::parentUnit
Unit * parentUnit() const