OpenASIP  2.0
ControlDependenceGraph.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 ControlDependenceGraph.cc
26  *
27  * Implementation of prototype control dependence graph of TTA program
28  * representation.
29  *
30  * @author Andrea Cilio 2005 (cilio-no.spam-cs.tut.fi)
31  * @author Vladimir Guzma 2006 (vladimir.guzma-no.spam-tut.fi)
32  * @note rating: red
33  */
34 
35 #include <iostream>
36 
37 #include <vector>
38 #include <algorithm>
39 #include <functional>
40 #include <list>
41 #include <map>
42 
43 // these need to be included before Boost so we include a working
44 // and warning-free hash_map
45 #include "hash_set.hh"
46 #include "hash_map.hh"
47 
48 #include "CompilerWarnings.hh"
49 IGNORE_CLANG_WARNING("-Wunused-local-typedef")
50 IGNORE_COMPILER_WARNING("-Wunused-parameter")
51 #include <boost/graph/reverse_graph.hpp>
52 #include <boost/graph/depth_first_search.hpp>
53 #include <boost/graph/breadth_first_search.hpp>
54 #include <boost/graph/properties.hpp>
55 #include <boost/graph/strong_components.hpp>
56 #include <boost/graph/graph_utility.hpp>
57 #include <boost/timer.hpp>
58 #include <boost/format.hpp>
61 
63 #include "ControlFlowGraph.hh"
64 #include "BasicBlockNode.hh"
65 #include "ControlFlowEdge.hh"
66 #include "BaseType.hh"
67 #include "MapTools.hh"
68 #include "Conversion.hh"
69 #include "SetTools.hh"
70 #include "AssocTools.hh"
71 #include "SequenceTools.hh"
72 #include "Instruction.hh"
73 #include "Move.hh"
75 #include "Immediate.hh"
76 
77 #define DEBUG_LEVEL 0
78 //#define DEBUG_ANNOTATOR
79 
81  // removeNode() also removes edges and deletes them
82  while (nodeCount() > 0) {
83  ControlDependenceNode* n = &node(0);
84  removeNode(*n);
85  delete n;
86  }
87  for (unsigned int i = 0; i < strongComponents_.size(); i++) {
88  strongComponents_[i].clear();
89  }
90  strongComponents_.clear();
91 }
92 /**
93  * Reads ControlFlowGraph of procedure and creates ControlDependenceGraph
94  * @param cGraph Control Flow Graph
95  */
96 
98  const ControlFlowGraph& cGraph) :
99  BoostGraph<Node, Edge>(cGraph.name()) ,
100  startAddress_(TTAProgram::NullAddress::instance()),
101  analyzed_(false), entryNode_(NULL), componentsDetected_(false) {
102 
103  program_ = cGraph.program();
104  alignment_ = cGraph.alignment();
105  cGraph_ = &const_cast<ControlFlowGraph&>(cGraph);
107 }
108 /**
109  * Compute control flow post-dominance information (in the form of an
110  * immediate post-dominator tree).
111  * Compute the control dependencies of the control flow graph using the
112  * pre-computed tree of immediate post-dominators.
113  *
114  * The base algorithm implemented is described in
115  * K.D. Cooper, T.J. Harvey, K. Kennedy: "A Simple, Fast Dominance Algorithm"
116  * and Ferrante, Ottenstein, Warren: "The Program Dependence Graphs and Its
117  * Use in Optimisation"
118  *
119  * @throw Throws InvalidData exception in case CFG can not be analyzed
120  */
121 void
123 
124  BlockVector nodes;
125  PostOrderMap poMap;
126  PostOrder postOrder(poMap);
127 
128  createPostDominanceTree(nodes, postOrder);
129  // For each edge we have to record what is predicate it is controlled
130  // by...
131  DependenceMap dependencies;
132  std::vector<Node*> cdNodes;
133  detectControlDependencies(nodes, cdNodes, postOrder, dependencies);
134 
135  // edge added while creating CD dependencies, not part of CFG by
136  // itself so it should be removed now that we have dominance tree
138  // set of control dependencies for given region node
139  DependenceMap regionNodes;
140 
141  // Creates region node for each set of control dependencies
142  // and adds the record to regionNodes
143  for (unsigned int i = 0; i < iDomTree_.size(); i++) {
144  Node* cNode = cdNodes[i];
145  if (cNode->isEntryNode() || cNode->isExitNode()) {
146  // Exit postdominate every node including Entry so
147  // they do not have any dependencies
148  continue;
149  }
150  DependenceMap::iterator rItr;
151  rItr = regionNodes.begin();
152  bool found = false;
153  // Find if previously created region node have subset of dependencies
154  // of currently tested node. If so, replace subset with dependence
155  // on previously created region node
156  // TODO: The tested set of created nodes should be sorted from
157  // largest to smallest
158  while (rItr != regionNodes.end()) {
159  if (!MapTools::containsKey(dependencies, cNode)) {
160  TCEString msg = (boost::format(
161  "Node %s of procedure %s is missing dependencies. "
162  "Most likely CFG with unreachable BB. Can not create CDG!")
163  % cNode->toString() % name()).str();
164  throw InvalidData(__FILE__, __LINE__, __func__, msg);
165  }
166  if (findSubset(
167  dependencies[cNode], (*rItr).second, (*rItr).first)){
168  found = true;
169  }
170  rItr ++;
171  }
172  if (found == true && dependencies[cNode]->size() == 1) {
173  // only one dependence and is identical
174  // with already existing one, just create edge to existing region
176  *dependencies[cNode]->at(0).first, *cNode);
177  continue;
178  }
179  if (dependencies[cNode]->size() > 0) {
180  // Create new region node and add edge from it to tested node
181  // record set of dependences for future reuse
182  Node* newNode = new Node(Node::CDEP_NODE_REGION);
183  addNode(*newNode);
184  DependentOn* dOn = new DependentOn(*(dependencies[cNode]));
185  regionNodes.insert(
186  std::pair<Node*, DependentOn*>(newNode, dOn));
187  createControlDependenceEdge(*newNode, *cNode);
188  }
189  }
190 
191  // create dependent edges INTO region nodes
192  DependenceMap::iterator regionItr;
193  regionItr = regionNodes.begin();
194  while (regionItr != regionNodes.end()) {
195  // For each region node, add edge from all nodes it is depending on
196  // into the region node
197  for (unsigned int i = 0; i < (*regionItr).second->size(); i++) {
199  *(*regionItr).second->at(i).first, *(*regionItr).first,
200  (*regionItr).second->at(i).second);
201  }
202  regionItr++;
203  }
204 
206  /// Removes artificial Exit node, it is not dependent on anything
207  /// Move edges from Entry's child region to Entry and delete region
208  for (int i = 0; i < nodeCount(); i++) {
209  Node& testNode = node(i);
210  if (testNode.isExitNode()) {
211  if (outDegree(testNode) == 0 && inDegree(testNode) == 0) {
212  removeNode(testNode);
213  delete &testNode;
214  continue;
215  }
216  }
217 
218  if (testNode.isEntryNode()) {
219  if (outDegree(testNode) != 1) {
220  TCEString msg = (boost::format(
221  "Entry node of procedure %s has more then one child node."
222  "Invalid graph!") % name()).str();
223  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
224  }
225  Edge& edge = outEdge(testNode, 0);
226  Node& entryChild = headNode(edge);
227  moveOutEdges(entryChild, testNode);
228  removeNode(entryChild);
229  delete &entryChild;
230  }
231  }
232  MapTools::deleteAllValues(regionNodes);
233  MapTools::deleteAllKeys(regionNodes);
234  MapTools::deleteAllValues(dependencies);
235  MapTools::deleteAllKeys(dependencies);
236  cdNodes.clear();
237  nodes.clear();
238 }
239 
240 /**
241  * Internal helper. Find already existing region node in set of dependencies.
242  *
243  * Find if set of dependencies contains a subset that has already a region
244  * node. If so, modifies dependencies to contain dependence to existing
245  * region node.
246  *
247  * @param wholeSet Set of dependencies for node we want to test
248  * @param subSet Set corresponding to some already existing region node
249  * @param regNode Region node we are testing
250  * @return True if the intersection was found
251  */
252 bool
254  DependentOn* wholeSet,
255  DependentOn* subSet,
256  Node* regNode) {
257 
258  if (subSet->size() > wholeSet->size()) {
259  return false;
260  }
261  std::vector<SourceType> missing;
262  unsigned int numberOfFound = 0;
263  for (unsigned int i = 0; i < wholeSet->size(); i++) {
264  SourceType test = wholeSet->at(i);
265  bool found = false;
266  for (unsigned int j = 0; j < subSet->size(); j++) {
267  SourceType tmp = subSet->at(j);
268  if (test.first == tmp.first && test.second == tmp.second) {
269  found = true;
270  numberOfFound++;
271  }
272  }
273  if (found == false) {
274  missing.push_back(test);
275  }
276  }
277  if (numberOfFound != subSet->size()) {
278  return false;
279  }
280  wholeSet->clear();
281  for (unsigned int i = 0; i < missing.size(); i++) {
282  wholeSet->push_back(missing[i]);
283  }
284  wholeSet->push_back(
286  missing.clear();
287  return true;
288 }
289 
290 /**
291  * Internal hepler. Compute the nearest common dominator of two nodes.
292  *
293  * Given two nodes (identified by their traversal order), find the nearest
294  * common ancestor that dominates both.
295  *
296  * Note: this method should go in separate immediate dominator class.
297  *
298  * @param iDom Tree of immediate dominators.
299  * @param node1 A graph node.
300  * @param node2 Another graph node.
301  * @return The post-order number of the nearest dominator of given nodes.
302  */
303 int
305  std::vector<int>& iDom,
306  int node1,
307  int node2) const {
308 
309  int finger1 = node1;
310  int finger2 = node2;
311  do {
312  while (finger1 < finger2) {
313  finger1 = iDom[finger1];
314  }
315  while (finger2 < finger1) {
316  finger2 = iDom[finger2];
317  }
318  } while (finger1 != finger2);
319  return finger1;
320 }
321 
322 /**
323  * Create a control dependence edge between two basic blocks.
324  *
325  * Creates new Control Dependence edge between two basic blocks passed as
326  * parameters
327  * @param bTail The tail basic block.
328  * @param bHead The head basic block.
329  * @return The created control dependence edge.
330  */
333  Node& bTail,
334  Node& bHead,
335  Edge::CDGEdgeType edgeValue) {
336 
337  Edge* theEdge = 0;
338  try {
339  // By construction, there should not! be duplication of CD edges!!!
340  if (hasEdge(bTail, bHead)) {
341  theEdge = graph_[connectingEdge(bTail, bHead)];
342  } else {
343  theEdge = new Edge(edgeValue);
344  connectNodes(bTail, bHead, *theEdge);
345  }
346  } catch (const ObjectAlreadyExists& e) {
347  throw ObjectAlreadyExists(
348  __FILE__, __LINE__, __func__, e.errorMessageStack());
349  }
350  return *theEdge;
351 }
352 
353 /**
354  * Internal helper. Creates a tree of immediate post dominators for
355  * constructing a control dependencies
356  *
357  * @param nodes Will be filled with pointers to BasicBlocks indexed
358  * by post order number
359  * @param postOrder Will be filled by post order numbers
360  */
361 void
363  BlockVector& nodes,
364  PostOrder& postOrder) {
365 
366  // Add false edge from entry to exit
368  ControlFlowGraph::ReversedGraph* revGraph_ = NULL;
369  revGraph_ = &cGraph_->reversedGraph();
370 
371  bool modified = false;
372  int counter = 0;
373  std::vector<ControlFlowEdge*> addedEdges;
374  BasicBlockNode& cfgExitNode = cGraph_->exitNode();
375  do {
376  ColorMap cMap;
377  Color colors(cMap);
378  modified = false;
379  int tStamp(-1);
380  boost::time_stamper<PostOrder, int, boost::on_finish_vertex>
381  pOrderStamper(postOrder, tStamp);
382  // the order of nodes within the reversed graph remains unchanged,
383  // have to look for the sink node (of the original graph) when we
384  // want to get the start node of the reverse graph.
385  boost::depth_first_visit(
386  *revGraph_, cGraph_->descriptor(cfgExitNode),
387  boost::make_dfs_visitor(pOrderStamper), colors);
388  // there can be just one node with post order number 0
389  // if there are several, then some of them are not post
390  // dominated by Exit - endless loop without break or return
391  // we add and edge from one of those nodes to exit and redo
392  // the dfs visit.
393  std::vector<BasicBlockNode*> postZero;
394  for (int i = cGraph_->nodeCount() - 1; i >=0; i--) {
395  BasicBlockNode* testedNode = &cGraph_->node(i);
396  if (postOrder[cGraph_->descriptor(*testedNode)] == 0) {
397  postZero.push_back(testedNode);
398  }
399  }
400  if (postZero.size() > 1) {
401  for (unsigned int i = 0; i < postZero.size(); i++) {
402  BasicBlockNode* testedNode = postZero[i];
403  if (!testedNode->isEntryBB()) {
404  ControlFlowEdge* edge = new
408  *testedNode, cGraph_->exitNode(), *edge);
409  addedEdges.push_back(edge);
410  delete revGraph_;
411  revGraph_ = &cGraph_->reversedGraph();
412  modified = true;
413  break;
414  }
415  }
416  }
417  postZero.clear();
418  counter++;
419  } while (modified);
420  delete revGraph_;
421  revGraph_ = NULL;
422 
423  // tree of immediate dominators, mapping a node to its immediate
424  // dominator; each node is represented by its inverted post-order number
425  iDomTree_.resize(cGraph_->nodeCount());
426  const int startNodePO = cGraph_->nodeCount() - 1;
427  // create inverse map from post-order to node
428  // initialise tree of immediate dominators
429  nodes.resize(cGraph_->nodeCount());
430  for (unsigned int i = 0; i < nodes.size(); i++) {
431  nodes[postOrder[cGraph_->descriptor(cGraph_->node(i))]] =
432  &(cGraph_->node(i));
433  iDomTree_[i] = -1;
434  }
435 
436  iDomTree_[startNodePO] = startNodePO;
437  bool changed = true;
438  while (changed) {
439  changed = false;
440  // traverse graph in reverse post-order, skipping start node
441  for (int i = cGraph_->nodeCount() - 2; i >= 0; i--) {
442  BasicBlockNode& b(*nodes[i]);
443  int newDom;
444  int predIndex;
445  for (predIndex = 0; predIndex < cGraph_->outDegree(b);
446  predIndex++) {
447  BasicBlockNode& predecessor(cGraph_->headNode(
448  cGraph_->outEdge(b, predIndex)));
449  int predPO = postOrder[cGraph_->descriptor(predecessor)];
450  // Find first processed predecessor of b
451  if (iDomTree_[predPO] != -1) {
452  break;
453  }
454  }
455  // outgoing edges of original graph are in-edges of reverse graph
456  BasicBlockNode& predecessor(cGraph_->headNode(
457  cGraph_->outEdge(b, predIndex)));
458  newDom = postOrder[cGraph_->descriptor(predecessor)];
459  // because nodes are searched in inverse post-order, at least
460  // one of predecessors of current node must have been processed
461  if (newDom == -1) {
462  TCEString message =
463  "Missing postOrder number of predecessor!";
464  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, message);
465  }
466 
467  for (predIndex = predIndex + 1;
468  predIndex < cGraph_->outDegree(b);
469  predIndex++) {
470  BasicBlockNode& predecessor(cGraph_->headNode(
471  cGraph_->outEdge(b, predIndex)));
472  int predPO = postOrder[cGraph_->descriptor(predecessor)];
473  if (iDomTree_[predPO] != -1) {
474  newDom = nearestCommonDom(iDomTree_, newDom, predPO);
475  }
476  }
477  if (newDom != iDomTree_[i]) {
478  changed = true;
479  iDomTree_[i] = newDom;
480  }
481  }
482  }
483  for (unsigned int i = 0; i < addedEdges.size(); i++) {
484  cGraph_->removeEdge(*addedEdges[i]);
485  }
486 }
487 
488 /**
489  * Return the entry node of the graph. Cache it after it's found for alter use
490  *
491  * @return The entry node of the graph.
492  * @exception InstanceNotFound if the graph does not have a entry node.
493  * @exception ModuleRunTimeError if the graph has multiple nodes that are
494  * recognised as entry nodes.
495  */
498  if (entryNode_ == NULL) {
499  Node* result = NULL;
500  bool found = false;
501  for (int i = 0; i < nodeCount(); i++) {
502  if (inDegree(node(i)) == 0) {
503  // sanity check
504  if (!static_cast<Node&>(node(i)).isEntryNode()) {
505  // probably the entry node is not present
506  TCEString errorMsg = (boost::format(
507  "Graph %s has node %s with no input edges which is "
508  "not the entry node!\n") % name()
509  % node(i).toString()).str();
510  throw ModuleRunTimeError(__FILE__, __LINE__, __func__,
511  errorMsg);
512  }
513  if (found == true) {
514  throw ModuleRunTimeError(
515  __FILE__, __LINE__, __func__,
516  "Corrupted graph. Found multiple entry nodes!");
517  }
518  result = dynamic_cast<Node*>(&node(i));
519  found = true;
520  }
521  }
522  if (found == false || result == NULL) {
523  TCEString errorMsg = (boost::format(
524  "Graph %s does not have entry node or has mutliple nodes with"
525  " no input edges!") % name()).str();
526  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, errorMsg);
527  }
528  entryNode_ = result;
529  return *result;
530  } else {
531  return *entryNode_;
532  }
533 }
534 
535 /**
536  * Internal helper. Implemented detection of control dependencies.
537  *
538  * @param nodes Vector of basic block nodes indexed by reverse post order
539  * number
540  * @param cdNodes Vector of control dependence nodes indexed by reverse post
541  * order number
542  * @param postOrder Post order numbering of nodes
543  * @param dependencies For each node, the list of nodes it is dependent on
544  */
545 void
547  BlockVector& nodes,
548  std::vector<Node*>& cdNodes,
549  PostOrder& postOrder,
550  DependenceMap& dependencies) {
551 
552  std::map<BasicBlockNode*, Node*> BBCD;
553  for (int i = 0; i < cGraph_->nodeCount(); i++) {
554  BasicBlockNode* bbNode = &cGraph_->node(i);
555  int nodeOutDegree = cGraph_->outDegree(*bbNode);
556  if (!MapTools::containsKey(BBCD, bbNode)) {
557  Node* cd = NULL;
558  Node::NodeType typeOfNode = Node::CDEP_NODE_BB;
559  if (nodeOutDegree == 2 && (!bbNode->isEntryBB())) {
560  // 2 out edges in CFG means BB ends with conditional jump
561  // therefore it is predicate BB
562  typeOfNode = Node::CDEP_NODE_PREDICATE;
563  } else if(nodeOutDegree > 2){
564  /// Basic block is either 3way jump - forbidden
565  /// or it is indirect jump with edges to all data-code
566  /// rellocations. We can not deal with such situation
567  /// at the moment. Fix cfg to original form and throw exception
569  TCEString msg = (boost::format(
570  "Basic block %s has out degree of %d. Most likely "
571  "indirect jump. Can not create CDG for that atm.")
572  % bbNode->toString() % nodeOutDegree).str();
573  throw InvalidData(__FILE__, __LINE__, __func__, msg);
574  }
575  cd = new Node(typeOfNode, bbNode);
576  addNode(*cd);
577  BBCD.insert(std::pair<BasicBlockNode*,Node*>(
578  bbNode, cd));
579  }
580  if (nodeOutDegree < 2) {
581  /// node is not predicate
582  continue;
583  } else if(nodeOutDegree > 2){
584  /// Basic block is either 3way jump - forbidden
585  /// or it is indirect jump with edges to all data-code
586  /// rellocations. We can not deal with such situation
587  /// at the moment. Fix cfg to original form and throw exception
589  TCEString msg = (boost::format(
590  "Basic block %s has out degree of %d. Most likely "
591  "indirect jump. Can not create CDG for that atm.")
592  % bbNode->toString() % nodeOutDegree).str();
593  throw InvalidData(__FILE__, __LINE__, __func__, msg);
594  }
595  for (int j = 0 ; j < nodeOutDegree; j++) {
596  Edge::CDGEdgeType edgeType =
599  cGraph_->outEdge(*bbNode, j)));
600 
601  int nPO = postOrder[cGraph_->descriptor(*bbNode)];
602  int tPO = postOrder[cGraph_->descriptor(*t)];
603  int nPoDom = iDomTree_[nPO];
604  if (nPoDom == tPO) {
605  // t is target of n, so if it post-dominate n
606  // it is immediate post dominator!
607  continue;
608  }
609  int runnerPo = tPO;
610  if (cGraph_->outEdge(*bbNode, j).isTrueEdge()) {
611  edgeType = Edge::CDEP_EDGE_TRUE;
612  }
613  if (cGraph_->outEdge(*bbNode, j).isFalseEdge()) {
614  edgeType = Edge::CDEP_EDGE_FALSE;
615  }
616  SourceType newSource = SourceType(
617  MapTools::valueForKey<Node*>(
618  BBCD, bbNode), edgeType);
619 
620  while (nPoDom != runnerPo) {
621  // Walk through postDominator tree
622  // Store found CD in multimap
623  Node* runnerCD = NULL;
624  if (MapTools::containsKey(BBCD, nodes[runnerPo])) {
625  runnerCD = MapTools::valueForKey<Node*>(
626  BBCD, nodes[runnerPo]);
627  } else {
628  if (cGraph_->outDegree(*nodes[runnerPo]) == 2 &&
629  !nodes[runnerPo]->isEntryBB()) {
630  // 2 out edges in CFG means BB ends with conditional
631  //jump therefore it is predicate BB
632  runnerCD = new Node(
633  Node::CDEP_NODE_PREDICATE, nodes[runnerPo]);
634  } else {
635  runnerCD = new Node(
636  Node::CDEP_NODE_BB, nodes[runnerPo]);
637  }
638  addNode(*runnerCD);
639  BBCD.insert(
640  std::pair<BasicBlockNode*,Node*>(
641  nodes[runnerPo], runnerCD));
642  }
643  if (MapTools::containsKey(dependencies, runnerCD)) {
644  DependentOn* dep = MapTools::valueForKey<DependentOn*>(
645  dependencies, runnerCD);
646  dep->push_back(newSource);
647  } else {
648  DependentOn* dep = new DependentOn;
649  dep->push_back(newSource);
650  dependencies.insert(
651  std::pair<Node*, DependentOn*>(
652  runnerCD, dep));
653  }
654  runnerPo = iDomTree_[runnerPo];
655  }
656  }
657 
658  }
659  for (unsigned int i = 0; i < nodes.size(); i++) {
660  Node* cdNode;
661  cdNode = MapTools::valueForKey<Node*>(
662  BBCD, nodes[i]);
663  cdNodes.push_back(cdNode);
664  }
665  BBCD.clear();
666 }
667 
668 /**
669  * Returns an alignment of procedure in original POM
670  * @return Alignment take from original POM
671  */
672 int
674  return alignment_;
675 }
676 
677 /**
678  * Returns the pointer to Program object of POM procedure
679  * belongs to.
680  * @return Pointer to TTAProgram::Program
681  */
684  return program_;
685 }
686 
687 /**
688  * Internal helper. Replaces several output edges with same truth value with
689  * region node. Combines several output edges without truth value (indirect
690  * jumps for example);
691  */
692 void
694  for (int i = 0; i < nodeCount(); i++) {
695  if (outDegree(node(i)) > 1 && node(i).isBBNode()) {
696  std::vector<Node*> trueLinks;
697  std::vector<Node*> falseLinks;
698  Node& currNode = node(i);
699  int currDegree = outDegree(currNode);
700  for (int j = 0; j < currDegree; j++) {
701  Edge* currentOutEdge = &outEdge(currNode, j);
702  if (currentOutEdge->isTrueEdge()) {
703  trueLinks.push_back(&headNode(*currentOutEdge));
704  continue;
705  }
706  if (currentOutEdge->isFalseEdge()) {
707  falseLinks.push_back(&headNode(*currentOutEdge));
708  continue;
709  }
710  }
711  /// Combine all "true" children of predicate with region
712  if (trueLinks.size() > 1) {
713  Node* regNode = new Node(Node::CDEP_NODE_REGION);
714  addNode(*regNode);
716  currNode, *regNode, Edge::CDEP_EDGE_TRUE);
717  for (unsigned int j = 0; j < trueLinks.size(); j++) {
718  createControlDependenceEdge(*regNode, *trueLinks[j]);
719  disconnectNodes(currNode, *(trueLinks[j]));
720  }
721  }
722  /// Combine all "false" children of predicate with region
723  if (falseLinks.size() > 1) {
724  Node* regNode = new Node(Node::CDEP_NODE_REGION);
725  addNode(*regNode);
727  currNode, *regNode, Edge::CDEP_EDGE_FALSE);
728  for (unsigned int j = 0; j < falseLinks.size(); j++) {
729  createControlDependenceEdge(*regNode, *falseLinks[j]);
730  disconnectNodes(currNode, *(falseLinks[j]));
731  }
732  }
733  }
734  }
735 }
736 
737 /**
738  * Performs serialization of ControlDependenceGraph, turning it into
739  * Control Flow Graph.
740  *
741  * @return ControlFlowGraph representation of CDG
742  * @throw InvalidData in case serialization of graph is not possible
743  */
744 void
746  // CDG was previously analyzed
747  if (analyzed()) {
748  return;
749  }
751  Application::logStream() << (boost::format(
752  "\tStarting CDG serialization for %s with %d nodes and %d edges.\n")
753  % name() % nodeCount() % edgeCount()).str();
754  }
755 
756  CDGOrderMap componentMap;
757  DescriptorMap rootMap;
758  boost::timer timer;
759  /// Find all strong components (loops) in a graph, loop entry nodes
760  /// will have number identifying for which loop component they are entries
761  /// and the strongComponents_ will contains all nodes that are part
762  /// of each component
763  long elapsed = 0;
764  int componentCount = detectStrongComponents(componentMap, rootMap);
765  elapsed = static_cast<long>(timer.elapsed());
767  Application::logStream() << (boost::format(
768  "\t\tStrong components: %d components, %d minutes and %d seconds.\n")
769  % componentCount % (elapsed/60) % (elapsed%60)).str();
770  }
771 
772  /// map to store post order information for all the nodes of a graph
773  /// From now on, post order info in lastMap will not change
774  CDGOrderMap lastMap;
775  CDGOrder lastOrder(lastMap);
776  /// map to store color information during dfs
777  ColorMap colorMap;
778  Color colorsDFS(colorMap);
779  int fStamp(-1);
780  /// boost::on_finish_vertex will give us post order numbering
781  boost::time_stamper<CDGOrder, int, boost::on_finish_vertex>
782  lastOrderStamper(lastOrder, fStamp);
783  timer.restart();
784  /// Sort nodes in post order, starting from entry node
785  boost::depth_first_visit(
787  boost::make_dfs_visitor(lastOrderStamper), colorsDFS);
788  elapsed = static_cast<long>(timer.elapsed());
790  Application::logStream() << (boost::format(
791  "\t\tPost order: %d minutes and %d seconds.\n")
792  % (elapsed/60) % (elapsed%60)).str();
793  }
794 
795  timer.restart();
796  /// Computes "region" information, for each node X, set of nodes that are
797  /// executed when X is executed (for node Z, on all paths from X to entry,
798  /// if node Z is region all children of Z will be in "region" of X
799  computeRegionInfo(lastMap);
800  elapsed = static_cast<long>(timer.elapsed());
802  Application::logStream() << (boost::format(
803  "\t\tRegion: %d minutes and %d seconds.\n")
804  % (elapsed/60) % (elapsed%60)).str();
805  }
806 
807  timer.restart();
808  /// Computes "eec" information, for each node X, set of nodes that are
809  /// executed when any node in subgraph of X is executed, computed using
810  /// region information
811  computeEECInfo(lastMap);
812  elapsed = static_cast<long>(timer.elapsed());
814  Application::logStream() << (boost::format(
815  "\t\tEEC: %d minutes and %d seconds.\n")
816  % (elapsed/60) % (elapsed%60)).str();
817  }
818  analyzed_ = true;
819  timer.restart();
820 #if 0
821  // This is really not needed, just for comparing with PDG edge generation
822  // if necessary
823  computeRelations(lastMap);
824  elapsed = static_cast<long>(timer.elapsed());
826  Application::logStream() << (boost::format(
827  "\t\tRelations: %d minutes and %d seconds.\n")
828  % (elapsed/60) % (elapsed%60)).str();
829  }
830 #endif
831 }
832 
833 /**
834  * Detects all strong components of a CDG graph (loops). Strong components are
835  * maximal sets of nodes that are reachable from each other. Each node is member
836  * of some component. If it is not in loop then node is components of it's own.
837  * Augments graph with loop entry and close nodes.
838  * Works iterativly, first detects maximal component, then proceeds to ones
839  * that are "embedded".
840  *
841  * @param components After return contains for each node number of component
842  * to which node belongs
843  * @param roots After return contains for each node a node that is root of
844  * component to which node belongs
845  * @return returns number of components in a graph
846  */
847 int
849  CDGOrderMap& components,
850  DescriptorMap& roots) {
851 
852  if (componentsDetected_) {
853  return strongComponents_.size();
854  }
855 
856  std::vector<std::pair<Node*, Node*> > backEdges;
857  int componentCount = 0;
858  int currentComponents = 0;
859  /// Will repeat untill all the strong components will be found
860  /// Including weirdly nested :-)
861  do {
862  CDGOrder componentOrder(components);
863  Descriptors componentRoots(roots);
864  currentComponents = 0;
865  /// Node count will change with addition of close nodes
866  currentComponents = boost::strong_components(
867  graph_, componentOrder, boost::root_map(componentRoots));
868 
869  // for each component add vector of nodes that belongs to it
870  std::vector<std::set<Node*> > componentVector;
871  componentVector.resize(componentCount + currentComponents);
872 
873  /// If the number of components is identical to number of nodes
874  /// there are no loops in graph
875  if (currentComponents == nodeCount()) {
877  break;
878  }
879  /// Add to strong components only those which are loops
880  /// Store them as CDNode*, use of descriptors is not possible
881  /// due to later addition of Nodes which will invalidate
882  /// descriptors
883  for (CDGOrderMap::iterator iterA = components.begin();
884  iterA != components.end(); iterA ++) {
885  Node* cNode = graph_[(*iterA).first];
886  componentVector[(*iterA).second].insert(cNode);
887  }
888 
889  for (unsigned int i = componentCount; i < componentVector.size(); i++) {
890  if (componentVector[i].size() > 1) {
891  std::set<Node*>& vector = componentVector[i];
892  std::set<Node*> ref;
893  int componentsSize = strongComponents_.size();
894  for (std::set<Node*>::iterator iterB = vector.begin();
895  iterB != vector.end();
896  iterB++) {
897  ref.insert(*iterB);
898  // Set component number
899  if ((*iterB)->component() == -1){
900  (*iterB)->setComponent(componentsSize);
901  }
902  }
903  strongComponents_.push_back(ref);
904  }
905  }
906 
907  /// Detects all loop entry nodes
908  /// Stores Nodes which are identified as loop entry nodes
909  /// together with number to which loop they belong
910  std::vector<std::pair<Node*,int> > newEntry;
911  /// for each entry node, collect edges that points to it from outside
912  /// the loop, deals only with newly added components
913  std::map<Node*, std::vector<Node*> > incomingToEntry;
914  for (unsigned int i = componentCount;
915  i < strongComponents_.size();
916  i++) {
917  std::set<Node*>& nodes = strongComponents_[i];
918  for (std::set<Node*>::iterator iterD = nodes.begin();
919  iterD != nodes.end();
920  iterD++) {
921  EdgeSet edges = inEdges(**iterD);
922  for (EdgeSet::iterator ei = edges.begin();
923  ei != edges.end();
924  ei++) {
925  Node* testedNode = &tailNode(**ei);
926  if (nodes.find(testedNode) == nodes.end()) {
927  if (!(*iterD)->isLoopEntryNode(i)) {
928  /// This may change in which component node it
929  (*iterD)->setLoopEntryNode(i);
930  newEntry.push_back(
931  std::pair<Node*,int>(*iterD,i));
932  incomingToEntry[*iterD].push_back(testedNode);
933  } else {
934  /// Several nodes points to loop entry node
935  /// we create dummy region node to collect those
936  /// edges
937  incomingToEntry[*iterD].push_back(testedNode);
938  }
939  }
940  }
941  }
942  }
943 
944  /// Adds close nodes for each loop entry node
945  /// Node and edge descriptors are invalidated here!
946  for (unsigned int j = 0; j < newEntry.size(); j++) {
947  Node* loopNode = newEntry[j].first;
948  std::set<Node*>& nodes =
949  strongComponents_[newEntry[j].second];
950  /// Create one "close" node for each loop entry
951  Node* close = new Node(Node::CDEP_NODE_LOOPCLOSE);
952  close->setComponent(newEntry[j].second);
953  addNode(*close);
954  /// Close node is also part of component
955  strongComponents_[newEntry[j].second].insert(close);
956 
957  /// Detect edges to loop entry node from inside component and
958  /// redirect them to close node
959  EdgeSet edges = inEdges(*loopNode);
960  std::vector<Edge*> storeEdges;
961  for (EdgeSet::iterator ei = edges.begin();
962  ei != edges.end();
963  ei++) {
964  Node* sourceNode = &tailNode(**ei);
965  if (nodes.find(sourceNode) != nodes.end()){
966  storeEdges.push_back(*ei);
967  }
968  }
969  /// Actually redirect edges
970  for (unsigned int counter = 0;
971  counter < storeEdges.size();
972  counter++) {
973  moveInEdge(*loopNode, *close, *storeEdges[counter]);
974  }
975  /// Back edge will be added later, after all loops are found
976  backEdges.push_back(
977  std::pair<Node*, Node*>(close, loopNode));
978 
979  /// Test if edges were redirected successfully
980  if (inDegree(*close) == 0) {
981  TCEString msg = (boost::format(
982  "Close node for loop entry node %s was not connected!\n")
983  % loopNode->toString()).str();
984  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
985  }
986 
987  /// In case loop entry has multiple incoming edges
988  /// outside loop, we add new region to group them together
989  std::vector<Node*> tmp =
990  MapTools::valueForKey<std::vector<Node*> >(
991  incomingToEntry, loopNode);
992  if (tmp.size() > 1) {
993  Node* collect = new Node(Node::CDEP_NODE_REGION);
994  addNode(*collect);
995  for (unsigned int i = 0; i < tmp.size(); i++) {
996  Node* input = tmp[i];
997  EdgeDescriptor ed = connectingEdge(*input, *loopNode);
998  Edge* e = graph_[ed];
999  moveInEdge(*loopNode, *collect, *e);
1000  }
1001  ControlDependenceEdge* edge2 =
1002  new ControlDependenceEdge();
1003  connectNodes(*collect, *loopNode, *edge2);
1004  }
1005  }
1006  newEntry.clear();
1008  } while (true);
1009 
1010  // Add edges from close nodes to their respective loop entries
1011  for (unsigned int i = 0; i < backEdges.size(); i++) {
1013  *backEdges[i].first, *backEdges[i].second, Edge::CDEP_EDGE_LOOPCLOSE);
1014  }
1015  backEdges.clear();
1016  componentsDetected_ = true;
1017  return componentCount;
1018 }
1019 
1020 /**
1021  * Compute the "region" information for each node of graph. Region is used to
1022  * compute "eec" to determine order in which sibling subgraphs will be in
1023  * resulting cfg.
1024  *
1025  * "Region" of node X is set of nodes that will be executed in case is X
1026 executed.
1027  *
1028  * @param orderMap post order map of CDG graph, nodes will be augmented with
1029  * "region" information.
1030  */
1031 void
1033 
1034  int mapSize = orderMap.size();
1035  if (mapSize == 0) {
1036  throw ModuleRunTimeError(__FILE__, __LINE__, __func__,
1037  "No nodes in CDG graph for " + name() + "!");
1038  }
1039  /// Compute "region" information using reverse post-order processing
1040  for (int i = mapSize -1 ; i >= 0 ; i--) {
1041  NodeDescriptor des =
1042  MapTools::keyForValue<NodeDescriptor>(orderMap,i);
1043  Node* node = graph_[des];
1044  if (!node->isLoopEntryNode()) {
1045  /// For non loop entry nodes, simply compute region info
1046  /// and store it in the node
1047  Node::NodesInfo finalNodesInfo;
1048  regionHelper(node, finalNodesInfo);
1049 
1050  for (Node::NodesInfo::iterator k = finalNodesInfo.begin();
1051  k != finalNodesInfo.end(); k++) {
1052  node->addToRegion(**k);
1053  }
1054  } else if (node->region().size() == 0) {
1055  /// for loop entry node, find all other entry nodes
1056  /// of the same loop (component)
1057  /// final region info will be intersection of region infos from
1058  /// all the entry nodes in the same loop
1059  /// it will be same for all the nodes too (they are reachable)
1060  std::vector<Node*> entries;
1061  std::set<Node*> component = strongComponents_[node->component()];
1062  for (std::set<Node*>::iterator si = component.begin();
1063  si != component.end(); si++) {
1064  /// Test for loop entries of same component
1065  /// Loop entry of one component can be regular region node of
1066  /// other "larger" loop
1067  if ((*si)->isLoopEntryNode(node->component())) {
1068  entries.push_back(*si);
1069  }
1070  }
1071  Node::NodesInfo finalNodesInfo;
1072  for (unsigned int i = 0; i < entries.size(); i++) {
1073  Node* entryNode = entries[i];
1074  regionHelper(entryNode, finalNodesInfo);
1075  }
1076  for (unsigned j = 0; j < entries.size(); j++) {
1077  Node* result = entries[j];
1078  for (Node::NodesInfo::iterator k = finalNodesInfo.begin();
1079  k != finalNodesInfo.end(); k++) {
1080  result->addToRegion(**k);
1081  }
1082  }
1083  }
1084  }
1085 }
1086 
1087 /**
1088  * Compute the "eec" information for each node of graph. Eec is used to
1089  * determine order in which sibling subgraphs needs to be scheduled in
1090  * resulting cfg.
1091  *
1092  * "eec" of node X is set of nodes that will be executed in case any of the
1093 nodes
1094  * in subgraph of X will be executed.
1095  *
1096  * @param orderMap post order map of CDG graph, nodes augmented with
1097  * "region" information, "eec" information will be added.
1098  */
1099 void
1101  int mapSize = orderMap.size();
1102  for (int i = 0; i < mapSize; i++) {
1103  NodeDescriptor des =
1104  MapTools::keyForValue<NodeDescriptor>(
1105  orderMap, i);
1106  Node* node = graph_[des];
1107  /// eec already exists, skip
1108  if (node->eec().size() > 0) {
1109  continue;
1110  }
1111  /// Found close node, eec(node) == intersection of all close
1112  /// nodes of same loop region(node) (close node is as leaf node)
1113  if (node->isLoopCloseNode() && node->eec().size() == 0) {
1114  std::vector<Node*> closeNodes;
1115  std::set<Node*> component = strongComponents_[node->component()];
1116  // collect all loop close nodes of same loop
1117  for (std::set<Node*>::iterator si = component.begin();
1118  si != component.end(); si++) {
1119  if ((*si)->isLoopCloseNode()) {
1120  closeNodes.push_back(*si);
1121  } else if ((*si)->isRegionNode()
1122  || (*si)->isPredicateNode()) {
1123  (*si)->setLastNode();
1124  }
1125  }
1126  Node::NodesInfo finalInfo;
1127  Node::NodesInfo storeResult;
1128  finalInfo.insert(node->region().begin(),node->region().end());
1129  for (unsigned int i = 0; i < closeNodes.size(); i++) {
1131  finalInfo, closeNodes[i]->region(), storeResult);
1132  finalInfo.swap(storeResult);
1133  storeResult.clear();
1134  }
1135  // add intersection of all region infos to each close node in loop
1136  for (unsigned j = 0; j < closeNodes.size(); j++) {
1137  Node* result = closeNodes[j];
1138  if(result->eec().size() != 0) {
1139  TCEString msg = (boost::format(
1140  "Close node %s in %s already has eec!\n")
1141  % result->toString() % node->toString()).str();
1142  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
1143  }
1144  for (Node::NodesInfo::iterator k = finalInfo.begin();
1145  k != finalInfo.end(); k++) {
1146  result->addToEEC(**k);
1147  }
1148  }
1149  continue;
1150  }
1151  if (outDegree(*node) == 0) {
1152  /// Found leaf node, eec(node) == region(node)
1153  Node::NodesInfo regionX = node->region();
1154  for (Node::NodesInfo::iterator t = regionX.begin();
1155  t != regionX.end(); t++) {
1156  node->addToEEC( **t);
1157  }
1158  continue;
1159  } else {
1160  if (node->isPredicateNode()) {
1161  /// if node is predicate we also store pseudo information for
1162  /// part of basic block which does not compute predicate
1163  /// itself, it is just set of statements - leafs
1164  Node::NodesInfo regionX = node->region();
1165  for (Node::NodesInfo::iterator t = regionX.begin();
1166  t != regionX.end(); t++) {
1168  }
1169  }
1170 
1171  /// Not a leaf node,
1172  /// eec(x) = intersection(eec(children(x)) \ children(x)
1173  NodeSet succ = successors(*node);
1174  Node::NodesInfo childNodes;
1175  // copy successors from NodeSet to NodesInfo otherwise
1176  // comparator function object in NodeSet makes chaos with
1177  // set_difference
1178  for (NodeSet::iterator su = succ.begin();
1179  su != succ.end(); su++) {
1180  childNodes.insert(*su);
1181  }
1182  Node::NodesInfo finalEEC;
1183 
1184  // Fill in candidate set with data from first successor
1185  finalEEC.insert(
1186  (*(childNodes.begin()))->eec().begin(),
1187  (*(childNodes.begin()))->eec().end());
1188  // compute intersection of successors eec
1189  for(Node::NodesInfo::iterator j = childNodes.begin();
1190  j != childNodes.end(); j++ ) {
1191  Node::NodesInfo storeResult;
1192  SetTools::intersection(finalEEC, (*j)->eec(), storeResult);
1193  finalEEC.swap(storeResult);
1194  storeResult.clear();
1195  }
1196  std::vector<Node*> result(finalEEC.size(), NULL);
1197  // compute set difference, returns iterator pointing to .end()
1198  // of the result
1199  std::vector<Node*>::iterator resultEnd =
1200  std::set_difference(finalEEC.begin(), finalEEC.end(),
1201  childNodes.begin(), childNodes.end(), result.begin());
1202  // push resulting eec into the node eec info
1203  for (std::vector<Node*>::iterator t = result.begin();
1204  t != resultEnd; t++) {
1205  node->addToEEC(**t);
1206  }
1207  }
1208  }
1209 }
1210 
1211 /**
1212  * Defined relation between two sibling nodes based on their type and eec info
1213  */
1216  bool AinA = false;
1217  bool BinB = false;
1218  bool BinA = false;
1219  bool AinB = false;
1220  // both a and b are simple basic blocks, order is given by data dependencies
1221  // no need to test eec info
1222  if (a->isBBNode() && b->isBBNode()
1223  && !a->isPredicateNode() && !b->isPredicateNode()) {
1224  return ANY_ORDER;
1225  }
1226 
1227  if (AssocTools::containsKey(a->eec(), a)) {
1228  AinA = true;
1229  }
1230  if (AssocTools::containsKey(b->eec(), b)) {
1231  BinB = true;
1232  }
1233  if (AssocTools::containsKey(a->eec(), b)) {
1234  BinA = true;
1235  }
1236  if (AssocTools::containsKey(b->eec(), a)) {
1237  AinB = true;
1238  }
1239  if ((a->isLoopEntryNode() || a->isPredicateNode())
1240  && (b->isBBNode() && !b->isPredicateNode())
1241  && AinA == true) {
1242  if (a->isLastNode()) {
1243  return B_BEFORE_A;
1244  }
1245  return ANY_ORDER;
1246  }
1247  if ((a->isLoopEntryNode() || a->isPredicateNode())
1248  && (b->isLoopEntryNode() || b->isPredicateNode())
1249  && AinA == true && BinB == true) {
1250  if (a->isLastNode()) {
1251  return B_BEFORE_A;
1252  }
1253  if (b->isLastNode()) {
1254  return A_BEFORE_B;
1255  }
1256  return ANY_ORDER;
1257  }
1258  if ((a->isLoopEntryNode() || a->isPredicateNode())
1259  && (b->isBBNode() && !b->isPredicateNode())
1260  && AinA == false) {
1261  return B_BEFORE_A;
1262  }
1263  if ((a->isLoopEntryNode() || a->isPredicateNode())
1264  && (b->isLoopEntryNode() || b->isPredicateNode())
1265  && AinA == false && BinB == true) {
1266  return B_BEFORE_A;
1267  }
1268  if ((a->isLoopEntryNode() || a->isPredicateNode())
1269  && (b->isLoopEntryNode() || b->isPredicateNode())
1270  && AinA == false && BinB == false) {
1271  return UNORDERABLE;
1272  }
1273  if ((a->isRegionNode() && AinB == true)
1274  && (b->isBBNode() || b->isLoopEntryNode() || b->isPredicateNode())) {
1275  return B_BEFORE_A;
1276  }
1277  if ((a->isRegionNode() && AinB == false)
1278  && (b->isLoopEntryNode() || b->isPredicateNode())
1279  && AinB == false) {
1280  return UNORDERABLE;
1281  }
1282  if ((a->isRegionNode() && AinB == false)
1283  && (b->isRegionNode() && BinA == true)) {
1284  return B_BEFORE_A;
1285  }
1286  if ((a->isRegionNode() && AinB == false)
1287  && (b->isRegionNode() && BinA == false)) {
1288  return UNORDERABLE;
1289  }
1290  if ((a->isLoopCloseNode() && AinB == true)
1291  && (b->isBBNode() || b->isPredicateNode() || b->isLoopEntryNode()
1292  || b->isRegionNode())) {
1293  return B_BEFORE_A;
1294  }
1295  if ((a->isLoopCloseNode() && AinB == false)
1296  && (b->isPredicateNode() || b->isLoopEntryNode()
1297  || b->isRegionNode())) {
1298  return UNORDERABLE;
1299  }
1300  /// FIXME:
1301  /// Unique region node rule is broken when creating loop
1302  /// entry nodes (removing loop back edge) and creating new region for
1303  /// incoming edges into loop entry - there can be another region
1304  /// which already has same set of dependences and loop entry was
1305  /// supposed to be child of that, but was not. Problem with detection
1306  /// of subsets of dependencies when creating region nodes!
1307  if ((a->isRegionNode() && AinB == true)
1308  && (b->isRegionNode() && BinA == true)) {
1309  if (a->isLastNode()) {
1310  return B_BEFORE_A;
1311  }
1312  if (b->isLastNode()) {
1313  return A_BEFORE_B;
1314  }
1315  return ANY_ORDER;
1316  }
1317  return ERROR;
1318 }
1319 
1320 /**
1321  * Helper function to compute actual region information for a node.
1322  * Called several times for a case when there are loop entry nodes
1323  * detected.
1324  *
1325  * @param node Node for which to compute region info
1326  * @param cdg Filtered PDG graph with only control dependence edges
1327  * @param finalNodesInfo stores actuall computed region info
1328  */
1329 void
1331  Node* node,
1332  Node::NodesInfo& finalNodesInfo){
1333 
1334  std::vector<Node::NodesInfo> tmpResult;
1335  /// Find all incoming control dependence edges
1336  EdgeSet edges = inEdges(*node);
1337  for (EdgeSet::iterator ei = edges.begin();
1338  ei != edges.end();
1339  ++ei) {
1340  Node* previous = &tailNode(**ei);
1341  if (previous->isRegionNode()
1342  || previous->isLoopEntryNode()
1343  || previous->isEntryNode()) {
1344  if (previous->region().size() == 0 &&
1345  !previous->isEntryNode()) {
1346  /// If parent's region is not yet computed (should be btw)
1347  /// compute it before continuing.
1348  Node::NodesInfo addedNodesInfo;
1349  regionHelper(previous, addedNodesInfo);
1350  for (Node::NodesInfo::iterator k = addedNodesInfo.begin();
1351  k != addedNodesInfo.end();
1352  k++) {
1353  previous->addToRegion(**k);
1354  }
1355  }
1356  /// region(node,parent) == region(parent) U childern(parent)
1357  Node::NodesInfo tmp = previous->region();
1358  EdgeSet outgoingEdges = outEdges(*previous);
1359  for (EdgeSet::iterator ei = outgoingEdges.begin();
1360  ei != outgoingEdges.end();
1361  ++ei) {
1362  Node* testedNode = &headNode(**ei);
1363  tmp.insert(testedNode);
1364  }
1365  tmpResult.push_back(tmp);
1366  } else if (previous->isPredicateNode()){
1367  /// region(node,parent) == region(parent)
1368  Node::NodesInfo tmp = previous->region();
1369  tmpResult.push_back(tmp);
1370  } else {
1371  if (!previous->isLoopCloseNode()) {
1372  TCEString message = (boost::format(
1373  "Node: %s , parent %s.")
1374  % node->toString() % previous->toString()).str();
1375  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, message);
1376  }
1377  }
1378  }
1379  /// fill in final region info with info from first of parents
1380  if (tmpResult.size() > 0) {
1381  finalNodesInfo.insert(
1382  tmpResult[0].begin(), tmpResult[0].end());
1383  }
1384  /// region(node) = intersection(region(node,parent(node)))
1385  /// for all parents. finalNodesInfo is already initialized from
1386  /// counter 0
1387  for (unsigned int l = 1; l < tmpResult.size(); l++) {
1388  Node::NodesInfo storeResult;
1390  finalNodesInfo, tmpResult[l], storeResult);
1391  finalNodesInfo.swap(storeResult);
1392  storeResult.clear();
1393  }
1394 }
1395 
1396 /**
1397  * Computes relation between every pair of nodes in a graph that has
1398  * common parent.
1399  *
1400  * @param orderMap Post order map of a graph
1401  */
1402 void
1404  /// Process nodes in post order, guarantees child nodes will be processed
1405  /// before their parent
1406  int mapSize = orderMap.size();
1407  for (int i = 0; i < mapSize; i++) {
1408  NodeDescriptor des =
1409  MapTools::keyForValue<NodeDescriptor>(orderMap, i);
1410  Node* node = graph_[des];
1411  /// MoveNodes are skipped here, they are always child of region
1412  if (node->isRegionNode()
1413  || node->isLoopEntryNode()
1414  || node->isPredicateNode()) {
1416  continue;
1417  }
1418  }
1419 }
1420 
1421 /**
1422  * "Sorts" all the child nodes of a region in topological order based on
1423  * their control and data dependencies.
1424  *
1425  * @param regionNode Region node who's child nodes to process
1426  * @param cdgGraph Control Dependence subraph
1427  */
1428 void
1430 
1431  /// Get all child nodes of region node
1432 
1433  EdgeSet edges = outEdges(*regionNode);
1434 
1435  std::vector<std::pair<Node*, Node*> > newEdges;
1436  for (EdgeSet::iterator ei1 = edges.begin();
1437  ei1 != edges.end();
1438  ++ei1) {
1439  Node* node1 = &headNode(**ei1);
1440 
1441  /// node1 will be compared against all the other previously untested
1442  /// nodes
1443  EdgeSet::iterator ei2 = ei1;
1444  ei2++;
1445  for (; ei2 != edges.end(); ++ei2) {
1446  Node* node2 = &headNode(**ei2);
1447 
1448  /// Test relation between siblings, should never return ERROR twice!
1449  CompareResult result = compareSiblings(node1, node2);
1450  if (result == ERROR) {
1451  result = compareSiblings(node2, node1);
1452  }
1453  switch(result) {
1454  case A_BEFORE_B:
1455  newEdges.push_back(std::pair<Node*, Node*>(node1, node2));
1456  break;
1457  case B_BEFORE_A:
1458  newEdges.push_back(std::pair<Node*, Node*>(node2, node1));
1459  break;
1460  case UNORDERABLE:
1462  Application::logStream() << (boost::format(
1463  "Nodes %s and %s can not be put into any order.\n")
1464  % node1->toString()% node2->toString()).str();
1465  }
1466  break;
1467  case ANY_ORDER:
1468  break;
1469  case ERROR:
1470  throw ModuleRunTimeError(
1471  __FILE__, __LINE__, __func__, (boost::format(
1472  "Ordering error for A='%s' and B='%s'.")
1473  % node1->toString() % node2->toString()).str());
1474  break;
1475  }
1476  }
1477  }
1478  return;
1479 #if 0
1480  /// This is just for testing
1481  /// Add actuall control dependence edges for serialization
1482  /// Edges are really not needed here, they will be added into PDG
1483  for (unsigned int i = 0; i < newEdges.size(); i++) {
1484  ControlDependenceEdge* direction = new ControlDependenceEdge();
1485  connectNodes(*newEdges[i].first, *newEdges[i].second, *direction);
1486  }
1487  return;
1488 #endif
1489 }
ControlFlowEdge::CFLOW_EDGE_LOOP_BREAK
@ CFLOW_EDGE_LOOP_BREAK
Definition: ControlFlowEdge.hh:56
ControlFlowGraph::program
TTAProgram::Program * program() const
Definition: ControlFlowGraph.cc:1171
ControlDependenceGraph::program
TTAProgram::Program * program() const
Definition: ControlDependenceGraph.cc:683
TTAProgram
Definition: Estimator.hh:65
ControlDependenceNode::isRegionNode
bool isRegionNode() const
Definition: ControlDependenceNode.cc:145
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::connectNodes
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::outEdge
virtual Edge & outEdge(const Node &node, const int index) const
TTAProgram::Program
Definition: Program.hh:63
MapTools::deleteAllKeys
static void deleteAllKeys(MapType &aMap)
POP_CLANG_DIAGS
#define POP_CLANG_DIAGS
Definition: CompilerWarnings.hh:96
ControlDependenceGraph::analyzeCDG
void analyzeCDG()
Definition: ControlDependenceGraph.cc:745
ControlDependenceEdge::CDEP_EDGE_LOOPCLOSE
@ CDEP_EDGE_LOOPCLOSE
Definition: ControlDependenceEdge.hh:51
BoostGraph::removeEdge
virtual void removeEdge(Edge &e)
BaseType.hh
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::tailNode
virtual Node & tailNode(const Edge &edge) const
ControlDependenceGraph::analyzed_
bool analyzed_
Indicates that CDG already has data required for serialization.
Definition: ControlDependenceGraph.hh:142
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::hasEdge
virtual bool hasEdge(const Node &nTail, const Node &nHead) const
ControlDependenceGraph::ANY_ORDER
@ ANY_ORDER
Definition: ControlDependenceGraph.hh:72
ControlFlowGraph::alignment
int alignment() const
Definition: ControlFlowGraph.cc:1160
ControlDependenceGraph::BlockVector
std::vector< BasicBlockNode * > BlockVector
Definition: ControlDependenceGraph.hh:102
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::headNode
virtual Node & headNode(const Edge &edge) const
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::node
Node & node(const int index) const
ControlDependenceGraph::DependenceMap
std::map< Node *, DependentOn *, Node::Comparator > DependenceMap
Definition: ControlDependenceGraph.hh:104
ControlFlowGraph::reversedGraph
ReversedGraph & reversedGraph() const
Definition: ControlFlowGraph.cc:989
ControlDependenceGraph.hh
ControlDependenceNode::eec
const NodesInfo & eec()
Definition: ControlDependenceNode.cc:243
ControlDependenceNode::isEntryNode
bool isEntryNode() const
Definition: ControlDependenceNode.cc:161
ControlDependenceGraph::B_BEFORE_A
@ B_BEFORE_A
Definition: ControlDependenceGraph.hh:71
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::NodeSet
std::set< ControlDependenceNode *, typename ControlDependenceNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
MapTools.hh
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::Edge
ControlDependenceEdge Edge
The (base) edge type managed by this graph.
Definition: BoostGraph.hh:92
SequenceTools.hh
IGNORE_CLANG_WARNING
#define IGNORE_CLANG_WARNING(X)
Definition: CompilerWarnings.hh:85
ControlDependenceGraph::ERROR
@ ERROR
Definition: ControlDependenceGraph.hh:74
BasicBlockNode.hh
ControlDependenceEdge::CDEP_EDGE_FALSE
@ CDEP_EDGE_FALSE
Definition: ControlDependenceEdge.hh:50
ControlDependenceGraph::regionHelper
void regionHelper(Node *, Node::NodesInfo &)
Definition: ControlDependenceGraph.cc:1330
MapTools::deleteAllValues
static void deleteAllValues(MapType &aMap)
ControlDependenceGraph::ColorMap
std::map< NodeDescriptor, boost::default_color_type > ColorMap
Storage for color property used by dfs.
Definition: ControlDependenceGraph.hh:97
ControlDependenceEdge::isTrueEdge
bool isTrueEdge() const
Definition: ControlDependenceEdge.hh:61
ControlDependenceNode::toString
std::string toString() const
Definition: ControlDependenceNode.cc:72
ControlDependenceGraph::SourceType
std::pair< Node *, Edge::CDGEdgeType > SourceType
Definition: ControlDependenceGraph.hh:100
ControlDependenceGraph::componentCount
int componentCount() const
Definition: ControlDependenceGraph.hh:85
ControlDependenceNode::addToPseudoPredicateEEC
void addToPseudoPredicateEEC(ControlDependenceNode &node)
Definition: ControlDependenceNode.cc:257
ControlDependenceGraph::CompareResult
CompareResult
Definition: ControlDependenceGraph.hh:69
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::addNode
virtual void addNode(Node &node)
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::edgeCount
int edgeCount() const
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
hash_set.hh
ControlFlowEdge
Definition: ControlFlowEdge.hh:50
ProgramDependenceNode::NodesInfo
std::set< ProgramDependenceNode * > NodesInfo
Definition: ProgramDependenceNode.hh:64
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::outDegree
virtual int outDegree(const Node &node) const
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::moveInEdge
virtual void moveInEdge(const Node &source, const Node &destination, Edge &edge, const Node *tail=NULL, bool childs=false)
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::disconnectNodes
virtual void disconnectNodes(const Node &nTail, const Node &nHead)
ControlDependenceGraph::CDGOrderMap
std::map< NodeDescriptor, int > CDGOrderMap
Stores data to compute post order relation on CDG and strong components.
Definition: ControlDependenceGraph.hh:91
ControlDependenceGraph::Color
boost::associative_property_map< ColorMap > Color
Definition: ControlDependenceGraph.hh:98
ControlDependenceGraph::Descriptors
boost::associative_property_map< DescriptorMap > Descriptors
Definition: ControlDependenceGraph.hh:95
ControlFlowGraph::removeEntryExitEdge
void removeEntryExitEdge()
Definition: ControlFlowGraph.cc:1125
ControlDependenceEdge
Definition: ControlDependenceEdge.hh:44
ControlDependenceGraph::ControlDependenceGraph
ControlDependenceGraph(const ControlFlowGraph &cGraph)
Definition: ControlDependenceGraph.cc:97
ControlFlowGraph::ReversedGraph
reverse_graph< ControlFlowGraph::Graph > ReversedGraph
Definition: ControlFlowGraph.hh:197
ControlDependenceEdge::CDEP_EDGE_TRUE
@ CDEP_EDGE_TRUE
Definition: ControlDependenceEdge.hh:49
InvalidData
Definition: Exception.hh:149
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::EdgeSet
std::set< ControlDependenceEdge *, typename ControlDependenceEdge ::Comparator > EdgeSet
Definition: BoostGraph.hh:87
ControlDependenceGraph::findSubset
bool findSubset(DependentOn *, DependentOn *, Node *)
Definition: ControlDependenceGraph.cc:253
Instruction.hh
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::removeNode
virtual void removeNode(Node &node)
ControlFlowGraph.hh
ControlDependenceGraph::entryNode
ControlDependenceNode & entryNode()
Definition: ControlDependenceGraph.cc:497
Conversion.hh
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::connectingEdge
EdgeDescriptor connectingEdge(const Node &nTail, const Node &nHead) const
ControlDependenceNode::region
const NodesInfo & region()
Definition: ControlDependenceNode.cc:222
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::moveOutEdges
virtual void moveOutEdges(const Node &source, const Node &destination)
__func__
#define __func__
Definition: Application.hh:67
ControlDependenceGraph::computeDependence
void computeDependence()
Definition: ControlDependenceGraph.cc:122
DEBUG_LEVEL
#define DEBUG_LEVEL
Definition: ControlDependenceGraph.cc:77
ControlDependenceGraph::detectControlDependencies
void detectControlDependencies(BlockVector &nodes, std::vector< Node * > &cdNodes, PostOrder &postOrder, DependenceMap &dependencies)
Definition: ControlDependenceGraph.cc:546
BasicBlockNode
Definition: BasicBlockNode.hh:64
BasicBlockNode::isEntryBB
bool isEntryBB() const
Definition: BasicBlockNode.cc:248
Exception::errorMessageStack
std::string errorMessageStack(bool messagesOnly=false) const
Definition: Exception.cc:138
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::Node
ProgramDependenceNode Node
The (base) node type managed by this graph.
Definition: BoostGraph.hh:90
ControlDependenceGraph::PostOrder
boost::associative_property_map< PostOrderMap > PostOrder
Definition: ControlDependenceGraph.hh:89
ControlDependenceEdge::CDEP_EDGE_NORMAL
@ CDEP_EDGE_NORMAL
Definition: ControlDependenceEdge.hh:48
ControlDependenceGraph::processRegion
void processRegion(Node *region)
Definition: ControlDependenceGraph.cc:1429
ControlDependenceEdge::isFalseEdge
bool isFalseEdge() const
Definition: ControlDependenceEdge.hh:62
ControlDependenceGraph::createPostDominanceTree
void createPostDominanceTree(BlockVector &nodes, PostOrder &postOrder)
Definition: ControlDependenceGraph.cc:362
ModuleRunTimeError
Definition: Exception.hh:1043
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::EdgeDescriptor
GraphTraits::edge_descriptor EdgeDescriptor
Type with which edges of the graph are seen internally.
Definition: BoostGraph.hh:262
ControlDependenceGraph::entryNode_
Node * entryNode_
Stores reference to entryNode of the graph.
Definition: ControlDependenceGraph.hh:144
ControlDependenceNode::CDEP_NODE_PREDICATE
@ CDEP_NODE_PREDICATE
Definition: ControlDependenceNode.hh:65
ControlDependenceGraph::computeRegionInfo
void computeRegionInfo(const CDGOrderMap &orderMap)
Definition: ControlDependenceGraph.cc:1032
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::inDegree
virtual int inDegree(const Node &node) const
ControlDependenceGraph::CDGOrder
boost::associative_property_map< CDGOrderMap > CDGOrder
Definition: ControlDependenceGraph.hh:92
ControlDependenceGraph::A_BEFORE_B
@ A_BEFORE_B
Definition: ControlDependenceGraph.hh:70
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::NodeDescriptor
GraphTraits::vertex_descriptor NodeDescriptor
Type with which nodes of the graph are seen internally.
Definition: BoostGraph.hh:264
ControlDependenceGraph::compareSiblings
CompareResult compareSiblings(Node *a, Node *b) const
Definition: ControlDependenceGraph.cc:1215
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::inEdges
virtual EdgeSet inEdges(const Node &node) const
ControlDependenceNode::CDEP_NODE_REGION
@ CDEP_NODE_REGION
Definition: ControlDependenceNode.hh:64
ControlFlowGraph::exitNode
BasicBlockNode & exitNode() const
Definition: ControlFlowGraph.cc:1058
ControlDependenceGraph::strongComponents_
std::vector< std::set< Node * > > strongComponents_
Definition: ControlDependenceGraph.hh:140
ControlDependenceGraph::analyzed
bool analyzed() const
Definition: ControlDependenceGraph.hh:84
ControlDependenceNode::isPredicateNode
bool isPredicateNode() const
Definition: ControlDependenceNode.cc:150
ControlDependenceNode::addToRegion
void addToRegion(ControlDependenceNode &node)
Definition: ControlDependenceNode.cc:212
ControlDependenceNode::addToEEC
void addToEEC(ControlDependenceNode &node)
Definition: ControlDependenceNode.cc:232
ControlDependenceNode::component
int component() const
Definition: ControlDependenceNode.hh:91
ControlDependenceGraph::PostOrderMap
std::map< ControlFlowGraph::NodeDescriptor, int > PostOrderMap
Stores data to compute post order relation on CFG.
Definition: ControlDependenceGraph.hh:88
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::edge
virtual Edge & edge(const int index) const
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::outEdges
virtual EdgeSet outEdges(const Node &node) const
hash_map.hh
SetTools::intersection
static void intersection(const std::set< ValueType > &firstContainer, const std::set< ValueType > &secondContainer, std::set< ValueType > &intersection)
ControlDependenceGraph::DependentOn
std::vector< SourceType > DependentOn
Definition: ControlDependenceGraph.hh:101
ControlDependenceNode::CDEP_NODE_LOOPCLOSE
@ CDEP_NODE_LOOPCLOSE
Definition: ControlDependenceNode.hh:68
ControlDependenceGraph::createControlDependenceEdge
ControlDependenceEdge & createControlDependenceEdge(Node &bTail, Node &bHead, Edge::CDGEdgeType edgeValue=Edge::CDEP_EDGE_NORMAL)
Definition: ControlDependenceGraph.cc:332
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
IGNORE_COMPILER_WARNING
#define IGNORE_COMPILER_WARNING(X)
Definition: CompilerWarnings.hh:51
ProgramDependenceGraph::entryNode_
Node * entryNode_
Stores pointer to entry node of the PDG graph.
Definition: ProgramDependenceGraph.hh:224
SetTools.hh
ControlDependenceEdge::CDGEdgeType
CDGEdgeType
Definition: ControlDependenceEdge.hh:47
Immediate.hh
false
find Finds info of the inner loops in the false
Definition: InnerLoopFinder.cc:81
ControlDependenceGraph::UNORDERABLE
@ UNORDERABLE
Definition: ControlDependenceGraph.hh:73
AssocTools.hh
ObjectAlreadyExists
Definition: Exception.hh:1002
ControlDependenceGraph::program_
TTAProgram::Program * program_
Definition: ControlDependenceGraph.hh:134
TCEString
Definition: TCEString.hh:53
POP_COMPILER_DIAGS
#define POP_COMPILER_DIAGS
Definition: CompilerWarnings.hh:68
ControlDependenceGraph::~ControlDependenceGraph
virtual ~ControlDependenceGraph()
Definition: ControlDependenceGraph.cc:80
ControlDependenceGraph::iDomTree_
std::vector< int > iDomTree_
Definition: ControlDependenceGraph.hh:139
ControlDependenceGraph::detectStrongComponents
int detectStrongComponents(CDGOrderMap &components, DescriptorMap &roots)
Definition: ControlDependenceGraph.cc:848
ControlDependenceGraph::alignment_
int alignment_
Definition: ControlDependenceGraph.hh:136
ControlDependenceNode::isLoopCloseNode
bool isLoopCloseNode() const
Definition: ControlDependenceNode.cc:181
ControlDependenceGraph::cGraph_
ControlFlowGraph * cGraph_
Definition: ControlDependenceGraph.hh:138
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::graph_
Graph graph_
The internal graph structure.
Definition: BoostGraph.hh:331
ControlDependenceGraph::alignment
int alignment() const
Definition: ControlDependenceGraph.cc:673
BoostGraph
Definition: BoostGraph.hh:83
ControlDependenceGraph::componentsDetected_
bool componentsDetected_
Definition: ControlDependenceGraph.hh:145
ControlFlowGraph::addEntryExitEdge
void addEntryExitEdge()
Definition: ControlFlowGraph.cc:1097
TerminalInstructionAddress.hh
ControlDependenceNode::isBBNode
bool isBBNode() const
Definition: ControlDependenceNode.cc:155
Move.hh
ControlDependenceNode
Definition: ControlDependenceNode.hh:61
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::name
virtual const TCEString & name() const
ControlFlowEdge.hh
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::nodeCount
int nodeCount() const
ControlDependenceNode::NodeType
NodeType
Definition: ControlDependenceNode.hh:63
ControlDependenceGraph::DescriptorMap
std::map< NodeDescriptor, NodeDescriptor > DescriptorMap
Storage for relations between nodes.
Definition: ControlDependenceGraph.hh:94
BoostGraph::descriptor
EdgeDescriptor descriptor(const Edge &e) const
ControlDependenceGraph::computeRelations
void computeRelations(const CDGOrderMap &orderMap)
Definition: ControlDependenceGraph.cc:1403
ControlDependenceNode::isLoopEntryNode
bool isLoopEntryNode() const
Definition: ControlDependenceNode.cc:171
BoostGraph< ControlDependenceNode, ControlDependenceEdge >::successors
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
ControlDependenceGraph::computeEECInfo
void computeEECInfo(const CDGOrderMap &orderMap)
Definition: ControlDependenceGraph.cc:1100
CompilerWarnings.hh
BasicBlockNode::toString
std::string toString() const
Definition: BasicBlockNode.cc:185
ControlFlowGraph
Definition: ControlFlowGraph.hh:100
ControlDependenceNode::CDEP_NODE_BB
@ CDEP_NODE_BB
Definition: ControlDependenceNode.hh:66
ControlDependenceGraph::eliminateMultipleOutputs
void eliminateMultipleOutputs()
Definition: ControlDependenceGraph.cc:693
ControlDependenceGraph::nearestCommonDom
int nearestCommonDom(std::vector< int > &iDom, int node1, int node2) const
Definition: ControlDependenceGraph.cc:304