90 if (cfg_->hasMultipleUnconditionalSuccessors(jumpingBB)) {
91 bbnStatus_[&jumpingBB] = BBN_BOTH_FILLED;
96 if (jumpingBB.isLoopScheduled() || jumpingBB.isHWLoop()) {
97 bbnStatus_[&jumpingBB] = BBN_BOTH_FILLED;
101 bool cfgChanged =
false;
104 switch (bbnStatus_[&jumpingBB]) {
106 bbnStatus_[&jumpingBB] = BBN_FALLTHRU_FILLED;
108 case BBN_JUMP_FILLED:
109 bbnStatus_[&jumpingBB] = BBN_BOTH_FILLED;
115 switch (bbnStatus_[&jumpingBB]) {
117 bbnStatus_[&jumpingBB] = BBN_JUMP_FILLED;
119 case BBN_FALLTHRU_FILLED:
120 bbnStatus_[&jumpingBB] = BBN_BOTH_FILLED;
130 cfg_->program()->instructionReferenceManager();
133 std::pair<int, TTAProgram::Move*> jumpData = findJump(thisBB);
134 std::pair<Move*, std::shared_ptr<Immediate> > jumpAddressData;
137 int jumpIndex = jumpData.first;
138 Move* jumpMove = jumpData.second;
144 if (jumpMove == NULL) {
150 jumpAddressData = findJumpImmediate(jumpIndex, *jumpMove, irm);
151 if (jumpAddressData.first == NULL &&
152 jumpAddressData.second == NULL) {
157 jumpAddressData.first = jumpMove;
162 unsigned int grIndex = 0;
165 int maxFillCount = std::min(
169 int maxGuardedFillCount = 0;
181 maxGuardedFillCount = INT_MAX;
191 MoveNode& jumpNode = ddg_->nodeOfMove(*jumpMove);
193 ddg_->guardDefMoves(jumpNode);
194 if (guardDefs.size() != 1) {
197 maxGuardedFillCount = std::min(maxGuardedFillCount,delaySlots+1);
199 MoveNode& guardDefMove = **guardDefs.begin();
200 if (&ddg_->getBasicBlockNode(guardDefMove) == &jumpingBB) {
202 *resourceManagers_[&jumpingBB.basicBlock()];
204 int earliestToFill = guardDefMove.
cycle() -
208 maxGuardedFillCount =
209 std::min(maxGuardedFillCount,
215 maxGuardedFillCount =
216 std::min(maxGuardedFillCount,
224 for (ControlFlowGraph::EdgeSet::iterator iter = outEdges.begin();
225 iter != outEdges.end(); iter++) {
227 int myMaxGuardedFillCount = maxGuardedFillCount;
246 if (&nextBBN == &jumpingBB) {
249 maxFillCount = std::min(maxFillCount, nextInsCount/2);
252 maxFillCount = std::min(maxFillCount,nextInsCount);
256 if (jumpMove != NULL) {
264 myMaxGuardedFillCount = 0;
272 for (
int i = 0; i < maxFillCount; i++) {
280 if (maxFillCount == 0) {
295 ddg_->fixInterBBAntiEdges(jumpingBB, nextBBN, edge.
isBackEdge());
301 for (
int fillSize = maxFillCount; fillSize > 0; fillSize--) {
302 int removeGuards = (fillSize > myMaxGuardedFillCount) ?
303 fillSize - myMaxGuardedFillCount : 0;
305 bool ok = tryToFillSlots(
306 jumpingBB, nextBBN, fillFallThru, jumpMove, fillSize,
307 removeGuards, grIndex, grFile, skippedJump, delaySlots);
309 slotsFilled = fillSize;
315 if (slotsFilled != 0) {
320 cfgChanged |= updateJumpsAndCfg(
321 jumpingBB, nextBBN, edge, jumpAddressData.first,
322 jumpAddressData.second, jumpMove, slotsFilled,
325 cfgChanged |= updateFTBBAndCfg(
326 jumpingBB, nextBBN, edge, slotsFilled);
338 cfg_->program()->instructionReferenceManager();
340 for (
int i = 0; i < slotsFilled; i++) {
346 cfg_->inDegree(nextBBN) == 1) {
347 auto oEdges = cfg_->outEdges(nextBBN);
348 assert(oEdges.size() == 1);
359 cfg_->disconnectNodes(jumpingBB, nextBBN);
360 cfg_->connectNodes(jumpingBB, newDestNode, *newEdge);
362 cfg_->removeNode(nextBBN);
363 finishBB(nextBBN,
true);
366 i < nextBBN.
basicBlock().instructionCount(); i++) {
371 MoveNode & mn = ddg_->nodeOfMove(move);
372 ddg_->removeNode(mn);
415 for (
int i = 0; i < cfg.
nodeCount(); i++) {
418 if (bbnStatus_[&bbn] == BBN_SCHEDULED ||
419 bbnStatus_[&bbn] == BBN_FALLTHRU_FILLED) {
421 bbn, delaySlots,
false);
427 for (
int i = 0; i < cfg.
nodeCount(); i++) {
430 if (bbnStatus_[&bbn] == BBN_JUMP_FILLED) {
432 bbn, delaySlots,
true);
438 for (std::map<BasicBlockNode*, BBNStates>::iterator i =
439 bbnStatus_.begin(); i != bbnStatus_.end(); i++) {
440 if (i->second != BBN_ALL_DONE) {
446 for (std::map<BasicBlock*, SimpleResourceManager*>::iterator i =
447 resourceManagers_.begin(); i != resourceManagers_.end(); i++) {
448 if (i->second != NULL) {
452 resourceManagers_.clear();
454 tempResultNodes_.clear();
471 bool allJumpPredsFilled =
true;
473 for (ControlFlowGraph::EdgeSet::iterator inIter =
474 inEdges.begin(); inIter != inEdges.end();
482 (bbnStatus_[&jumpOrigin] < BBN_JUMP_FILLED ||
483 bbnStatus_[&jumpOrigin] == BBN_FALLTHRU_FILLED)) {
484 allJumpPredsFilled =
false;
488 return allJumpPredsFilled;
499 bool allPredsScheduled =
true;
501 for (ControlFlowGraph::EdgeSet::iterator inIter =
502 inEdges.begin(); inIter != inEdges.end();
509 if (bbnStatus_[&jumpOrigin] == BBN_UNKNOWN &&
511 allPredsScheduled =
false;
515 return allPredsScheduled;
525 if (bbnStatus_[&bbn] == BBN_BOTH_FILLED) {
538 if (bbnStatus_[&bbn] == BBN_UNKNOWN) {
541 if (!areAllJumpPredsScheduled(bbn)) {
545 bool cfgChanged =
false;
546 bool cfgChangedAfterRecheck =
false;
551 for (
auto inIter = jumpEdges.begin(); inIter != jumpEdges.end();) {
556 (bbnStatus_[&jumpOrigin] == BBN_SCHEDULED ||
557 bbnStatus_[&jumpOrigin] == BBN_FALLTHRU_FILLED)) {
559 bool changed = fillDelaySlots(jumpOrigin, delaySlots_,
false);
560 cfgChanged |= changed;
561 cfgChangedAfterRecheck |= changed;
563 bbFilled(jumpOrigin);
566 cfg_->fallThruSuccessor(jumpOrigin);
569 if (fallThruSisterNode != NULL &&
570 bbnStatus_[fallThruSisterNode] > BBN_UNKNOWN &&
571 bbnStatus_[&jumpOrigin] < BBN_TEMPS_CLEANED &&
572 areAllJumpPredsFilled(*fallThruSisterNode)) {
573 changed = fillDelaySlots(jumpOrigin, delaySlots_,
true);
574 cfgChanged |= changed;
575 cfgChangedAfterRecheck |= changed;
576 bbFilled(jumpOrigin);
581 if (cfgChangedAfterRecheck) {
582 if (!cfg_->hasNode(bbn)) {
585 cfgChangedAfterRecheck =
false;
586 jumpEdges = cfg_->incomingJumpEdges(bbn);
587 inIter = jumpEdges.begin();
595 if (cfgChanged && !cfg_->hasNode(bbn)) {
600 auto ftEdge = cfg_->incomingFTEdge(bbn);
602 if (ftEdge !=
nullptr && ftEdge->isFallThroughEdge()) {
606 if (bbnStatus_[&ftOrigin] == BBN_JUMP_FILLED) {
607 cfgChanged |= fillDelaySlots(ftOrigin, delaySlots_,
true);
611 if (bbnStatus_[&ftOrigin] == BBN_SCHEDULED) {
613 cfg_->jumpSuccessor(bbn);
614 if (jumpSisterNode != NULL &&
617 areAllJumpPredsFilled(*jumpSisterNode)) {
619 cfgChanged |= fillDelaySlots(ftOrigin, delaySlots_,
true);
642 assert(bbnStatus_[&bbn] == BBN_UNKNOWN);
644 if (resourceManagers_.find(&bbn.
basicBlock())==resourceManagers_.end()) {
648 bbnStatus_[&bbn] = BBN_SCHEDULED;
653 bool fillableSuccessor =
false;
654 for (ControlFlowGraph::EdgeSet::iterator outIter = oEdges.begin();
655 outIter != oEdges.end();) {
660 fillableSuccessor =
true;
661 auto& head = cfg_->headNode(cfe);
662 if (mightFillIncomingTo(head)) {
664 if (!cfg_->hasNode(bbn)) {
667 oEdges = cfg_->outEdges(bbn);
668 outIter = oEdges.begin();
675 if (!fillableSuccessor && bbnStatus_[&bbn] != BBN_ALL_DONE) {
680 mightFillIncomingTo(bbn);
693 resourceManagers_[&bb] = &rm;
704 std::pair<TTAProgram::Move*, std::shared_ptr<TTAProgram::Immediate> >
708 Move* irMove = &jumpMove;
709 int irIndex = jumpIndex;
718 int regIndex =
static_cast<int>(irMove->
source().
index());
724 return std::pair<Move*,std::shared_ptr<Immediate> >(
nullptr,
nullptr);
732 return std::pair<Move*,std::shared_ptr<Immediate> >(
735 for (
int j = 0; j < ins.
moveCount(); j++ ) {
750 return std::pair<Move*,std::shared_ptr<Immediate> >(
755 return std::pair<Move*,std::shared_ptr<Immediate> >(irMove,
nullptr);
761 int index =
static_cast<int>(irMove->
source().
index());
762 for (
int i = irIndex - immu.
latency(); i >= 0; i--) {
766 if (imm->destination().index() == index &&
767 &imm->destination().immediateUnit() == &immu) {
768 return std::pair<Move*,std::shared_ptr<Immediate> >(
775 return std::pair<Move*,std::shared_ptr<Immediate> >(
780 return std::pair<Move*, std::shared_ptr<Immediate> >(
nullptr,
nullptr);
795 static_cast<int>(registerIndex)) {
819 Move* jumpMove,
int slotsToFill,
int removeGuards,
int grIndex,
827 if (nextRm == NULL) {
831 int firstCycleToFill =
839 blockToFillNode, nextBBNode, moves, slotsToFill,fallThru,
840 removeGuards, jumpMove, grIndex, grFile, skippedJump,
847 if (!checkImmediatesAfter(nextBB, slotsToFill)) {
857 if (tryToAssignNodes(moves, slotsToFill, firstCycleToFill,rm, nextBBStart,
861 loseCopies(&tempAssigns);
866 loseCopies(&tempAssigns);
867 unassignTempAssigns(tempAssigns, rm);
895 Move*& skippedJump,
int delaySlots) {
899 *cfg_->connectingEdges(blockToFillNode, nextBBN).begin();
905 int firstIndexToFill =
912 for (
int i = 0; i < slotsToFill; i++) {
922 if (&blockToFillNode == &nextBBN) {
938 pendingImmediateMap[immName] = &imm.
value();
944 for (
int j = 0; j < filler.
moveCount(); j++) {
946 bool dontGuard = i < removeGuards;
958 if (i != slotsToFill - delaySlots -1) {
973 if (jumpMove ==
nullptr
979 skippedJump = &oldMove;
990 if (writesRegister(oldMove, grFile, grIndex)) {
993 if (i != slotsToFill-1) {
1000 MoveNode& mnOld = ddg_->nodeOfMove(oldMove);
1026 if (!allowedToSpeculate(mnOld)) {
1039 if (!checkIncomingDeps(mnOld, blockToFillNode, cycleDiff)) {
1045 mnOld, blockToFillNode, connectingEdge->
isBackEdge());
1055 PendingImmediateMap::iterator immWriteIter =
1056 pendingImmediateMap.find(immName);
1059 if (immWriteIter == pendingImmediateMap.end()) {
1062 newMove.
setSource(immWriteIter->second->copy());
1063 pendingImmediateMap.erase(immWriteIter);
1079 MoveNode& jumpNode = ddg_->nodeOfMove(*jumpMove);
1081 guardOp->addGuardOutputNode(mn);
1085 MoveNode& jumpNode = ddg_->nodeOfMove(*jumpMove);
1086 ddg_->copyIncomingGuardEdges(jumpNode, mn);
1088 moves.at(i).push_back(&mn);
1092 if (&blockToFillNode == &nextBBN) {
1108 pendingImmediateMap[immName] = &imm.
value();
1117 for (
int j = 0; j < firstNotToFill.
moveCount(); j++) {
1118 Move& move = firstNotToFill.
move(j);
1123 MoveNode& mn = ddg_->nodeOfMove(move);
1126 if (!checkIncomingDeps(mn, blockToFillNode, cycleDiff)) {
1133 return pendingImmediateMap.empty();
1163 if (pendingImmediateMap.find(immName) !=
1164 pendingImmediateMap.end()) {
1168 pendingImmediateMap[immName] = &imm.
value();
1173 for (
int j=0; j < filler. moveCount(); j++) {
1181 PendingImmediateMap::iterator immWriteIter =
1182 pendingImmediateMap.find(immName);
1184 if (immWriteIter == pendingImmediateMap.end()) {
1190 pendingImmediateMap.erase(immWriteIter);
1202 if (pendingImmediateMap.find(immName) !=
1203 pendingImmediateMap.end()) {
1207 pendingImmediateMap[immName] = &imm.
value();
1213 if (!pendingImmediateMap.empty()) {
1231 for (DataDependenceGraph::EdgeSet::iterator ieIter =
1232 inEdges.begin(); ieIter != inEdges.end(); ieIter++) {
1233 int mnCycle = mnOld.
cycle();
1236 MoveNode& pred = ddg_->tailNode(ddEdge);
1243 if (&predBlock == &blockToFillNode) {
1252 nodeCycle = pred.
cycle() - delay+1;
1261 nodeCycle = pred.
cycle()+delay;
1263 if (nodeCycle > cycleDiff+mnCycle) {
1287 bool failed =
false;
1290 for (
unsigned int i = 0; i < (unsigned)slotsToFill &&
1291 i < moves.size() && !failed; i++) {
1292 list<MoveNode*>& movesInThisCycle = moves.at(i);
1293 int currentCycle = firstCycleToFill + i;
1295 for (std::list<MoveNode*>::iterator iter = movesInThisCycle.begin();
1296 iter != movesInThisCycle.end() && !failed; iter++) {
1305 MoveNode* old = oldMoveNodes_[&mn];
1310 if (allowedToSpeculate(*old)) {
1313 guardOp->removeGuardOutputNode(mn);
1331 rm.
assign(currentCycle, mn);
1333 if (mn.
cycle() != currentCycle) {
1343 bool limmFound =
false;
1344 for (
int j = (firstCycleToFill+i-immu.
latency());
1345 j >= firstCycleToFill && !limmFound; j--) {
1371 if (!tryToAssignOtherMovesOfDestOps(
1372 mn, firstCycleToFill, rm,
1373 firstCycleToFill + (slotsToFill-1), nextBBStart,
1383 for (
int i = 0; i < slotsToFill; i++) {
1384 list<MoveNode*>& movesInThisCycle = moves.at(i);
1385 for (std::list<MoveNode*>::iterator iter =
1386 movesInThisCycle.begin();
1387 iter != movesInThisCycle.end();iter++) {
1410 if (!tryToAssignOtherMovesOfOp(po, firstCycleToFill, rm, lastCycle,
1411 nextBBStart, tempAssigns)) {
1430 oldMoveNodes_[&operMn]->
cycle() -
1433 mnCycle > lastCycle ? moveNodeBuses_[&operMn] :
nullptr;
1435 if (!rm.
canAssign(mnCycle, operMn, bus)) {
1439 if (!allowedToSpeculate(operMn)) {
1444 guardOp->removeGuardOutputNode(operMn);
1448 if (!rm.
canAssign(mnCycle, operMn, bus)) {
1453 rm.
assign(mnCycle, operMn);
1455 if (mnCycle > lastCycle) {
1456 tempAssigns.insert(&operMn);
1467 firstCycleToFill + oldMoveNodes_[&resMn]->
cycle() -
1471 mnCycle > lastCycle ? moveNodeBuses_[&resMn] :
nullptr;
1472 if (!rm.
canAssign(mnCycle, resMn, bus)) {
1475 rm.
assign(mnCycle, resMn);
1476 if (mnCycle > lastCycle) {
1477 tempAssigns.insert(&resMn);
1500 return *moveNodes_[&old];
1502 auto movePtr = getMove(old.
move());
1504 ddg_->addNode(*newMN, bbn);
1505 ddg_->copyDependencies(old,*newMN,
false, fillOverBackEdge);
1506 moveNodeBuses_[newMN] = &old.
move().
bus();
1508 moveNodes_[&old] = newMN;
1509 oldMoveNodes_[newMN] = &old;
1510 mnOwned_[newMN] =
true;
1513 getProgramOperationPtr(
1524 getProgramOperationPtr(
1545 return programOperations_[old.get()];
1550 programOperations_[old.get()] = po;
1551 oldProgramOperations_[po.get()] = old;
1552 for (
int i = 0; i < old->inputMoveCount();i++) {
1555 po->addInputNode(getMoveNode(mn, bbn, fillOverBackEdge));
1557 for (
int j = 0; j < old->outputMoveCount();j++) {
1560 po->addOutputNode(getMoveNode(mn,bbn,fillOverBackEdge));
1562 po->addGuardOutputNode(getMoveNode(mn,bbn, fillOverBackEdge));
1577 std::shared_ptr<Move>
1580 return moves_[&old];
1582 MoveNode& oldMN = ddg_->nodeOfMove(old);
1584 auto newMove = old.
copy();
1585 newMove->setBus(um_->universalBus());
1587 Terminal& source = newMove->source();
1595 newMove->setAnnotation(srcUnit);
1598 HWOperation& hwop = *um_->universalFunctionUnit().operation(
1603 if (source.
isRA()) {
1606 *um_->controlUnit()->returnAddressPort()));
1610 Terminal& dest = newMove->destination();
1619 newMove->setAnnotation(dstUnit);
1622 HWOperation& hwop = *um_->universalFunctionUnit().operation(
1628 newMove->setDestination(
1630 *um_->controlUnit()->returnAddressPort()));
1635 moves_[&old] = newMove;
1640 newMove->setGuard(g);
1654 std::list<MoveNode*> toDeleteNodes;
1655 for (std::map<MoveNode*,MoveNode*,MoveNode::Comparator>::iterator mnIter =
1656 moveNodes_.begin(); mnIter != moveNodes_.end();
1659 if (mnOwned_[second] ==
true) {
1660 mnOwned_.erase(second);
1662 if ((keptTempNodes == NULL ||
1663 (keptTempNodes->find(second) == keptTempNodes->end()))
1666 toDeleteNodes.push_back(second);
1671 moveNodeBuses_.clear();
1673 oldMoveNodes_.clear();
1676 for (std::list<MoveNode*>::iterator i = toDeleteNodes.begin();
1677 i != toDeleteNodes.end(); i++) {
1678 assert (!(*i)->isScheduled());
1679 ddg_->removeNode(**i);
1685 programOperations_.clear();
1686 oldProgramOperations_.clear();
1693 assert(programOperations_.size() == 0);
1694 assert(moveNodes_.size() == 0);
1695 assert(mnOwned_.size() == 0);
1696 assert(moves_.size() == 0);
1719 for (
int i = 0; i < po->inputMoveCount(); i++) {
1721 if (tempAssigns.find(&mn) != tempAssigns.end()) {
1724 for (
unsigned int j = 0; j < movesToCopy.size(); j++) {
1725 std::list<MoveNode*>& moveList = movesToCopy.at(j);
1726 for (std::list<MoveNode*>::iterator iter = moveList.begin();
1727 iter != moveList.end(); iter++) {
1734 for (
int i = 0; i < po->outputMoveCount(); i++) {
1736 if (tempAssigns.find(&mn) != tempAssigns.end()) {
1750 std::pair<int, TTAProgram::Move*>
1756 for (
int j = 0; j < ins.
moveCount(); j++ ) {
1759 if (pred ==
nullptr) {
1760 return std::pair<int, TTAProgram::Move*>(i, &move);
1764 return std::pair<int, TTAProgram::Move*>(i, &move);
1769 == (guard.isInverted())) {
1770 return std::pair<int, TTAProgram::Move*>(i, &move);
1777 return std::pair<int, TTAProgram::Move*>(-1,NULL);
1781 return std::pair<int, TTAProgram::Move*>(-1,NULL);
1799 Move* jumpAddressMove, std::shared_ptr<Immediate> jumpAddressImmediate,
1800 Move* jumpMove,
int slotsFilled,
Move* skippedJump) {
1802 bool cfgChanged =
false;
1805 &jumpAddressMove->
source()) :
1807 &jumpAddressImmediate->
value());
1811 instructionReferenceManager();
1813 assert(slotsFilled <= nextBB.instructionCount());
1816 if (slotsFilled == nextBB.instructionCount()) {
1819 cfg_->successors(fillingBBN);
1820 if (nextBBs.size() != 1) {
1821 std::string msg =
"no succeessors but no jump";
1829 cfg_->disconnectNodes(jumpBBN, fillingBBN);
1830 cfg_->connectNodes(jumpBBN, newDestNode, *newEdge);
1833 if (skippedJump != NULL) {
1838 assert(jumpMove != NULL);
1842 ANN_STACKFRAME_PROCEDURE_RETURN);
1844 if (jumpAddressMove != NULL && jumpAddressMove != jumpMove) {
1852 if (jumpAddressImmediate != NULL) {
1873 if (cfg_->inDegree(fillingBBN) == 0) {
1878 cfg_->removeNode(fillingBBN);
1879 finishBB(fillingBBN,
true);
1881 for (
int i = 0; i < nextBB.instructionCount(); i++) {
1885 MoveNode & mn = ddg_->nodeOfMove(move);
1886 ddg_->removeNode(mn);
1900 assert(skippedJump == NULL);
1901 assert(slotsFilled >= nextBB.skippedFirstInstructions());
1903 nextBB.instructionAtIndex(slotsFilled));
1907 if (cfg_->incomingFTEdge(fillingBBN) ==
nullptr
1908 && &fillingBBN != &cfg_->firstNormalNode()) {
1909 int deadInsCount = 0;
1910 while (nextBB.instructionCount() > deadInsCount &&
1912 nextBB.instructionAtIndex(deadInsCount))) {
1915 nextBB.skipFirstInstructions(deadInsCount);
1916 if (deadInsCount >= nextBB.instructionCount()) {
1919 "BB got empty illegally");
1951 std::map<BasicBlockNode*,DataDependenceGraph::NodeSet>::iterator
1952 i = tempResultNodes_.find(&bbn);
1954 if (i != tempResultNodes_.end()) {
1957 std::map<BasicBlock*,SimpleResourceManager*>::iterator rmi =
1958 resourceManagers_.find(&i->first->basicBlock());
1959 assert (rmi != resourceManagers_.end());
1961 unassignTempAssigns(ns, rm);
1965 bbnStatus_[&bbn] = BBN_TEMPS_CLEANED;
1972 for (ControlFlowGraph::EdgeSet::iterator inIter = iEdges.begin();
1973 inIter != iEdges.end(); inIter++) {
1979 bbnStatus_[&prevBBN] < BBN_BOTH_FILLED) {
1987 std::map<BasicBlock*,SimpleResourceManager*>::iterator rmi =
1989 if (rmi != resourceManagers_.end()) {
1990 if (rmi->second != NULL) {
1993 resourceManagers_.erase(rmi);
1995 bbnStatus_[&bbn] = BBN_ALL_DONE;
2003 for (DataDependenceGraph::NodeSet::iterator j = tempAssigns.begin();
2004 j != tempAssigns.end(); j++) {
2005 assert((**j).isScheduled());
2007 ddg_->removeNode(**j);
2010 tempAssigns.clear();