Program Listing for File ControlFlowGraph.h

Program Listing for File ControlFlowGraph.h#

Return to documentation for file (src/midend/programAnalysis/staticInterproceduralSlicing/ControlFlowGraph.h)

#ifndef _CONTROLFLOWGRAPH_H_
#define _CONTROLFLOWGRAPH_H_

#include "SimpleDirectedGraph.h"
#include "CFGImpl.h"
#include "GraphDotOutput.h"
#include "virtualCFG.h"

#include <map>
#include <queue>
#include <set>

// DQ (12/30/2005): This is a Bad Bad thing to do (I can explain)
// it hides names in the global namespace and causes errors in
// otherwise valid and useful code. Where it is needed it should
// appear only in *.C files (and only ones not included for template
// instantiation reasons) else they effect user who use ROSE unexpectedly.
// using namespace std;


// DQ (3/21/2006): Namespace introduced to hide redundent use of
// ControlFlowGraph class also found in:
//      src/midend/programTransformation/partialRedundancyElimination
namespace DominatorTreesAndDominanceFrontiers {

class ControlNode;

class ControlFlowGraph : public SimpleDirectedGraph {

public:

  enum ID_dir // NO_STRINGIFY
  {
    FORWARD,
    BACKWARD
  };

  ControlFlowGraph(SgNode * head);

  void createNode(CFGNodeImpl * node);

  int getSize() {return _numNodes;}

  ControlNode * getNode(int id, ID_dir dir) {return (dir == FORWARD)?_forIndex[id]:_backIndex[id];}

  void outputCFGImpl();

private:

  void _buildCFGImpl(SgNode * head);

  void _buildCFG();
  void _buildBranches(ControlNode * from, CFGNodeImpl * curr);
  void _setupIDs(ID_dir);

  virtual void _displayData(SimpleDirectedGraphNode * data, std::ostream & os);

  DefaultCFGImpl * _cfg;

  int _numNodes;
  ControlNode * _entry;
  ControlNode * _exit;

  std::map<CFGNodeImpl *, ControlNode *> _cfgnodemap;
  std::map<SgNode *, ControlNode *> _sgnodemap;

  ControlNode ** _forIndex;
  ControlNode ** _backIndex;
};

class ControlNode : public SimpleDirectedGraphNode {

public:

  enum Type // NO_STRINGIFY
  {
    SGNODE,
    EMPTY
  };

  ControlNode(SgNode * node = NULL) : _node(node) {
    if (_node)
      _type = SGNODE;
    else
      _type = EMPTY;
  }

  SgNode * getNode() {return _node;}
  Type getType() {return _type;}

  int getID(ControlFlowGraph::ID_dir dir) {
    if (dir == ControlFlowGraph::FORWARD) {
      return _forID;
    } else {
      return _backID;
    }
  }

  void setID(int id, ControlFlowGraph::ID_dir dir) {
    if (dir == ControlFlowGraph::FORWARD) {
      _forID = id;
    } else {
      _backID = id;
    }
  }

  virtual void writeOut(std::ostream & os) {
    char buf[sizeof(ControlNode *)*2 + 3];
    sprintf(buf, "%p", this);
    os << "(" << _forID << "/" << _backID << ": " << buf << ") ";
    if (_type == EMPTY) {
      os << "EMPTY";
    } else {
      char buf[sizeof(SgNode *) * 2 + 3];
      sprintf(buf, "%p", _node);
      os << buf << ":" << _node->sage_class_name() << " ";
      os << "[" << escapeString(_node->unparseToString()) << "]";
    }
  }

private:

  SgNode * _node;
  Type _type;

  int _forID;
  int _backID;

};

// end of namespace: DominatorTreesAndDominanceFrontiers
 }

#endif