56#include "tce_config.h"
76 machine_(
machine), bb_(bb), ddg_(NULL){
100 for (
int i = 0; i < regNav.count(); i++) {
101 bool isTempRf =
false;
106 unsigned int regCount = isTempRf ? rf->
size()-1 : rf->
size();
107 for (
unsigned int j = 0; j < regCount; j++ ) {
122 std::map<TCEString,int> lastUses;
144 for (std::set<TCEString>::iterator allIter =
freeGPRs_.begin();
146 bool aliveOver =
false;
147 bool aliveAtBeginning =
false;
148 bool aliveAtEnd =
false;
149 bool aliveAtMid =
false;
159 aliveAtBeginning =
true;
160 LiveRangeData::MoveNodeUseMapSet::iterator i =
164 for (LiveRangeData::MoveNodeUseSet::iterator j =
165 lastUses.begin(); j != lastUses.end(); j++) {
172 aliveAtBeginning =
true;
184 if (aliveAtEnd && aliveAtBeginning) {
199 if (aliveAtBeginning) {
227 std::set<TCEString> regs;
236 std::set<TCEString> gprs;
239 i != rfs.end(); i++) {
240 bool isTempRF =
false;
245 int lowestFreeIndex = 0;
249 for (
int j = lowestFreeIndex;
250 j < (isTempRF ? rf->
size() - 1 : rf->
size()); j++) {
264 std::set<TCEString> availableRegs;
267 if (earliestCycle < 1) {
268 return availableRegs;
275 std::set<TCEString> regs2;
281 for (std::set<TCEString>::iterator i = regs2.begin();
282 i != regs2.end(); i++) {
283 TCEString rfName = i->substr(0, i->find(
'.'));
287 unsigned int regIndex = atoi(i->substr(i->find(
'.')+1).c_str());
289 availableRegs.insert(*i);
294 if (guardMoves.empty()) {
295 return availableRegs;
297 std::set<TCEString> guardedRegs =
299 std::set<TCEString> guardedAvailableRegs;
301 availableRegs, guardedRegs, guardedAvailableRegs);
302 return guardedAvailableRegs;
313 std::set<TCEString> availableRegs;
321 std::set<TCEString> regs2;
326 for (std::set<TCEString>::iterator i = regs2.begin();
327 i != regs2.end(); i++) {
328 TCEString rfName = i->substr(0, i->find(
'.'));
332 unsigned int regIndex = atoi(i->substr(i->find(
'.')+1).c_str());
334 availableRegs.insert(*i);
337 return availableRegs;
342 int bitWidth,
int earliestCycle,
344 std::set<TCEString> availableRegs;
347 if (earliestCycle < 1) {
348 return availableRegs;
355 for (std::set<TCEString>::iterator i = regs.begin();
356 i != regs.end(); i++) {
358 TCEString rfName = i->substr(0, i->find(
'.'));
361 unsigned int regIndex = atoi(i->substr(i->find(
'.')+1).c_str());
363 rf->
width() == bitWidth) {
364 availableRegs.insert(*i);
368 if (guardMoves.empty()) {
369 return availableRegs;
371#ifdef DEBUG_REGISTER_RENAMER
372 if (!liveRange->guards.empty()) {
373 std::cerr <<
"\t\t\t\tpartiallyusedregs: ";
374 for (std::set<TCEString>::iterator i =
376 i != regs.end(); i++) {
377 std::cerr << *i <<
" ";
379 std::cerr << std::endl;
384 std::set<TCEString> guardedRegs =
386 std::set<TCEString> guardedAvailableRegs;
388 availableRegs, guardedRegs, guardedAvailableRegs);
389 return guardedAvailableRegs;
395 int bitWidth,
int latestCycle)
const {
396 std::set<TCEString> availableRegs;
402 for (std::set<TCEString>::iterator i = regs.begin();
403 i != regs.end(); i++) {
405 TCEString rfName = i->substr(0, i->find(
'.'));
408 unsigned int regIndex = atoi(i->substr(i->find(
'.')+1).c_str());
410 rf->
width() == bitWidth) {
411 availableRegs.insert(*i);
414 return availableRegs;
419 int bitWidth)
const {
421 std::set<TCEString> availableRegs;
423 for (std::set<TCEString>::iterator i =
freeGPRs_.begin();
426 TCEString rfName = i->substr(0, i->find(
'.'));
429 if (rf->
width() == bitWidth) {
430 availableRegs.insert(*i);
433 return availableRegs;
440 std::set<TCEString> availableRegs;
449 return availableRegs;
459 MoveNode& node,
bool loopScheduling,
460 bool allowSameRf,
bool differentRfOnlyDirectlyReachable,
471 if (loopScheduling) {
477 std::unique_ptr<LiveRange> liveRange(
480 if (liveRange->writes.empty()) {
483 std::set<TCEString> availableRegisters;
485 if (!liveRange->noneScheduled()) {
493 earliestCycle = std::min(earliestCycle, liveRange->firstCycle());
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;
509 rf.
width(), earliestCycle, liveRange->guards);
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 <<
" ";
519 std::cerr << std::endl;
524 if (!differentRfOnlyDirectlyReachable) {
529 rfs, earliestCycle, liveRange->guards);
530 if (availableRegisters.empty()) {
535 rfs, earliestCycle, liveRange->guards);
540 if (availableRegisters.empty()) {
543 if (!liveRange->noneScheduled()) {
544 if (liveRange->guards.empty()) {
552 if (liveRange->guards.empty()) {
556#ifdef DEBUG_REG_RENAMER
557 std::cerr <<
"\t\tSearching for avail guard regs" << std::endl;
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 <<
" ";
570 std::cerr << std::endl;
576 if (liveRange->guards.empty()) {
577 if (!differentRfOnlyDirectlyReachable) {
583 if (availableRegisters.empty()) {
597 liveRange->guards, rf.
width(), rfs);
601 if (availableRegisters.empty()) {
608 *liveRange, *availableRegisters.begin(),
609 reused,
false, loopScheduling);
618 MoveNode& node,
bool loopScheduling,
619 bool allowSameRf,
bool differentRfOnlyDirectlyReachable,
int latestCycle) {
627 if (loopScheduling) {
634 std::unique_ptr<LiveRange> liveRange(
637 if (liveRange->writes.empty()) {
640 std::set<TCEString> availableRegisters;
642 if (!liveRange->noneScheduled()) {
649 latestCycle = std::max(latestCycle, liveRange->lastCycle());
658 if (!differentRfOnlyDirectlyReachable) {
665 if (availableRegisters.empty()) {
675 if (availableRegisters.empty()) {
678 if (!liveRange->noneScheduled()) {
689 if (!differentRfOnlyDirectlyReachable) {
695 if (availableRegisters.empty()) {
702 if (availableRegisters.empty()) {
709 *liveRange, *availableRegisters.begin(),
false, reused,
716 bool usedAfter,
bool loopScheduling) {
718 if (liveRange.
writes.size() <1) {
722 if (liveRange.
reads.size() == 0 && liveRange.
guards.size() == 0) {
726 assert(newReg.length() > 2);
727 TCEString rfName = newReg.substr(0, newReg.find(
'.'));
732 atoi(newReg.substr(newReg.find(
'.')+1).c_str());
751 for (DataDependenceGraph::NodeSet::iterator i =
752 liveRange.
writes.begin(); i != liveRange.
writes.end(); i++) {
755 for (DataDependenceGraph::NodeSet::iterator
756 j = lastReads.begin(); j != lastReads.end(); j++) {
766 for (DataDependenceGraph::NodeSet::iterator
767 j = lastGuards.begin(); j != lastGuards.end(); j++) {
777 for (DataDependenceGraph::NodeSet::iterator
778 j = lastWrites.begin(); j != lastWrites.end(); j++) {
795 if (liveRange.
writes.size() == 1 &&
796 (*liveRange.
writes.begin())->move().isUnconditional()) {
804 for (DataDependenceGraph::NodeSet::iterator i =
805 liveRange.
writes.begin(); i != liveRange.
writes.end(); i++) {
811 updateRegWrite(mnd, newReg,
bb_);
815 for (DataDependenceGraph::NodeSet::iterator i =
816 liveRange.
reads.begin(); i != liveRange.
reads.end(); i++) {
824 for (DataDependenceGraph::NodeSet::iterator i =
825 liveRange.
guards.begin(); i != liveRange.
guards.end(); i++) {
841 for (DataDependenceGraph::NodeSet::iterator
842 j = firstWrites.begin(); j != firstWrites.end(); j++) {
844 for (DataDependenceGraph::NodeSet::iterator i =
845 liveRange.
reads.begin(); i != liveRange.
reads.end();
852 for (DataDependenceGraph::NodeSet::iterator i =
864 for (DataDependenceGraph::NodeSet::iterator
865 j = firstWrites.begin(); j != firstWrites.end(); j++) {
868 for (DataDependenceGraph::NodeSet::iterator i =
880 for (DataDependenceGraph::NodeSet::iterator i =
881 liveRange.
reads.begin(); i != liveRange.
reads.end();
894 if (liveRange.
writes.size() == 1 &&
895 (*liveRange.
writes.begin())->move().isUnconditional()) {
902 for (DataDependenceGraph::NodeSet::iterator i =
903 liveRange.
writes.begin(); i != liveRange.
writes.end(); i++) {
910 for (DataDependenceGraph::NodeSet::iterator i =
911 liveRange.
reads.begin(); i != liveRange.
reads.end(); i++) {
918 if (loopScheduling) {
926 for (DataDependenceGraph::NodeSet::iterator i = liveRange.
writes.begin();
927 i != liveRange.
writes.end(); i++) {
932 oldPort, newRegIndex));
941 for (DataDependenceGraph::NodeSet::iterator i = liveRange.
reads.begin();
942 i != liveRange.
reads.end(); i++) {
947 oldPort, newRegIndex));
956 for (DataDependenceGraph::NodeSet::iterator i = liveRange.
guards.begin();
957 i != liveRange.
guards.end(); i++) {
963#ifdef DEBUG_REG_RENAMER
967 std::cerr <<
"We should be updating guard here for: "
970 std::cerr <<
"\tnew guard reg: " << rf->
name() <<
"." << newRegIndex
973 std::cerr <<
"\tBus: " << bus.
name() << std::endl;
977#ifdef DEBUG_REG_RENAMER
978 std::cerr <<
"\tGuard bus: " << guardBus->
name() << std::endl;
980 for (
int j = 0 ; j < guardBus->
guardCount(); j++) {
989#ifdef DEBUG_REG_RENAMER
990 std::cerr <<
"\tset new guard: " << mn.
toString()
1011 for (DataDependenceGraph::NodeSet::iterator i = liveRange.
writes.begin();
1012 i != liveRange.
writes.end(); i++) {
1023 for (DataDependenceGraph::NodeSet::iterator iter =
1024 writeSuccessors.begin();
1025 iter != writeSuccessors.end(); iter++) {
1030 for (DataDependenceGraph::NodeSet::iterator iter =
1031 writePredecessors.begin();
1032 iter != writePredecessors.end(); iter++) {
1039 for (DataDependenceGraph::NodeSet::iterator i = liveRange.
reads.begin();
1040 i != liveRange.
reads.end(); i++) {
1050 for (DataDependenceGraph::NodeSet::iterator iter =
1052 iter != successors.end(); iter++) {
1057 for (DataDependenceGraph::NodeSet::iterator iter =
1058 predecessors.begin();
1059 iter != predecessors.end(); iter++) {
1065 for (DataDependenceGraph::NodeSet::iterator i = liveRange.
guards.begin();
1066 i != liveRange.
guards.end(); i++) {
1076 for (DataDependenceGraph::NodeSet::iterator iter =
1078 iter != successors.end(); iter++) {
1083 for (DataDependenceGraph::NodeSet::iterator iter =
1084 predecessors.begin();
1085 iter != predecessors.end(); iter++) {
1141 int loopDepth)
const {
1142 std::set<MoveNodeUse>& firstDefs =
1145 for (std::set<MoveNodeUse>::iterator i = firstDefs.begin();
1146 i != firstDefs.end(); i++) {
1152 for (DataDependenceGraph::NodeSet::iterator j =
1153 liveRange.
writes.begin();
1154 j != liveRange.
writes.end(); j++) {
1161 false,
false,
false, destination.
pseudo(), loopDepth);
1165 **j, *destination.
mn(), dde);
1169 for (DataDependenceGraph::NodeSet::iterator j =
1170 liveRange.
reads.begin();
1171 j != liveRange.
reads.end(); j++) {
1178 false,
false,
false, destination.
pseudo(), 1);
1182 **j, *destination.
mn(), dde);
1186 for (DataDependenceGraph::NodeSet::iterator j =
1187 liveRange.
guards.begin();
1188 j != liveRange.
guards.end(); j++) {
1195 true,
false,
false, destination.
pseudo(), 1);
1199 **j, *destination.
mn(), dde);
1211 (*lr.
writes.begin())->move().destination().port().parentUnit());
1213 int bitwidth = originalRF->
width();
1220 for (
int i = 0; i < rfNav.
count(); i++) {
1222 if (rf->
width() != bitwidth) {
1227 bool connected =
true;
1229 for (DataDependenceGraph::NodeSet::iterator j = lr.
writes.begin();
1230 j != lr.
writes.end() && connected; j++) {
1233 write, writePorts)) {
1235 connected = allowLimm;
1250 for (DataDependenceGraph::NodeSet::iterator j = lr.
reads.begin();
1251 j != lr.
reads.end() && connected; j++) {
1276 for (DataDependenceGraph::NodeSet::iterator i = guardMoves.begin();
1277 i != guardMoves.end(); i++) {
1286 return std::set<TCEString>();
1294 return std::set<TCEString>();
1305 std::set<TCEString> trueGuards;
1306 std::set<TCEString> falseGuards;
1309 for (
int i = 0 ; i < bus.
guardCount(); i++) {
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();
#define assert(condition)
TTAMachine::Machine * machine
the architecture definition of the estimated processor
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
Node & node(const int index) const
bool hasNode(const Node &) const
bool hasPath(GraphNode &src, const GraphNode &dest) const
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
LiveRange * findLiveRange(MoveNode &lrNode, bool writingNode, bool guardUseNode) const
NodeSet lastScheduledRegisterWrites(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
int firstRegisterCycle(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
DataDependenceGraph::UndoData sourceRenamed(MoveNode &mn)
NodeSet lastScheduledRegisterGuardReads(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
NodeSet firstScheduledRegisterWrites(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
NodeSet lastScheduledRegisterReads(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
int lastRegisterCycle(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
DataDependenceGraph::UndoData guardRenamed(MoveNode &mn)
DataDependenceGraph::UndoData destRenamed(MoveNode &mn)
bool connectOrDeleteEdge(const MoveNode &tailNode, const MoveNode &headNode, DataDependenceEdge *edge)
static TCEString registerName(const TTAMachine::RegisterFile &rf, int index, char delim='.')
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
static std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegisterFiles(const TTAMachine::Machine &machine)
static PortSet findWritePorts(const TTAMachine::Unit &rf)
static int canSourceWriteToAnyDestinationPort(const MoveNode &src, PortSet &ports, bool ignoreGuard=false)
static PortSet findReadPorts(const TTAMachine::Unit &rf)
static bool canAnyPortWriteToDestination(PortSet &ports, const MoveNode &dest)
std::set< const TTAMachine::Port *, const TTAMachine::MachinePart::Comparator > PortSet
virtual void mightBeReady(MoveNode &node)=0
const MoveNode * mn() const
std::string toString() const
TTAProgram::Move & move()
std::set< TCEString > findPartiallyUsedRegistersInRFBeforeCycle(const RegisterFileSet &rfs, int earliestCycle, const DataDependenceGraph::NodeSet &guardMoves) const
void revertedRenameToRegister(const TCEString ®)
MoveNodeSelector * selector_
std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegFiles_
std::set< TCEString > findPartiallyUsedRegistersBeforeCycle(int bitWidth, int earliestCycle, const DataDependenceGraph::NodeSet &guardMoves) const
DataDependenceGraph * ddg_
std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > RegisterFileSet
TTAProgram::BasicBlock & bb()
std::set< TCEString > allNormalGPRs_
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.
std::set< TCEString > freeGPRs_
bool renameLiveRange(LiveRange &liveRange, const TCEString &newReg, bool usedBefore, bool usedAfter, bool loopScheduling)
bool renameDestinationRegister(MoveNode &node, bool loopScheduling, bool allowSameRf, bool differentRfOnlyDirectlyReachable, int earliestCycle=-1)
std::set< TCEString > findFreeGuardRegisters(const DataDependenceGraph::NodeSet &guardUseNodes, int bitWidth, const RegisterFileSet &rfs) const
void setSelector(MoveNodeSelector *selector)
RegisterRenamer(const TTAMachine::Machine &machine, TTAProgram::BasicBlock &bb)
std::set< TCEString > onlyEndPartiallyUsedRegs_
bool renameSourceRegister(MoveNode &node, bool loopScheduling, bool allowSameRf, bool differentRfOnlyDirectlyReachable, int latestCycle=INT_MAX)
std::set< TCEString > registersOfRFs(const RegisterFileSet &rfs) const
std::set< TCEString > findFreeRegistersInRF(const RegisterFileSet &rfs) const
std::set< TCEString > onlyBeginPartiallyUsedRegs_
std::set< TCEString > findGuardRegisters(const DataDependenceGraph::NodeSet &guardMoves, const RegisterFileSet &rfs) const
std::set< TCEString > findPartiallyUsedRegistersAfterCycle(int bitWidth, int latestCycle) const
std::set< TCEString > findFreeRegisters(int bitWidth) const
const TTAMachine::Machine & machine_
std::set< TCEString > findPartiallyUsedRegistersInRFAfterCycle(const RegisterFileSet &rfs, int latestCycle) const
TTAProgram::BasicBlock & bb_
void renamedToRegister(const TCEString &newReg)
std::set< TCEString > onlyMidPartiallyUsedRegs_
void initializeFreeRegisters()
RegisterFileSet findConnectedRFs(LiveRange &lr, bool allowLimm)
std::set< TCEString > usedGPRs_
void updateAntiEdgesFromLRTo(LiveRange &liveRange, const TCEString &newReg, TTAProgram::BasicBlock &bb, int loopDepth) const
virtual int width() const
Guard * guard(int index) const
virtual TCEString name() const
virtual bool isInverted() const
virtual Bus * parentBus() const
ComponentType * item(int index) const
virtual RegisterFileNavigator registerFileNavigator() const
Unit * parentUnit() const
Port * firstReadPort() const
virtual bool zeroRegister() const
Port * firstWritePort() const
int registerIndex() const
const RegisterFile * registerFile() const
LiveRangeData * liveRangeData_
const TTAMachine::Guard & guard() const
void setSource(Terminal *src)
MoveGuard & guard() const
bool isUnconditional() const
Terminal & source() const
void setGuard(MoveGuard *guard)
Terminal & destination() const
void setDestination(Terminal *dst)
const TTAMachine::Bus & bus() const
virtual int index() const
virtual bool isGPR() const
virtual const TTAMachine::Port & port() const
virtual const TTAMachine::RegisterFile & registerFile() const
MoveNodeUseMapSet regFirstUses_
MoveNodeUseMapSet regLastUses_
std::set< MoveNodeUse > MoveNodeUseSet
std::set< TCEString > registersUsedAfter_
MoveNodeUseMapSet regFirstDefines_
MoveNodeUseMapPair regKills_
MoveNodeUseMapPair regLastKills_
MoveNodeUseMapSet regDefines_
MoveNodeUseMapSet regDefReaches_
DataDependenceGraph::NodeSet reads
DataDependenceGraph::NodeSet guards
DataDependenceGraph::NodeSet writes