77 interPassData_(data), rm_(rm),
78 buScheduler_(buScheduler) {
105 for (
int i = 0; i <= FUs.
count(); i++) {
112 std::string operationName = programOperation.
operation().
name();
115 registerCopiesRequired[&unit] =
121 return registerCopiesRequired;
144 #ifdef DEBUG_REG_COPY_ADDER
146 <<
"# Add minimum register copies for the following operation: "
148 <<
"# " << programOperation.
toString() << std::endl << std::endl;
152 registerCopiesRequired =
158 for (RegisterCopyAdder::RegisterCopyCountIndex::const_iterator
159 i = registerCopiesRequired.begin();
160 i != registerCopiesRequired.end(); ++i) {
166 int copies = (*i).second;
183 }
else if (unit != NULL && min < INT_MAX) {
195 std::string(
"Cannot schedule '") +
197 "' ensure that at least one FU supports the operation and is "
198 "connected to some register file.");
217 int registerCopyCount = 0;
220 #ifdef DEBUG_REG_COPY_ADDER
222 <<
"# Add register copies to \""
223 << moveNode.
toString() <<
"\" R-R move."
224 << std::endl << std::endl;
228 moveNode, ddg, &addedNodes);
230 if (count == INT_MAX) {
232 "Temp moves not possible for the Register-Register move.");
234 registerCopyCount += count;
239 copies.
count_ = registerCopyCount;
265 int registerCopyCount = 0;
266 for (
int input = 0; input < programOperation.
inputMoveCount(); ++input) {
270 m, fu, countOnly, ddg, &addedNodes, neededCopies);
271 if (count == INT_MAX) {
275 assert(
false &&
"Temp moves not possible for the FU.");
277 registerCopyCount += count;
278 if (count != 0 && !countOnly) {
286 #ifdef DEBUG_REG_COPY_ADDER
289 << m.
toString() <<
"\" output move."
294 m, fu, countOnly, ddg, &addedNodes, neededCopies);
295 if (count == INT_MAX) {
299 assert(
false &&
"Temp moves not possible for the FU.");
301 registerCopyCount += count;
302 if (count != 0 && !countOnly) {
306 copies.
count_ = registerCopyCount;
342 std::vector<std::pair<const TTAMachine::RegisterFile*, int> > >
345 std::string srDatumName =
"SCRATCH_REGISTERS";
347 (
dynamic_cast<TempRegData&
>(
358 "No scratch registers available for temporary moves.");
360 const TempRegData& tempRegs =
363 const int minRegisterWidth =
364 std::min(sourcePort.
width(), destinationPort.
width());
372 std::vector<int> tempRegsDist(tempRegs.size(), 0);
373 std::vector<int> tempRegsConn(tempRegs.size(), 0);
374 bool connectionFound =
false;
376 int lastRegisterIndex = -1;
377 int firstRegisterIndex = -1;
378 int regsRequired = INT_MAX;
388 int correctSizeTempsFound = 0;
392 for (std::size_t i = 0; i < tempRegs.size(); ++i) {
394 if (rf.
width() < minRegisterWidth) {
397 ++correctSizeTempsFound;
406 lastRegisterIndex = tempRegs.at(i).second;
408 connectionFound =
true;
418 while (!connectionFound) {
422 for (std::size_t i = 0; i < tempRegs.size(); ++i) {
426 if (tempRegsDist[i] == 0) {
428 if (rf.
width() < minRegisterWidth) {
431 ++correctSizeTempsFound;
435 for (std::size_t j = 0; j < tempRegs.size(); ++j) {
436 if (tempRegsDist[j] == level - 1) {
442 tempRegsDist[i] = level;
453 lastRegisterIndex = tempRegs.at(i).second;
455 connectionFound =
true;
471 regsRequired = level;
473 if (correctSizeTempsFound == 0) {
477 "Register allocator didn't reserve a large enough "
478 "connectivity register for routing the move %s.")
486 if (!connectionFound){
489 std::string(
"Cannot schedule ") +
491 " ensure that all FUs are connected to at least one RF." +
509 for (
int p = 0; p < lastRF->
portCount(); ++p) {
516 assert(dstRFPort != NULL);
540 assert(neededCopies != 0);
544 if (ddg != NULL && neededCopies == 1) {
551 if (rawSource != NULL && ddg->
rWarEdgesOut(*rawSource) == 0 &&
554 if (rawSrcSrc.
isGPR()) {
558 rf, destinationPort)) {
585 delete originalDestination;
594 lastMove = &originalMove;
601 if (addedNodes != NULL) {
602 addedNodes->insert(firstMove);
609 firstMove = &originalMove;
615 if (addedNodes != NULL) {
616 addedNodes->insert(lastMove);
621 firstMove = &originalMove;
627 if (addedNodes != NULL) {
628 addedNodes->insert(lastMove);
640 #ifdef DEBUG_REG_COPY_ADDER
642 <<
"# Last move of the chain: "
644 <<
"# " << lastMove->
toString() << std::endl;
653 std::vector<MoveNode*> intMoves(regsRequired - 1);
654 std::vector<const TTAMachine::RegisterFile*> intRF(regsRequired - 1);
655 std::vector<int> intRegisterIndex(regsRequired - 1);
658 if (regsRequired >= 2) {
659 int tempRegisterIndexDst = lastRegisterIndex;
660 int dstID = lastRegID;
662 for (
int i = 0; i < regsRequired - 1; ++i){
666 int srcID = tempRegsConn[dstID];
667 int tempRegisterIndexSrc = tempRegs.at(srcID).second;
671 for (
int p = 0; p < srcRF.
portCount(); ++p) {
678 assert(srcRFPort != NULL);
682 *srcRFPort, tempRegisterIndexSrc);
689 ddg->
addNode(*regToRegCopy,bbn);
691 if (addedNodes != NULL) {
692 addedNodes->insert(regToRegCopy);
698 intMoves[regsRequired - 2 - i] = regToRegCopy;
699 intRF[regsRequired - 2 - i] = tempRegs.at(dstID).first;
700 intRegisterIndex[regsRequired - 2 - i] = tempRegisterIndexDst;
702 #ifdef DEBUG_REG_COPY_ADDER
704 <<
"# Intermediate move #" << regsRequired - 2 - i <<
" :"
706 <<
"# " << regToRegCopy->
toString() << std::endl;
711 tempRegisterIndexDst = tempRegisterIndexSrc;
716 firstRF = tempRegs.at(dstID).first;
717 firstRegisterIndex = tempRegisterIndexDst;
728 if (regsRequired >= 2) {
730 *ddg, originalMove, firstMove, intMoves, lastMove, firstRF,
731 intRF, lastRF, firstRegisterIndex, intRegisterIndex,
732 lastRegisterIndex, regsRequired, bbn);
737 *ddg, originalMove, firstMove, lastMove, lastRF,
777 std::vector<std::pair<const TTAMachine::RegisterFile*, int> > >
781 (
dynamic_cast<TempRegData&
>(
785 "No scratch registers available for temporary move for: " +
788 const TempRegData& tempRegs =
795 const int immediateBitWidth =
817 int immediateTargetIndex = -1;
820 int targetConnectedIndex = -1;
822 int correctSizeTempsFound = 0;
823 for (std::size_t i = 0; i < tempRegs.size(); ++i) {
825 if (rf.
width() < immediateBitWidth) {
828 ++correctSizeTempsFound;
830 immediateTargetRF = &rf;
831 immediateTargetIndex = tempRegs.at(i).second;
836 targetConnectedRF = &rf;
837 targetConnectedIndex = tempRegs.at(i).second;
838 if (immediateTargetRF == targetConnectedRF) {
847 correctSizeTempsFound > 0 &&
848 "Register allocator didn't reserve a large enough temp reg!");
850 const bool machineHasIU =
852 immediateUnitNavigator().count() > 0;
854 if (targetConnectedRF == NULL) {
861 "%s is not connected to any register file, unable to "
867 int tempRegisterIndex1 = -1;
868 int tempRegisterIndex2 = -1;
870 int regsRequired = INT_MAX;
875 if (targetConnectedRF == immediateTargetRF || machineHasIU) {
879 tempRF1 = targetConnectedRF;
880 tempRegisterIndex1 = targetConnectedIndex;
884 tempRF1 = immediateTargetRF;
885 tempRegisterIndex1 = immediateTargetIndex;
886 tempRF2 = targetConnectedRF;
887 tempRegisterIndex2 = targetConnectedIndex;
916 if (tempRF1 == NULL) {
920 "Unable to schedule move '%s' due to lacking "
921 "immediate resources (required width %d bits).")
929 for (
int p = 0; p < tempRF1->
portCount(); ++p) {
932 immediate, *RFport)) {
962 lastMove = &originalMove;
968 if (addedNodes != NULL) {
969 addedNodes->insert(firstMove);
984 if (tempRF2 != NULL) {
989 for (
int p = 0; p < tempRF2->
portCount(); ++p) {
992 *RFport, destinationPort)) {
997 assert(dstRFPort2 != NULL);
1004 lastMoveSrc = temp2;
1008 ddg->
addNode(*regToRegCopy,bbn);
1010 if (addedNodes != NULL) {
1011 addedNodes->insert(regToRegCopy);
1025 *ddg, originalMove, firstMove, regToRegCopy, lastMove, tempRF1,
1026 tempRF2, tempRegisterIndex1, tempRegisterIndex2, bbn);
1029 return regsRequired;
1054 int lastRegisterIndex,
1056 bool bottomUpScheduler,
1057 bool loopScheduling) {
1062 for (DataDependenceGraph::EdgeSet::iterator i = inEdges.begin();
1063 i != inEdges.end(); ++i) {
1075 if (lastMove == &originalMove) {
1082 if (lastMove == &originalMove) {
1087 assert (firstMove == &originalMove);
1099 for (DataDependenceGraph::EdgeSet::iterator i = outEdges.begin();
1100 i != outEdges.end(); ++i) {
1111 if (lastMove == &originalMove) {
1145 *firstMove, *lastMove, originalMove, *lastRF, lastRegisterIndex,
1146 ddg, currentBBNode, bottomUpScheduler, loopScheduling);
1174 std::vector<MoveNode*> intMoves,
1177 std::vector<const TTAMachine::RegisterFile*> intRF,
1179 int firstRegisterIndex,
1180 std::vector<int> intRegisterIndex,
1181 int lastRegisterIndex,
1188 for (DataDependenceGraph::EdgeSet::iterator i = inEdges.begin();
1189 i != inEdges.end(); ++i) {
1203 for (
int i = 0; i < regsRequired - 1; ++i) {
1208 if (lastMove == &originalMove) {
1211 assert (firstMove == &originalMove);
1216 if (lastMove == &originalMove) {
1218 ddg.
moveInEdge(originalMove, *firstMove, edge);
1221 assert (firstMove == &originalMove);
1224 ddg.
moveInEdge(originalMove, *lastMove, edge);
1233 for (DataDependenceGraph::EdgeSet::iterator i = outEdges.begin();
1234 i != outEdges.end(); ++i) {
1245 if (lastMove == &originalMove) {
1267 *firstRF, firstRegisterIndex);
1274 ddg.
connectNodes(*firstMove, *intMoves[0], *edgeFirst);
1277 *firstMove, *intMoves[0], originalMove,
1278 *firstRF, firstRegisterIndex, ddg, currentBBNode,
buScheduler_,
false);
1280 for (
int i = 0; i < regsRequired - 2; ++i) {
1282 TCEString tempReg = intRF[i+1]->name() +
'.' +
1289 ddg.
connectNodes(*intMoves[i], *intMoves[i + 1], *edgeInt);
1292 *intMoves[i], *intMoves[i+1], originalMove,
1293 *intRF[i], intRegisterIndex[i], ddg, currentBBNode,
buScheduler_,
false);
1297 *lastRF, lastRegisterIndex);
1302 ddg.
connectNodes(*intMoves[regsRequired - 2], *lastMove, *edgeLast);
1305 *intMoves[regsRequired - 2], *lastMove, originalMove,
1306 *lastRF, lastRegisterIndex, ddg, currentBBNode,
buScheduler_,
false);
1317 bool loopScheduling) {
1328 for (DataDependenceGraph::NodeSet::iterator i =
1329 firstScheduledDefs0.begin();
1330 i != firstScheduledDefs0.end(); i++) {
1347 if (loopScheduling) {
1351 for (DataDependenceGraph::NodeSet::iterator i =
1352 lastScheduledReads0.begin();
1353 i != lastScheduledReads0.end(); i++) {
1359 false,
false,
false,
false, 1);
1367 for (DataDependenceGraph::NodeSet::iterator i =
1368 lastScheduledDefs0.begin();
1369 i != lastScheduledDefs0.end(); i++) {
1375 false,
false,
false,
false, 1);
1382 if (lastScheduledKill0 == NULL) {
1422 for (DataDependenceGraph::NodeSet::iterator i =
1423 lastScheduledUses0.begin();
1424 i != lastScheduledUses0.end(); i++) {
1434 for (DataDependenceGraph::NodeSet::iterator i =
1435 lastScheduledDefs0.begin();
1436 i != lastScheduledDefs0.end(); i++) {
1447 if (firstScheduledKill0 == NULL) {
1509 int tempRegisterIndex1,
1510 int tempRegisterIndex2,
1516 for (DataDependenceGraph::EdgeSet::iterator i = inEdges.begin();
1517 i != inEdges.end(); ++i) {
1530 if (regToRegCopy != NULL) {
1535 if (lastMove == &originalMove) {
1537 ddg.
moveInEdge(originalMove, *firstMove, edge);
1540 assert (firstMove == &originalMove);
1543 ddg.
moveInEdge(originalMove, *lastMove, edge);
1552 for (DataDependenceGraph::EdgeSet::iterator i = outEdges.begin();
1553 i != outEdges.end(); ++i) {
1564 if (lastMove == &originalMove) {
1589 if (regToRegCopy != NULL) {
1608 *firstMove, *regToRegCopy, originalMove,
1609 *tempRF1, tempRegisterIndex1, ddg, currentBBNode,
1620 *firstMove, *lastMove, originalMove,
1621 *tempRF1, tempRegisterIndex1, ddg, currentBBNode,
buScheduler_,
false);
1646 std::set<const TTAMachine::Port*> dstPorts;
1651 for (
int p = 0; p < ports; ++p) {
1654 dstPorts.insert(port);
1658 dstPorts.insert(&(dest.
port()));
1661 "Unsupported move destination type in move '" +
1668 std::set<const TTAMachine::Port*> srcPorts;
1670 if (source.
isGPR()) {
1674 for (
int p = 0; p < ports; ++p) {
1677 srcPorts.insert(port);
1689 "Unsupported move source type in move '" +
1698 std::pair<const TTAMachine::Port*, const TTAMachine::Port*>,
1702 CombinationSet pairs = AssocTools::pairs<TTAMachine::Port::PairComparator>(
1703 srcPorts, dstPorts);
1706 for (CombinationSet::const_iterator i = pairs.begin(); i != pairs.end();
1715 const std::pair<const TTAMachine::Port*, const TTAMachine::Port*>*
1716 bestConnection = NULL;
1717 int registersRequired = INT_MAX;
1718 for (CombinationSet::const_iterator i = pairs.begin(); i != pairs.end();
1725 if (regCount == 0) {
1729 if (regCount < registersRequired) {
1730 bestConnection = &(*i);
1731 registersRequired = regCount;
1735 if (bestConnection == NULL) {
1738 "Could not schedule move '" + moveNode.
toString() +
1739 "' due to missing connectivity. "
1740 "Add a connection or a register file that connects "
1741 "the source and the destination.");
1749 moveNode, src, dst,
false, ddg, addedNodes);
1774 std::set<const TTAMachine::Port*> dstPorts;
1779 for (
int p = 0; p < ports; ++p) {
1782 dstPorts.insert(port);
1796 "Unsupported move destination type in move '" +
1802 std::set<const TTAMachine::Port*> srcPorts;
1804 if (source.
isGPR()) {
1808 for (
int p = 0; p < ports; ++p) {
1811 srcPorts.insert(port);
1847 if (destPort == NULL) {
1851 "Could not find destination FU port candidate for "
1852 "move '%s'. Is the operand-port binding missing?")
1855 const bool connectionFound =
1862 if (connectionFound) {
1892 if (busFound && !connectionFound) {
1895 }
else if (!busFound && !connectionFound) {
1904 for (
int i = 0; i < nav.
count(); ++i) {
1916 moveNode, *(*dstPorts.begin()), countOnly, ddg, addedNodes);
1926 "Unsupported move source type in move '" +
1935 std::pair<const TTAMachine::Port*, const TTAMachine::Port*>,
1939 CombinationSet pairs = AssocTools::pairs<TTAMachine::Port::PairComparator>(
1940 srcPorts, dstPorts);
1943 for (CombinationSet::const_iterator i = pairs.begin(); i != pairs.end();
1953 const std::pair<const TTAMachine::Port*, const TTAMachine::Port*>*
1954 bestConnection = NULL;
1955 int registersRequired = INT_MAX;
1956 for (CombinationSet::const_iterator i = pairs.begin(); i != pairs.end();
1963 if (regCount == 0) {
1967 if (regCount < registersRequired) {
1968 bestConnection = &(*i);
1969 registersRequired = regCount;
1974 return registersRequired;
1977 if (bestConnection == NULL) {
1980 "Could not schedule move '" + moveNode.
toString() +
1981 "' due to missing connectivity. "
1982 "Add a connection or a register file that connects "
1983 "the source and the destination.");
1991 moveNode, src, dst, countOnly, ddg, addedNodes, neededCopies);
2007 registerCopiesRequired =
2010 std::set<std::string> candidates;
2012 bool allGoodFUCandidates =
true;
2019 i = registerCopiesRequired.begin();
2020 i != registerCopiesRequired.end(); ++i) {
2026 if (registerCopiesRequired[u] > 0) {
2027 allGoodFUCandidates =
false;
2029 candidates.insert(u->
name());
2035 if (allGoodFUCandidates) {
2044 for (
int input = 0; input < programOperation.
inputMoveCount(); ++input) {
2047 for (std::set<std::string>::const_iterator i = candidates.begin();
2048 i != candidates.end(); ++i) {
2049 std::string candidateFU = (*i);
2061 for (std::set<std::string>::const_iterator i = candidates.begin();
2062 i != candidates.end(); ++i) {
2063 std::string candidateFU = (*i);
2086 for (RegisterCopyAdder::AddedRegisterCopyMap::iterator iter =
2092 inputMoves.insert(result);
2093 for (DataDependenceGraph::NodeSet::iterator i2 =
2094 iter->second.begin(); i2 != iter->second.end(); i2++) {
2095 inputMoves.insert(*i2);
2115 for (RegisterCopyAdder::AddedRegisterCopyMap::iterator iter =
2120 outputMoves.insert(result);
2121 for (DataDependenceGraph::NodeSet::iterator i2 =
2122 iter->second.begin(); i2 != iter->second.end(); i2++) {
2124 if ((*i2)->isScheduled())
2125 outputMoves.insert(*i2);
2142 std::vector<std::pair<const TTAMachine::RegisterFile*,int> > >
2145 typedef std::pair<const TTAMachine::RegisterFile*, int> Register;
2147 std::set<Register> guardRegs;
2148 TempRegData* tempRegData =
new TempRegData;
2152 for (
int i = 0; i < busNav.
count(); i++) {
2154 for (
int j = 0; j < bus->
guardCount(); j++) {
2157 if (regGuard != NULL) {
2165 std::vector<const TTAMachine::RegisterFile*> tempRegRFVec;
2166 for (
auto rf: tempRegRFs) {
2167 tempRegRFVec.push_back(rf);
2173 return rf0->
width() < rf1->width();
2175 std::sort(tempRegRFVec.begin(), tempRegRFVec.end(), rfLessFn);
2179 for (
unsigned int i = 0; i < tempRegRFVec.size(); i++) {
2181 for (
int j = rf->
size()-1; j >= 0; j--) {
2185 tempRegData->push_back(
2186 std::pair<const TTAMachine::RegisterFile*,int>(rf, j));
2192 ipd.
setDatum(
"SCRATCH_REGISTERS", tempRegData);