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

#include <RegisterRenamer.hh>

Collaboration diagram for RegisterRenamer:
Collaboration graph

Public Types

typedef std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::ComparatorRegisterFileSet
 

Public Member Functions

 RegisterRenamer (const TTAMachine::Machine &machine, TTAProgram::BasicBlock &bb)
 
unsigned int freeGPRCount () const
 
void initialize (DataDependenceGraph &ddg)
 
bool renameDestinationRegister (MoveNode &node, bool loopScheduling, bool allowSameRf, bool differentRfOnlyDirectlyReachable, int earliestCycle=-1)
 
bool renameSourceRegister (MoveNode &node, bool loopScheduling, bool allowSameRf, bool differentRfOnlyDirectlyReachable, int latestCycle=INT_MAX)
 
void setSelector (MoveNodeSelector *selector)
 
bool renameLiveRange (LiveRange &liveRange, const TCEString &newReg, bool usedBefore, bool usedAfter, bool loopScheduling)
 
std::set< TCEStringfindPartiallyUsedRegistersAfterCycle (int bitWidth, int latestCycle) const
 
std::set< TCEStringfindFreeRegisters (int bitWidth) const
 
std::set< TCEStringfindPartiallyUsedRegistersInRFAfterCycle (const RegisterFileSet &rfs, int latestCycle) const
 
std::set< TCEStringfindFreeRegistersInRF (const RegisterFileSet &rfs) const
 
RegisterFileSet findConnectedRFs (LiveRange &lr, bool allowLimm)
 
TTAProgram::BasicBlockbb ()
 
void renamedToRegister (const TCEString &newReg)
 
void revertedRenameToRegister (const TCEString &reg)
 

Private Member Functions

std::set< TCEStringregistersOfRFs (const RegisterFileSet &rfs) const
 
void initializeFreeRegisters ()
 
std::set< TCEStringfindPartiallyUsedRegistersInRFBeforeCycle (const RegisterFileSet &rfs, int earliestCycle, const DataDependenceGraph::NodeSet &guardMoves) const
 
std::set< TCEStringfindPartiallyUsedRegistersBeforeCycle (int bitWidth, int earliestCycle, const DataDependenceGraph::NodeSet &guardMoves) const
 
std::set< TCEStringfindFreeGuardRegisters (const DataDependenceGraph::NodeSet &guardUseNodes, int bitWidth, const RegisterFileSet &rfs) const
 
std::set< TCEStringfindGuardRegisters (const DataDependenceGraph::NodeSet &guardMoves, const RegisterFileSet &rfs) const
 
std::set< TCEStringfindGuardRegisters (const TTAMachine::Bus &bus, const RegisterFileSet &rfs) const
 
void updateAntiEdgesFromLRTo (LiveRange &liveRange, const TCEString &newReg, TTAProgram::BasicBlock &bb, int loopDepth) const
 
void initialize ()
 

Private Attributes

std::set< TCEStringallNormalGPRs_
 
std::set< TCEStringfreeGPRs_
 
std::set< TCEStringusedGPRs_
 
std::set< TCEStringonlyBeginPartiallyUsedRegs_
 
std::set< TCEStringonlyEndPartiallyUsedRegs_
 
std::set< TCEStringonlyMidPartiallyUsedRegs_
 
std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::ComparatortempRegFiles_
 
const TTAMachine::Machinemachine_
 
TTAProgram::BasicBlockbb_
 
DataDependenceGraphddg_
 
MoveNodeSelectorselector_
 

Static Private Attributes

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.
 

Detailed Description

Definition at line 59 of file RegisterRenamer.hh.

Member Typedef Documentation

◆ RegisterFileSet

Definition at line 62 of file RegisterRenamer.hh.

Constructor & Destructor Documentation

◆ RegisterRenamer()

RegisterRenamer::RegisterRenamer ( const TTAMachine::Machine machine,
TTAProgram::BasicBlock bb 
)

Constructor.

Parameters
machinemachine for which we are scheudling

RegisterRenamer::RegisterRenamer(const TTAMachine::Machine& machine) : machine_(machine) { initialize(); } Constructor.

Parameters
machinemachine for which we are scheudling

Definition at line 74 of file RegisterRenamer.cc.

75 :
76 machine_(machine), bb_(bb), ddg_(NULL){
77 initialize();
78}
TTAMachine::Machine * machine
the architecture definition of the estimated processor
DataDependenceGraph * ddg_
TTAProgram::BasicBlock & bb()
const TTAMachine::Machine & machine_
TTAProgram::BasicBlock & bb_

References initialize().

Here is the call graph for this function:

Member Function Documentation

◆ bb()

TTAProgram::BasicBlock & RegisterRenamer::bb ( )
inline

Definition at line 102 of file RegisterRenamer.hh.

102{ return bb_; }

References bb_.

Referenced by BFRenameLiveRange::operator()(), and updateAntiEdgesFromLRTo().

◆ findConnectedRFs()

RegisterRenamer::RegisterFileSet RegisterRenamer::findConnectedRFs ( LiveRange lr,
bool  allowLimm 
)

Definition at line 1206 of file RegisterRenamer.cc.

1206 {
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 }
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}
#define assert(condition)
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 int width() const
ComponentType * item(int index) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
DataDependenceGraph::NodeSet reads
Definition LiveRange.hh:40
DataDependenceGraph::NodeSet writes
Definition LiveRange.hh:39

References assert, MachineConnectivityCheck::canAnyPortWriteToDestination(), MachineConnectivityCheck::canSourceWriteToAnyDestinationPort(), TTAMachine::Machine::Navigator< ComponentType >::count(), MachineConnectivityCheck::findReadPorts(), MachineConnectivityCheck::findWritePorts(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, LiveRange::reads, TTAMachine::Machine::registerFileNavigator(), TTAMachine::BaseRegisterFile::width(), and LiveRange::writes.

Referenced by BFRenameLiveRange::operator()(), renameDestinationRegister(), and renameSourceRegister().

Here is the call graph for this function:

◆ findFreeGuardRegisters()

std::set< TCEString > RegisterRenamer::findFreeGuardRegisters ( const DataDependenceGraph::NodeSet guardUseNodes,
int  bitWidth,
const RegisterFileSet rfs 
) const
private

Definition at line 437 of file RegisterRenamer.cc.

439 {
440 std::set<TCEString> availableRegs;
441
443 (rfs.empty() ?
444 findFreeRegisters(bitWidth) :
446 findGuardRegisters(guardUseNodes, rfs),
447 availableRegs);
448
449 return availableRegs;
450}
std::set< TCEString > findFreeRegistersInRF(const RegisterFileSet &rfs) const
std::set< TCEString > findGuardRegisters(const DataDependenceGraph::NodeSet &guardMoves, const RegisterFileSet &rfs) const
std::set< TCEString > findFreeRegisters(int bitWidth) const
static void intersection(const std::set< ValueType > &firstContainer, const std::set< ValueType > &secondContainer, std::set< ValueType > &intersection)

References findFreeRegisters(), findFreeRegistersInRF(), findGuardRegisters(), and SetTools::intersection().

Referenced by renameDestinationRegister().

Here is the call graph for this function:

◆ findFreeRegisters()

std::set< TCEString > RegisterRenamer::findFreeRegisters ( int  bitWidth) const

Definition at line 418 of file RegisterRenamer.cc.

419 {
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}
std::set< TCEString > freeGPRs_

References freeGPRs_, TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, TTAMachine::Machine::registerFileNavigator(), and TTAMachine::BaseRegisterFile::width().

Referenced by findFreeGuardRegisters(), renameDestinationRegister(), and renameSourceRegister().

Here is the call graph for this function:

◆ findFreeRegistersInRF()

std::set< TCEString > RegisterRenamer::findFreeRegistersInRF ( const RegisterFileSet rfs) const

Definition at line 223 of file RegisterRenamer.cc.

224 {
225
226 std::set<TCEString> allowedGprs = registersOfRFs(rfs);
227 std::set<TCEString> regs;
228 SetTools::intersection(allowedGprs, freeGPRs_, regs);
229 return regs;
230}
std::set< TCEString > registersOfRFs(const RegisterFileSet &rfs) const

References freeGPRs_, SetTools::intersection(), and registersOfRFs().

Referenced by findFreeGuardRegisters(), BFRenameLiveRange::operator()(), renameDestinationRegister(), and renameSourceRegister().

Here is the call graph for this function:

◆ findGuardRegisters() [1/2]

std::set< TCEString > RegisterRenamer::findGuardRegisters ( const DataDependenceGraph::NodeSet guardMoves,
const RegisterFileSet rfs 
) const
private

Definition at line 1270 of file RegisterRenamer.cc.

1272 {
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}
TTAProgram::Move & move()
virtual Bus * parentBus() const
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
MoveGuard & guard() const
Definition Move.cc:345
bool isUnconditional() const
Definition Move.cc:154

References assert, findGuardRegisters(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), TTAProgram::Move::isUnconditional(), MoveNode::move(), and TTAMachine::Guard::parentBus().

Referenced by findFreeGuardRegisters(), findGuardRegisters(), findPartiallyUsedRegistersBeforeCycle(), and findPartiallyUsedRegistersInRFBeforeCycle().

Here is the call graph for this function:

◆ findGuardRegisters() [2/2]

std::set< TCEString > RegisterRenamer::findGuardRegisters ( const TTAMachine::Bus bus,
const RegisterFileSet rfs 
) const
private

Finds registers which can guard moves from the given bus.

Definition at line 1302 of file RegisterRenamer.cc.

1303 {
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}
static TCEString registerName(const TTAMachine::RegisterFile &rf, int index, char delim='.')
Guard * guard(int index) const
Definition Bus.cc:456
int guardCount() const
Definition Bus.cc:441
virtual bool isInverted() const
const RegisterFile * registerFile() const

References TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), TTAMachine::Guard::isInverted(), TTAMachine::RegisterGuard::registerFile(), TTAMachine::RegisterGuard::registerIndex(), and DisassemblyRegister::registerName().

Here is the call graph for this function:

◆ findPartiallyUsedRegistersAfterCycle()

std::set< TCEString > RegisterRenamer::findPartiallyUsedRegistersAfterCycle ( int  bitWidth,
int  latestCycle 
) const

Definition at line 394 of file RegisterRenamer.cc.

395 {
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}
static void append(const ContainerType &src, ContainerType &dest)
int firstRegisterCycle(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
std::set< TCEString > onlyEndPartiallyUsedRegs_
std::set< TCEString > onlyMidPartiallyUsedRegs_
std::set< TCEString > usedGPRs_

References AssocTools::append(), ddg_, DataDependenceGraph::firstRegisterCycle(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, onlyEndPartiallyUsedRegs_, onlyMidPartiallyUsedRegs_, TTAMachine::Machine::registerFileNavigator(), usedGPRs_, and TTAMachine::BaseRegisterFile::width().

Referenced by renameSourceRegister().

Here is the call graph for this function:

◆ findPartiallyUsedRegistersBeforeCycle()

std::set< TCEString > RegisterRenamer::findPartiallyUsedRegistersBeforeCycle ( int  bitWidth,
int  earliestCycle,
const DataDependenceGraph::NodeSet guardMoves 
) const
private

Definition at line 341 of file RegisterRenamer.cc.

343 {
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}
int lastRegisterCycle(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > RegisterFileSet
std::set< TCEString > onlyBeginPartiallyUsedRegs_

References AssocTools::append(), ddg_, findGuardRegisters(), SetTools::intersection(), TTAMachine::Machine::Navigator< ComponentType >::item(), DataDependenceGraph::lastRegisterCycle(), machine_, onlyBeginPartiallyUsedRegs_, onlyMidPartiallyUsedRegs_, TTAMachine::Machine::registerFileNavigator(), usedGPRs_, and TTAMachine::BaseRegisterFile::width().

Referenced by renameDestinationRegister().

Here is the call graph for this function:

◆ findPartiallyUsedRegistersInRFAfterCycle()

std::set< TCEString > RegisterRenamer::findPartiallyUsedRegistersInRFAfterCycle ( const RegisterFileSet rfs,
int  latestCycle 
) const

Finds registers which are used but only after given earliestCycle.

Definition at line 310 of file RegisterRenamer.cc.

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

References AssocTools::append(), ddg_, DataDependenceGraph::firstRegisterCycle(), SetTools::intersection(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, onlyEndPartiallyUsedRegs_, onlyMidPartiallyUsedRegs_, TTAMachine::Machine::registerFileNavigator(), registersOfRFs(), and usedGPRs_.

Referenced by BFRenameLiveRange::operator()(), and renameSourceRegister().

Here is the call graph for this function:

◆ findPartiallyUsedRegistersInRFBeforeCycle()

std::set< TCEString > RegisterRenamer::findPartiallyUsedRegistersInRFBeforeCycle ( const RegisterFileSet rfs,
int  earliestCycle,
const DataDependenceGraph::NodeSet guardMoves 
) const
private

Finds registers which are used but only before given earliestCycle.

Definition at line 260 of file RegisterRenamer.cc.

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

References AssocTools::append(), ddg_, findGuardRegisters(), SetTools::intersection(), TTAMachine::Machine::Navigator< ComponentType >::item(), DataDependenceGraph::lastRegisterCycle(), machine_, onlyBeginPartiallyUsedRegs_, onlyMidPartiallyUsedRegs_, TTAMachine::Machine::registerFileNavigator(), registersOfRFs(), and usedGPRs_.

Referenced by renameDestinationRegister().

Here is the call graph for this function:

◆ freeGPRCount()

unsigned int RegisterRenamer::freeGPRCount ( ) const
inline

Definition at line 66 of file RegisterRenamer.hh.

66{ return freeGPRs_.size(); }

References freeGPRs_.

◆ initialize() [1/2]

void RegisterRenamer::initialize ( )
private

Definition at line 87 of file RegisterRenamer.cc.

87 {
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}
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
static std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegisterFiles(const TTAMachine::Machine &machine)
std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegFiles_
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.
virtual int size() const

References allNormalGPRs_, AssocTools::containsKey(), machine_, TTAMachine::Machine::registerFileNavigator(), DisassemblyRegister::registerName(), TTAMachine::BaseRegisterFile::size(), tempRegFileCache_, tempRegFiles_, and MachineConnectivityCheck::tempRegisterFiles().

Referenced by RegisterRenamer().

Here is the call graph for this function:

◆ initialize() [2/2]

void RegisterRenamer::initialize ( DataDependenceGraph ddg)

◆ initializeFreeRegisters()

void RegisterRenamer::initializeFreeRegisters ( )
private

Definition at line 114 of file RegisterRenamer.cc.

114 {
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) !=
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}
int nodeCount() const
Node & node(const int index) const
LiveRangeData * liveRangeData_
Terminal & source() const
Definition Move.cc:302
Terminal & destination() const
Definition Move.cc:323
virtual int index() const
Definition Terminal.cc:274
virtual bool isGPR() const
Definition Terminal.cc:107
virtual const TTAMachine::RegisterFile & registerFile() const
Definition Terminal.cc:225
MoveNodeUseMapSet regFirstUses_
MoveNodeUseMapSet regLastUses_
std::set< MoveNodeUse > MoveNodeUseSet
std::set< TCEString > registersUsedAfter_
MoveNodeUseMapSet regDefines_
MoveNodeUseMapSet regDefReaches_

References allNormalGPRs_, assert, bb_, ddg_, TTAProgram::Move::destination(), freeGPRs_, TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), TTAProgram::BasicBlock::liveRangeData_, MoveNode::move(), BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), onlyBeginPartiallyUsedRegs_, onlyEndPartiallyUsedRegs_, onlyMidPartiallyUsedRegs_, LiveRangeData::regDefines_, LiveRangeData::regDefReaches_, LiveRangeData::regFirstUses_, TTAProgram::Terminal::registerFile(), DisassemblyRegister::registerName(), LiveRangeData::registersUsedAfter_, LiveRangeData::regLastUses_, and TTAProgram::Move::source().

Referenced by initialize().

Here is the call graph for this function:

◆ registersOfRFs()

std::set< TCEString > RegisterRenamer::registersOfRFs ( const RegisterFileSet rfs) const
private

Definition at line 233 of file RegisterRenamer.cc.

234 {
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}
virtual bool zeroRegister() const

References AssocTools::containsKey(), DisassemblyRegister::registerName(), TTAMachine::BaseRegisterFile::size(), tempRegFiles_, and TTAMachine::RegisterFile::zeroRegister().

Referenced by findFreeRegistersInRF(), findPartiallyUsedRegistersInRFAfterCycle(), and findPartiallyUsedRegistersInRFBeforeCycle().

Here is the call graph for this function:

◆ renameDestinationRegister()

bool RegisterRenamer::renameDestinationRegister ( MoveNode node,
bool  loopScheduling,
bool  allowSameRf,
bool  differentRfOnlyDirectlyReachable,
int  earliestCycle = -1 
)

Renames destination register of a move (from the move itself and from all other moves in same liverange)

Definition at line 458 of file RegisterRenamer.cc.

461 {
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 =
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}
LiveRange * findLiveRange(MoveNode &lrNode, bool writingNode, bool guardUseNode) const
bool isMove() const
std::set< TCEString > findPartiallyUsedRegistersInRFBeforeCycle(const RegisterFileSet &rfs, int earliestCycle, const DataDependenceGraph::NodeSet &guardMoves) const
std::set< TCEString > findPartiallyUsedRegistersBeforeCycle(int bitWidth, int earliestCycle, const DataDependenceGraph::NodeSet &guardMoves) const
bool renameLiveRange(LiveRange &liveRange, const TCEString &newReg, bool usedBefore, bool usedAfter, bool loopScheduling)
std::set< TCEString > findFreeGuardRegisters(const DataDependenceGraph::NodeSet &guardUseNodes, int bitWidth, const RegisterFileSet &rfs) const
RegisterFileSet findConnectedRFs(LiveRange &lr, bool allowLimm)

References ddg_, TTAProgram::Move::destination(), findConnectedRFs(), findFreeGuardRegisters(), findFreeRegisters(), findFreeRegistersInRF(), DataDependenceGraph::findLiveRange(), findPartiallyUsedRegistersBeforeCycle(), findPartiallyUsedRegistersInRFBeforeCycle(), TTAProgram::Terminal::isGPR(), MoveNode::isMove(), MoveNode::move(), TTAProgram::Terminal::registerFile(), renameLiveRange(), tempRegFiles_, and TTAMachine::BaseRegisterFile::width().

Referenced by BUBasicBlockScheduler::scheduleMove(), and BasicBlockScheduler::scheduleMove().

Here is the call graph for this function:

◆ renamedToRegister()

void RegisterRenamer::renamedToRegister ( const TCEString newReg)

Definition at line 1094 of file RegisterRenamer.cc.

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

References freeGPRs_, onlyBeginPartiallyUsedRegs_, onlyEndPartiallyUsedRegs_, onlyMidPartiallyUsedRegs_, and usedGPRs_.

Referenced by BFRenameLiveRange::renameLiveRange(), and renameLiveRange().

◆ renameLiveRange()

bool RegisterRenamer::renameLiveRange ( LiveRange liveRange,
const TCEString newReg,
bool  usedBefore,
bool  usedAfter,
bool  loopScheduling 
)

Definition at line 714 of file RegisterRenamer.cc.

716 {
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.
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}
BoostGraph * rootGraph()
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) 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)
NodeSet lastScheduledRegisterWrites(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
DataDependenceGraph::UndoData guardRenamed(MoveNode &mn)
DataDependenceGraph::UndoData destRenamed(MoveNode &mn)
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
Definition Graph.hh:53
virtual void mightBeReady(MoveNode &node)=0
std::string toString() const
Definition MoveNode.cc:576
MoveNodeSelector * selector_
void renamedToRegister(const TCEString &newReg)
void updateAntiEdgesFromLRTo(LiveRange &liveRange, const TCEString &newReg, TTAProgram::BasicBlock &bb, int loopDepth) const
virtual TCEString name() const
Unit * parentUnit() const
Port * firstReadPort() const
Port * firstWritePort() const
void setSource(Terminal *src)
Definition Move.cc:312
void setGuard(MoveGuard *guard)
Definition Move.cc:360
void setDestination(Terminal *dst)
Definition Move.cc:333
const TTAMachine::Bus & bus() const
Definition Move.cc:373
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378
MoveNodeUseMapSet regFirstDefines_
MoveNodeUseMapPair regKills_
MoveNodeUseMapPair regLastKills_
DataDependenceGraph::NodeSet guards
Definition LiveRange.hh:41

References assert, bb_, TTAProgram::Move::bus(), BoostGraph< GraphNode, GraphEdge >::connectNodes(), ddg_, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, TTAProgram::Move::destination(), DataDependenceGraph::destRenamed(), DataDependenceEdge::EDGE_REGISTER, TTAMachine::RegisterFile::firstReadPort(), DataDependenceGraph::firstScheduledRegisterWrites(), TTAMachine::RegisterFile::firstWritePort(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), DataDependenceGraph::guardRenamed(), LiveRange::guards, BoostGraph< GraphNode, GraphEdge >::hasPath(), TTAMachine::Guard::isInverted(), TTAMachine::Machine::Navigator< ComponentType >::item(), DataDependenceGraph::lastScheduledRegisterGuardReads(), DataDependenceGraph::lastScheduledRegisterReads(), DataDependenceGraph::lastScheduledRegisterWrites(), TTAProgram::BasicBlock::liveRangeData_, machine_, MoveNodeSelector::mightBeReady(), MoveNode::move(), TTAMachine::Component::name(), TTAMachine::Guard::parentBus(), TTAMachine::Port::parentUnit(), TTAProgram::Terminal::port(), BoostGraph< GraphNode, GraphEdge >::predecessors(), LiveRange::reads, LiveRangeData::regDefines_, LiveRangeData::regFirstDefines_, LiveRangeData::regFirstUses_, TTAMachine::RegisterGuard::registerFile(), TTAMachine::Machine::registerFileNavigator(), TTAMachine::RegisterGuard::registerIndex(), LiveRangeData::regKills_, LiveRangeData::regLastKills_, LiveRangeData::regLastUses_, renamedToRegister(), BoostGraph< GraphNode, GraphEdge >::rootGraph(), selector_, TTAProgram::Move::setDestination(), TTAProgram::Move::setGuard(), TTAProgram::Move::setSource(), TTAProgram::Move::source(), DataDependenceGraph::sourceRenamed(), BoostGraph< GraphNode, GraphEdge >::successors(), MoveNode::toString(), updateAntiEdgesFromLRTo(), and LiveRange::writes.

Referenced by renameDestinationRegister(), and renameSourceRegister().

Here is the call graph for this function:

◆ renameSourceRegister()

bool RegisterRenamer::renameSourceRegister ( MoveNode node,
bool  loopScheduling,
bool  allowSameRf,
bool  differentRfOnlyDirectlyReachable,
int  latestCycle = INT_MAX 
)

Renames source register of a move (from the move itself and from all other moves in same liverange)

Definition at line 617 of file RegisterRenamer.cc.

619 {
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 =
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 =
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}
std::set< TCEString > findPartiallyUsedRegistersAfterCycle(int bitWidth, int latestCycle) const
std::set< TCEString > findPartiallyUsedRegistersInRFAfterCycle(const RegisterFileSet &rfs, int latestCycle) const

References ddg_, findConnectedRFs(), findFreeRegisters(), findFreeRegistersInRF(), DataDependenceGraph::findLiveRange(), findPartiallyUsedRegistersAfterCycle(), findPartiallyUsedRegistersInRFAfterCycle(), TTAProgram::Terminal::isGPR(), MoveNode::isMove(), MoveNode::move(), TTAProgram::Terminal::registerFile(), renameLiveRange(), TTAProgram::Move::source(), tempRegFiles_, and TTAMachine::BaseRegisterFile::width().

Referenced by BUBasicBlockScheduler::scheduleMove(), and BasicBlockScheduler::scheduleMove().

Here is the call graph for this function:

◆ revertedRenameToRegister()

void RegisterRenamer::revertedRenameToRegister ( const TCEString reg)

◆ setSelector()

void RegisterRenamer::setSelector ( MoveNodeSelector selector)

Registers the selector being used to the bypasser.

If the bypasser has been registered to the selector, bypasses can notify the selector about dependence changes. Currently it notifies the successors of a node being removed due dead result elimination.

Parameters
selectorselector which bypasser notifies on some dependence changes.

Definition at line 1126 of file RegisterRenamer.cc.

1126 {
1127 selector_ = selector;
1128}

References selector_.

Referenced by BUBasicBlockScheduler::handleDDG(), BasicBlockScheduler::handleDDG(), BF2Scheduler::handleLoopDDG(), BasicBlockScheduler::handleLoopDDG(), BUBasicBlockScheduler::handleLoopDDG(), and BF2Scheduler::scheduleDDG().

◆ updateAntiEdgesFromLRTo()

void RegisterRenamer::updateAntiEdgesFromLRTo ( LiveRange liveRange,
const TCEString newReg,
TTAProgram::BasicBlock bb,
int  loopDepth 
) const
private

Updates antidep edges from this liverange to first def of some other bb.

Parameters
liveRangeliverange which is the origin of the deps
newRegname of the new register
bbdestination BB where to draw the edges to @loopDepth loop depth of added edges.

Definition at line 1139 of file RegisterRenamer.cc.

1141 {
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 =
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 =
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 =
1195 true, false, false, destination.pseudo(), 1);
1196
1197 // and connect.
1199 **j, *destination.mn(), dde);
1200 }
1201 }
1202 }
1203}
bool hasNode(const Node &) const
bool connectOrDeleteEdge(const MoveNode &tailNode, const MoveNode &headNode, DataDependenceEdge *edge)
const MoveNode * mn() const
bool pseudo() const

References bb(), DataDependenceGraph::connectOrDeleteEdge(), ddg_, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::EDGE_REGISTER, LiveRange::guards, BoostGraph< GraphNode, GraphEdge >::hasNode(), TTAProgram::BasicBlock::liveRangeData_, MoveNodeUse::mn(), MoveNodeUse::pseudo(), LiveRange::reads, LiveRangeData::regFirstDefines_, and LiveRange::writes.

Referenced by renameLiveRange().

Here is the call graph for this function:

Member Data Documentation

◆ allNormalGPRs_

std::set<TCEString> RegisterRenamer::allNormalGPRs_
private

Definition at line 140 of file RegisterRenamer.hh.

Referenced by initialize(), and initializeFreeRegisters().

◆ bb_

TTAProgram::BasicBlock& RegisterRenamer::bb_
private

◆ ddg_

DataDependenceGraph* RegisterRenamer::ddg_
private

◆ freeGPRs_

std::set<TCEString> RegisterRenamer::freeGPRs_
private

◆ machine_

const TTAMachine::Machine& RegisterRenamer::machine_
private

◆ onlyBeginPartiallyUsedRegs_

std::set<TCEString> RegisterRenamer::onlyBeginPartiallyUsedRegs_
private

◆ onlyEndPartiallyUsedRegs_

std::set<TCEString> RegisterRenamer::onlyEndPartiallyUsedRegs_
private

◆ onlyMidPartiallyUsedRegs_

std::set<TCEString> RegisterRenamer::onlyMidPartiallyUsedRegs_
private

◆ selector_

MoveNodeSelector* RegisterRenamer::selector_
private

Definition at line 165 of file RegisterRenamer.hh.

Referenced by renameLiveRange(), and setSelector().

◆ tempRegFileCache_

std::map< const TTAMachine::Machine *, std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > > RegisterRenamer::tempRegFileCache_
staticprivate

To avoid reanalysing machine every time hen new rr created.

Definition at line 157 of file RegisterRenamer.hh.

Referenced by initialize().

◆ tempRegFiles_

std::set<const TTAMachine::RegisterFile*, TTAMachine::MachinePart::Comparator> RegisterRenamer::tempRegFiles_
private

◆ usedGPRs_

std::set<TCEString> RegisterRenamer::usedGPRs_
private

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