OpenASIP  2.0
ProgramDependenceGraph.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 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 ProgramDependenceGraph.cc
26  *
27  * Implementation of prototype of graph-based program representation:
28  * declaration of the program dependence graph.
29  *
30  * @author Vladimir Guzma 2006 (vladimir.guzma-no.spam-tut.fi)
31  * @note rating: red
32  */
33 
34 #include <utility>
35 
36 // include this before boost to avoid deprecation
37 // warnings
38 #include "hash_set.hh"
39 
40 #include <boost/graph/depth_first_search.hpp>
41 #include <boost/graph/properties.hpp>
42 #include <boost/graph/strong_components.hpp>
43 #include <boost/graph/graph_utility.hpp>
44 #include <boost/graph/topological_sort.hpp>
45 #include <boost/graph/exception.hpp>
46 #include <boost/timer.hpp>
47 #include <boost/format.hpp>
48 #include <boost/graph/graphviz.hpp>
49 
51 #include "UniversalMachine.hh"
52 #include "Procedure.hh"
53 #include "POMDisassembler.hh"
54 #include "MapTools.hh"
55 #include "Exception.hh"
56 #include "MoveGuard.hh"
57 #include "SequenceTools.hh"
59 #include "InstructionReference.hh"
61 #include "TerminalFUPort.hh"
62 #include "ControlUnit.hh"
63 #include "HWOperation.hh"
64 #include "Machine.hh"
65 #include "Guard.hh"
66 #include "MoveGuard.hh"
67 #include "Move.hh"
68 #include "Instruction.hh"
69 #include "Program.hh"
70 #include "DataDependenceGraph.hh"
71 #include "BasicBlock.hh"
72 
73 #define DEBUG_LEVEL 1
74 
76  // Boost destructor will delete nodes from graph
77  for (int i = 0; i < nodeCount(); i++) {
78  Node* n = &node(i);
79  delete n;
80  }
81  for (unsigned int i = 0; i < strongComponents_.size(); i++) {
82  strongComponents_[i].clear();
83  }
84  strongComponents_.clear();
85 }
86 
87 /**
88  * Constructor.
89  * Build Program Dependence Graph from Control and Data Dependence graphs.
90  * @param cdg Control Dependence Graph of procedure
91  * @param ddg Data Dependence Graph of procedure
92  */
95  DataDependenceGraph& ddg) :
97  cdg_(&cdg),
98  ddg_(&ddg),
99  entryNode_(NULL),
100  ddgEntryNode_(NULL),
101  insCount_(0),
102  wrongCounter_(0) {
103 
104  ControlToProgram cNodePNode;
105  BBToCD BBNodeCDNode;
106  MoveNodeToPDGNode movePD;
107  MovesInCD moveToCD;
108  program_ = cdg.program();
109 
110  // Creates PDG node for each region node of CDG
111  for (int i = 0; i < cdg.nodeCount(); i++) {
112  ControlDependenceNode& cnode = cdg.node(i);
113  if (cnode.isRegionNode()
114  || cnode.isEntryNode()
115  || cnode.isLoopEntryNode()
116  || cnode.isLoopCloseNode()) {
117 
120  if (cnode.isLoopCloseNode()) {
122  }
123  if (cnode.isLoopEntryNode()) {
125  }
126 
127  ProgramDependenceNode* newNode = new
128  ProgramDependenceNode(cnode, type);
129  if (cnode.isLastNode()) {
130  newNode->setLastNode();
131  }
132  addNode(*newNode);
133  cNodePNode.insert(
134  std::pair<ControlDependenceNode*, ProgramDependenceNode*>(
135  &cnode, newNode));
136  if (cnode.isEntryNode()) {
137  BBNodeCDNode.insert(
138  std::pair<BasicBlockNode*, ControlDependenceNode*>(
139  cnode.basicBlockNode(), &cnode));
140  entryNode_ = newNode;
141  }
142  } else {
143  BBNodeCDNode.insert(
144  std::pair<BasicBlockNode*, ControlDependenceNode*>(
145  cnode.basicBlockNode(), &cnode));
146  }
147  }
148  assert(entryNode_ != NULL && "Entry node of the graph was not defined!");
149  // Copies edges between region nodes of CDG into the PDG
150  for (int i = 0; i < cdg.edgeCount(); i++) {
151  ControlDependenceEdge& edge = cdg.edge(i);
154  headNode = &cdg.headNode(edge);
155  tailNode = &cdg.tailNode(edge);
156  // CDG predicate node is special type of BB node with 2 outgoing
157  // edges
158  // Entry node is special kind of BB, which we are also interested in
159  // here
160  if (!headNode->isBBNode()
161  && !headNode->isPredicateNode()
162  && (!tailNode->isBBNode() || tailNode->isEntryNode())
163  && !tailNode->isPredicateNode()) {
164  // headNode is one with arrow in boost graphs
165  ProgramDependenceNode* sourceNode;
166  ProgramDependenceNode* targetNode;
167  try {
168  sourceNode = MapTools::valueForKey<ProgramDependenceNode*>(
169  cNodePNode, tailNode);
170  targetNode = MapTools::valueForKey<ProgramDependenceNode*>(
171  cNodePNode, headNode);
172  } catch (const Exception& e) {
173  throw InvalidData(
174  __FILE__, __LINE__, __func__, e.errorMessageStack());
175  }
176  ProgramDependenceEdge* pEdge;
177  pEdge = new ProgramDependenceEdge(edge);
178  connectNodes(*sourceNode, *targetNode, *pEdge);
179  }
180  }
181 
182  // Add each MoveNode of DDG also to PDG
183  for (int i = 0; i < ddg.nodeCount(); i++) {
184  Node* newNode = NULL;
185  Node::NodeType typeOfNode = Node::PDG_NODE_MOVE;
186  // Guarded jumps and calls becomes predicates
187  MoveNode& node = ddg.node(i);
188  if (node.isMove() &&
189  node.move().isControlFlowMove() &&
190  !node.move().isUnconditional()) {
191  typeOfNode = Node::PDG_NODE_PREDICATE;
192  } else if (node.isMove() &&
193  node.move().isControlFlowMove() &&
194  node.move().isJump() &&
195  !node.move().isReturn()){
196  /// Ignore unconditional jumps
197  continue;
198  }
199  newNode = new ProgramDependenceNode(node, typeOfNode);
200  addNode(*newNode);
201  if(!node.isMove()) {
202  ddgEntryNode_ = newNode;
203  }
204  movePD.insert(std::pair<MoveNode*, ProgramDependenceNode*>(
205  &node, newNode));
206  }
207 
208  // Add the edges between MoveNodes in DDG
209  for (int j = 0; j < ddg.edgeCount(); j++) {
210  ProgramDependenceNode* pSource = NULL;
211  ProgramDependenceNode* pTarget = NULL;
212  DataDependenceEdge& edge = ddg.edge(j);
213  if (!MapTools::containsKey(movePD, &ddg.tailNode(edge))) {
214  continue;
215  }
216  pSource = MapTools::valueForKey<ProgramDependenceNode*>(
217  movePD, &ddg.tailNode(edge));
218  if (!MapTools::containsKey(movePD, &ddg.headNode(edge))) {
219  continue;
220  }
221  pTarget = MapTools::valueForKey<ProgramDependenceNode*>(
222  movePD, &ddg.headNode(edge));
223  ProgramDependenceEdge* pEdge;
224  pEdge = new ProgramDependenceEdge(edge);
225  connectNodes(*pSource, *pTarget, *pEdge);
226  }
227 
228  // edges between region nodes and move nodes
229  for (int i = 0; i < ddg.nodeCount(); i++) {
230  // Some jumps were not copied so we skip them when adding edges
231  MoveNode& node = ddg.node(i);
232  if (!MapTools::containsKey(movePD, &node)) {
233  continue;
234  }
235 
236  BasicBlockNode* b = NULL;
237  b = &ddg.getBasicBlockNode(node);
238  ControlDependenceNode* cNode = NULL;
239  if (!MapTools::containsKey(BBNodeCDNode, b)) {
240  throw InvalidData(
241  __FILE__, __LINE__, __func__,
242  "No Control Dependence Node for Basic Block Node!");
243  }
244  try {
245  cNode = MapTools::valueForKey<ControlDependenceNode*>(
246  BBNodeCDNode, b);
247  } catch (const Exception& e) {
248  throw InvalidData(
249  __FILE__, __LINE__, __func__, e.errorMessageStack());
250  }
251 
252  ProgramDependenceNode* pNode = NULL;
253  try {
254  pNode = MapTools::valueForKey<ProgramDependenceNode*>(
255  movePD, &node);
256  } catch (const Exception& e) {
257  throw InvalidData(
258  __FILE__, __LINE__, __func__, e.errorMessageStack());
259  }
260  if (pNode->isMoveNode() && pNode->moveNode().isMove() == false) {
261  /// Found dummy entry node of ddg, connect it to entry node of
262  /// pdg as well.
264  ProgramDependenceEdge* pEdge = new ProgramDependenceEdge(*cdgEdge);
265  connectNodes(entryNode(), *pNode, *pEdge);
266  continue;
267  }
268  if (!MapTools::containsKey(moveToCD, cNode)) {
269  std::vector<Node*> tmp;
270  tmp.push_back(pNode);
271  moveToCD[cNode] = tmp;
272  } else {
273  std::vector<Node*> tmp = moveToCD[cNode];
274  tmp.push_back(pNode);
275  moveToCD[cNode] = tmp;
276  }
277  // For each MoveNode, find in which Basic Block it was
278  // and all input edges that went into CDG for given Basic Block
279  // are also added to the MoveNode
280  for (int j = 0; j < cdg.inDegree(*cNode); j++) {
281  ControlDependenceNode* source;
282  source = &cdg.tailNode(cdg.inEdge(*cNode, j));
283  if (source->isRegionNode()
284  || source->isEntryNode()
285  || source->isLoopEntryNode()
286  || source->isLoopCloseNode()) {
287  ProgramDependenceEdge* pEdge;
288  pEdge = new
289  ProgramDependenceEdge(cdg.inEdge(*cNode, j));
290  ProgramDependenceNode* pSource = NULL;
291  try {
292  pSource = MapTools::valueForKey<ProgramDependenceNode*>(
293  cNodePNode, source);
294  } catch (const Exception& e) {
295  throw InvalidData(
296  __FILE__, __LINE__, __func__, e.errorMessageStack());
297  }
298  connectNodes(*pSource, *pNode, *pEdge);
299  } else {
300  abortWithError("The source of control dependence is not\
301  region node!");
302  }
303  }
304  if (pNode->isPredicateMoveNode() &&
305  pNode->moveNode().move().isJump()){
306  removeGuardedJump(cNodePNode, *pNode, *cNode);
307  removeNode(*pNode);
308  }
309  }
310  /// If CDG already has analysis of Region and EEC done, just copy
311  /// results
312  if (cdg.analyzed()) {
313  copyRegionEECComponent(cNodePNode, BBNodeCDNode, movePD, moveToCD);
314  }
315 }
316 
317 /**
318  * Remove guarded jumps from the graph, makes guard generating operation
319  * a predicated node and fixes the true and false edges in case the jump
320  * had inverted guard.
321  * @param cToP mapping between Control Dependence nodes of original CDG and
322  * newly created Program Dependence nodes in PDG.
323  * @param pNode Program Dependence Node containing guarded jump
324  * @param cNode Control Dependence node which included guarded jump in CDG
325  */
326 void
328  ControlToProgram& cToP,
329  ProgramDependenceNode& pNode,
330  ControlDependenceNode& cNode) {
331 
332  ProgramDependenceNode* guardSource = NULL;
333  bool isInverted = pNode.moveNode().move().guard().isInverted();
334  if (inDegree(pNode) != 2) {
335  /// This used to be error, but now it possible
336  if(Application::verboseLevel() > 0) {
337  Application::logStream() << (boost::format(
338  "Guarded jump (%s) has inDegree different from 2! Degree =%d.\n")
339  % pNode.toString() % inDegree(pNode)).str();
340  EdgeSet e = inEdges(pNode);
341  for (EdgeSet::iterator ei = e.begin(); ei != e.end(); ei++) {
342  Node* n = & tailNode(**ei);
343  Application::logStream() << n->toString() << " "
344  << (*ei)->toString() << " ";
345  }
346  }
347  }
348  for (int i = 0; i < inDegree(pNode); i++) {
349  if (inEdge(pNode,i).isDataDependence()) {
350  guardSource = &tailNode(inEdge(pNode,i));
351  break;
352  }
353  }
354  if (guardSource == NULL) {
355  throw InvalidData(
356  __FILE__, __LINE__, __func__,
357  "Guarded jump did not have source of guard defined!");
358  }
359  guardSource->setPredicateMoveNode();
360  /// All incoming control dependence edges into the predicate node
361  /// are also incoming edges to the guard, since they were in same
362  /// block in CDG
363  for (int j = 0; j < cdg_->outDegree(cNode); j++) {
364  ControlDependenceNode* target;
365  target = &cdg_->headNode(cdg_->outEdge(cNode, j));
366  if (target->isRegionNode()
367  || target->isLoopEntryNode()
368  || target->isLoopCloseNode()) {
369  ProgramDependenceEdge* pEdge;
370  ControlDependenceEdge* newEdge = &cdg_->outEdge(cNode, j);;
371  if (isInverted) {
372  newEdge->invertEdgePredicate();
373  }
374  pEdge = new ProgramDependenceEdge(*newEdge);
375  ProgramDependenceNode* pTarget;
376  try {
377  pTarget = MapTools::valueForKey<ProgramDependenceNode*>(
378  cToP, target);
379  } catch (const Exception& e) {
380  throw InvalidData(
381  __FILE__, __LINE__, __func__, e.errorMessageStack());
382  }
383 
384  connectNodes(*guardSource, *pTarget, *pEdge);
385  } else {
386  throw InvalidData(
387  __FILE__, __LINE__, __func__,
388  "Basic block with guarded jump does not have"
389  " Region nodes as control dependent!");
390  }
391  }
392 }
393 /**
394  * Performs serialization of ProgramDependenceGraph, turning it into
395  * Control Flow Graph.
396  *
397  * @return ControlFlowGraph representation of PDG
398  * @throw InvalidData in case serialization of graph is not possible
399  */
400 bool
402 
404  Application::logStream() << (boost::format(
405  "\tStarting PDG serialization for %s with %d nodes and %d edges.\n")
406  % name() % nodeCount() % edgeCount()).str();
407  }
408 
409  /// Created filtered PDG graph containing only control dependence edges
410  CDGFilter<Graph> filter(graph_);
411  FilteredCDG filteredCDG = FilteredCDG(graph_, filter);
412  boost::timer timer;
413  long elapsed = 0;
414  /// Detect strong components if they were not detected in CDG and transferred
415  if (!cdg_->analyzed()) {
416  PDGOrderMap componentMap;
417  DescriptorMap rootMap;
418  /// Modifies graph_ with added close nodes and close edges
419  int componentCount = detectStrongComponents(
420  componentMap, rootMap, filteredCDG);
421  elapsed = static_cast<long>(timer.elapsed());
423  Application::logStream() << (boost::format(
424  "\t\tStrong components:%d components, %d minutes and %d seconds.\n")
425  % componentCount % (elapsed/60) % (elapsed%60)).str();
426  }
427  }
428 
429  /// map to store post order information for all the nodes of a graph
430  PDGOrderMap lastMap;
431  PDGOrder lastOrder(lastMap);
432  /// map to store color information during dfs
433  ColorMap colorMap;
434  Color colorsDFS(colorMap);
435  int fStamp(-1);
436  /// boost::on_finish_vertex will give us post order numbering
437  boost::time_stamper<PDGOrder, int, boost::on_finish_vertex>
438  lastOrderStamper(lastOrder, fStamp);
439  timer.restart();
440  /// Computes post order of all the nodes in PDG
441  boost::depth_first_visit(
442  filteredCDG, descriptor(entryNode()),
443  boost::make_dfs_visitor(lastOrderStamper), colorsDFS);
444  elapsed = static_cast<long>(timer.elapsed());
446  Application::logStream() << (boost::format(
447  "\t\tPost order: %d minutes and %d seconds.\n")
448  % (elapsed/60) % (elapsed%60)).str();
449  }
450  /// If not computed on CDG and copied, computes 'region' information for
451  /// all nodes of a graph
452  if (!cdg_->analyzed()) {
453  timer.restart();
454  computeRegionInfo(lastMap, filteredCDG);
455  elapsed = static_cast<long>(timer.elapsed());
457  Application::logStream() << (boost::format(
458  "\t\tRegion: %d minutes and %d seconds.\n")
459  % (elapsed/60) % (elapsed%60)).str();
460  }
461  /// If not computed on CDG and copied, computes 'eec' information for
462  /// all nodes of a graph
463  timer.restart();
464  computeEECInfo(lastMap, filteredCDG);
465  elapsed = static_cast<long>(timer.elapsed());
467  Application::logStream() << (boost::format(
468  "\t\tEEC: %d minutes and %d seconds.\n")
469  % (elapsed/60) % (elapsed%60)).str();
470  }
471  }
472 
473  timer.restart();
474  /// If CDG comes analyzed we need to add region and eec info for
475  /// dummy ENTRYNODE of DDG. By it's definition, ENTRYNODE is leaf
476  /// in terms of control dependence, region == eec
477  if(cdg_->analyzed() && ddgEntryNode_ != NULL) {
478  Node::NodesInfo finalNodesInfo;
479  regionHelper(ddgEntryNode_, filteredCDG, finalNodesInfo);
480  for (Node::NodesInfo::iterator k = finalNodesInfo.begin();
481  k != finalNodesInfo.end(); k++) {
483  ddgEntryNode_->addToEEC(**k);
484  }
485  }
486  return true;
487 #if 0
488  /// Compute actual relations between sibling nodes. Move Data Dependence
489  /// edges to root's of subgraph if they connect subgraph with outside
490  /// nodes
491  ///computeRelations(lastMap, filteredCDG);
492  elapsed = static_cast<long>(timer.elapsed());
494  Application::logStream() << (boost::format(
495  "\t\tRelations: %d minutes and %d seconds.\n")
496  % (elapsed/60) % (elapsed%60)).str();
497  }
499  Application::logStream() << (boost::format(
500  "Procedure %s has %d nodes and %d edges.\n")
501  % name() % nodeCount() % edgeCount()).str();
502  }
503  //writeToDotFile(name() + "_pdgSerialized.dot");
504  //disassemble();
505  return true;
506 #endif
507 }
508 
509 /**
510  * Detects all strong components of a PDG graph (loops). Strong components are
511  * maximal sets of nodes that are reachable from each other. Each node is member
512  * of some component. If it is not in loop then node is components of it's own.
513  * Augments graph with loop entry and close nodes.
514  * Works iteratively, first detects maximal component, then proceeds to ones
515  * that are "embedded".
516  *
517  * @param components After return contains for each node number of component
518  * to which node belongs
519  * @param roots After return contains for each node a node that is root of
520  * component to which node belongs
521  * @return returns number of components in a graph
522  */
523 int
525  PDGOrderMap& components,
526  DescriptorMap& roots,
527  FilteredCDG& cdg) {
528 
529  std::vector<std::pair<Node*, Node*> > backEdges;
530  int componentCount = 0;
531  int currentComponents = 0;
532  int numberOfNodes = 0;
533 
534  /// Will repeat until all the strong components will be found
535  /// Including weirdly nested :-)
536  do {
537  PDGOrder componentOrder(components);
538  Descriptors componentRoots(roots);
539  currentComponents = 0;
540  /// Node count will change with addition of close nodes
541  numberOfNodes = boost::num_vertices(cdg);
542  currentComponents = boost::strong_components(
543  cdg, componentOrder, boost::root_map(componentRoots));
544 
545  // for each component add vector of nodes that belongs to it
546  std::vector<std::set<Node*> > componentVector;
547  componentVector.resize(componentCount + currentComponents);
548 
549  /// If the number of components is identical to number of nodes
550  /// there are no loops in graph
551  if (currentComponents == numberOfNodes) {
552  componentCount = strongComponents_.size();
553  break;
554  }
555 
556  /// Add to strong components only those which are loops
557  /// Store them as Node*, use of descriptors is not possible
558  /// due to later addition of Nodes which will invalidate
559  /// descriptors
560  for (PDGOrderMap::iterator iterA = components.begin();
561  iterA != components.end(); iterA ++) {
562  Node* cNode = cdg[(*iterA).first];
563  componentVector[(*iterA).second].insert(cNode);
564  }
565  for (unsigned int i = componentCount; i < componentVector.size(); i++){
566  if (componentVector[i].size() > 1) {
567  std::set<Node*>& vector = componentVector[i];
568  std::set<Node*> ref;
569  int componentsSize = strongComponents_.size();
570  for (std::set<Node*>::iterator iterB = vector.begin();
571  iterB != vector.end();
572  iterB++) {
573  ref.insert(*iterB);
574  // Set component number
575  if ((*iterB)->component() == -1){
576  (*iterB)->setComponent(componentsSize);
577  }
578  }
579  strongComponents_.push_back(ref);
580  }
581  }
582 
583  /// Detects all loop entry nodes
584  /// Stores Nodes which are identified as loop entry nodes
585  /// together with number to which loop they belong
586  std::vector<std::pair<Node*,int> > newEntry;
587  /// for each entry node, collect edges that points to it from outside
588  /// the loop, deals only with newly added components
589  std::map<Node*, std::vector<Node*> > incomingToEntry;
590  for (unsigned int i = componentCount;
591  i < strongComponents_.size();
592  i++) {
593  std::set<Node*>& nodes = strongComponents_[i];
594  for (std::set<Node*>::iterator iterD = nodes.begin();
595  iterD != nodes.end();
596  iterD++) {
597 
599  vec = descriptor(**iterD);
600  FilteredInEdgePair edges = boost::in_edges(vec, cdg);
601  for (FilteredInEdgeIter ei = edges.first;
602  ei != edges.second;
603  ++ei) {
604 
605  Node* testedNode = cdg[boost::source(*ei, cdg)];
606  if (nodes.find(testedNode) == nodes.end()) {
607  /// tail of the edge is not inside component
608  /// it is external edge making this node loop entry
609  if (!(*iterD)->isLoopEntryNode(i)) {
610  (*iterD)->setLoopEntryNode(i);
611  newEntry.push_back(
612  std::pair<Node*,int>(*iterD,i));
613  incomingToEntry[*iterD].push_back(testedNode);
614  } else {
615  /// Several nodes points to loop entry node
616  /// we create dummy region node to collect those
617  /// edges
618  incomingToEntry[*iterD].push_back(testedNode);
619  }
620  }
621  }
622  }
623  }
624 
625  /// Adds close nodes for each loop entry node
626  /// Node and Edge descriptors are invalidated here!
627  for (unsigned int j = 0; j < newEntry.size(); j++) {
628  Node* loopNode = newEntry[j].first;
629  std::set<Node*>& nodes =
630  strongComponents_[newEntry[j].second];
631  /// Create one "close" node for each loop entry
632  Node* close = new Node(Node::PDG_NODE_LOOPCLOSE);
633  close->setComponent(newEntry[j].second);
634  addNode(*close);
635 
636  /// Close node is also part of component
637  strongComponents_[newEntry[j].second].insert(close);
638 
640  vec = descriptor(*loopNode);
641  FilteredInEdgePair edges = boost::in_edges(vec, cdg);
642  std::vector<Edge*> storeEdges;
643  /// Redirect edges to loop entry from inside the loop
644  /// to loop close node. Collect edges that needs redirecting
645  for (FilteredInEdgeIter ei = edges.first;
646  ei != edges.second;
647  ++ei) {
648  Node* sourceNode = cdg[boost::source(*ei, cdg)];
649  if (nodes.find(sourceNode) != nodes.end()){
650  /// store edges that will have to be moved
651  Edge* edge = cdg[*ei];
652  storeEdges.push_back(edge);
653  }
654  }
655  /// Actually redirect edges
656  for (unsigned int counter = 0;
657  counter < storeEdges.size();
658  counter++) {
659  moveInEdge(*loopNode, *close, *storeEdges[counter]);
660  }
661  /// Back edge will be added later, after all loops are found
662  backEdges.push_back(
663  std::pair<Node*, Node*>(close, loopNode));
664 
665  /// Close node is also added to unfiltered pdg, as well as edges
666  /// so we can test it directly there and not on filtered graph
667  if (inDegree(*close) == 0) {
668  TCEString msg = "Close node for loop entry node ";
669  msg += loopNode->toString() + " was not connected!";
670  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
671  }
672  /// In case loop entry has multiple incoming edges
673  /// outside loop, we add new region to group them together
674  /// This can be also on original pdg, no need to use filtered
675  /// version
676  std::vector<Node*> tmp =
677  MapTools::valueForKey<std::vector<Node*> >(
678  incomingToEntry, loopNode);
679  if (tmp.size() > 1) {
680  /// Creates new artificial region node without equivalent
681  /// one in CDG
682  Node* collect = new Node();
683  addNode(*collect);
684  for (unsigned int i = 0; i < tmp.size(); i++) {
685  Node* input = tmp[i];
686  EdgeDescriptor ed = connectingEdge(*input, *loopNode);
687  Edge* e = graph_[ed];
688  moveInEdge(*loopNode, *collect, *e);
689  }
690  ProgramDependenceEdge* pdgEdge =
691  new ProgramDependenceEdge();
692  connectNodes(*collect, *loopNode, *pdgEdge);
693  }
694  }
695  newEntry.clear();
696  componentCount = strongComponents_.size();
697  } while (true);
698 
699  /// Add edges from close nodes to their respective loop entries
700  for (unsigned int i = 0; i < backEdges.size(); i++) {
701  ProgramDependenceEdge* pdgEdge =
704  connectNodes(*backEdges[i].first, *backEdges[i].second, *pdgEdge);
705  }
706 
707 #if 0
708  for (unsigned int i = 0; i < strongComponents_.size() ; i++) {
709  std::cerr << "\tComponent: " << i << std::endl;
710  for (std::set<Node*>::iterator iter = strongComponents_[i].begin();
711  iter != strongComponents_[i].end(); iter++) {
712  std::cerr << "\t\t" << (*iter)->toString() << std::endl;
713  }
714  std::cerr << std::endl;
715  }
716 #endif
717  return componentCount;
718 }
719 
720 /**
721  * Compute the "region" information for each node of graph. Region is used to
722  * compute "eec" to determine order in which sibling subgraphs will be in
723  * resulting cfg.
724  *
725  * "Region" of node X is set of nodes that will be executed in case is X
726  * executed.
727  *
728  * @param orderMap post order map of PDG graph, nodes will be augmented with
729  * "region" information.
730  * @param cdg Program Dependence Graph filtered to us only control dependence
731  * edges.
732  */
733 void
735  const PDGOrderMap& orderMap,
736  FilteredCDG& cdg){
737 
738  int mapSize = orderMap.size();
739  if (mapSize == 0) {
740  throw ModuleRunTimeError(__FILE__, __LINE__, __func__,
741  "No nodes in CDG graph for " + name() + "!");
742  }
743  /// Compute "region" information using reverse post-order processing
744  /// Node descriptors in filtered graph are identical to original graph
745  /// we only care about edge filtering here
746  for (int i = mapSize -1 ; i >= 0 ; i--) {
747  NodeDescriptor des =
748  MapTools::keyForValue<NodeDescriptor>(orderMap,i);
749  Node* node = graph_[des];
750  if (!node->isLoopEntryNode()) {
751  /// For non loop entry nodes, simply compute region info
752  /// and store it in the node
753  Node::NodesInfo finalNodesInfo;
754  regionHelper(node, cdg, finalNodesInfo);
755  for (Node::NodesInfo::iterator k = finalNodesInfo.begin();
756  k != finalNodesInfo.end(); k++) {
757  node->addToRegion(**k);
758  }
759 
760  } else if (node->region().size() == 0) {
761  /// for loop entry node, find all other entry nodes
762  /// of the same loop (component)
763  /// final region info will be intersection of region info from
764  /// all the entry nodes in the same loop
765  /// it will be same for all the nodes too (they are reachable)
766  std::vector<Node*> entries;
767  std::set<Node*> component = strongComponents_[node->component()];
768  for (std::set<Node*>::iterator si = component.begin();
769  si != component.end(); si++) {
770  /// Check if node is loop entry node of tested component
771  if ((*si)->isLoopEntryNode(node->component())) {
772  entries.push_back(*si);
773  }
774  }
775  Node::NodesInfo finalNodesInfo;
776  for (unsigned int i = 0; i < entries.size(); i++) {
777  /// for every entry node of the loop compute region info
778  Node* entryNode = entries[i];
779  regionHelper(entryNode, cdg, finalNodesInfo);
780  }
781  for (unsigned j = 0; j < entries.size(); j++) {
782  Node* result = entries[j];
783  for (Node::NodesInfo::iterator k = finalNodesInfo.begin();
784  k != finalNodesInfo.end();
785  k++) {
786  result->addToRegion(**k);
787  }
788  }
789  }
790  }
791 }
792 
793 /**
794  * Compute the "eec" information for each node of graph. EEC is used to
795  * determine order in which sibling subgraphs needs to be scheduled in
796  * resulting cfg.
797  *
798  * "eec" of node X is set of nodes that will be executed in case any of the
799 nodes
800  * in subgraph of X will be executed.
801  *
802  * @param orderMap post order map of PDG graph, nodes augmented with
803  * "region" information, "eec" information will be added.
804  */
805 void
807  const PDGOrderMap& orderMap,
808  FilteredCDG& filteredCDG) {
809 
810  int mapSize = orderMap.size();
811 
812  for (int i = 0; i < mapSize; i++) {
813  NodeDescriptor des =
814  MapTools::keyForValue<NodeDescriptor>(
815  orderMap, i);
816  Node* node = graph_[des];
817  /// eec already exists, skip
818  if (node->eec().size() > 0) {
819  continue;
820  }
821  /// Found close node, eec(node) == intersection of all close
822  /// nodes of same loop region(node) (close node is as leaf node)
823  if (node->isLoopCloseNode() && node->eec().size() == 0) {
824  std::vector<Node*> closeNodes;
825  std::set<Node*> component = strongComponents_[node->component()];
826  // collect all loop close nodes of same loop
827  for (std::set<Node*>::iterator si = component.begin();
828  si != component.end(); si++) {
829  if ((*si)->isLoopCloseNode()) {
830  closeNodes.push_back(*si);
831  } else if ((*si)->isRegionNode()
832  || (*si)->isPredicateMoveNode()) {
833  (*si)->setLastNode();
834  }
835  }
836  Node::NodesInfo finalInfo;
837  Node::NodesInfo storeResult;
838  finalInfo.insert(node->region().begin(),node->region().end());
839  for (unsigned int i = 0; i < closeNodes.size(); i++) {
841  finalInfo, closeNodes[i]->region(), storeResult);
842  finalInfo.swap(storeResult);
843  storeResult.clear();
844  }
845  // add intersection of all region info to each close node in loop
846  for (unsigned j = 0; j < closeNodes.size(); j++) {
847  Node* result = closeNodes[j];
848  /// Close nodes eec must be empty before we get here
849  if(result->eec().size() != 0) {
850  TCEString msg = (boost::format(
851  "Close node %s in %s already has eec!\n")
852  % result->toString() % node->toString()).str();
853  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
854  }
855  for (Node::NodesInfo::iterator k = finalInfo.begin();
856  k != finalInfo.end(); k++) {
857  result->addToEEC(**k);
858  }
859  }
860 
861  } else if (boost::out_degree(descriptor(*node), filteredCDG) == 0) {
862  /// Found leaf node, eec(node) == region(node)
863  Node::NodesInfo regionX = node->region();
864  for (Node::NodesInfo::iterator t = regionX.begin();
865  t != regionX.end(); t++) {
866  node->addToEEC( **t);
867  }
868  } else {
869  /// Not a leaf node,
870  /// eec(x) = intersection(eec(children(x)) \ children(x)
871  Node::NodesInfo childNodes;
872  FilteredOutEdgePair edges =
873  boost::out_edges(descriptor(*node), filteredCDG);
874  for (FilteredOutEdgeIter ei = edges.first;
875  ei != edges.second;
876  ++ei) {
877  Node* testedNode = filteredCDG[boost::target(*ei, filteredCDG)];
878  childNodes.insert(testedNode);
879  }
880  Node::NodesInfo finalEEC;
881 
882  // Fill in candidate set with data from first successor
883  finalEEC.insert(
884  (*(childNodes.begin()))->eec().begin(),
885  (*(childNodes.begin()))->eec().end());
886  // compute intersection of successors eec
887  for(Node::NodesInfo::iterator j = childNodes.begin();
888  j != childNodes.end(); j++ ) {
889  Node::NodesInfo storeResult;
890  SetTools::intersection(finalEEC, (*j)->eec(), storeResult);
891  finalEEC.swap(storeResult);
892  storeResult.clear();
893  }
894  std::vector<Node*> result(finalEEC.size(), NULL);
895  // compute set difference, returns iterator pointing to
896  // .end() of the result
897  std::vector<Node*>::iterator resultEnd =
898  std::set_difference(finalEEC.begin(), finalEEC.end(),
899  childNodes.begin(), childNodes.end(), result.begin());
900  // push resulting eec into the node eec info
901  for (std::vector<Node*>::iterator t = result.begin();
902  t != resultEnd; t++) {
903  node->addToEEC(**t);
904  }
905  }
906  }
907 }
908 
909 /**
910  * Compare sibling nodes and determines their ordering relation
911  * based on eec information. In addition, nodes marked as lastNode
912  * are always ordered later in case ANY_ORDER is available.
913  *
914  * @param a First node to compare
915  * @param b Second node to compare
916  * @return value determining relation
917  */
920  bool AinA = false;
921  bool BinB = false;
922  bool BinA = false;
923  bool AinB = false;
924 
925 #ifdef AVOID_COMPILER_WARNINGS_REMOVE_THESE_LINES
926  bool extra = false;
927  if (a->isPredicateMoveNode() || b->isPredicateMoveNode()) {
928  extra = true;
929  }
930 #endif
931  /// Both a and b are simple statements, order is given by data dependencies
932  /// no need to test eec info
933  if (a->isMoveNode() && b->isMoveNode()
934  && !a->isPredicateMoveNode() && !b->isPredicateMoveNode()) {
935  return ANY_ORDER;
936  }
937  /// Find nodes relations in eec
938  if (AssocTools::containsKey(a->eec(), a)) {
939  AinA = true;
940  }
941  if (AssocTools::containsKey(b->eec(), b)) {
942  BinB = true;
943  }
944  if (AssocTools::containsKey(a->eec(), b)) {
945  BinA = true;
946  }
947  if (AssocTools::containsKey(b->eec(), a)) {
948  AinB = true;
949  }
950  //std::cerr << "AinA=" << AinA << ", BinB=" << BinB <<", AinB=" << AinB
951  // << ", BinA=" << BinA << std::endl;
952  if ((a->isLoopEntryNode() || a->isPredicateMoveNode())
953  && (b->isMoveNode() && !b->isPredicateMoveNode())
954  && AinA == true) {
955  if (a->isLastNode()) {
956  return B_BEFORE_A;
957  }
958  return ANY_ORDER;
959  }
960  if ((b->isLoopEntryNode() || b->isPredicateMoveNode())
961  && (a->isMoveNode() && !a->isPredicateMoveNode())
962  && BinB == true) {
963  if (b->isLastNode()) {
964  return A_BEFORE_B;
965  }
966  return ANY_ORDER;
967  }
968  if ((a->isLoopEntryNode() || a->isPredicateMoveNode())
969  && (b->isLoopEntryNode() || b->isPredicateMoveNode())
970  && AinA == true && BinB == true) {
971  if (a->isLastNode()) {
972  return B_BEFORE_A;
973  }
974  if (b->isLastNode()) {
975  return A_BEFORE_B;
976  }
977  return ANY_ORDER;
978  }
979  if ((a->isLoopEntryNode() || a->isPredicateMoveNode())
980  && (b->isMoveNode() && !b->isPredicateMoveNode())
981  && AinA == false) {
982  return B_BEFORE_A;
983  }
984  if ((b->isLoopEntryNode() || b->isPredicateMoveNode())
985  && (a->isMoveNode() && !a->isPredicateMoveNode())
986  && BinB == false) {
987  return A_BEFORE_B;
988  }
989  if ((a->isLoopEntryNode() || a->isPredicateMoveNode())
990  && (b->isLoopEntryNode() || b->isPredicateMoveNode())
991  && AinA == false && BinB == true) {
992  return B_BEFORE_A;
993  }
994  if ((b->isLoopEntryNode() || b->isPredicateMoveNode())
995  && (a->isLoopEntryNode() || a->isPredicateMoveNode())
996  && AinA == true && BinB == false) {
997  return A_BEFORE_B;
998  }
999  if ((a->isLoopEntryNode() || a->isPredicateMoveNode())
1000  && (b->isLoopEntryNode() || b->isPredicateMoveNode())
1001  && AinA == false && BinB == false) {
1002  //std::cerr << "\tUnorderable 1" << std::endl;
1003  return UNORDERABLE;
1004  }
1005  if ((a->isRegionNode() && AinB == true)
1006  && (b->isMoveNode() ||
1007  b->isLoopEntryNode() ||
1008  b->isPredicateMoveNode())){
1009  return B_BEFORE_A;
1010  }
1011  if ((b->isRegionNode() && BinA == true)
1012  && (a->isMoveNode() ||
1013  a->isLoopEntryNode() ||
1014  a->isPredicateMoveNode())){
1015  return A_BEFORE_B;
1016  }
1017  if ((a->isRegionNode() && AinB == false)
1018  && (b->isLoopEntryNode() || b->isPredicateMoveNode())
1019  && AinB == false) {
1020  //std::cerr << "\tUnorderable 2" << std::endl;
1021  return UNORDERABLE;
1022  }
1023  if ((b->isRegionNode() && BinA == false)
1024  && (a->isLoopEntryNode() || a->isPredicateMoveNode())
1025  && BinA == false) {
1026  //std::cerr << "\tUnorderable 3" << std::endl;
1027  return UNORDERABLE;
1028  }
1029  if ((a->isRegionNode() && AinB == false)
1030  && (b->isRegionNode() && BinA == true)) {
1031  return B_BEFORE_A;
1032  }
1033  if ((b->isRegionNode() && BinA == false)
1034  && (a->isRegionNode() && AinB == true)) {
1035  return A_BEFORE_B;
1036  }
1037  if ((a->isRegionNode() && AinB == false)
1038  && (b->isRegionNode() && BinA == false)) {
1039  return UNORDERABLE;
1040  }
1041  if ((a->isLoopCloseNode() && AinB == true)
1042  && (b->isMoveNode() || b->isPredicateMoveNode() || b->isLoopEntryNode()
1043  || b->isRegionNode())) {
1044  return B_BEFORE_A;
1045  }
1046  if ((b->isLoopCloseNode() && BinA == true)
1047  && (a->isMoveNode() || a->isPredicateMoveNode() || a->isLoopEntryNode()
1048  || a->isRegionNode())) {
1049  return A_BEFORE_B;
1050  }
1051  if ((a->isLoopCloseNode() && AinB == false)
1052  && (b->isPredicateMoveNode() || b->isLoopEntryNode()
1053  || b->isRegionNode())) {
1054  //std::cerr << "\tUnorderable 5" << std::endl;
1055  return UNORDERABLE;
1056  }
1057  if ((b->isLoopCloseNode() && BinA == false)
1058  && (a->isPredicateMoveNode() || a->isLoopEntryNode()
1059  || a->isRegionNode())) {
1060  //std::cerr << "\tUnorderable 6" << std::endl;
1061  return UNORDERABLE;
1062  }
1063  /// FIXME:
1064  /// Unique region node rule is broken when creating loop
1065  /// entry nodes (removing loop back edge) and creating new region for
1066  /// incoming edges into loop entry - there can be another region
1067  /// which already has same set of dependencies and loop entry was
1068  /// supposed to be child of that, but was not. Problem with detection
1069  /// of subsets of dependencies when creating region nodes!
1070  if ((a->isRegionNode() && AinB == true)
1071  && (b->isRegionNode() && BinA == true)) {
1072  Application::logStream() << (boost::format(
1073  "Found two regions with identical control dependencies. "
1074  "Known issue with CDG detection not reusing regions.\n")).str();
1075  if (a->isLastNode()) {
1076  return B_BEFORE_A;
1077  }
1078  if (b->isLastNode()) {
1079  return A_BEFORE_B;
1080  }
1081  return ANY_ORDER;
1082  }
1083  return ERROR;
1084 }
1085 
1086 /**
1087  * Returns entry node of the graph.
1088  * @return Entry node
1089  */
1092  if (entryNode_ == NULL ) {
1093  throw ModuleRunTimeError(
1094  __FILE__, __LINE__, __func__,
1095  "Trying to get entry node before it was defined!");
1096  }
1097  return *entryNode_;
1098 }
1099 
1100 /**
1101  * Helper function to compute actual region information for a node.
1102  * Called several times for a case when there are loop entry nodes
1103  * detected.
1104  *
1105  * @param node Node for which to compute region info
1106  * @param cdg Filtered PDG graph with only control dependence edges
1107  * @param finalNodesInfo stores actual computed region info
1108  */
1109 void
1111  Node* node,
1112  FilteredCDG& cdg,
1113  Node::NodesInfo& finalNodesInfo){
1114 
1115  NodeDescriptor des = descriptor(*node);
1116  std::vector<Node::NodesInfo> tmpResult;
1117  /// Find all incoming control dependence edges
1118  FilteredInEdgePair edges = boost::in_edges(des, cdg);
1119  for (FilteredInEdgeIter ei = edges.first;
1120  ei != edges.second;
1121  ++ei) {
1122  Node* previous = cdg[boost::source(*ei, cdg)];
1123  /// There is no Region info for Entry node
1124  if (previous->isRegionNode()
1125  || previous->isLoopEntryNode()) {
1126  if (previous->region().size() == 0 &&
1127  ! (previous == entryNode_)) {
1128  /// If parent's region is not yet computed (should be btw)
1129  /// compute it before continuing.
1130  Node::NodesInfo addedNodesInfo;
1131  regionHelper(previous, cdg, addedNodesInfo);
1132  for (Node::NodesInfo::iterator k = addedNodesInfo.begin();
1133  k != addedNodesInfo.end();
1134  k++) {
1135  previous->addToRegion(**k);
1136  }
1137 
1138 /* writeToDotFile(name() + "_broken.dot");
1139  TCEString msg = "Parent " + previous->toString();
1140  msg += " of node " + (*iter)->toString();
1141  msg += " has empty region information!";
1142  msg += " Procedure has " + Conversion::toString(nodeCount());
1143  msg += " nodes.";
1144  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);*/
1145  }
1146  /// region(node,parent) == region(parent) U children(parent)
1147  Node::NodesInfo tmp = previous->region();
1148  FilteredOutEdgePair edges =
1149  boost::out_edges(descriptor(*previous), cdg);
1150  for (FilteredOutEdgeIter ei = edges.first;
1151  ei != edges.second;
1152  ++ei) {
1153  Node* testedNode = cdg[boost::target(*ei, cdg)];
1154  tmp.insert(testedNode);
1155  }
1156  tmpResult.push_back(tmp);
1157  } else if (previous->isPredicateMoveNode()){
1158  /// region(node,parent) == region(parent)
1159  Node::NodesInfo tmp = previous->region();
1160  tmpResult.push_back(tmp);
1161  } else {
1162  assert(previous->isLoopCloseNode());
1163  }
1164  }
1165  /// fill in final region info with info from first of parents
1166  if (tmpResult.size() > 0) {
1167  finalNodesInfo.insert(
1168  tmpResult[0].begin(), tmpResult[0].end());
1169  }
1170  /// region(node) = intersection(region(node,parent(node)))
1171  /// for all parents. finalNodesInfo is already initialized from
1172  /// counter 0
1173  for (unsigned int l = 1; l < tmpResult.size(); l++) {
1174  Node::NodesInfo storeResult;
1176  finalNodesInfo, tmpResult[l], storeResult);
1177  finalNodesInfo.swap(storeResult);
1178  storeResult.clear();
1179  }
1180 }
1181 
1182 /**
1183  * "Sorts" all the child nodes of a region in topological order based on
1184  * their control and data dependencies.
1185  *
1186  * @param regionNode Region/Predicate node who's child nodes to process
1187  * @param filteredCDG Control Dependence subraph
1188  */
1189 void
1191  Node* regionNode,
1192  FilteredCDG& filteredCDG) {
1193 
1194  /// Get all child nodes of region node
1195  NodeDescriptor nodeDes = descriptor(*regionNode);
1196  FilteredOutEdgePair edges = boost::out_edges(nodeDes, filteredCDG);
1197  /// Store all child nodes, we will need to collect all edges
1198  /// to and from subgraph rooted by region
1199  NodeSet subgraphNodes;
1200  subgraphNodes.insert(regionNode);
1201  std::vector<std::pair<Node*, Node*> > newEdges;
1202  std::vector<std::pair<Node*, Node*> > unorderable;
1203  for (FilteredOutEdgeIter ei1 = edges.first;
1204  ei1 != edges.second;
1205  ++ei1) {
1206  NodeDescriptor des = boost::target(*ei1, filteredCDG);
1207  Node* node1 = graph_[des];
1208  subgraphNodes.insert(node1);
1209 
1210  /// node1 will be compared against all the other previously untested
1211  /// nodes
1212  FilteredOutEdgeIter ei2 = ei1;
1213  ei2++;
1214  for (; ei2 != edges.second; ++ei2) {
1215  Node* node2 = graph_[boost::target(*ei2, filteredCDG)];
1216  /// Test relation between siblings, should never return ERROR!
1217  CompareResult result = compareSiblings(node1, node2);
1218  switch(result) {
1219  case ERROR:
1220  if(Application::verboseLevel() > 0) {
1221  writeToDotFile(name() + "_pdg_broken.dot");
1222  node1->printRelations();
1223  node2->printRelations();
1224  }
1225  throw ModuleRunTimeError(
1226  __FILE__, __LINE__, __func__,
1227  (boost::format(
1228  "Ordering error for A='%s' and B='%s'")
1229  % node1->toString() % node2->toString()).str());
1230  case A_BEFORE_B:
1231  newEdges.push_back(std::pair<Node*, Node*>(node1, node2));
1232  break;
1233  case B_BEFORE_A:
1234  newEdges.push_back(std::pair<Node*, Node*>(node2, node1));
1235  break;
1236  case UNORDERABLE:
1237  if(Application::verboseLevel() >= 0) {
1238  Application::logStream() << (boost::format(
1239  "Nodes (%s) and (%s) can not "
1240  "be put into any order.\n")
1241  % node1->toString()% node2->toString()).str();
1242  }
1243  unorderable.push_back(
1244  std::pair<Node*, Node*>(node1, node2));
1245  break;
1246  case ANY_ORDER:
1247  break;
1248  }
1249 
1250  }
1251  }
1252  /// Move/copy edges between nodes "inside" subgraph and nodes outside the
1253  /// subgraph
1254  moveDDGedges(*regionNode, subgraphNodes, filteredCDG);
1255  /// Add actual control dependence edges for serialization
1256  for (unsigned int i = 0; i < newEdges.size(); i++) {
1257  ProgramDependenceEdge* direction = new ProgramDependenceEdge();
1258  connectNodes(*newEdges[i].first, *newEdges[i].second, *direction);
1259  }
1260  newEdges.clear();
1261  //return;
1262  /// Nodes of subgraph without it's root
1264  regionNode, subgraphNodes, graph_);
1265  /// No loop close edges or DDG loop edges
1266  BackFilter<Graph> backFilter(graph_);
1267  /// Create filtered graph
1268  Subgraph sub = Subgraph(graph_, backFilter, subgraph);
1269  /// Sort nodes of subgraph topologically
1270  std::vector<NodeDescriptor> sorted;
1271  try {
1272  boost::topological_sort(sub, std::back_inserter(sorted));
1273  } catch (boost::not_a_dag & x) {
1274  /// In case topological sort fails with graph not being DAG
1275  /// Write it out
1277  TCEString outName =
1278  name() + Conversion::toString(wrongCounter_) + "_notDAG.dot";
1279  wrongCounter_++;
1280  std::ofstream output(outName.c_str());
1281  boost::write_graphviz(output, sub,lb,lb);
1282 
1283  Application::logStream() << (boost::format(
1284  "Topological sort of %s(%s) failed.\n"
1285  "Most likely loop is present.\n")
1286  % name() % regionNode->toString()).str();
1287  return;
1288  } catch (...) {
1289  Application::logStream() << (boost::format(
1290  "Topological sort of %s(%s) failed.\n"
1291  "Most likely loop is present.\n")
1292  % name() % regionNode->toString()).str();
1293  return;
1294  }
1295 
1296  BasicBlockNode* lastBB = NULL;
1297  std::vector<BasicBlockNode*> leafBlocks;
1298  bool changeBB = false;
1299 
1300  for (std::vector<NodeDescriptor>::reverse_iterator iter = sorted.rbegin();
1301  iter != sorted.rend(); iter++) {
1302  Node* accessedNode = graph_[*iter];
1303  BasicBlockNode* bb = NULL;
1304 
1305  if(accessedNode->newFirstBB() != NULL) {
1306  // Child node is region or predicate and already has BBs
1307  // we will just link them
1308  bb = accessedNode->newFirstBB();
1309  if (regionNode->newFirstBB() == NULL) {
1310  assert(leafBlocks.size() == 0 && lastBB == NULL);
1311  /// It is first block so we add it as new first also to parent
1312  regionNode->setNewFirstBB(bb);
1313  }
1314  /// There was some previous node tested, we have to add edges
1315  if (lastBB != NULL) {
1316  assert(leafBlocks.size() == 0);
1317  /// Previously, statements created single basic block
1318  /// so we add edge from that to this one
1319  ControlFlowEdge* edge = NULL;
1320  /// If previous block ended with call we add CALL type of edge
1321  if (changeBB == true) {
1322  changeBB = false;
1323  edge = new
1326  } else {
1327  edge = new ControlFlowEdge();
1328  }
1329 /* Application::logStream() << (boost::format(
1330  "Adding edge from lastBB %s to %s in %s\n")
1331  % lastBB->toString() % bb->toString() % name()).str();*/
1332  newCFG_->connectNodes(*lastBB, *bb, *edge);
1333  std::cerr << "Adding for lastBB != NULL" << std::endl;
1334  createJump(lastBB, bb);
1335  /// clear lastBB, the edge was already added
1336 /* Application::logStream() << (boost::format(
1337  "\tChanged lastbb from %s to NULL\n")
1338  % lastBB->toString()).str();*/
1339  lastBB = NULL;
1340  leafBlocks.clear();
1341  }
1342 /* Application::logStream() << (boost::format(
1343  "\tStart adding leaf blocks for %s in region %s with bb %s\n")
1344  % accessedNode->toString() % regionNode->toString()
1345  % bb->toString()).str();*/
1346  addLeafEdges(leafBlocks, bb);
1347  /// leafs were processed, this node should have some leafs as well
1348  leafBlocks.clear();
1349  leafBlocks = accessedNode->leafBlocks();
1350  /// if we got this far, lastBB should be NULL
1351  assert(lastBB == NULL);
1352  /// Accessed node is loop entry, we add edge from corresponding
1353  /// loop close node to it.
1354  if (accessedNode->isLoopEntryNode()) {
1355  processLoopEntry(accessedNode, bb);
1356  }
1357  } else {
1358  /// We found single statement, time to add it to basic block
1359  if (lastBB == NULL || changeBB == true) {
1360  /// Time to create new BB
1361  TTAProgram::BasicBlock* block =
1363  insCount_++;
1364  bb = new BasicBlockNode(*block);
1365 /* Application::logStream() << (boost::format(
1366  "Create new BB %s in %s for %s\n")
1367  % bb->toString() % regionNode->toString() %
1368  accessedNode->toString()).str();*/
1369  newCFG_->addNode(*bb);
1370  if (regionNode->newFirstBB() == NULL) {
1371  /// We just created first BB for children of region
1372  /// so we set it as first BB
1373  regionNode->setNewFirstBB(bb);
1374  }
1375  /// Previous BB ended with CALL, so we link it to new one
1376  /// with call edge
1377  if (changeBB == true && lastBB != NULL) {
1378  changeBB = false;
1382  newCFG_->connectNodes(*lastBB, *bb, *edge);
1383  assert(leafBlocks.size() == 0);
1384  }
1385  /// Block just created is current lastBB
1386 /* Application::logStream() << (boost::format(
1387  "\tChanged lastbb to %s\n")
1388  %bb->toString()).str();*/
1389  lastBB = bb;
1390  }
1391  }
1392  if(accessedNode->isMoveNode()
1393  && accessedNode->moveNode().isMove()) {
1394  TTAProgram::Instruction* newIns =
1396  newIns->addMove(accessedNode->moveNode().movePtr());
1397  lastBB->basicBlock().add(newIns);
1398  insCount_++;
1399  if (accessedNode->moveNode().move().isCall()) {
1400  changeBB = true;
1401  }
1402  if (leafBlocks.size() > 0) {
1403 /* Application::logStream() << (boost::format(
1404  "\tStart adding leaf blocks: %s in region %s with bb %s\n")
1405  % accessedNode->toString() % regionNode->toString()
1406  % bb->toString()).str();*/
1407  addLeafEdges(leafBlocks, bb);
1408  /// Leaf blocks were added, we can clear them
1409  leafBlocks.clear();
1410  } else {
1411  if (Application::verboseLevel() > 2) {
1413  (boost::format(" Undetected case! %s inside %s\n")
1414  % accessedNode->toString() % regionNode->toString()
1415  ).str();
1416  }
1417  }
1418  }
1419  }
1420  if (leafBlocks.size() > 0) {
1421  regionNode->addLeafBlocks(leafBlocks);
1422  leafBlocks.clear();
1423  }
1424  if (lastBB != NULL) {
1425 /* Application::logStream() << (boost::format(
1426  "Add last bb %s as a leaf to %s\n")
1427  % lastBB->toString() % regionNode->toString()).str();*/
1428  regionNode->addLeafBlock(lastBB);
1429  }
1430  if(regionNode == entryNode_) {
1431  processEntry(regionNode->newFirstBB());
1432  }
1433  unorderable.clear();
1434 }
1435 
1436 /**
1437  * Computes relation between every pair of nodes in a graph that has
1438  * common parent.
1439  *
1440  * @param orderMap Post order map of a graph
1441  * @parem filteredCDG Filtered PDG with only control dependence edges
1442  */
1443 void
1445  const PDGOrderMap& orderMap,
1446  FilteredCDG& filteredCDG) {
1447 
1448  /// Process nodes in post order, guarantees child region/loopEntry/predicate
1449  /// nodes will be processed before their parent
1450  int mapSize = orderMap.size();
1451 
1452  cdg_->writeToDotFile(name() + "_originalCDG.dot");
1453 
1455  for (int i = 0; i < mapSize; i++) {
1456  NodeDescriptor des =
1457  MapTools::keyForValue<NodeDescriptor>(
1458  orderMap, i);
1459  Node* node = graph_[des];
1460  /// MoveNodes are skipped here, they are always children of region
1461  if (node->isRegionNode()
1462  || node->isLoopEntryNode()) {
1463  processRegion(node, filteredCDG);
1464  continue;
1465  }
1466  if (node->isPredicateMoveNode()){
1467  processPredicate(node, filteredCDG);
1468  continue;
1469  }
1470  if (node->isLoopCloseNode()) {
1472  continue;
1473  }
1474  }
1475  newCFG_->writeToDotFile(name() + "_newCFG.dot");
1476  writeToDotFile(name() + "_newPDG.dot");
1477 
1478 }
1479 
1480 /**
1481  * Helper method to move/copy DDG edges that connected subraph nodes with rest
1482  * of the graph to the root node of subgraph
1483  *
1484  * @param rootNode Root node of subgraph
1485  * @param subgraphNodes Nodes of the subgraph to test
1486  * @param filteredCDG Filtered cdg graph, containing only control dependence
1487 nodes
1488  */
1489 void
1491  Node& root,
1492  NodeSet& subgraphNodes,
1493  FilteredCDG& filteredCDG) {
1494 
1495  for (NodeSet::iterator iter = subgraphNodes.begin();
1496  iter != subgraphNodes.end();
1497  iter++) {
1498  /// Do not process root of a subtree, it is child of other node
1499  /// and will be processed later
1500  if ((*iter) == &root) {
1501  continue;
1502  }
1503  /// Test if target is region, predicate or loop node,
1504  /// those prefer copies
1505  bool copyInsteadOfMove = false;
1506  if (!(*iter)->isMoveNode()) {
1507  /// gets incoming control dependence edges of node
1508  /// more then one edge means node is reachable from several places
1509  int parentCount = boost::in_degree(descriptor(**iter), filteredCDG);
1510  if (parentCount > 1) {
1511  copyInsteadOfMove = true;
1512  }
1513  }
1514  /// Deal with incoming edges
1515  EdgeSet inputs = inEdges(**iter);
1516  for (EdgeSet::iterator ein = inputs.begin();
1517  ein != inputs.end();
1518  ein++) {
1519  /// No need to deal with control dependence edges or data dependence
1520  /// that had been "fixed" - meaning they are between nodes of same
1521  /// subtree (including edges between root of subtree and child node)
1522  if (!(*ein)->isDataDependence() || (*ein)->fixed()) {
1523  continue;
1524  }
1525  Node* tail = &tailNode(**ein);
1526  if (!AssocTools::containsKey(subgraphNodes, tail)) {
1527  Edge* testedEdge = *ein;
1528  EdgeSet inputEdges = connectingEdges(*tail, root);
1529  bool duplicateEdge = false;
1530  for (EdgeSet::iterator testIter = inputEdges.begin();
1531  testIter != inputEdges.end();
1532  testIter ++) {
1533  if (!(*testIter)->isDataDependence()) {
1534  continue;
1535  }
1536  if ((testedEdge->dataDependenceEdge().dependenceType() ==
1537  (*testIter)->dataDependenceEdge().dependenceType())
1538  &&
1539  (testedEdge->dataDependenceEdge().edgeReason() ==
1540  (*testIter)->dataDependenceEdge().edgeReason())) {
1541  /// Edges with identical properties already exists
1542  /// no need to copy or move, just remove edge
1543  duplicateEdge = true;
1544  }
1545  }
1546  if (copyInsteadOfMove && !duplicateEdge) {
1547  /// Creates copy of edge from outside subgraph
1548  /// to root of the graph
1549  copyInEdge(root, **ein, tail);
1550  } else if (duplicateEdge) {
1551  /// Edge is duplicate of already existing dependence
1552  removeEdge(**ein);
1553  } else {
1554  /// Moves edge from outside the subgraph to target root
1555  moveInEdge(**iter, root, **ein);
1556  }
1557  } else {
1558  /// Edge between nodes in subtree
1559  (*ein)->setFixed();
1560  }
1561  }
1562  /// Deal with outgoing edges
1563  EdgeSet outputs = outEdges(**iter);
1564  for (EdgeSet::iterator eout = outputs.begin();
1565  eout != outputs.end();
1566  eout++) {
1567  /// No need to deal with control dependence edges or data dependence
1568  /// that had been "fixed" - meaning they are between nodes of same
1569  /// subtree (including edges between root of subtree and child node)
1570  if (!(*eout)->isDataDependence() || (*eout)->fixed()) {
1571  continue;
1572  }
1573  Node* head = &headNode(**eout);
1574  if (!AssocTools::containsKey(subgraphNodes, head)) {
1575  Edge* testedEdge = *eout;
1576  EdgeSet outputEdges = connectingEdges(root, *head);
1577  bool duplicateEdge = false;
1578  for (EdgeSet::iterator testIter = outputEdges.begin();
1579  testIter != outputEdges.end();
1580  testIter ++) {
1581  if (!(*testIter)->isDataDependence()) {
1582  continue;
1583  }
1584  if ((testedEdge->dataDependenceEdge().dependenceType() ==
1585  (*testIter)->dataDependenceEdge().dependenceType())
1586  &&
1587  (testedEdge->dataDependenceEdge().edgeReason() ==
1588  (*testIter)->dataDependenceEdge().edgeReason())) {
1589  /// Edges with identical properties already exists
1590  /// no need to copy or move, just remove edge
1591  duplicateEdge = true;
1592  }
1593  }
1594  if (copyInsteadOfMove && !duplicateEdge) {
1595  /// Creates copy of edge from outside subgraph
1596  /// to root of the graph if such edge does not exists
1597  copyOutEdge(root, **eout, head);
1598  } else if (duplicateEdge) {
1599  /// Edge is duplicate of already existing dependence
1600  removeEdge(**eout);
1601  } else {
1602  /// Moves edge from outside the subgraph to target root
1603  moveOutEdge(**iter, root, **eout);
1604  }
1605  } else {
1606  /// Edge between nodes in subtree
1607  (*eout)->setFixed();
1608  }
1609  }
1610  }
1611 }
1612 
1613 /**
1614  * Copies Region and EEC information from CDG nodes to PDG. Only used if
1615  * "preprocessing" is done via CDG analysis. Copies also component members.
1616  *
1617  * @param cDNodeToPNode Map between CDG nodes and PDG nodes
1618  * @param bBlockToCDNode Map between basic blocks and CDG nodes
1619  * @param moveToPNode Map between move nodes and their PDG equivalents
1620  * @param moveToCD Map between CDG node and all PDG equivalents of it's content
1621  */
1622 void
1624  ControlToProgram& cDNodeToPNode,
1625  BBToCD& bBlockToCDNode,
1626  MoveNodeToPDGNode& /*moveToPNode*/,
1627  MovesInCD& moveToCD) {
1628 
1629  int componentCount = cdg_->componentCount();
1630  strongComponents_.resize(componentCount);
1631 
1632  for (int i = 0; i < nodeCount(); i++) {
1634  ControlDependenceNode* cNode = NULL;
1635 
1636  /// Find source of region and eec. In case node is move or predicate
1637  /// have to find parent CDG node
1638  if (node == entryNode_) {
1639  /// No region or eec info in entry
1640  continue;
1641  }
1642  if (node->isRegionNode()
1643  || node->isLoopEntryNode()
1644  || node->isLoopCloseNode()) {
1645  /// For non basic block/predicate nodes, we copied them so
1646  /// they will also be in 'region' and 'eec'.
1647  /// Set component info for nodes that are part of loop as well
1648  cNode = &node->cdgNode();
1649  if (cNode->component() != -1) {
1650  node->setComponent(cNode->component());
1651  strongComponents_[node->component()].insert(node);
1652  }
1653  } else {
1654  const BasicBlockNode* BB =
1656  if (MapTools::containsKey(bBlockToCDNode, BB)) {
1657  cNode =
1658  MapTools::valueForKey<ControlDependenceNode*>(
1659  bBlockToCDNode, BB);
1660  } else {
1661  throw InvalidData(__FILE__, __LINE__, __func__,
1662  "No CD node for basic block!" + BB->toString());
1663  }
1664  /// If cdg node is basic block or predicate, all moves inside
1665  /// will be part of same component
1666  if (cNode->component() != -1) {
1667  std::vector<Node*> nodesInBB = moveToCD[cNode];
1668  int currentComponent = cNode->component();
1669  for (unsigned int i = 0; i < nodesInBB.size(); i++) {
1670  strongComponents_[currentComponent].insert(
1671  nodesInBB[i]);
1672  nodesInBB[i]->setComponent(currentComponent);
1673  }
1674  }
1675  }
1676 
1677  ControlDependenceNode::NodesInfo rInfo = cNode->region();
1678  for (ControlDependenceNode::NodesInfo::iterator iter = rInfo.begin();
1679  iter != rInfo.end();
1680  iter++) {
1681  /// If destination in 'region' is CDG node, add it
1682  if ((*iter)->isRegionNode()
1683  || (*iter)->isLoopCloseNode()
1684  || (*iter)->isLoopEntryNode()) {
1685  Node* target = cDNodeToPNode[*iter];
1686  node->addToRegion(*target);
1687  } else {
1688  /// If destination in 'region' is BB, add all the moves in it
1689  std::vector<Node*> nodesInBB = moveToCD[*iter];
1690  for (unsigned int i = 0; i < nodesInBB.size(); i++) {
1691  node->addToRegion(*nodesInBB[i]);
1692  }
1693  }
1694  }
1696  if (cNode->isPredicateNode() && !node->isPredicateMoveNode()) {
1697  /// We have node which was in predicate basic block but is not
1698  /// the actual predicate move node.
1699  /// We have to copy "shadow" eec information
1700  eecInfo = cNode->pseudoPredicateEEC();
1701  } else {
1702  /// any other type of node should have same eec information as it's
1703  /// CDG counterpart or basic block it belonged to
1704  eecInfo = cNode->eec();
1705  /// If node was in predicate basic block and is predicate we also
1706  /// test if it is lastNode and set info
1707  if (cNode->isPredicateNode()
1709  && cNode->isLastNode()) {
1710  node->setLastNode();
1711  }
1712  }
1713  for (ControlDependenceNode::NodesInfo::iterator iter =
1714  eecInfo.begin(); iter != eecInfo.end(); iter++) {
1715  if ((*iter)->isRegionNode()
1716  || (*iter)->isLoopCloseNode()
1717  || (*iter)->isLoopEntryNode()) {
1718  Node* target = cDNodeToPNode[*iter];
1719  node->addToEEC(*target);
1720  } else {
1721  std::vector<Node*> nodesInBB = moveToCD[*iter];
1722  for (unsigned int i = 0; i < nodesInBB.size(); i++) {
1723  node->addToEEC(*nodesInBB[i]);
1724  }
1725  }
1726  }
1727  }
1728 }
1729 
1730 /**
1731  * When entry node is found during serialization, the artificial Entry and Exit
1732  * nodes are added to CFG. There is added edge from Entry to first BB and
1733  * All leaf nodes will have edge to the exit.
1734  */
1735 void
1737  BasicBlockNode* newEntry = new BasicBlockNode(0, 0, true, false);
1738  newCFG_->addNode(*newEntry);
1740  newCFG_->connectNodes(*newEntry, *firstBB, *edge);
1741  newCFG_->addExit();
1742 // Application::logStream() << (boost::format(
1743 // "Create new Entry %s for %s\n")
1744 // % newEntry->toString() % firstBB->toString()).str();
1745 }
1746 
1747 /**
1748  * Process predicate node of the graph.
1749  *
1750  * Add edges from predicate to one or two child region nodes and fill in
1751  * next basic block with last BB of first child region and fall through
1752  * BB with last BB of second child (if exists), otherwise predicate BB
1753  * itself. Also moves DDG edges between child nodes and out of subtree
1754  * to point to predicate for topological sorting of region where predicate
1755  * itself belongs.
1756  * @param predicate Predicate node to process
1757  * @param filteredCDG Filtered graph from where we get child nodes of predicate
1758  */
1759 void
1761  Node* predicate,
1762  FilteredCDG& filteredCDG) {
1763 
1764  /// Get all child nodes of predicate node
1765  NodeDescriptor nodeDes = descriptor(*predicate);
1766  FilteredOutEdgePair edges = boost::out_edges(nodeDes, filteredCDG);
1767  /// Store all child nodes, we will need to collect all edges
1768  /// to and from subgraph rooted by predicate
1769  NodeSet subgraphNodes;
1770  subgraphNodes.insert(predicate);
1771  /// Create basic block with predicate, it will be also first to
1772  /// execute
1774  BasicBlockNode* bb = new BasicBlockNode(*block);
1775 // Application::logStream() << (boost::format(
1776 // "Create new Predicate BB %s for %s\n")
1777 // % bb->toString() % predicate->toString()).str();
1778 
1779  newCFG_->addNode(*bb);
1781  newIns->addMove(predicate->moveNode().movePtr());
1782  TTAProgram::Terminal& guardReg =
1783  predicate->moveNode().move().destination();
1784 
1785  bb->basicBlock().add(newIns);
1786  insCount_++;
1787  predicate->setNewFirstBB(bb);
1788 
1789  bool hasTrue = false;
1790  bool hasFalse = false;
1791  for (FilteredOutEdgeIter ei1 = edges.first;
1792  ei1 != edges.second;
1793  ++ei1) {
1794  Edge* edge = graph_[*ei1];
1796  continue;
1797  }
1798  NodeDescriptor des = boost::target(*ei1, filteredCDG);
1799  Node* node = graph_[des];
1800  subgraphNodes.insert(node);
1801 
1802  /// In case one of branches had only single
1803  /// absolute jump to "exit" of procedure, there
1804  /// is no child basic block
1805  if(node->newFirstBB() != NULL) {
1806  ControlFlowEdge::CFGEdgePredicate predicateValue =
1809  predicateValue = ControlFlowEdge::CFLOW_EDGE_TRUE;
1810  hasTrue = true;
1811  } else {
1812  predicateValue = ControlFlowEdge::CFLOW_EDGE_FALSE;
1813  hasFalse = true;
1814  }
1815  ControlFlowEdge *newEdge = new ControlFlowEdge(predicateValue);
1816 /* Application::logStream() << (boost::format(
1817  "Adding edge for predicate %s to %s in %s\n")
1818  % bb->toString() % node->newFirstBB()->toString() % name()).str();*/
1820  *bb, *node->newFirstBB(), *newEdge);
1821  std::cerr << "Adding for predicate" << std::endl;
1822  createJump(bb, node->newFirstBB(), &guardReg, predicateValue);
1823  //predicate->addLeafBlocks(node->leafBlocks());
1824  } else {
1825  if(boost::out_degree(des, filteredCDG) != 0) {
1826  TCEString msg = (boost::format(
1827  "Found a node without first BB set. %s for predicate %s"
1828  " in procedure %s\n")
1829  % node->toString() % predicate->toString() % name()).str();
1830  throw InvalidData(__FILE__, __LINE__, __func__, msg);
1831  }
1832  }
1833  if (node->isLoopCloseNode()) {
1834  assert(node->newFirstBB() != NULL);
1835  //predicate->setLastNode();
1836  }
1837  if (node->isLoopEntryNode()) {
1839  }
1840  }
1841  /// One of the outgoing edges is missing, we will have to add edge
1842  /// from predicate itself to next BB
1843  if (!(hasTrue && hasFalse)) {
1844  predicate->addLeafBlock(bb);
1845  }
1846  /// Move/copy edges between nodes "inside" subgraph and nodes outside the
1847  /// subgraph
1848  moveDDGedges(*predicate, subgraphNodes, filteredCDG);
1849 }
1850 
1851 /**
1852  * Add edges from 'leaf' blocks of a subgraph to the basic block
1853  *
1854  * @param leafBlocks vector of basic blocks to add
1855  * @param bb Basic block to which the edges will point to
1856  */
1857 void
1859  std::vector<BasicBlockNode*> leafBlocks,
1860  BasicBlockNode* bb) {
1861  for (unsigned int i = 0; i < leafBlocks.size(); i++) {
1862  /// One previously tested was predicate or region
1863  /// we have to add edges from all of their leafs to this block
1865  newCFG_->outEdges(*leafBlocks[i]);
1868  /// Predicate had only one outgoing edge, we add second with
1869  /// inverse value
1870  for(ControlFlowGraph::EdgeSet::iterator cfe = edges.begin();
1871  cfe != edges.end(); cfe++) {
1872  if ((*cfe)->isTrueEdge()) {
1874  break;
1875  }
1876  if ((*cfe)->isFalseEdge()) {
1878  break;
1879  }
1880  }
1881  if (newCFG_->connectingEdges(*leafBlocks[i], *bb).size() == 0) {
1882  ControlFlowEdge* edge = new ControlFlowEdge(predicate);
1883  Application::logStream() << (boost::format(
1884  "Adding leaf edge from %s to %s in %s\n")
1885  % leafBlocks[i]->toString() % bb->toString() % name()).str();
1886  newCFG_->connectNodes(*leafBlocks[i], *bb, *edge);
1887  std::cerr << "Adding for leaf edges" << std::endl;
1888  createJump(leafBlocks[i], bb);
1889  }
1890  }
1891  leafBlocks.clear();
1892 }
1893 
1894 void
1897  BasicBlockNode* bb = new BasicBlockNode(*block);
1898  newCFG_->addNode(*bb);
1900  /// Add empty instruction, actual jump move will be created when
1901  /// we process corresponding loop entry
1902  bb->basicBlock().add(newIns);
1903  insCount_++;
1904  node->setNewFirstBB(bb);
1905  /*NodeSet predecessorsNodes = predecessors(*node);
1906  for (NodeSet::iterator iter = predecessorsNodes.begin();
1907  iter != predecessorsNodes.end(); iter++) {
1908  (*iter)->setLastNode();
1909  }*/
1910 /* Application::logStream() << (boost::format(
1911  "Creating BB %s for loop close %s")
1912  % bb->toString() % node->toString()).str();*/
1913 }
1914 
1915 void
1917  /// Add edge from loop close node to corresponding loop entry
1918  if (bb == NULL) {
1919  return;
1920  }
1921  NodeSet inputs = predecessors(*node);
1922  for(NodeSet::iterator ni = inputs.begin(); ni != inputs.end();
1923  ni++) {
1924  if((*ni)->isLoopCloseNode()
1925  && (*ni)->newFirstBB() != NULL
1926  && (*ni)->component() == node->component()) {
1927 /* Application::logStream() << "Adding loop edge "
1928  << (*ni)->newFirstBB()->toString() << " to "
1929  << bb->toString() << std::endl;*/
1931  edge->setBackEdge();
1932  newCFG_->connectNodes(*(*ni)->newFirstBB(), *bb, *edge);
1933  std::cerr << "Adding for loop entry" << std::endl;
1934  createJump((*ni)->newFirstBB(), bb);
1935  }
1936  }
1937 }
1938 
1939 void
1941 #if 0
1942  BackCFGFilter<ControlFlowGraph> backCFGFilter(*newCFG_);
1943  /// Create filtered graph
1944  CFGSubgraph sub = CFGSubgraph(*newCFG_, backCFGFilter);
1945  /// Sort nodes of subgraph topologically
1946  std::vector<ControlFlowGraph::NodeDescriptor> sorted;
1947  try {
1948  boost::topological_sort(*newCFG_, std::back_inserter(sorted));
1949  } catch (...) {
1950  Application::logStream() << (boost::format(
1951  "CFG %s can not be topologically sorted\n")
1952  % name()).str();
1953  }
1954  for (std::vector<ControlFlowGraph::NodeDescriptor>::reverse_iterator iter =
1955  sorted.rbegin();
1956  iter != sorted.rend(); iter++) {
1957  BasicBlockNode* node = newCFG_[*iter];
1958  if (node->isNormalBB()) {
1960  POMDIsassembler::disassemble(node->basicBlock());
1961  }
1962  }
1963 
1964  Application::logStream() << (boost::format(
1965  "Trying out %s with node count %d\n")
1966  % name() % newCFG_->nodeCount()).str();
1967  TTAMachine::AddressSpace& space =
1969  TTAProgram::Procedure newProc(name(), space, 0);
1970  Application::logStream() << "Is in program " << newProc.isInProgram() <<
1971  std::endl;
1972  cdg_->program()->addProcedure(&newProc);
1973  newCFG_->copyToProcedure(newProc);
1974  //newCFG_->updateReferencesFromProcToCfg();
1975  Application::logStream() << "Procedure copied" <<
1976  std::endl;
1977  Application::logStream() << " start " << newProc.startAddress().location()
1978  << " end " << newProc.endAddress().location() << std::endl;
1979  //Application::logStream() <<
1980  // POMDisassembler::disassemble(newProc);
1981  cdg_->program()->removeProcedure(newProc);
1982  int count = newProc.instructionCount();
1983  for (int i = 0; i < count; i++) {
1984  Application::logStream() << (boost::format(
1985  "%s\n")
1986  % POMDisassembler::disassemble(newProc.instructionAtIndex(i),1)).str();
1987  }
1988  //ControlFlowGraph testCFG(newProc);
1989  //testCFG.writeToDotFile(name() + "_testCFG.dot");
1990  //delete newCFG_;
1991 #endif
1992 }
1993 
1994 void
1996  BasicBlockNode* from,
1997  BasicBlockNode* to,
1998  TTAProgram::Terminal* guardReg,
2000  return;
2001  if (from->isNormalBB() && to->isNormalBB()
2002  //&& !from->basicBlock().lastInstruction().hasControlFlowMove()
2003  ) {
2004  if (from->basicBlock().lastInstruction().hasControlFlowMove()) {
2005  Application::logStream() << "\tMove already has CF " <<
2006  from->basicBlock().lastInstruction().toString() << std::endl;
2007  }
2008  Application::logStream() << (boost::format(
2009  "Creating jump from %s to %s\n")
2010  % from->toString() % to->toString()).str();
2013  /// If reference already exists, just return it
2015  manager.createReference(to->basicBlock().firstInstruction());
2016 
2017  TTAMachine::HWOperation* hwOp =
2019 
2020  TTAProgram::TerminalFUPort* jump1Terminal =
2021  new TTAProgram::TerminalFUPort(*hwOp, 1);
2022 
2023  TTAProgram::Terminal* jump0Terminal =
2025 
2026  auto jumpMove = std::make_shared<TTAProgram::Move>(
2027  jump0Terminal, jump1Terminal,
2029 
2030  if (predicate == ControlFlowEdge::CFLOW_EDGE_TRUE) {
2033  for (int i = 0; i < busNav.count(); i++) {
2034  TTAMachine::Bus* bus = busNav.item(i);
2035  for (int i = 0; i < bus->guardCount(); i++) {
2036  TTAMachine::RegisterGuard* regGuard =
2037  dynamic_cast<TTAMachine::RegisterGuard*>(bus->guard(i));
2038  if (regGuard != NULL &&
2039  regGuard->registerFile() == &guardReg->registerFile() &&
2040  regGuard->registerIndex() == (int)guardReg->index()) {
2041  jumpMove->setGuard(
2042  new TTAProgram::MoveGuard(*regGuard));
2043  break;
2044  }
2045  }
2046  }
2047  } else if (predicate == ControlFlowEdge::CFLOW_EDGE_FALSE) {
2050  for (int i = 0; i < busNav.count(); i++) {
2051  TTAMachine::Bus* bus = busNav.item(i);
2052  for (int i = 0; i < bus->guardCount(); i++) {
2053  TTAMachine::RegisterGuard* regGuard =
2054  dynamic_cast<TTAMachine::RegisterGuard*>(bus->guard(i));
2055  if (regGuard != NULL &&
2056  regGuard->registerFile() == &guardReg->registerFile() &&
2057  regGuard->registerIndex() == (int)guardReg->index() &&
2058  regGuard->isInverted() == true) {
2059  jumpMove->setGuard(
2060  new TTAProgram::MoveGuard(*regGuard));
2061  break;
2062  }
2063  }
2064  }
2065  }
2066 
2068  if (inst->moveCount() > 0) {
2069  inst = new TTAProgram::Instruction();
2070  from->basicBlock().add(inst);
2071  }
2072  std::cerr << " before result " << inst->toString() << std::endl;
2073  inst->addMove(jumpMove);
2074  std::cerr << " after result " << inst->toString() << std::endl;
2075  } else {
2076  Application::logStream() << (boost::format(
2077  "Failed to add jump for %s %s, %s, %s\n")
2078  % from->toString() % to->toString() %
2079  from->basicBlock().lastInstruction().toString() %
2080  to->basicBlock().firstInstruction().toString()).str();
2081  }
2082 }
ProgramDependenceNode::isRegionNode
bool isRegionNode() const
Definition: ProgramDependenceNode.hh:65
ControlDependenceGraph::program
TTAProgram::Program * program() const
Definition: ControlDependenceGraph.cc:683
ProgramDependenceGraph::ANY_ORDER
@ ANY_ORDER
Definition: ProgramDependenceGraph.hh:58
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::predecessors
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
TerminalInstructionReference.hh
ProgramDependenceGraph::compareSiblings
CompareResult compareSiblings(Node *a, Node *b)
Definition: ProgramDependenceGraph.cc:919
ControlDependenceNode::isRegionNode
bool isRegionNode() const
Definition: ControlDependenceNode.cc:145
ProgramDependenceNode::isPredicateMoveNode
bool isPredicateMoveNode() const
Definition: ProgramDependenceNode.hh:66
BoostGraph::outEdge
virtual Edge & outEdge(const Node &node, const int index) const
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::connectNodes
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
TTAProgram::Instruction::addMove
void addMove(std::shared_ptr< Move > move)
Definition: Instruction.cc:147
TTAProgram::Program::addProcedure
void addProcedure(Procedure *proc)
Definition: Program.cc:524
ProgramDependenceGraph::regionHelper
void regionHelper(Node *node, FilteredCDG &filteredCDG, Node::NodesInfo &finalNodesInfo)
Definition: ProgramDependenceGraph.cc:1110
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::removeEdge
virtual void removeEdge(Edge &e)
ProgramDependenceNode::toString
std::string toString() const
Definition: ProgramDependenceNode.cc:93
TTAProgram::CodeSnippet::firstInstruction
virtual Instruction & firstInstruction() const
Definition: CodeSnippet.cc:216
ProgramDependenceNode::PDG_NODE_PREDICATE
@ PDG_NODE_PREDICATE
Definition: ProgramDependenceNode.hh:47
ProgramDependenceGraph::computeEECInfo
void computeEECInfo(const PDGOrderMap &orderMap, FilteredCDG &filteredCDG)
Definition: ProgramDependenceGraph.cc:806
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::tailNode
virtual Node & tailNode(const Edge &edge) const
ProgramDependenceGraph::FilteredOutEdgePair
std::pair< FilteredOutEdgeIter, FilteredOutEdgeIter > FilteredOutEdgePair
Definition: ProgramDependenceGraph.hh:107
TTAProgram::Terminal::index
virtual int index() const
Definition: Terminal.cc:274
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::headNode
virtual Node & headNode(const Edge &edge) const
ControlDependenceNode::basicBlockNode
BasicBlockNode * basicBlockNode() const
Definition: ControlDependenceNode.cc:116
ControlFlowGraph::copyToProcedure
void copyToProcedure(TTAProgram::Procedure &proc, TTAProgram::InstructionReferenceManager *irm=NULL)
Definition: ControlFlowGraph.cc:1448
TTAMachine::HWOperation
Definition: HWOperation.hh:52
ProgramDependenceEdge::PDG_EDGE_LOOP_CLOSE
@ PDG_EDGE_LOOP_CLOSE
Indicates Data Dependence Edge from DDG.
Definition: ProgramDependenceEdge.hh:46
ProgramDependenceNode::addLeafBlocks
void addLeafBlocks(std::vector< BasicBlockNode * > newLeafs)
Definition: ProgramDependenceNode.hh:92
TTAMachine::AddressSpace
Definition: AddressSpace.hh:51
Exception.hh
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node
Node & node(const int index) const
ProgramDependenceGraph::PDGOrder
boost::associative_property_map< PDGOrderMap > PDGOrder
Definition: ProgramDependenceGraph.hh:110
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
ProgramDependenceNode::isLoopEntryNode
bool isLoopEntryNode() const
Definition: ProgramDependenceNode.hh:68
ProgramDependenceGraph::FilteredInEdgePair
std::pair< FilteredInEdgeIter, FilteredInEdgeIter > FilteredInEdgePair
Definition: ProgramDependenceGraph.hh:105
TTAProgram::Terminal::registerFile
virtual const TTAMachine::RegisterFile & registerFile() const
Definition: Terminal.cc:225
MoveNode::movePtr
std::shared_ptr< TTAProgram::Move > movePtr()
ProgramDependenceGraph::BBToCD
std::map< const BasicBlockNode *, ControlDependenceNode *, BasicBlockNode::Comparator > BBToCD
Definition: ProgramDependenceGraph.hh:76
TTAProgram::MoveGuard::isInverted
bool isInverted() const
Definition: MoveGuard.cc:76
UniversalMachine::universalBus
TTAMachine::Bus & universalBus() const
Definition: UniversalMachine.cc:306
ProgramDependenceGraph::detectStrongComponents
int detectStrongComponents(PDGOrderMap &components, DescriptorMap &roots, FilteredCDG &filteredCDG)
Definition: ProgramDependenceGraph.cc:524
ControlDependenceNode::eec
const NodesInfo & eec()
Definition: ControlDependenceNode.cc:243
ControlDependenceNode::isEntryNode
bool isEntryNode() const
Definition: ControlDependenceNode.cc:161
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::NodeSet
std::set< ProgramDependenceNode *, typename ProgramDependenceNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
TTAProgram::Instruction
Definition: Instruction.hh:57
MapTools.hh
Procedure.hh
TTAMachine::Bus
Definition: Bus.hh:53
SequenceTools.hh
ProgramDependenceGraph::insCount_
int insCount_
Counts new instructions when creating basic blocks.
Definition: ProgramDependenceGraph.hh:232
ProgramDependenceNode::PDG_NODE_REGION
@ PDG_NODE_REGION
Definition: ProgramDependenceNode.hh:46
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
ProgramDependenceNode::setLoopEntryNode
void setLoopEntryNode(int component)
Definition: ProgramDependenceNode.cc:292
ProgramDependenceGraph::serializePDG
bool serializePDG()
Definition: ProgramDependenceGraph.cc:401
TTAProgram::InstructionReferenceManager::createReference
InstructionReference createReference(Instruction &ins)
Definition: InstructionReferenceManager.cc:73
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::copyInEdge
virtual void copyInEdge(const Node &destination, Edge &edge, const Node *tail=NULL)
ProgramDependenceNode::PDG_NODE_LOOPENTRY
@ PDG_NODE_LOOPENTRY
Definition: ProgramDependenceNode.hh:49
ProgramDependenceNode::leafBlocks
std::vector< BasicBlockNode * > leafBlocks()
Definition: ProgramDependenceNode.hh:89
ProgramDependenceEdge::isDataDependence
bool isDataDependence() const
Definition: ProgramDependenceEdge.cc:137
ProgramDependenceGraph::processLoopEntry
void processLoopEntry(Node *node, BasicBlockNode *bb)
Definition: ProgramDependenceGraph.cc:1916
ControlFlowEdge::CFGEdgePredicate
CFGEdgePredicate
Definition: ControlFlowEdge.hh:52
ControlDependenceEdge::isTrueEdge
bool isTrueEdge() const
Definition: ControlDependenceEdge.hh:61
TTAProgram::Instruction::toString
std::string toString() const
Definition: Instruction.cc:576
DataDependenceGraph.hh
MoveNode
Definition: MoveNode.hh:65
ControlDependenceGraph::componentCount
int componentCount() const
Definition: ControlDependenceGraph.hh:85
ProgramDependenceGraph::processRegion
void processRegion(Node *region, FilteredCDG &filteredCDG)
Definition: ProgramDependenceGraph.cc:1190
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
TTAProgram::CodeSnippet::startAddress
virtual Address startAddress() const
Definition: CodeSnippet.cc:780
ProgramDependenceGraph::addLeafEdges
void addLeafEdges(std::vector< BasicBlockNode * > leafs, BasicBlockNode *bb)
Definition: ProgramDependenceGraph.cc:1858
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::addNode
virtual void addNode(Node &node)
ProgramDependenceNode::setNewFirstBB
void setNewFirstBB(BasicBlockNode *newBB)
Definition: ProgramDependenceNode.hh:88
ProgramDependenceGraph::ddgEntryNode_
Node * ddgEntryNode_
Stored reference to PDG equivalent of DDG ENTRYNODE.
Definition: ProgramDependenceGraph.hh:226
TTAMachine::Machine::Navigator::count
int count() const
ProgramDependenceNode::eec
const NodesInfo & eec()
Definition: ProgramDependenceNode.cc:281
ProgramDependenceGraph::wrongCounter_
int wrongCounter_
Definition: ProgramDependenceGraph.hh:250
BoostGraph::edgeCount
int edgeCount() const
ProgramDependenceGraph::Subgraph
boost::filtered_graph< Graph, BackFilter< Graph >, SubgraphTypeTest< NodeSet, Graph > > Subgraph
Definition: ProgramDependenceGraph.hh:149
ProgramDependenceGraph::cdg_
const ControlDependenceGraph * cdg_
Stores original control dependence graph.
Definition: ProgramDependenceGraph.hh:220
ProgramDependenceEdge
Definition: ProgramDependenceEdge.hh:41
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::moveOutEdge
virtual void moveOutEdge(const Node &source, const Node &destination, Edge &edge, const Node *head=NULL, bool childs=false)
DataDependenceEdge::dependenceType
DependenceType dependenceType() const
Definition: DataDependenceEdge.hh:88
ProgramDependenceNode::moveNode
MoveNode & moveNode()
Definition: ProgramDependenceNode.cc:182
ProgramDependenceEdge::controlDependenceEdge
ControlDependenceEdge & controlDependenceEdge()
Definition: ProgramDependenceEdge.cc:166
ProgramDependenceGraph::ColorMap
std::map< NodeDescriptor, boost::default_color_type > ColorMap
Storage for color property used by dfs.
Definition: ProgramDependenceGraph.hh:115
Conversion::toString
static std::string toString(const T &source)
ProgramDependenceGraph::computeRegionInfo
void computeRegionInfo(const PDGOrderMap &orderMap, FilteredCDG &filteredCDG)
Definition: ProgramDependenceGraph.cc:734
ControlDependenceNode::NodesInfo
std::set< ControlDependenceNode * > NodesInfo
Storage type for other nodes of same graph needed to define some non graph relations....
Definition: ControlDependenceNode.hh:73
ProgramDependenceGraph::processLoopClose
void processLoopClose(Node *node)
Definition: ProgramDependenceGraph.cc:1895
hash_set.hh
ControlFlowEdge
Definition: ControlFlowEdge.hh:50
ProgramDependenceNode::NodesInfo
std::set< ProgramDependenceNode * > NodesInfo
Definition: ProgramDependenceNode.hh:64
BoostGraph::outDegree
virtual int outDegree(const Node &node) const
ProgramDependenceNode::region
const NodesInfo & region()
Definition: ProgramDependenceNode.cc:260
ProgramDependenceGraph::disassemble
void disassemble() const
Definition: ProgramDependenceGraph.cc:1940
ControlFlowEdge::CFLOW_EDGE_NORMAL
@ CFLOW_EDGE_NORMAL
Definition: ControlFlowEdge.hh:53
ProgramDependenceGraph::FilteredOutEdgeIter
boost::graph_traits< FilteredCDG >::out_edge_iterator FilteredOutEdgeIter
Definition: ProgramDependenceGraph.hh:101
ProgramDependenceGraph::SubgraphTypeTest
Filter nodes of subgraph only.
Definition: ProgramDependenceGraph.hh:120
POMDisassembler.hh
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::moveInEdge
virtual void moveInEdge(const Node &source, const Node &destination, Edge &edge, const Node *tail=NULL, bool childs=false)
ProgramDependenceGraph::processEntry
void processEntry(BasicBlockNode *firstBB)
Definition: ProgramDependenceGraph.cc:1736
BasicBlockNode::basicBlock
TTAProgram::BasicBlock & basicBlock()
Definition: BasicBlockNode.cc:126
ProgramDependenceGraph::CDGFilter
Filter control dependence edges only.
Definition: ProgramDependenceGraph.hh:84
ProgramDependenceGraph::entryNode
ProgramDependenceNode & entryNode() const
Definition: ProgramDependenceGraph.cc:1091
assert
#define assert(condition)
Definition: Application.hh:86
ControlDependenceEdge
Definition: ControlDependenceEdge.hh:44
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::copyOutEdge
virtual void copyOutEdge(const Node &destination, Edge &edge, const Node *head=NULL)
UniversalMachine.hh
MoveNode::isMove
bool isMove() const
ProgramDependenceGraph.hh
ProgramDependenceGraph::label_writer
Definition: ProgramDependenceGraph.hh:238
ProgramDependenceGraph::~ProgramDependenceGraph
virtual ~ProgramDependenceGraph()
Definition: ProgramDependenceGraph.cc:75
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
ProgramDependenceNode::printRelations
void printRelations() const
Definition: ProgramDependenceNode.cc:297
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
HWOperation.hh
ProgramDependenceEdge::isArtificialControlDependence
bool isArtificialControlDependence() const
Definition: ProgramDependenceEdge.cc:147
TTAProgram::Move::isCall
bool isCall() const
Definition: Move.cc:190
InvalidData
Definition: Exception.hh:149
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::EdgeSet
std::set< ProgramDependenceEdge *, typename ProgramDependenceEdge ::Comparator > EdgeSet
Definition: BoostGraph.hh:87
Instruction.hh
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::removeNode
virtual void removeNode(Node &node)
ProgramDependenceNode::component
int component() const
Definition: ProgramDependenceNode.hh:76
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
ProgramDependenceGraph::UNORDERABLE
@ UNORDERABLE
Definition: ProgramDependenceGraph.hh:59
TTAProgram::CodeSnippet::add
virtual void add(Instruction *ins)
Definition: CodeSnippet.cc:432
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::connectingEdge
EdgeDescriptor connectingEdge(const Node &nTail, const Node &nHead) const
TTAMachine::RegisterGuard
Definition: Guard.hh:137
BoostGraph::inEdge
virtual Edge & inEdge(const Node &node, const int index) const
ControlDependenceNode::region
const NodesInfo & region()
Definition: ControlDependenceNode.cc:222
ProgramDependenceGraph::ddg_
const DataDependenceGraph * ddg_
Stores original data dependence graph.
Definition: ProgramDependenceGraph.hh:222
ProgramDependenceGraph::MovesInCD
std::map< const ControlDependenceNode *, std::vector< Node * > > MovesInCD
Definition: ProgramDependenceGraph.hh:80
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
ProgramDependenceNode::cdgNode
ControlDependenceNode & cdgNode()
Definition: ProgramDependenceNode.cc:214
ProgramDependenceGraph::FilteredCDG
boost::filtered_graph< Graph, CDGFilter< Graph > > FilteredCDG
Type of filtered graph with CD edges only.
Definition: ProgramDependenceGraph.hh:96
__func__
#define __func__
Definition: Application.hh:67
ProgramDependenceGraph::Descriptors
boost::associative_property_map< DescriptorMap > Descriptors
Definition: ProgramDependenceGraph.hh:113
BasicBlockNode
Definition: BasicBlockNode.hh:64
ControlFlowGraph::addExit
void addExit(NodeSet &retSourceNodes)
ProgramDependenceNode::addLeafBlock
void addLeafBlock(BasicBlockNode *newLeaf)
Definition: ProgramDependenceNode.hh:90
TTAProgram::TerminalInstructionReference
Definition: TerminalInstructionReference.hh:48
BasicBlockNode::isNormalBB
bool isNormalBB() const
Definition: BasicBlockNode.cc:239
TTAProgram::CodeSnippet::lastInstruction
virtual Instruction & lastInstruction() const
Definition: CodeSnippet.cc:387
Guard.hh
ProgramDependenceNode::addToEEC
void addToEEC(ProgramDependenceNode &node)
Definition: ProgramDependenceNode.cc:270
Exception::errorMessageStack
std::string errorMessageStack(bool messagesOnly=false) const
Definition: Exception.cc:138
ProgramDependenceGraph::ProgramDependenceGraph
ProgramDependenceGraph(ControlDependenceGraph &cdg, DataDependenceGraph &ddg)
Definition: ProgramDependenceGraph.cc:93
ProgramDependenceGraph::BackCFGFilter
Definition: ProgramDependenceGraph.hh:152
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::Node
ProgramDependenceNode Node
The (base) node type managed by this graph.
Definition: BoostGraph.hh:90
ProgramDependenceGraph::strongComponents_
std::vector< std::set< Node * > > strongComponents_
stores nodes present in each of the found components
Definition: ProgramDependenceGraph.hh:228
TerminalFUPort.hh
ProgramDependenceGraph::computeRelations
void computeRelations(const PDGOrderMap &orderMap, FilteredCDG &filteredCDG)
Definition: ProgramDependenceGraph.cc:1444
ProgramDependenceGraph::BackFilter
Filter away back edges.
Definition: ProgramDependenceGraph.hh:136
TTAProgram::Address::location
InstructionAddress location() const
ControlDependenceEdge::invertEdgePredicate
void invertEdgePredicate()
Definition: ControlDependenceEdge.cc:64
Machine.hh
ProgramDependenceNode::isMoveNode
bool isMoveNode() const
Definition: ProgramDependenceNode.hh:67
Exception
Definition: Exception.hh:54
ModuleRunTimeError
Definition: Exception.hh:1043
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::EdgeDescriptor
GraphTraits::edge_descriptor EdgeDescriptor
Type with which edges of the graph are seen internally.
Definition: BoostGraph.hh:262
ProgramDependenceGraph::newCFG_
ControlFlowGraph * newCFG_
Newly created control flow graph.
Definition: ProgramDependenceGraph.hh:230
BoostGraph::inDegree
virtual int inDegree(const Node &node) const
ProgramDependenceGraph::CompareResult
CompareResult
Definition: ProgramDependenceGraph.hh:55
ProgramDependenceGraph::MoveNodeToPDGNode
std::map< const MoveNode *, ProgramDependenceNode *, MoveNode::Comparator > MoveNodeToPDGNode
Definition: ProgramDependenceGraph.hh:78
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
TTAProgram::Program::universalMachine
UniversalMachine & universalMachine() const
Definition: Program.cc:104
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::NodeDescriptor
GraphTraits::vertex_descriptor NodeDescriptor
Type with which nodes of the graph are seen internally.
Definition: BoostGraph.hh:264
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::inEdges
virtual EdgeSet inEdges(const Node &node) const
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::connectingEdges
EdgeSet connectingEdges(const Node &nTail, const Node &nHead) const
GraphBase< ProgramDependenceNode, ProgramDependenceEdge >::writeToDotFile
virtual void writeToDotFile(const TCEString &fileName) const
ProgramDependenceGraph::FilteredVertexDescriptor
boost::graph_traits< FilteredCDG >::vertex_descriptor FilteredVertexDescriptor
Definition: ProgramDependenceGraph.hh:103
ProgramDependenceGraph::ERROR
@ ERROR
Definition: ProgramDependenceGraph.hh:60
UniversalMachine::instructionAddressSpace
TTAMachine::AddressSpace & instructionAddressSpace() const
Definition: UniversalMachine.cc:280
ProgramDependenceGraph::A_BEFORE_B
@ A_BEFORE_B
Definition: ProgramDependenceGraph.hh:56
ControlDependenceGraph::analyzed
bool analyzed() const
Definition: ControlDependenceGraph.hh:84
TTAProgram::TerminalFUPort
Definition: TerminalFUPort.hh:56
ControlDependenceNode::isPredicateNode
bool isPredicateNode() const
Definition: ControlDependenceNode.cc:150
ControlDependenceNode::isLastNode
bool isLastNode() const
Definition: ControlDependenceNode.hh:95
ControlDependenceNode::component
int component() const
Definition: ControlDependenceNode.hh:91
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::edge
virtual Edge & edge(const int index) const
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::outEdges
virtual EdgeSet outEdges(const Node &node) const
SetTools::intersection
static void intersection(const std::set< ValueType > &firstContainer, const std::set< ValueType > &secondContainer, std::set< ValueType > &intersection)
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
MoveNode::move
TTAProgram::Move & move()
ProgramDependenceNode::PDG_NODE_LOOPCLOSE
@ PDG_NODE_LOOPCLOSE
Definition: ProgramDependenceNode.hh:50
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
POMDisassembler::disassemble
static std::string disassemble(const TTAProgram::Move &move)
Definition: POMDisassembler.cc:629
ProgramDependenceNode::newFirstBB
BasicBlockNode * newFirstBB()
Definition: ProgramDependenceNode.hh:87
ProgramDependenceGraph::entryNode_
Node * entryNode_
Stores pointer to entry node of the PDG graph.
Definition: ProgramDependenceGraph.hh:224
TTAProgram::InstructionReferenceManager
Definition: InstructionReferenceManager.hh:82
TTAProgram::Program::instructionReferenceManager
InstructionReferenceManager & instructionReferenceManager() const
Definition: Program.cc:688
ProgramDependenceGraph::CFGSubgraph
boost::filtered_graph< Graph, BackCFGFilter< Graph > > CFGSubgraph
Definition: ProgramDependenceGraph.hh:162
ProgramDependenceGraph::PDGOrderMap
std::map< NodeDescriptor, int > PDGOrderMap
Stores data to compute post order relation on CDG and strong components.
Definition: ProgramDependenceGraph.hh:109
TTAMachine::Guard::isInverted
virtual bool isInverted() const
Program.hh
ProgramDependenceNode::setPredicateMoveNode
void setPredicateMoveNode()
Definition: ProgramDependenceNode.cc:168
ProgramDependenceGraph::createJump
void createJump(BasicBlockNode *from, BasicBlockNode *to, TTAProgram::Terminal *guardReg=NULL, ControlFlowEdge::CFGEdgePredicate predicate=ControlFlowEdge::CFLOW_EDGE_NORMAL)
Definition: ProgramDependenceGraph.cc:1995
ProgramDependenceNode::isLastNode
bool isLastNode() const
Definition: ProgramDependenceNode.hh:72
InstructionReference.hh
TCEString
Definition: TCEString.hh:53
ProgramDependenceNode::setLastNode
void setLastNode()
Definition: ProgramDependenceNode.hh:75
BasicBlock.hh
ProgramDependenceGraph::B_BEFORE_A
@ B_BEFORE_A
Definition: ProgramDependenceGraph.hh:57
ProgramDependenceGraph::removeGuardedJump
void removeGuardedJump(ControlToProgram &, ProgramDependenceNode &, ControlDependenceNode &)
Definition: ProgramDependenceGraph.cc:327
sub
#define sub
Definition: ConstantTransformer.cc:63
ControlUnit.hh
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
ControlFlowEdge::CFLOW_EDGE_FALSE
@ CFLOW_EDGE_FALSE
Definition: ControlFlowEdge.hh:55
ProgramDependenceNode::addToRegion
void addToRegion(ProgramDependenceNode &node)
Definition: ProgramDependenceNode.cc:250
ProgramDependenceNode::isLoopCloseNode
bool isLoopCloseNode() const
Definition: ProgramDependenceNode.hh:71
ProgramDependenceGraph::ControlToProgram
std::map< const ControlDependenceNode *, ProgramDependenceNode *, ControlDependenceNode::Comparator > ControlToProgram
Definition: ProgramDependenceGraph.hh:74
InstructionReferenceManager.hh
ProgramDependenceNode
Definition: ProgramDependenceNode.hh:43
ControlDependenceGraph
Definition: ControlDependenceGraph.hh:65
ControlDependenceNode::isLoopCloseNode
bool isLoopCloseNode() const
Definition: ControlDependenceNode.cc:181
TTAProgram::Terminal
Definition: Terminal.hh:60
DataDependenceEdge
Definition: DataDependenceEdge.hh:43
TTAProgram::CodeSnippet::endAddress
virtual Address endAddress() const
Definition: CodeSnippet.cc:788
TTAProgram::CodeSnippet::instructionAtIndex
virtual Instruction & instructionAtIndex(int index) const
Definition: CodeSnippet.cc:285
ControlDependenceNode::pseudoPredicateEEC
const NodesInfo & pseudoPredicateEEC()
Definition: ControlDependenceNode.cc:268
ProgramDependenceEdge::dataDependenceEdge
DataDependenceEdge & dataDependenceEdge()
Definition: ProgramDependenceEdge.cc:179
DEBUG_LEVEL
#define DEBUG_LEVEL
Definition: ProgramDependenceGraph.cc:73
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::graph_
Graph graph_
The internal graph structure.
Definition: BoostGraph.hh:331
TTAProgram::Instruction::hasControlFlowMove
bool hasControlFlowMove() const
Definition: Instruction.cc:471
BoostGraph
Definition: BoostGraph.hh:83
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
ProgramDependenceGraph::Color
boost::associative_property_map< ColorMap > Color
Definition: ProgramDependenceGraph.hh:116
TTAProgram::Move::isJump
bool isJump() const
Definition: Move.cc:164
ProgramDependenceGraph::copyRegionEECComponent
void copyRegionEECComponent(ControlToProgram &, BBToCD &, MoveNodeToPDGNode &, MovesInCD &)
Definition: ProgramDependenceGraph.cc:1623
Move.hh
ProgramDependenceGraph::FilteredInEdgeIter
boost::graph_traits< FilteredCDG >::in_edge_iterator FilteredInEdgeIter
Few types to work with filtered graph.
Definition: ProgramDependenceGraph.hh:99
ControlDependenceNode
Definition: ControlDependenceNode.hh:61
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::name
virtual const TCEString & name() const
TTAProgram::Program::removeProcedure
void removeProcedure(Procedure &proc)
Definition: Program.cc:901
TTAProgram::MoveGuard
Definition: MoveGuard.hh:47
ProgramDependenceNode::setComponent
void setComponent(int component)
Definition: ProgramDependenceNode.hh:74
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::nodeCount
int nodeCount() const
ControlFlowEdge::CFLOW_EDGE_TRUE
@ CFLOW_EDGE_TRUE
Definition: ControlFlowEdge.hh:54
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::descriptor
EdgeDescriptor descriptor(const Edge &e) const
ProgramDependenceGraph::processPredicate
void processPredicate(Node *predicate, FilteredCDG &filteredCDG)
Definition: ProgramDependenceGraph.cc:1760
TTAProgram::InstructionReference
Definition: InstructionReference.hh:49
ProgramDependenceGraph::program_
TTAProgram::Program * program_
Original Program object, to get instruction reference manager.
Definition: ProgramDependenceGraph.hh:234
TTAProgram::Procedure
Definition: Procedure.hh:55
ControlFlowEdge::CFLOW_EDGE_CALL
@ CFLOW_EDGE_CALL
Definition: ControlFlowEdge.hh:61
ControlDependenceNode::isLoopEntryNode
bool isLoopEntryNode() const
Definition: ControlDependenceNode.cc:171
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
ProgramDependenceGraph::DescriptorMap
std::map< NodeDescriptor, NodeDescriptor > DescriptorMap
Storage for relations between nodes.
Definition: ProgramDependenceGraph.hh:112
TTAProgram::Instruction::moveCount
int moveCount() const
Definition: Instruction.cc:176
DataDependenceGraph::getBasicBlockNode
const BasicBlockNode & getBasicBlockNode(const MoveNode &mn) const
Definition: DataDependenceGraph.cc:186
ProgramDependenceGraph::moveDDGedges
void moveDDGedges(Node &root, NodeSet &subgraphNodes, FilteredCDG &filteredCDG)
Definition: ProgramDependenceGraph.cc:1490
DataDependenceEdge::edgeReason
EdgeReason edgeReason() const
Definition: DataDependenceEdge.hh:91
BasicBlockNode::toString
std::string toString() const
Definition: BasicBlockNode.cc:185
ControlFlowGraph
Definition: ControlFlowGraph.hh:100
TTAProgram::CodeSnippet::isInProgram
virtual bool isInProgram() const
Definition: CodeSnippet.cc:151
ProgramDependenceNode::NodeType
NodeType
Definition: ProgramDependenceNode.hh:45
ProgramDependenceNode::PDG_NODE_MOVE
@ PDG_NODE_MOVE
Definition: ProgramDependenceNode.hh:48
MoveGuard.hh