38 #include "llvm/CodeGen/MachineInstr.h"
39 #include "llvm/CodeGen/MachineBasicBlock.h"
40 #include "llvm/CodeGen/MachineFunction.h"
41 #include "tce_config.h"
42 #include "llvm/CodeGen/TargetRegisterInfo.h"
43 #include "llvm/IR/Function.h"
44 #include <llvm/CodeGen/TargetSubtargetInfo.h>
67 llvm::MachineFunction& mf,
70 std::string(mf.getFunction().getName().str()) +
"_middg", true),
71 onlyTrueDeps_(onlyTrueDeps), mf_(mf),
72 regInfo_(mf_.getTarget().getSubtargetImpl(
73 mf_.getFunction())->getRegisterInfo())
74 , printOnlyCriticalPath_(
false) {
76 for (llvm::MachineFunction::const_iterator bbi = mf.begin();
77 bbi != mf.end(); ++bbi) {
78 const llvm::MachineBasicBlock& bb = *bbi;
79 for (llvm::MachineBasicBlock::const_iterator ii = bb.begin();
80 ii != bb.end(); ++ii) {
81 const llvm::MachineInstr& i = *ii;
87 for (
unsigned oi = 0; oi < i.getNumOperands(); ++oi) {
88 const llvm::MachineOperand& operand = i.getOperand(oi);
92 if (operand.isUndef()) {
97 if (operand.isImplicit()) {
102 if (llvm::Register::isPhysicalRegister(
109 <<
"found a phys reg " << operand.getReg()
111 if (operand.getType() == llvm::MachineOperand::MO_FrameIndex)
117 if (operand.isUse()) {
121 <<
"uses: " << operand.getReg() << std::endl;
123 }
else if (operand.isDef()) {
124 if (
definers_[operand.getReg()] != NULL) {
127 if (
definers_[operand.getReg()]->machineInstr()->
128 getParent() != &bb) {
131 <<
"found a potential back edge case, "
132 <<
"using the definer from another BB"
143 <<
"unknown operand " << oi << std::endl;
158 for (std::set<MIDDGNode*>::iterator u = users.begin(); u != users.end();
165 <<
"ignoring edge that would create a loop"
183 std::string(parent.name(), true)),
184 onlyTrueDeps_(parent.onlyTrueDeps_), mf_(parent.mf_) {
201 std::pair<MIDDGNode*, MIDDGNode*>
205 std::pair<MIDDGNode*, MIDDGNode*> none = std::make_pair(
null,
null);
237 source = lastPhysRegUser;
247 if (lastPhysRegDefiner != NULL) {
248 dest = lastPhysRegDefiner;
250 dest = lastPhysRegUser;
256 if (dest != source &&
hasPath(*dest, *source))
259 return std::make_pair(source, dest);
283 std::pair<MIDDGNode*, MIDDGNode*> fdep =
286 int hdelta = INT_MIN;
287 if (fdep.first != NULL && fdep.second != NULL) {
288 if (fdep.first == fdep.second)
304 for (NodeSet::const_iterator i = users.begin(); i != users.end();
307 if (lastUse < node->sequentialAddress()) {
327 for (NodeSet::const_iterator i = pred.begin(); i != pred.end(); ++i) {
330 for (
unsigned operand = 0; operand < instr->getNumOperands();
332 const llvm::MachineOperand& mo = instr->getOperand(operand);
335 if (mo.getReg() == physReg ||
342 if (instr->readsRegister(physReg) ||
343 instr->modifiesRegister(physReg,
regInfo_)) {
360 for (
int nc = 0; nc <
nodeCount(); ++nc) {
371 std::ostringstream s;
372 s <<
"digraph " <<
name() <<
" {" << std::endl;
378 s <<
"\t{" << std::endl
379 <<
"\t\tnode [shape=plaintext];" << std::endl
383 for (
int c = smallest; c <= largest; ++c) {
384 s <<
"\"cycle " << c <<
"\" -> ";
386 s <<
"\"cycle " << largest + 1 <<
"\"; "
387 << std::endl <<
"\t}" << std::endl;
390 for (
int c = smallest; c <= largest; ++c) {
391 std::list<MIDDGNode*> ops =
schedule_[c];
392 if (ops.size() > 0) {
393 s <<
"\t{ rank = same; \"cycle " << c <<
"\"; ";
394 for (std::list<MIDDGNode*>::iterator i = ops.begin();
395 i != ops.end(); ++i) {
401 s <<
"n" << n.
nodeID() <<
"; ";
403 s <<
"}" << std::endl;
408 typedef std::map<TCEString, int> OpCountMap;
412 OpCountMap maxParallelOps;
415 OpCountMap operationMix;
417 for (
int c = smallest; c <= largest; ++c) {
418 std::list<MIDDGNode*> ops =
schedule_[c];
419 if (ops.size() == 0)
continue;
421 std::map<TCEString, int> parallelOpsAtCycle;
422 for (std::list<MIDDGNode*>::iterator i = ops.begin();
423 i != ops.end(); ++i) {
426 if (opName ==
"" || opName ==
"?jump")
continue;
427 operationMix[opName]++;
428 parallelOpsAtCycle[opName]++;
431 for (OpCountMap::const_iterator i = parallelOpsAtCycle.begin();
432 i != parallelOpsAtCycle.end(); ++i) {
434 int count = (*i).second;
435 maxParallelOps[opName] =
436 std::max(maxParallelOps[opName], count);
440 const int COL_WIDTH = 14;
442 s <<
"/* statistics: " << std::endl << std::endl;
443 s << std::setw(COL_WIDTH) << std::right <<
"virtual regs: ";
444 s <<
definers_.size() << std::endl << std::endl;
445 s << std::setw(COL_WIDTH) << std::right <<
"operation stats: ";
446 s << std::endl << std::endl;
448 for (OpCountMap::const_iterator i = maxParallelOps.begin();
449 i != maxParallelOps.end(); ++i) {
451 int parCount = (*i).second;
452 int total = operationMix[opName];
453 s << std::setw(COL_WIDTH) << std::right << opName +
": ";
454 s << std::setw(COL_WIDTH) << std::right << total;
455 s <<
" total, " << std::setw(COL_WIDTH) << std::right
456 << parCount <<
" at most in parallel" << std::endl;
458 s <<
"*/" << std::endl;
471 s <<
",shape=box,color=\"red\"";
472 s <<
"]; " << std::endl;
476 for (
int count =
edgeCount(), i = 0; i < count ; ++i) {
485 s <<
"\tn" << tail.
nodeID() <<
" -> n"
490 s <<
"];" << std::endl;
493 s <<
"}" << std::endl;
514 if (lastDefiner == NULL ||
517 lastDefiner = previousDefiner;
520 if (lastDefiner != NULL) {
531 if (lastUser == NULL ||
537 if (lastUser != NULL) {
541 std::pair<MIDDGNode*, MIDDGNode*> fdep =
544 if (fdep.first != NULL && fdep.second != NULL &&
545 fdep.first != fdep.second) {
551 << fdep.first->sequentialAddress() <<
" to "
552 << fdep.second->sequentialAddress() << std::endl;
567 const llvm::TargetInstrInfo *TII =
570 machineInstr()->getParent()->getParent()->getFunction())->
576 if (
mi_->isInlineAsm()) {
577 unsigned numDefs = 0;
578 while (
mi_->getOperand(numDefs).isReg() &&
579 mi_->getOperand(numDefs).isDef())
581 opName =
mi_->getOperand(numDefs).getSymbolName();
583 opName = TII->getName(
mi_->getOpcode()).str();
590 for (
size_t i = 0; i < opName.size(); ++i) {
591 if (upper[i] == opName[i])
592 cleaned += opName[i];