46 #pragma GCC diagnostic ignored "-Wunused-parameter"
49 #include <boost/graph/depth_first_search.hpp>
51 #include <llvm/CodeGen/MachineFunction.h>
52 #include <llvm/Target/TargetMachine.h>
53 #include "tce_config.h"
54 #include <llvm/CodeGen/TargetInstrInfo.h>
56 #include <llvm/IR/Function.h>
57 #include <llvm/IR/Module.h>
58 #include <llvm/CodeGen/TargetSubtargetInfo.h>
59 #include <llvm/MC/MCContext.h>
60 #pragma GCC diagnostic warning "-Wunused-parameter"
150 startAddress_(
TTAProgram::NullAddress::instance()),
151 endAddress_(
TTAProgram::NullAddress::instance()),
167 procedure_(&procedure),
168 startAddress_(
TTAProgram::NullAddress::instance()),
169 endAddress_(
TTAProgram::NullAddress::instance()),
189 procedure_(&procedure),
190 startAddress_(
TTAProgram::NullAddress::instance()),
191 endAddress_(
TTAProgram::NullAddress::instance()),
192 passData_(&passData) {
220 leaders, dataCodeRellocations, procedure);
246 bool hasCFMove =
false;
249 bool hasExit =
false;
268 for (
int insIndex = 0; insIndex < iCount; insIndex++) {
280 for (
int i = 0, count = instruction->
moveCount(); i < count; i++) {
285 if (iCount > nextIndex) {
301 *leaders[leaderAddr], iNext,
312 leaders, leaderAddr, dataCodeRellocations,
313 procedure, insIndex, i);
317 if (iCount > insIndex+1) {
324 if (hasCFMove ==
false &&
329 if (!
hasEdge(blockSource, blockTarget)) {
331 *leaders[leaderAddr],nextInstruction,
358 "For access to reference manager procedure \
359 must be registered in Program!");
368 for (InstructionReferenceManager::Iterator i = refManager.
begin();
369 i != refManager.
end(); ++i) {
375 leaders[insAddr] = &instruction;
405 "For access to Relocations procedure \
406 must be registered in Program!");
424 leaders[targetAddress.
location()] = &iTarget;
425 dataCodeRellocations[targetAddress.
location()] = &iTarget;
455 for (
unsigned int insIndex = 0;insIndex < iCount;) {
458 bool increase =
true;
459 for (
int i = 0; i < instruction->
moveCount(); i++) {
470 leaders[targetAddr] = &iTarget;
478 unsigned int nextIndex =
findNextIndex(procedure, insIndex, i);
479 if (iCount > nextIndex) {
480 insIndex = nextIndex;
509 std::set<InstructionAddress> iAddresses;
510 iAddresses = MapTools::keys<InstructionAddress>(leaders);
512 sortedLeaders(iAddresses.begin(), iAddresses.end());
513 sort(sortedLeaders.begin(), sortedLeaders.end());
514 int blockSize = sortedLeaders.size();
517 for (i = 0; i < blockSize - 1; i++) {
555 "Basic block with given start address already exists!");
557 if (blockStart > blockEnd) {
560 "Basic block start address is higher then it's end address!");
565 for (
unsigned int i = blockStartIndex; i <= blockEndIndex; i++) {
588 static_cast<unsigned>(
629 "Source instruction %d:%s\nDestination instruction %d:%s\n")
638 "Source basic block is missing!");
643 "Source instruction %d:%s\nDestination instruction %d:%s\n")
652 "Destination basic block is missing!");
682 int insIndex,
int cfMoveIndex,
694 "Target basic block of jump is missing!");
704 if (!hasAnotherJump) {
705 int nextIndex =
findNextIndex(procedure, insIndex, cfMoveIndex);
710 "Fall-through of jump missing:"
711 "Address: %d jump: %s\n")
721 "Fall through basic block is missing!");
727 *leaders[leaderAddr], instructionTarget,
731 *leaders[leaderAddr], *iNext,
737 *leaders[leaderAddr], instructionTarget,
741 *leaders[leaderAddr], *iNext,
760 for (
int i = 0; i < ins.
moveCount(); i++) {
783 int insIndex,
int cfMoveIndex,
787 InstructionAddressMap::iterator dataCodeIterator =
788 dataCodeRellocations.begin();
793 int nextIndex =
findNextIndex(procedure, insIndex, cfMoveIndex);
797 *leaders[leaderAddr], iNext,
803 "Jump to next annotation without next instruction");
824 int nextIndex =
findNextIndex(procedure, insIndex, cfMoveIndex);
831 "Fall through basic block is missing!");
835 *leaders[leaderAddr], iNext,fallPredicate,
845 ProgramAnnotation::ANN_STACKFRAME_PROCEDURE_RETURN)) {
851 while (dataCodeIterator != dataCodeRellocations.end()) {
859 *leaders[leaderAddr], *(*dataCodeIterator).second,
886 if (control == NULL) {
888 __FILE__, __LINE__,
__func__, (boost::format(
889 "Control flow move '%s' has destination unit %s, "
890 "not global control unit!")
892 % unit.
name()).str());
895 int nextIndex = jumpInsIndex + delaySlots + 1;
899 "Procedure ends before all delay slot instructions");
902 for (
int i = jumpInsIndex + 1; i < nextIndex; i++) {
908 "Control flow operation in delay slot"
909 " in %d! Instruction:\n%s")
935 "Source instr %d:%s\nDestination instr %d:%s\n")
942 "Source basic block of edge to exit is missing!");
957 for (
auto blockSource: retSourceNodes) {
1016 if (found ==
true) {
1019 "Corrupted graph. Found multiple entry nodes.");
1025 if (found ==
false || result == NULL) {
1026 TCEString errorMsg(
"Graph does not have entry node.");
1035 if (entrySucc.size() != 1) {
1037 "Entry node has not exactly one successor");
1042 "Successor of entry node is not normal bb");
1062 bool unlinkedExitNode =
false;
1069 unlinkedExitNode =
true;
1072 if (found ==
true) {
1075 "Corrupted graph. Found multiple exit nodes.");
1081 if (found ==
false || result == NULL || unlinkedExitNode ==
true) {
1082 TCEString errorMsg(
"Graph does not have exit node.");
1101 std::vector<std::pair<BasicBlockNode*, int> > fromEntry;
1102 for (
int i = 0; i <
outDegree(entry); i++) {
1103 fromEntry.push_back(
1104 std::pair<BasicBlockNode*, int>(
1107 for (
unsigned int i = 0; i < fromEntry.size(); i++) {
1129 std::vector<std::pair<BasicBlockNode*, int> > fromEntry;
1130 for (
int i = 0; i <
outDegree(entry); i++) {
1131 fromEntry.push_back(
1132 std::pair<BasicBlockNode*, int>(
1135 for (
unsigned int i = 0; i < fromEntry.size(); i++) {
1200 Move* tmp = &instruction.
move(moveIndex);
1202 leaders, leaderAddr, insIndex, moveIndex,
1222 if (sourceTerm->
equals(*destTerm)) {
1224 leaders, leaderAddr, insIndex, moveIndex,
1232 if (sourceTerm->
isGPR()) {
1233 for (
int j = 0; j < iPrev->
moveCount(); j++){
1237 if (destTerm == NULL) {
1241 if (sourceTerm->
equals(*destTerm)) {
1244 leaders, leaderAddr, insIndex, moveIndex,
1249 if (tmpTerm->
isGPR() ||
1258 leaders, leaderAddr,
1259 dataCodeRellocations, insIndex, moveIndex,
1271 "Source of immediate write not found!");
1274 leaders, leaderAddr, dataCodeRellocations,
1275 insIndex, moveIndex, procedure);
1290 result += (boost::format(
"Procedure '%s' has %d moves, %d immediate"
1291 " writes, %d instructions and %d bypassed moves in %d basic blocks.")
1295 result += (boost::format(
"\n\tLargest basic block has %d moves, %d"
1296 " immediate writes, %d instructions and %d bypassed moves.\n")
1312 int immediateCount = 0;
1313 int instructionCount = 0;
1314 int bypassCount = 0;
1315 int normalBBCount = 0;
1316 int maxMoveCount = 0;
1317 int immediateCountInMax = 0;
1318 int instructionCountInMax = 0;
1319 int bypassCountInMax = 0;
1364 for (EdgeSet::iterator i = oEdges.begin(); i != oEdges.end(); i++) {
1365 if ((*i)->isFallThroughEdge() || (*i)->isCallPassEdge()) {
1385 for (
auto i: iEdges) {
1386 if (i->isFallThroughEdge() || i->isCallPassEdge()) {
1403 for (EdgeSet::iterator i = iEdges.begin(); i != iEdges.end(); i++) {
1404 if ((*i)->isFallThroughEdge() || (*i)->isCallPassEdge()) {
1422 while (queuedBBs.size() != 0) {
1425 processedBBs.insert(¤t);
1427 for (NodeSet::iterator i = succs.begin(); i != succs.end(); i++) {
1429 queuedBBs.insert(*i);
1432 processedBBs.insert(¤t);
1434 queuedBBs.erase(¤t);
1436 return processedBBs;
1453 typedef std::map<TTAProgram::Instruction*,TTAProgram::Instruction*>
1457 std::vector<Instruction*> oldInstructions;
1459 int jumpsRemoved = 0;
1461 assert(firstBBs.size() == 1);
1472 std::cerr <<
"First Basic block is not normal basic block. "
1473 <<
"This is propably due function that is completely empty,"
1474 <<
" not containg even return jump. The cause of this "
1475 <<
"might be LLVM optimizing away code it considers dead."
1477 <<
"Control flow graph written to empty_fn.dot"
1496 while (currentBBN != NULL) {
1504 std::cerr <<
"\tSkipped inst has refs, proc: " << proc.
name()
1505 <<
" index: " << i << std::endl;
1517 copiedInsFromCFG[ins] = copiedIns;
1521 proc.CodeSnippet::add(copiedIns);
1524 queuedNodes.erase(currentBBN);
1531 if (ftNode != NULL && ftNode->
isNormalBB()) {
1533 if (queuedNodes.find(ftNode) == queuedNodes.end()) {
1534 std::cerr <<
"not-queued fall-thru: " << ftNode->
toString()
1535 <<
" current: " << currentBBN->
toString() <<
1540 assert(queuedNodes.find(ftNode) != queuedNodes.end());
1541 currentBBN = ftNode;
1548 for (EdgeSet::iterator i = oEdges.begin(); i != oEdges.end(); i++) {
1552 queuedNodes.find(&head) != queuedNodes.end()) {
1568 skippedFirstInstructions()));
1588 if (nextNode == NULL) {
1589 bool ftPred =
false;
1590 for (NodeSet::iterator i = queuedNodes.begin();
1591 i != queuedNodes.end(); i++) {
1603 if (nextNode == NULL && ftPred) {
1604 for (NodeSet::iterator i = unreachableNodes.begin();
1605 i != unreachableNodes.end(); i++) {
1608 unreachableNodes.erase(*i);
1616 if (nextNode == NULL && ftPred) {
1618 "CopyToProcedure_multiple_fall_thorough_nodes.dot");
1619 assert(0 &&
"CFG may have multiple fall-thorough nodes!");
1622 currentBBN = nextNode;
1633 for (InsMap::iterator i = copiedInsFromCFG.begin();
1634 i != copiedInsFromCFG.end(); i++) {
1635 std::pair<Instruction*,Instruction*> insPair = *i;
1637 irm->
replace(*insPair.first, *insPair.second);
1680 llvm::MachineFunction& mf,
1685 typedef std::map<TTAProgram::Instruction*,TTAProgram::Instruction*>
1689 std::vector<Instruction*> oldInstructions;
1692 assert(firstBBs.size() == 1);
1706 for (
int i = 0; i < proc.instructionCount(); i++) {
1712 mf.erase(mf.begin());
1723 unreachableNodes.insert(&n);
1730 while (currentBBN != NULL) {
1738 queuedNodes.erase(currentBBN);
1745 if (ftNode != NULL && ftNode->
isNormalBB()) {
1747 if (queuedNodes.find(ftNode) == queuedNodes.end()) {
1748 std::cerr <<
"not-queued fall-thru: " << ftNode->
toString()
1749 <<
" current: " << currentBBN->
toString() <<
1754 assert(queuedNodes.find(ftNode) != queuedNodes.end());
1755 currentBBN = ftNode;
1767 if (nextNode == NULL) {
1768 bool ftPred =
false;
1769 for (NodeSet::iterator i = queuedNodes.begin();
1770 i != queuedNodes.end(); i++) {
1782 if (nextNode == NULL && ftPred) {
1783 for (NodeSet::iterator i = unreachableNodes.begin();
1784 i != unreachableNodes.end(); i++) {
1787 unreachableNodes.erase(*i);
1795 if (nextNode == NULL && ftPred) {
1797 "CopyToProcedure_multiple_fall_thorough_nodes.dot");
1798 assert(0 &&
"CFG may have multiple fall-thorough nodes!");
1801 currentBBN = nextNode;
1813 for (InsMap::iterator i = copiedInsFromCFG.begin();
1814 i != copiedInsFromCFG.end(); i++) {
1815 std::pair<Instruction*,Instruction*> insPair = *i;
1817 irm->
replace(*insPair.first, *insPair.second);
1824 for (
unsigned int j = 0; j < nCount; j++) {
1826 llvm::MachineBasicBlock* mbb = &
getMBB(mf, bb);
1835 for (std::set<std::pair<ProgramOperationPtr, llvm::MCSymbol*> >::const_iterator i =
1838 llvm::MCSymbol* symbol = (*i).second;
1842 const llvm::TargetInstrInfo& tii =
1843 *mf.getTarget().getSubtargetImpl(mf.getFunction())->getInstrInfo();
1844 const llvm::MCInstrDesc& tid =
1846 llvm::MachineInstr* labelInstruction =
1847 mf.CreateMachineInstr(tid, llvm::DebugLoc());
1848 labelInstruction->addOperand(
1849 llvm::MachineOperand::CreateMCSymbol(symbol));
1850 mi->getParent()->insert(
1851 llvm::MachineBasicBlock::instr_iterator (mi), labelInstruction);
1858 for (
unsigned int i = 0; i < eCount; i++) {
1860 if (!
headNode(testEdge).isNormalBB() ||
1864 llvm::MachineBasicBlock& hNode =
1866 llvm::MachineBasicBlock& tNode =
1868 if (hNode.isSuccessor(&tNode))
1870 tNode.addSuccessor(&hNode);
1880 const llvm::MCInstrDesc&
1883 const llvm::MCInstrInfo& tii)
const {
1884 for (
unsigned opc = 0; opc < tii.getNumOpcodes(); ++opc) {
1886 return tii.get(opc);
1894 llvm::MachineBasicBlock& mbb,
1897 #ifdef DEBUG_POM_TO_MI
1899 <<
"TTA instructions:" << std::endl
1900 << bb.
toString() << std::endl << std::endl
1901 <<
"OTA instructions:" << std::endl;
1911 if (!instr.
isNOP()) {
1920 typedef std::vector<const TTAMachine::FunctionUnit*> BundleOrderIndex;
1921 BundleOrderIndex bundleOrder;
1927 bundleOrder.push_back(fu);
1942 for (
int m = 0; m < instr.
moveCount(); ++m) {
1957 if (startedOps.size() == 0)
1961 std::vector<TTAProgram::Terminal*> > OperandMap;
1962 OperandMap operands;
1968 for (OpsMap::const_iterator opsi = startedOps.begin();
1969 opsi != startedOps.end(); ++opsi) {
1977 for (
int m = 0; m < resultInstr.
moveCount(); ++m) {
1991 operands[hwOp].size()) {
1996 operands[hwOp].size());
2003 for (
int m = 0; m < instr.
moveCount(); ++m) {
2009 hwOp->
port(input + 1)) ==
2014 for (
int mm = 0; mm < instr.
moveCount(); ++mm) {
2027 operands[hwOp].push_back(&move.
source());
2035 operands[hwOp].size()) {
2042 (
int)operands[hwOp].size());
2046 for (BundleOrderIndex::const_iterator boi = bundleOrder.begin();
2047 boi != bundleOrder.end(); ++boi) {
2048 llvm::MachineInstr* mi = NULL;
2049 const llvm::TargetInstrInfo& tii =
2050 *mbb.getParent()->getTarget().getSubtargetImpl(
2051 mbb.getParent()->getFunction())->getInstrInfo();
2052 if (startedOps.find(*boi) == startedOps.end()) {
2060 mi = mbb.getParent()->CreateMachineInstr(
2065 #ifdef DEBUG_POM_TO_MI
2070 (*startedOps.find(*boi)).second;
2072 #ifdef DEBUG_POM_TO_MI
2076 const llvm::MCInstrDesc& tid =
2078 mi = mbb.getParent()->CreateMachineInstr(
2079 tid, llvm::DebugLoc());
2081 #ifdef DEBUG_POM_TO_MI
2087 std::vector<TTAProgram::Terminal*>& opr = operands[hwop];
2089 unsigned counter = 0;
2092 for (std::vector<TTAProgram::Terminal*>::const_iterator opri =
2093 opr.begin(); opri != opr.end() &&
2094 (counter < tid.getNumOperands() || mi->getDesc().isReturn());
2095 ++opri, ++counter) {
2103 std::vector<TCEString> refs =
2108 llvm::MachineOperand::CreateCPI(index, offset));
2113 llvm::MachineOperand::CreateJTI(index, 0));
2116 llvm::MachineOperand::CreateES(
2120 llvm::MachineBasicBlock& mbb2 =
2123 llvm::MachineOperand::CreateMBB(&mbb2));
2124 mbb.addSuccessor(&mbb2);
2130 llvm::MCSymbol* symbol =
2131 mbb.getParent()->getContext().getOrCreateSymbol(
2132 llvm::StringRef(tpo.
label()));
2133 mi->addOperand(llvm::MachineOperand::CreateMCSymbol(symbol));
2138 if (!mi->getDesc().isReturn()) {
2140 llvm::MachineOperand::CreateImm(
2143 }
else if (terminal->
isGPR()) {
2146 bool isDef = counter < tid.getNumDefs();
2151 if (mi->getDesc().isReturn()) {
2158 if (!mi->getDesc().isReturn()) {
2160 llvm::MachineOperand::CreateReg(
2161 terminal->
index() + 1, isDef, isImp));
2166 "Unsupported Terminal -> MachineOperand conversion attempted.");
2168 #ifdef DEBUG_POM_TO_MI
2177 assert(startedPOs.find(*boi) != startedPOs.end());
2179 assert(po.get() != NULL);
2180 if (po.get() != NULL) {
2186 #ifdef DEBUG_POM_TO_MI
2190 #ifdef DEBUG_POM_TO_MI
2195 #ifdef DEBUG_POM_TO_MI
2215 #if 0 // TODO: why does this irm claim to be unuser variable??
2236 for (
auto i = edges.first; i != edges.second; ++i) {
2256 for (
auto e: jumpEdges) {
2269 for (
auto i = edges.first; i != edges.second; ++i) {
2273 result.insert(
edge);
2296 Move* lastJump = NULL;
2297 for (;index >= idx ; index--) {
2299 for (
int j = 0; j < ins.
moveCount(); j++) {
2315 if (lastJump != NULL) {
2328 isUniversalMachine()) {
2329 invG = CodeGenerator::createInverseGuard(
2332 invG = CodeGenerator::createInverseGuard(
2342 #ifdef DEBUG_BB_OPTIMIZER
2343 std::cerr <<
"removing jump node from ddg."
2359 #ifdef DEBUG_BB_OPTIMIZER
2360 std::cerr <<
"removing jump node from ddg(2)."
2405 "cfg does not have program");
2412 for (
int i = 0; i <
outDegree(bbn); i++) {
2432 boost::depth_first_search(
graph_, visitor(vis));
2447 for (
int k = 0; k < ins.
moveCount(); k++) {
2487 for (
int i = 0; i <
outDegree(bbn); i++) {
2494 std::cerr <<
"node in question: " << bbn.
toString() <<
2495 " edge: " << e.
toString() << std::endl;
2497 assert(
false &&
"Can only reverse predicate true or false");
2511 unreachableNodes.insert(&n);
2514 return unreachableNodes;
2526 #ifdef DEBUG_BB_OPTIMIZER
2528 (boost::format(
"%s_before_optimize_cfg.dot") %
2533 assert(firstBBs.size() == 1);
2542 if (removeDeadCode) {
2548 while (currentBBN != NULL) {
2550 #ifdef DEBUG_BB_OPTIMIZER
2551 std::cerr <<
"current node: " << currentBBN->
toString() <<
2556 queuedNodes.erase(currentBBN);
2560 bool unhandledFT =
false;
2561 while (ftNode != NULL && ftNode->
isNormalBB()) {
2562 if (queuedNodes.find(ftNode) == queuedNodes.end()) {
2563 std::cerr <<
"not-queued fall-thru: " << ftNode->
toString()
2564 <<
" current: " << currentBBN->
toString() <<
2569 assert(queuedNodes.find(ftNode) != queuedNodes.end());
2571 #ifdef DEBUG_BB_OPTIMIZER
2572 std::cerr <<
"\tfound FT node: " << ftNode->
toString() << std::endl;
2585 #ifdef DEBUG_BB_OPTIMIZER
2586 std::cerr <<
"Merging: " << currentBBN->
toString()
2587 <<
" with: " << ftNode->
toString() << std::endl;
2590 std::cerr <<
"Warning: merging over back edge." <<
2594 queuedNodes.erase(ftNode);
2596 #ifdef DEBUG_BB_OPTIMIZER
2598 std::cerr <<
"Merged with ft node." << std::endl;
2602 currentBBN->
link(ftNode);
2603 #ifdef DEBUG_BB_OPTIMIZER
2606 currentBBN = ftNode;
2612 if (unhandledFT)
continue;
2617 for (EdgeSet::iterator i = oEdges.begin(); i != oEdges.end(); i++) {
2621 queuedNodes.find(&head) != queuedNodes.end()
2639 skippedFirstInstructions()));
2642 queuedNodes.erase(&head);
2644 #ifdef DEBUG_BB_OPTIMIZER
2645 std::cerr <<
"Merged with after jump removal(1)" <<
2648 nextNode = currentBBN;
2655 #ifdef DEBUG_BB_OPTIMIZER
2656 std::cerr <<
"Merging after jump removal.." << std::endl;
2660 queuedNodes.erase(&head);
2662 nextNode = currentBBN;
2663 #ifdef DEBUG_BB_OPTIMIZER
2664 std::cerr <<
"Merged with after jump removal(2)" <<
2686 if (nextNode != NULL) {
2694 bool ftPred =
false;
2695 for (NodeSet::iterator i = queuedNodes.begin();
2696 i != queuedNodes.end(); i++) {
2705 if (!removeDeadCode) {
2709 if (nextNode == NULL && ftPred) {
2710 for (NodeSet::iterator i = unreachableNodes.begin();
2711 i != unreachableNodes.end(); i++) {
2714 unreachableNodes.erase(*i);
2720 if (nextNode == NULL) {
2725 currentBBN->
link(nextNode);
2726 currentBBN = nextNode;
2729 #ifdef DEBUG_BB_OPTIMIZER
2731 (boost::format(
"%s_after_optimize_cfg.dot") %
2742 for (NodeSet::iterator i = nodes.begin(); i != nodes.end(); i++) {
2749 for (
int k = 0; k < ins.
moveCount(); k++) {
2778 for (
int k = 0; k < ins.
moveCount(); k++) {
2801 for (EdgeSet::iterator i = n2in.begin(); i != n2in.end(); i++) {
2804 if (&tail != &node1) {
2810 for (EdgeSet::iterator i = n2out.begin(); i != n2out.end(); i++) {
2828 llvm::MachineBasicBlock&
2830 llvm::MachineFunction& mf,
2836 llvm::MachineBasicBlock* mbb = mf.CreateMachineBasicBlock();
2851 std::set<BasicBlockNode*> bbsToHandle;
2854 bbsToHandle.insert(&bb);
2857 while (bbsToHandle.size() > 0) {
2873 bbsToHandle.erase(bbn);
2942 auto& bb = n.basicBlock();
2946 for (
int j = bb.skippedFirstInstructions(); j > 0; j--) {
2950 std::cerr <<
"Skipped ins has ref: " << ins.toString()
2952 std::cerr <<
"node: " << n.toString() << std::endl;
2959 bb.skipFirstInstructions(0);
2962 if (!bb.instructionCount())
continue;
2965 auto& firstIns = bb[0];
2968 for (
int j = 1; j < bb.instructionCount(); j++) {
2982 if (!e->isJumpEdge()) {
3008 for (
int i = bb.instructionCount()-1;
3009 i >= bb.skippedFirstInstructions(); i--) {
3011 for (
int j = 0; j < ins.moveCount(); j++) {
3012 auto& m = ins.move(j);
3017 if (m.source().isInstructionAddress()) {
3022 return &limm->value();
3042 int i = moveIndex - lat;
3043 while (i >= bb.skippedFirstInstructions()) {
3047 if (&imm.destination().immediateUnit() == &immu &&
3048 move.
source().
index() == imm.destination().index()) {
3105 bool hasUncondSucc =
false;
3107 for (
int i = 0; i <
outDegree(bbn); i++) {
3110 if (hasUncondSucc) {
3113 hasUncondSucc =
true;
3145 while (ftBBN !=
nullptr && ftBBN->
isNormalBB()) {
3151 if (nextSz == INT_MAX) {
3161 while (ftBBN !=
nullptr) {
3165 if (sz == INT_MAX) {
3181 while (ftBBN !=
nullptr && ftBBN->
isNormalBB()) {
3182 if (ftBBN == &dst) {