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;
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++) {
567 node->basicBlock().add(newInstruction);
581 node->basicBlock().setInInnerLoop();
582 node->basicBlock().setTripCount(0);
588 static_cast<unsigned>(
593 node->basicBlock().setTripCount(tripCount);
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;
1321 if (
node(i).isNormalBB()) {
1323 node(i).statistics();
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);
1880const 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
2236 for (
auto i = edges.first; i != edges.second; ++i) {
2238 if (!
edge->isJumpEdge()) {
2256 for (
auto e: jumpEdges) {
2269 for (
auto i = edges.first; i != edges.second; ++i) {
2271 if (
edge->isJumpEdge()) {
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++) {
2828llvm::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) {
#define abortWithError(message)
#define PRINT_VAR(VARIABLE__)
#define assert(condition)
UInt32 InstructionAddress
#define IGNORE_CLANG_WARNING(X)
find Finds info of the inner loops in the program
static RegisterPass< MachineDCE > R("machinedce","Symbol string based machine DCE for removing not used emulation functions", false, true)
std::shared_ptr< ProgramOperation > ProgramOperationPtr
static int verboseLevel()
static std::ostream & logStream()
void setScheduled(bool state=true)
TTAProgram::BasicBlock & basicBlock()
InstructionAddress originalEndAddress() const
void link(BasicBlockNode *succ)
InstructionAddress originalStartAddress() const
const BasicBlockNode * predecessor() const
std::string toString() const
const BasicBlockNode * successor() const
void updateReferencesFromProcToCfg(TTAProgram::Program &prog)
virtual void removeEdge(Edge &e)
virtual void disconnectNodes(const Node &nTail, const Node &nHead)
EdgeDescriptor descriptor(const Edge &e) const
virtual void moveOutEdges(const Node &source, const Node &destination)
virtual Node & headNode(const Edge &edge) const
std::set< ControlFlowEdge *, typename GraphEdge::Comparator > EdgeSet
virtual Edge & outEdge(const Node &node, const int index) const
virtual void removeNode(Node &node)
EdgeDescMap edgeDescriptors_
virtual bool hasEdge(const Node &nTail, const Node &nHead) const
virtual void addNode(Node &node)
virtual void moveOutEdge(const Node &source, const Node &destination, Edge &edge, const Node *head=NULL, bool childs=false)
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
Node & node(const int index) const
EdgeDescriptor connectingEdge(const Node &nTail, const Node &nHead) const
virtual const TCEString & name() const
virtual int inDegree(const Node &node) const
std::set< BasicBlockNode *, typename GraphNode::Comparator > NodeSet
virtual void moveInEdge(const Node &source, const Node &destination, Edge &edge, const Node *tail=NULL, bool childs=false)
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
virtual int outDegree(const Node &node) const
EdgeSet connectingEdges(const Node &nTail, const Node &nHead) const
virtual EdgeSet outEdges(const Node &node) const
virtual Node & tailNode(const Edge &edge) const
virtual Edge & edge(const int index) const
Graph graph_
The internal graph structure.
virtual EdgeSet inEdges(const Node &node) const
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
virtual int normalBBCount() const
virtual void setMaxMoveCount(int)
virtual void setMaxImmediateCount(int)
virtual int maxImmediateCount() const
virtual int maxMoveCount() const
virtual void setMaxInstructionCount(int)
virtual int maxBypassedCount() const
virtual int maxInstructionCount() const
virtual void setNormalBBCount(int)
virtual void setMaxBypassedCount(int)
TCEString toString() const
void setPredicate(CFGEdgePredicate pred)
bool isNormalEdge() const
static ControlFlowEdge::CFGEdgePredicate edgePredicateFromMove(const TTAProgram::Move &move)
bool isCallPassEdge() const
CFGEdgePredicate edgePredicate() const
DFS visitor which when finding back edge marks such edge as back edge.
std::vector< InstructionAddress > InstructionAddressVector
virtual ~ControlFlowGraph()
void copyToLLVMMachineFunction(llvm::MachineFunction &mf, TTAProgram::InstructionReferenceManager *irm=NULL)
ControlFlowGraph(const TCEString name, TTAProgram::Program *program=NULL)
void splitBasicBlocksWithCallsAndRefs()
BasicBlockNode & entryNode() const
void updateReferencesFromProcToCfg()
void deleteNodeAndRefs(BasicBlockNode &node)
BasicBlockNode * fallThruSuccessor(const BasicBlockNode &bbn) const
const CFGStatistics & statistics()
void createJumps(InstructionAddressMap &leaders, const InstructionAddress &leaderAddr, InstructionAddressMap &dataCodeRellocations, const TTAProgram::Procedure &procedure, int insIndex, int moveIndex)
ReturnSourceSet returnSources_
@ LAST_ELEMENT_REMOVED
jump removed, other things remain in BB
@ JUMP_REMOVED
nothing removed
void mergeNodes(BasicBlockNode &node1, BasicBlockNode &node2, DataDependenceGraph *ddg, const ControlFlowEdge &connectingEdge)
void convertBBRefsToInstRefs()
hash_map< TTAProgram::Instruction *, TTAProgram::Instruction * > InsMap
bool jumpToBBN(const TTAProgram::Terminal &jumpAddr, const BasicBlockNode &bbn) const
void addExitFromSinkNodes(BasicBlockNode *exitNode)
void createBBEdges(const TTAProgram::Procedure &procedure, InstructionAddressMap &leaders, InstructionAddressMap &dataCodeRellocations)
unsigned int findNextIndex(const TTAProgram::Procedure &proc, int jumpInsIndex, int jumpMoveIndex)
bool hasIncomingExternalJumps(const BasicBlockNode &bbn) const
void buildFrom(const TTAProgram::Procedure &procedure)
void indirectJump(InstructionAddressMap &leaders, const InstructionAddress &leaderAddr, InstructionAddressMap &dataCodeRellocations, int insIndex, int moveIndex, const TTAProgram::Procedure &procedure)
hash_map< InstructionAddress, BasicBlockNode * > blocks_
void buildMBBFromBB(llvm::MachineBasicBlock &mbb, const TTAProgram::BasicBlock &bb) const
ControlFlowEdge * incomingFTEdge(const BasicBlockNode &bbn) const
TTAProgram::InstructionReferenceManager & instructionReferenceManager()
std::map< ProgramOperation *, llvm::MachineInstr * > programOperationToMIMap_
For LLVM conversion: mapping of created MachineInstructions to TCE ProgramOperations.
bool computeLeadersFromJumpSuccessors(InstructionAddressMap &leaders, const TTAProgram::Procedure &procedure)
BasicBlockNode * fallThroughPredecessor(const BasicBlockNode &bbn) const
void copyToProcedure(TTAProgram::Procedure &proc, TTAProgram::InstructionReferenceManager *irm=NULL)
ReversedGraph & reversedGraph() const
std::pair< InstructionAddress, ControlFlowEdge::CFGEdgePredicate > ReturnSource
std::set< std::pair< ProgramOperationPtr, llvm::MCSymbol * > > tpos_
For LLVM conversion: the dummy label instructions for SPU should be created for with the given MCSymb...
reverse_graph< ControlFlowGraph::Graph > ReversedGraph
BasicBlockNode * jumpSuccessor(BasicBlockNode &bbn)
bool hasMultipleUnconditionalSuccessors(const BasicBlockNode &node) const
TTAProgram::Address startAddress_
BasicBlockNode * splitBB(BasicBlockNode &n, int remainingSize)
bool hasFallThruPredecessor(const BasicBlockNode &bbn)
EdgeSet incomingJumpEdges(const BasicBlockNode &bbn) const
BasicBlockNode & exitNode() const
void directJump(InstructionAddressMap &leaders, const InstructionAddress &leaderAddr, int insIndex, int moveIndex, const TTAProgram::Instruction &instructionTarget, const TTAProgram::Procedure &procedure)
void removeEntryExitEdge()
void computeLeadersFromRelocations(InstructionAddressMap &leaderSet, InstructionAddressMap &dataCodeRellocations, const TTAProgram::Procedure &procedure)
NodeSet findReachableNodes()
TTAProgram::Program * program() const
ControlFlowEdge & createControlFlowEdge(const TTAProgram::Instruction &iTail, const TTAProgram::Instruction &iHead, ControlFlowEdge::CFGEdgePredicate edgePredicate=ControlFlowEdge::CFLOW_EDGE_NORMAL, ControlFlowEdge::CFGEdgeType edgeType=ControlFlowEdge::CFLOW_EDGE_JUMP)
int findRelJumpDistance(const BasicBlockNode &src, const TTAProgram::Terminal &jumpAddr, const TTAMachine::Machine &mach) const
std::map< const TTAProgram::BasicBlock *, llvm::MachineBasicBlock * > bbMap_
bool allScheduledInBetween(const BasicBlockNode &src, const BasicBlockNode &dst) const
TTAProgram::Terminal * findJumpAddress(BasicBlockNode &src, ControlFlowEdge &e)
TTAProgram::Immediate * findLimmWrite(TTAProgram::Move &move, BasicBlockNode &bb, int moveIndex)
NodeSet findUnreachableNodes(const NodeSet &reachableNodes)
void createAllBlocks(InstructionAddressMap &leaders, const TTAProgram::Procedure &procedure)
void reverseGuardOnOutEdges(const BasicBlockNode &bbn)
void removeUnreachableNodes(const NodeSet &unreachableNodes, DataDependenceGraph *ddg)
hash_map< InstructionAddress, const TTAProgram::Instruction * > InstructionAddressMap
const llvm::MCInstrDesc & findLLVMTargetInstrDesc(TCEString name, const llvm::MCInstrInfo &tii) const
BasicBlockNode & createBlock(TTAProgram::Instruction &leader, const TTAProgram::Instruction &endBlock)
void computeLeadersFromRefManager(InstructionAddressMap &leaders, const TTAProgram::Procedure &procedure)
TTAProgram::Program * program_
TCEString procedureName() const
bool isSingleBBLoop(const BasicBlockNode &node) const
bool hasInstructionAnotherJump(const TTAProgram::Instruction &ins, int moveIndex)
TCEString printStatistics()
TTAProgram::InstructionReferenceManager * irm_
llvm::MachineBasicBlock & getMBB(llvm::MachineFunction &mf, const TTAProgram::BasicBlock &bb) const
BasicBlockNode & firstNormalNode() const
RemovedJumpData removeJumpToTarget(TTAProgram::CodeSnippet &cs, const TTAProgram::Instruction &target, int idx, DataDependenceGraph *ddg=NULL)
void optimizeBBOrdering(bool removeDeadCode, TTAProgram::InstructionReferenceManager &irm, DataDependenceGraph *ddg)
TTAProgram::Address endAddress_
BasicBlockNode * splitBasicBlockAtIndex(BasicBlockNode &bbn, int index)
const TTAProgram::Procedure * procedure_
static std::string toString(const T &source)
static int toInt(const T &source)
bool hasAllRegisterAntidependencies()
void fixInterBBAntiEdges(BasicBlockNode &bbn1, BasicBlockNode &bbn2, bool loopEdges)
MoveNode & nodeOfMove(const TTAProgram::Move &move)
void setBasicBlockNode(const MoveNode &mn, BasicBlockNode &bbn)
bool hasIntraBBRegisterAntidependencies()
void removeNode(MoveNode &node)
virtual void writeToDotFile(const TCEString &fileName) const
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
std::set< GraphEdge *, typename GraphEdge::Comparator > EdgeSet
Operation & operation(const char *name)
virtual TCEString name() const
virtual int numberOfInputs() const
virtual int numberOfOutputs() const
static std::string disassemble(const TTAProgram::Move &move)
bool ciEqual(const TCEString &other) const
bool startsWith(const std::string &str) const
std::vector< TCEString > split(const std::string &delim) const
virtual Machine * machine() const
virtual TCEString name() const
virtual FUPort * port(int operand) const
const std::string & name() const
FunctionUnit * parentUnit() const
ComponentType * item(int index) const
virtual FunctionUnitNavigator functionUnitNavigator() const
virtual ControlUnit * controlUnit() const
InstructionAddress location() const
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
virtual int instructionCount() const
virtual void setInstructionCount(int)
virtual void setBypassedCount(int)
virtual void setMoveCount(int)
virtual int bypassedCount() const
virtual void setImmediateCount(int)
virtual int moveCount() const
virtual int immediateCount() const
LiveRangeData * liveRangeData_
int skippedFirstInstructions() const
void skipFirstInstructions(int count)
virtual Instruction & previousInstruction(const Instruction &ins) const
virtual Address endAddress() const
virtual Instruction & firstInstruction() const
virtual bool isInProgram() const
virtual std::string toString() const
virtual void add(Instruction *ins)
virtual int instructionCount() const
virtual Instruction & instructionAt(UIntWord address) const
virtual void remove(Instruction &ins)
virtual Program & parent() const
virtual Address startAddress() const
virtual Instruction & lastInstruction() const
virtual Instruction & instructionAtIndex(int index) const
virtual Address destinationAddress() const
virtual bool isInstructionAddress() const
DataDefinition & dataDefinition(Address address) const
int dataDefinitionCount() const
void replace(Instruction &insA, Instruction &insB)
bool hasReference(Instruction &ins) const
InstructionReference createReference(Instruction &ins)
Instruction & instruction() const
Instruction * copy() const
int immediateCount() const
bool hasControlFlowMove() const
Immediate & immediate(int i) const
void removeMove(Move &move)
CodeSnippet & parent() const
void setSource(Terminal *src)
MoveGuard & guard() const
bool isControlFlowMove() const
bool isUnconditional() const
Terminal & source() const
void setGuard(MoveGuard *guard)
bool isTriggering() const
Terminal & destination() const
const TTAMachine::Bus & bus() const
@ ANN_LOOP_TRIP_COUNT
An instruction annotated with this annotation is the first instruction of a basic block in a loop wit...
@ ANN_LOOP_INNER
An instruction annotated with this annotation is the first instruction of a basic block in an inner l...
Procedure & procedure(int index) const
bool hasProcedure(const std::string &name) const
void moveProcedure(Procedure &proc, int howMuch)
DataMemory & dataMemory(int index) const
Procedure & nextProcedure(const Procedure &proc) const
InstructionReferenceManager & instructionReferenceManager() const
Procedure & lastProcedure() const
int dataMemoryCount() const
ProgramOperationPtr programOperation() const
virtual const TTAMachine::HWOperation * hwOperation() const
virtual bool equals(const Terminal &other) const
virtual const InstructionReference & instructionReference() const
ProgramOperationPtr programOperation() const
virtual bool isImmediateRegister() const
virtual bool isGPR() const
virtual bool equals(const Terminal &other) const
virtual SimValue value() const
virtual bool isRA() const
virtual bool isBasicBlockReference() const
virtual bool isCodeSymbolReference() const
virtual const TTAMachine::FunctionUnit & functionUnit() const
virtual int index() const
virtual const BasicBlock & basicBlock() const
virtual const InstructionReference & instructionReference() const
virtual bool isProgramOperationReference() const
virtual bool isGPR() const
virtual bool isInstructionAddress() const
virtual bool isImmediateRegister() const
virtual TCEString toString() const =0
virtual const TTAMachine::Port & port() const
virtual bool isImmediate() const
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
virtual bool isFUPort() const
void merge(LiveRangeData &succ)
std::set< TCEString > inlineAsmClobbers_
std::set< TCEString > inlineAsmRegDefs_
std::set< TCEString > inlineAsmRegUses_