OpenASIP  2.0
MachineInstrDDG.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2015 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file MachineInstrDDG.cc
26  *
27  * @author Pekka Jääskeläinen 2012
28  * @note rating: red
29  */
30 #ifdef NDEBUG
31 #undef NDEBUG
32 #endif
33 
34 #include "CompilerWarnings.hh"
35 
36 IGNORE_COMPILER_WARNING("-Wunused-parameter")
37 
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>
45 
46 #include "MachineInstrDDG.hh"
47 
48 #include "AssocTools.hh"
49 #include "Application.hh"
50 #include "LLVMTCECmdLineOptions.hh"
51 #include "TCETargetMachine.hh"
52 #include "OperationPool.hh"
53 #include "Operation.hh"
54 
55 #include <utility>
56 
58 
59 // #define DEBUG_MI_DDG
60 
61 /**
62  * Constructs a DDG out of MachineInstructions.
63  *
64  * Only true dependencies are supported at the moment.
65  */
67  llvm::MachineFunction& mf,
68  bool onlyTrueDeps) :
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) {
75  int instructions = 0;
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;
82  MIDDGNode* node = new MIDDGNode(i, instructions);
83  nodes_.insert(node);
84  addNode(*node);
85  assert(hasNode(*node));
86  ++instructions;
87  for (unsigned oi = 0; oi < i.getNumOperands(); ++oi) {
88  const llvm::MachineOperand& operand = i.getOperand(oi);
89  if (!operand.isReg())
90  continue;
91 
92  if (operand.isUndef()) {
93  // this is probably a global register defined in some other
94  // function, thus it can be ignored (only reads from it in this func)
95  continue;
96  }
97  if (operand.isImplicit()) {
98  // the call clobbered regs
99  continue;
100  }
101 
102  if (llvm::Register::isPhysicalRegister(
103  operand.getReg())) {
104 
105  // only physical reg at this point should be the stack pointer,
106  // which is a global reg we can ignore
107 #ifdef DEBUG_MI_DDG
109  << "found a phys reg " << operand.getReg()
110  << std::endl;
111  if (operand.getType() == llvm::MachineOperand::MO_FrameIndex)
112  Application::logStream() << "SP";
113 #endif
114  continue;
115  }
116 
117  if (operand.isUse()) {
118  users_[operand.getReg()].insert(node);
119 #ifdef DEBUG_MI_DDG
121  << "uses: " << operand.getReg() << std::endl;
122 #endif
123  } else if (operand.isDef()) {
124  if (definers_[operand.getReg()] != NULL) {
125  // in case we already have a definer, use the
126  // one from the different basic block to avoid loops
127  if (definers_[operand.getReg()]->machineInstr()->
128  getParent() != &bb) {
129 #ifdef DEBUG_MI_DDG
131  << "found a potential back edge case, "
132  << "using the definer from another BB"
133  << std::endl;
134 #endif
135  continue;
136  }
137  } else {
138  definers_[operand.getReg()] = node;
139  }
140  } else {
141 #ifdef DEBUG_MI_DDG
143  << "unknown operand " << oi << std::endl;
144 #endif
145  continue;
146  }
147  allRegisters_.insert(operand.getReg());
148  }
149  }
150  }
151 
152 
153  for (DefinerMap::iterator i = definers_.begin(); i != definers_.end();
154  ++i) {
155  Register reg = (*i).first;
156  MIDDGNode* source = (*i).second;
157  NodeSet& users = users_[reg];
158  for (std::set<MIDDGNode*>::iterator u = users.begin(); u != users.end();
159  ++u) {
160  MIDDGNode* dest = *u;
161 
162  if (hasPath(*dest, *source)) {
163 #ifdef DEBUG_MI_DDG
165  << "ignoring edge that would create a loop"
166  << std::endl;
167 #endif
168  continue;
169  }
170 
171  MIDDGEdge* edge = new MIDDGEdge(reg);
172  edges_.insert(edge);
173  connectNodes(*source, *dest, *edge);
174  }
175  }
176 }
177 
178 /**
179  * Constructor for creating a subgraph.
180  */
183  std::string(parent.name(), true)),
184  onlyTrueDeps_(parent.onlyTrueDeps_), mf_(parent.mf_) {
185 }
186 
187 
189 }
190 
191 
192 /**
193  * Creates a false dependency edge introduced when the given virtual
194  * reg is assigned the given physical register.
195  *
196  * Does not add the edge to the graph. Note, only creates a single edge
197  * although in a multi-BB DDG there is usually many in case edge
198  * spans CFG branch points. Returns a pair with NULLs in case no false dep is
199  * introduced.
200  */
201 std::pair<MIDDGNode*, MIDDGNode*>
203 
204  MIDDGNode* null = NULL;
205  std::pair<MIDDGNode*, MIDDGNode*> none = std::make_pair(null, null);
206 
207 
208  if (lastPhysRegUsers_.find(physReg) == lastPhysRegUsers_.end()) {
209  return none;
210  }
211 
212  MIDDGNode* lastPhysRegUser = (*lastPhysRegUsers_.find(physReg)).second;
213 
214  if (this->vregDefiner(vreg) == NULL) {
215  // could not find a definer for the given vreg, thus probably
216  // a global register such as stack pointer, there won't be
217  // many assignment possibilities for them anyways
218  return none;
219  }
220  MIDDGNode* vregDefiner = this->vregDefiner(vreg);
221  MIDDGNode* lastVregUser = this->lastVregUser(vreg);
222 
223  MIDDGNode* lastPhysRegDefiner = NULL;
224  if (lastPhysRegDefiners_.find(physReg) != lastPhysRegDefiners_.end()) {
225  lastPhysRegDefiner = (*lastPhysRegDefiners_.find(physReg)).second;
226  }
227 
228  assert(vregDefiner != NULL);
229 
230  // the source and destination nodes for the introduced antidep
231  MIDDGNode* source = NULL;
232  MIDDGNode* dest = NULL;
233 
234  // the sequential instruction ordering defines the dep direction
236  lastPhysRegUser->sequentialAddress()) {
237  source = lastPhysRegUser;
238  dest = vregDefiner;
239  } else {
240  if (lastVregUser == NULL) {
241  // only writes to the vreg, thus it would be WaW
242  source = vregDefiner;
243  } else {
244  source = lastVregUser;
245  }
246 
247  if (lastPhysRegDefiner != NULL) {
248  dest = lastPhysRegDefiner;
249  } else {
250  dest = lastPhysRegUser;
251  }
252  }
253 
254  // ignore loop edges for now, but signal edges to itself as they are
255  // cheap false deps which should be treated as such
256  if (dest != source && hasPath(*dest, *source))
257  return none;
258 
259  return std::make_pair(source, dest);
260 }
261 
262 /**
263  * Returns the "height delta" of an antidep edge created in case the
264  * given virtual register is assigned the given physical register.
265  *
266  * Height delta is the difference between the DDG height of the source
267  * definer node and the DDG height of the latest read node of the physReg.
268  * The direction of the introduced false dep edge is determined from the
269  * sequential instruction order, direction is assumed to be from the
270  * earlier instruction to the later. Thus, an edge with 0 or greater height dep
271  * potentially constraints the schedule by potentially heightening the DDG.
272  * However, this is not generally the case in case the critical path length
273  * is not increased by the assignment.
274  *
275  * @param vreg The virtual register to test.
276  * @param physReg The physical register assigment to test.
277  * @return The height delta of the false dep from the assignment, or
278  * INT_MIN in case no false dep would be produced.
279  */
280 int
282 
283  std::pair<MIDDGNode*, MIDDGNode*> fdep =
284  createFalseDepEdge(vreg, physReg);
285 
286  int hdelta = INT_MIN;
287  if (fdep.first != NULL && fdep.second != NULL) {
288  if (fdep.first == fdep.second)
289  return -1; // treat fdep to itself as the least harmful one
290  hdelta =
291  maxSourceDistance(*fdep.first) - maxSourceDistance(*fdep.second);
292  }
293  return hdelta;
294 }
295 
296 MIDDGNode*
298  int lastUse = -1;
299  MIDDGNode* lastUser = NULL;
300  if (users_.find(vreg) == users_.end())
301  return NULL;
302 
303  NodeSet& users = (*users_.find(vreg)).second;
304  for (NodeSet::const_iterator i = users.begin(); i != users.end();
305  ++i) {
306  MIDDGNode* node = *i;
307  if (lastUse < node->sequentialAddress()) {
308  lastUse = node->sequentialAddress();
309  lastUser = node;
310  }
311  }
312  return lastUser;
313 }
314 
315 /**
316  * Checks if there is at least one preceeding node to the given node that
317  * defines or uses the given physical register.
318  *
319  * Also the uses in the same node are considered.
320  */
321 bool
323  const MIDDGNode& node, Register physReg) const {
324 
325  NodeSet pred = predecessors(node);
326  pred.insert(const_cast<MIDDGNode*>(&node));
327  for (NodeSet::const_iterator i = pred.begin(); i != pred.end(); ++i) {
328  MIDDGNode& p = (**i);
329  const llvm::MachineInstr* instr = p.machineInstr();
330  for (unsigned operand = 0; operand < instr->getNumOperands();
331  ++operand) {
332  const llvm::MachineOperand& mo = instr->getOperand(operand);
333  if (!mo.isReg())
334  continue;
335  if (mo.getReg() == physReg ||
336  (regAssignments_.find(mo.getReg()) != regAssignments_.end() &&
337  (*regAssignments_.find(mo.getReg())).second == physReg)) {
338  return true;
339  }
340  }
341 
342  if (instr->readsRegister(physReg) ||
343  instr->modifiesRegister(physReg, regInfo_)) {
344  return true;
345  }
346  }
347  return false;
348 }
349 
350 
351 /**
352  * Computes optimal top-down schedule assuming infinite resources and that
353  * each operation completes in one cycle.
354  */
355 void
357  smallestCycle_ = 0;
358  largestCycle_ = 0;
359  schedule_.clear();
360  for (int nc = 0; nc < nodeCount(); ++nc) {
361  MIDDGNode& n = node(nc);
362  int cycle = maxSourceDistance(n);
363  n.setOptimalCycle(cycle);
364  largestCycle_ = std::max(cycle, largestCycle_);
365  schedule_[cycle].push_back(&n);
366  }
367 }
368 
369 TCEString
371  std::ostringstream s;
372  s << "digraph " << name() << " {" << std::endl;
373 
374  const bool scheduled = nodeCount() > 1 && node(0).optimalCycle() != -1;
375 
376  if (scheduled) {
377  // print the "time line" to visualize the schedule
378  s << "\t{" << std::endl
379  << "\t\tnode [shape=plaintext];" << std::endl
380  << "\t\t";
381  const int smallest = smallestCycle_;
382  const int largest = largestCycle_;
383  for (int c = smallest; c <= largest; ++c) {
384  s << "\"cycle " << c << "\" -> ";
385  }
386  s << "\"cycle " << largest + 1 << "\"; "
387  << std::endl << "\t}" << std::endl;
388 
389  // print the nodes that have cycles
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) {
396  MIDDGNode& n = **i;
397  if (n.osalOperationName() == "llvm::DBG_VALUE")
398  continue;
400  continue;
401  s << "n" << n.nodeID() << "; ";
402  }
403  s << "}" << std::endl;
404  }
405  }
406 
407 
408  typedef std::map<TCEString, int> OpCountMap;
409  // Count how many times each operation could be potentially
410  // executed in parallel in an optimal schedule. This can direct
411  // the intial architecture design.
412  OpCountMap maxParallelOps;
413  // The operation mix. I.e., the static occurence of operations
414  // in the code.
415  OpCountMap operationMix;
416 
417  for (int c = smallest; c <= largest; ++c) {
418  std::list<MIDDGNode*> ops = schedule_[c];
419  if (ops.size() == 0) continue;
420 
421  std::map<TCEString, int> parallelOpsAtCycle;
422  for (std::list<MIDDGNode*>::iterator i = ops.begin();
423  i != ops.end(); ++i) {
424  MIDDGNode& n = **i;
425  TCEString opName = n.osalOperationName();
426  if (opName == "" || opName == "?jump") continue;
427  operationMix[opName]++;
428  parallelOpsAtCycle[opName]++;
429  }
430 
431  for (OpCountMap::const_iterator i = parallelOpsAtCycle.begin();
432  i != parallelOpsAtCycle.end(); ++i) {
433  TCEString opName = (*i).first;
434  int count = (*i).second;
435  maxParallelOps[opName] =
436  std::max(maxParallelOps[opName], count);
437  }
438  }
439 
440  const int COL_WIDTH = 14;
441  // print statistics of the graph as a comment
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;
447 
448  for (OpCountMap::const_iterator i = maxParallelOps.begin();
449  i != maxParallelOps.end(); ++i) {
450  TCEString opName = (*i).first;
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;
457  }
458  s << "*/" << std::endl;
459  }
460  // first print all the nodes and their properties
461  for (int i = 0; i < nodeCount(); ++i) {
462  Node& n = node(i);
463  if (n.osalOperationName() == "llvm::DBG_VALUE")
464  continue;
466  continue;
467 
468  s << "\tn" << n.nodeID()
469  << " [" << n.dotString();
470  if (isInCriticalPath(n))
471  s << ",shape=box,color=\"red\"";
472  s << "]; " << std::endl;
473  }
474 
475  // edges
476  for (int count = edgeCount(), i = 0; i < count ; ++i) {
477  Edge& e = edge(i);
478  Node& tail = tailNode(e);
479  Node& head = headNode(e);
480 
482  !isInCriticalPath(head))
483  continue;
484 
485  s << "\tn" << tail.nodeID() << " -> n"
486  << head.nodeID() << "["
487  << e.dotString();
488  if (isInCriticalPath(tail) && isInCriticalPath(head))
489  s << ",color=red";
490  s << "];" << std::endl;
491  }
492 
493  s << "}" << std::endl;
494 
495  return s.str();
496 
497 }
498 
499 /**
500  * Assigns the given physical register to the given virtual register.
501  *
502  * Does not yet add false dependence edges, just updates the last
503  * phys reg use bookkeeping.
504  */
505 void
507 
508  regAssignments_[vreg] = physReg;
509 
510  MIDDGNode* lastDefiner = vregDefiner(vreg);
511 
512  if (lastPhysRegDefiners_.find(physReg) != lastPhysRegDefiners_.end()) {
513  MIDDGNode* previousDefiner = lastPhysRegDefiners_[physReg];
514  if (lastDefiner == NULL ||
515  previousDefiner->sequentialAddress() >
516  lastDefiner->sequentialAddress()) {
517  lastDefiner = previousDefiner;
518  }
519  }
520  if (lastDefiner != NULL) {
521  lastPhysRegDefiners_[physReg] = lastDefiner;
522  }
523 
524  MIDDGNode* lastUser = NULL;
525  if (lastPhysRegUsers_.find(physReg) != lastPhysRegUsers_.end()) {
526  lastUser = lastPhysRegUsers_[physReg];
527  }
528 
529  MIDDGNode* lastVregUser = this->lastVregUser(vreg);
530  if (lastVregUser != NULL) {
531  if (lastUser == NULL ||
533  lastUser->sequentialAddress()) {
534  lastUser = lastVregUser;
535  }
536  }
537  if (lastUser != NULL) {
538  lastPhysRegUsers_[physReg] = lastUser;
539  }
540 
541  std::pair<MIDDGNode*, MIDDGNode*> fdep =
542  createFalseDepEdge(vreg, physReg);
543 
544  if (fdep.first != NULL && fdep.second != NULL &&
545  fdep.first != fdep.second) {
546  MIDDGEdge* edge = new MIDDGEdge(physReg, MIDDGEdge::DEP_WAR);
547  edges_.insert(edge);
548 #if 0
550  << "adding edge: " << edge->toString() << " from "
551  << fdep.first->sequentialAddress() << " to "
552  << fdep.second->sequentialAddress() << std::endl;
553 #endif
554  connectNodes(*fdep.first, *fdep.second, *edge);
555  }
556 }
557 
558 /**
559  * Try to figure out the name of the instruction opcode in OSAL,
560  * if available.
561  *
562  * If the operation with the produced name is not found in OSAL,
563  * llvm: is prepended to the name string.
564  */
565 TCEString
567  const llvm::TargetInstrInfo *TII =
568  machineInstr()->getParent()->getParent()->getTarget().
569  getSubtargetImpl(
570  machineInstr()->getParent()->getParent()->getFunction())->
571  getInstrInfo();
572  // If it's a custom operation call, try to figure out
573  // the called operation name and use it instead as the
574  // node label.
575  TCEString opName;
576  if (mi_->isInlineAsm()) {
577  unsigned numDefs = 0;
578  while (mi_->getOperand(numDefs).isReg() &&
579  mi_->getOperand(numDefs).isDef())
580  ++numDefs;
581  opName = mi_->getOperand(numDefs).getSymbolName();
582  } else {
583  opName = TII->getName(mi_->getOpcode()).str();
584  }
585 
586  // Clean up the operand type string encoded as
587  // lower case letter at the end of the string.
588  TCEString upper = opName.upper();
589  TCEString cleaned;
590  for (size_t i = 0; i < opName.size(); ++i) {
591  if (upper[i] == opName[i])
592  cleaned += opName[i];
593  else
594  break;
595  }
596 
597  OperationPool ops;
598  Operation& operation = ops.operation(cleaned.c_str());
599  if (operation.isNull())
600  return TCEString("llvm:") + opName;
601 
602  return cleaned;
603 }
604 
605 std::string
607  return (boost::format("label=\"%s\"") % osalOperationName()).str();
608 }
609 
MIDDGNode::osalOperationName
TCEString osalOperationName() const
Definition: MachineInstrDDG.cc:566
BoostGraph< MIDDGNode, MIDDGEdge >::predecessors
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
MIDDGEdge
Definition: MachineInstrDDG.hh:86
BoostGraph< MIDDGNode, MIDDGEdge >::connectNodes
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
MachineInstrDDG::largestCycle_
int largestCycle_
Definition: MachineInstrDDG.hh:197
OperationPool::operation
Operation & operation(const char *name)
Definition: OperationPool.cc:99
MIDDGNode::mi_
const llvm::MachineInstr * mi_
Definition: MachineInstrDDG.hh:81
MachineInstrDDG::lastPhysRegUsers_
std::map< Register, MIDDGNode * > lastPhysRegUsers_
Definition: MachineInstrDDG.hh:188
BoostGraph< MIDDGNode, MIDDGEdge >::tailNode
virtual Node & tailNode(const Edge &edge) const
BoostGraph< MIDDGNode, MIDDGEdge >::headNode
virtual Node & headNode(const Edge &edge) const
BoostGraph< MIDDGNode, MIDDGEdge >::node
Node & node(const int index) const
BoostGraph< MIDDGNode, MIDDGEdge >::hasPath
bool hasPath(MIDDGNode &src, const MIDDGNode &dest) const
BoostGraph< MIDDGNode, MIDDGEdge >::maxSourceDistance
int maxSourceDistance(const MIDDGNode &node) const
BoostGraph< MIDDGNode, MIDDGEdge >::NodeSet
std::set< MIDDGNode *, typename MIDDGNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
GraphNode::nodeID
int nodeID() const
MachineInstrDDG::lastPhysRegDefiners_
std::map< Register, MIDDGNode * > lastPhysRegDefiners_
Definition: MachineInstrDDG.hh:189
MIDDGNode::optimalCycle
int optimalCycle() const
Definition: MachineInstrDDG.hh:79
MachineInstrDDG::assignPhysReg
void assignPhysReg(Register vreg, Register physReg)
Definition: MachineInstrDDG.cc:506
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
BoostGraph< MIDDGNode, MIDDGEdge >::addNode
virtual void addNode(Node &node)
MachineInstrDDG::regInfo_
const llvm::TargetRegisterInfo * regInfo_
Definition: MachineInstrDDG.hh:201
BoostGraph< MIDDGNode, MIDDGEdge >::edgeCount
int edgeCount() const
TCEString::upper
TCEString upper() const
Definition: TCEString.cc:86
MachineInstrDDG.hh
MachineInstrDDG::allRegisters_
RegisterSet allRegisters_
Definition: MachineInstrDDG.hh:181
MIDDGEdge::toString
TCEString toString() const
Definition: MachineInstrDDG.hh:111
MachineInstrDDG::schedule_
std::map< int, std::list< MIDDGNode * > > schedule_
Definition: MachineInstrDDG.hh:198
assert
#define assert(condition)
Definition: Application.hh:86
MIDDGNode::setOptimalCycle
void setOptimalCycle(int cycle)
Definition: MachineInstrDDG.hh:78
MachineInstrDDG
Definition: MachineInstrDDG.hh:140
MachineInstrDDG::createFalseDepEdge
std::pair< MIDDGNode *, MIDDGNode * > createFalseDepEdge(Register vreg, Register physReg) const
Definition: MachineInstrDDG.cc:202
LLVMTCECmdLineOptions.hh
MIDDGEdge::DEP_WAR
@ DEP_WAR
Definition: MachineInstrDDG.hh:90
TCETargetMachine.hh
MachineInstrDDG::lastVregUser
MIDDGNode * lastVregUser(Register vreg) const
Definition: MachineInstrDDG.cc:297
Application.hh
MachineInstrDDG::preceedingNodeUsesOrDefinesReg
bool preceedingNodeUsesOrDefinesReg(const MIDDGNode &node, Register physReg) const
Definition: MachineInstrDDG.cc:322
MIDDGNode
Definition: MachineInstrDDG.hh:58
MachineInstrDDG::definers_
DefinerMap definers_
Definition: MachineInstrDDG.hh:183
Operation.hh
MIDDGEdge::dotString
TCEString dotString() const
Definition: MachineInstrDDG.hh:106
MIDDGNode::dotString
std::string dotString() const
Definition: MachineInstrDDG.cc:606
BoostGraph< MIDDGNode, MIDDGEdge >::hasNode
bool hasNode(const Node &) const
Operation
Definition: Operation.hh:59
MachineInstrDDG::smallestCycle_
int smallestCycle_
Definition: MachineInstrDDG.hh:196
MachineInstrDDG::~MachineInstrDDG
virtual ~MachineInstrDDG()
Definition: MachineInstrDDG.cc:188
BoostGraph< MIDDGNode, MIDDGEdge >::edge
virtual Edge & edge(const int index) const
MachineInstrDDG::dotString
TCEString dotString() const
Definition: MachineInstrDDG.cc:370
BoostGraph< MIDDGNode, MIDDGEdge >::isInCriticalPath
bool isInCriticalPath(const MIDDGNode &node) const
Definition: BoostGraph.hh:179
IGNORE_COMPILER_WARNING
#define IGNORE_COMPILER_WARNING(X)
Definition: CompilerWarnings.hh:51
MachineInstrDDG::computeOptimalSchedule
void computeOptimalSchedule()
Definition: MachineInstrDDG.cc:356
MachineInstrDDG::users_
UserMap users_
Definition: MachineInstrDDG.hh:184
MachineInstrDDG::nodes_
NodeSet nodes_
Definition: MachineInstrDDG.hh:186
Operation::isNull
bool isNull() const
false
find Finds info of the inner loops in the false
Definition: InnerLoopFinder.cc:81
AssocTools.hh
MachineInstrDDG::Register
unsigned Register
Definition: MachineInstrDDG.hh:143
TCEString
Definition: TCEString.hh:53
POP_COMPILER_DIAGS
#define POP_COMPILER_DIAGS
Definition: CompilerWarnings.hh:68
MachineInstrDDG::edges_
std::set< MIDDGEdge * > edges_
Definition: MachineInstrDDG.hh:187
BoostGraph
Definition: BoostGraph.hh:83
OperationPool
Definition: OperationPool.hh:52
BoostGraph< MIDDGNode, MIDDGEdge >::name
virtual const TCEString & name() const
BoostGraph< MIDDGNode, MIDDGEdge >::nodeCount
int nodeCount() const
MachineInstrDDG::falseDepHeightDelta
int falseDepHeightDelta(Register vreg, Register physReg) const
Definition: MachineInstrDDG.cc:281
MachineInstrDDG::printOnlyCriticalPath_
bool printOnlyCriticalPath_
Definition: MachineInstrDDG.hh:203
OperationPool.hh
MachineInstrDDG::vregDefiner
MIDDGNode * vregDefiner(Register vreg) const
Definition: MachineInstrDDG.hh:156
MIDDGNode::sequentialAddress
int sequentialAddress() const
Definition: MachineInstrDDG.hh:73
MIDDGNode::machineInstr
const llvm::MachineInstr * machineInstr() const
Definition: MachineInstrDDG.hh:72
CompilerWarnings.hh
MachineInstrDDG::regAssignments_
RegisterMap regAssignments_
Definition: MachineInstrDDG.hh:190
MachineInstrDDG::MachineInstrDDG
MachineInstrDDG(const MachineInstrDDG &parent)
Definition: MachineInstrDDG.cc:181