OpenASIP 2.2
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
ProgramDependenceGraph Class Reference

#include <ProgramDependenceGraph.hh>

Inheritance diagram for ProgramDependenceGraph:
Inheritance graph
Collaboration diagram for ProgramDependenceGraph:
Collaboration graph

Classes

struct  BackCFGFilter
 
struct  BackFilter
 Filter away back edges. More...
 
struct  CDGFilter
 Filter control dependence edges only. More...
 
class  label_writer
 
struct  SubgraphTypeTest
 Filter nodes of subgraph only. More...
 

Public Types

enum  CompareResult {
  A_BEFORE_B , B_BEFORE_A , ANY_ORDER , UNORDERABLE ,
  ERROR
}
 
- Public Types inherited from BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >
typedef std::set< ProgramDependenceNode *, typename GraphNode::ComparatorNodeSet
 
typedef std::set< ProgramDependenceEdge *, typename GraphEdge::ComparatorEdgeSet
 
typedef ProgramDependenceNode Node
 The (base) node type managed by this graph.
 
typedef ProgramDependenceEdge Edge
 The (base) edge type managed by this graph.
 
- Public Types inherited from GraphBase< GraphNode, GraphEdge >
typedef std::set< GraphNode *, typename GraphNode::ComparatorNodeSet
 
typedef std::set< GraphEdge *, typename GraphEdge::ComparatorEdgeSet
 
typedef GraphNode Node
 Node type of this graph (possibly, a base class).
 
typedef GraphEdge Edge
 Edge type of this graph (possibly, a base class).
 

Public Member Functions

 ProgramDependenceGraph (ControlDependenceGraph &cdg, DataDependenceGraph &ddg)
 
virtual ~ProgramDependenceGraph ()
 
ProgramDependenceNodeentryNode () const
 
bool serializePDG ()
 
void disassemble () const
 
- Public Member Functions inherited from BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >
 BoostGraph (bool allowLoopEdges=true)
 
 BoostGraph (const TCEString &name, bool allowLoopEdges=true)
 
 BoostGraph (const BoostGraph &other, bool allowLoopEdges=true)
 
 ~BoostGraph ()
 
int nodeCount () const
 
int edgeCount () const
 
Nodenode (const int index) const
 
Nodenode (const int index, bool cacheResult) const
 
virtual Edgeedge (const int index) const
 
virtual void addNode (Node &node)
 
virtual EdgeoutEdge (const Node &node, const int index) const
 
virtual EdgeinEdge (const Node &node, const int index) const
 
virtual EdgeSet outEdges (const Node &node) const
 
virtual EdgeSet inEdges (const Node &node) const
 
virtual EdgeSet rootGraphOutEdges (const Node &node) const
 
virtual EdgeSet rootGraphInEdges (const Node &node) const
 
virtual EdgerootGraphInEdge (const Node &node, const int index) const
 
virtual EdgerootGraphOutEdge (const Node &node, const int index) const
 
virtual int rootGraphInDegree (const Node &node) const
 
virtual int rootGraphOutDegree (const Node &node) const
 
virtual int outDegree (const Node &node) const
 
virtual int inDegree (const Node &node) const
 
virtual NodetailNode (const Edge &edge) const
 
virtual NodeheadNode (const Edge &edge) const
 
virtual void connectNodes (const Node &nTail, const Node &nHead, Edge &e)
 
virtual void disconnectNodes (const Node &nTail, const Node &nHead)
 
virtual void moveInEdges (const Node &source, const Node &destination)
 
virtual void moveOutEdges (const Node &source, const Node &destination)
 
virtual void moveInEdge (const Node &source, const Node &destination, Edge &edge, const Node *tail=NULL, bool childs=false)
 
virtual void moveOutEdge (const Node &source, const Node &destination, Edge &edge, const Node *head=NULL, bool childs=false)
 
virtual void copyInEdge (const Node &destination, Edge &edge, const Node *tail=NULL)
 
virtual void copyOutEdge (const Node &destination, Edge &edge, const Node *head=NULL)
 
virtual void removeNode (Node &node)
 
virtual void removeEdge (Edge &e)
 
virtual void dropNode (Node &node)
 
virtual void dropEdge (Edge &edge)
 
virtual bool hasEdge (const Node &nTail, const Node &nHead) const
 
virtual NodeSet rootNodes () const
 useful utility functions
 
virtual NodeSet sinkNodes () const
 
virtual NodeSet successors (const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
 
virtual NodeSet predecessors (const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
 
int maxPathLength (const ProgramDependenceNode &node) const
 
int maxSinkDistance (const ProgramDependenceNode &node) const
 
int maxSourceDistance (const ProgramDependenceNode &node) const
 
bool isInCriticalPath (const ProgramDependenceNode &node) const
 
int height () const
 
void findAllPaths () const
 
void detachSubgraph (BoostGraph &subGraph)
 
BoostGraphparentGraph ()
 
BoostGraphrootGraph ()
 
const BoostGraphrootGraph () const
 
bool hasNode (const Node &) const
 
virtual const TCEStringname () const
 
void setName (const TCEString &newName)
 
bool hasPath (ProgramDependenceNode &src, const ProgramDependenceNode &dest) const
 
void restoreNodeFromParent (ProgramDependenceNode &node)
 
bool detectIllegalCycles () const
 
EdgeSet connectingEdges (const Node &nTail, const Node &nHead) const
 
- Public Member Functions inherited from GraphBase< GraphNode, GraphEdge >
 GraphBase ()
 
virtual ~GraphBase ()
 
virtual int outDegree (const Node &node) const =0
 
virtual int inDegree (const Node &node) const =0
 
virtual EdgeoutEdge (const Node &node, const int index) const =0
 
virtual EdgeinEdge (const Node &node, const int index) const =0
 
virtual EdgeSet outEdges (const Node &node) const =0
 
virtual EdgeSet inEdges (const Node &node) const =0
 
virtual NodetailNode (const Edge &edge) const =0
 
virtual NodeheadNode (const Edge &edge) const =0
 
virtual bool hasEdge (const Node &nTail, const Node &nHead) const =0
 
virtual EdgeSet connectingEdges (const Node &nTail, const Node &nHead) const =0
 
virtual TCEString dotString () const
 
virtual void writeToDotFile (const TCEString &fileName) const
 
virtual void addNode (Node &node)=0
 
virtual void removeNode (Node &node)=0
 
virtual void removeEdge (Edge &e)=0
 
virtual void connectNodes (const Node &nTail, const Node &nHead, Edge &e)=0
 
virtual void disconnectNodes (const Node &nTail, const Node &nHead)=0
 

Private Types

typedef std::map< const ControlDependenceNode *, ProgramDependenceNode *, ControlDependenceNode::ComparatorControlToProgram
 
typedef std::map< const BasicBlockNode *, ControlDependenceNode *, BasicBlockNode::ComparatorBBToCD
 
typedef std::map< const MoveNode *, ProgramDependenceNode *, MoveNode::ComparatorMoveNodeToPDGNode
 
typedef std::map< const ControlDependenceNode *, std::vector< Node * > > MovesInCD
 
typedef boost::filtered_graph< Graph, CDGFilter< Graph > > FilteredCDG
 Type of filtered graph with CD edges only.
 
typedef boost::graph_traits< FilteredCDG >::in_edge_iterator FilteredInEdgeIter
 Few types to work with filtered graph.
 
typedef boost::graph_traits< FilteredCDG >::out_edge_iterator FilteredOutEdgeIter
 
typedef boost::graph_traits< FilteredCDG >::vertex_descriptor FilteredVertexDescriptor
 
typedef std::pair< FilteredInEdgeIter, FilteredInEdgeIterFilteredInEdgePair
 
typedef std::pair< FilteredOutEdgeIter, FilteredOutEdgeIterFilteredOutEdgePair
 
typedef std::map< NodeDescriptor, int > PDGOrderMap
 Stores data to compute post order relation on CDG and strong components.
 
typedef boost::associative_property_map< PDGOrderMapPDGOrder
 
typedef std::map< NodeDescriptor, NodeDescriptorDescriptorMap
 Storage for relations between nodes.
 
typedef boost::associative_property_map< DescriptorMapDescriptors
 
typedef std::map< NodeDescriptor, boost::default_color_type > ColorMap
 Storage for color property used by dfs.
 
typedef boost::associative_property_map< ColorMapColor
 
typedef boost::filtered_graph< Graph, BackFilter< Graph >, SubgraphTypeTest< NodeSet, Graph > > Subgraph
 
typedef boost::filtered_graph< Graph, BackCFGFilter< Graph > > CFGSubgraph
 

Private Member Functions

void removeGuardedJump (ControlToProgram &, ProgramDependenceNode &, ControlDependenceNode &)
 
void copyRegionEECComponent (ControlToProgram &, BBToCD &, MoveNodeToPDGNode &, MovesInCD &)
 
int detectStrongComponents (PDGOrderMap &components, DescriptorMap &roots, FilteredCDG &filteredCDG)
 
void computeRegionInfo (const PDGOrderMap &orderMap, FilteredCDG &filteredCDG)
 
void computeEECInfo (const PDGOrderMap &orderMap, FilteredCDG &filteredCDG)
 
void computeRelations (const PDGOrderMap &orderMap, FilteredCDG &filteredCDG)
 
CompareResult compareSiblings (Node *a, Node *b)
 
void regionHelper (Node *node, FilteredCDG &filteredCDG, Node::NodesInfo &finalNodesInfo)
 
void processRegion (Node *region, FilteredCDG &filteredCDG)
 
void processPredicate (Node *predicate, FilteredCDG &filteredCDG)
 
void processEntry (BasicBlockNode *firstBB)
 
void processLoopClose (Node *node)
 
void processLoopEntry (Node *node, BasicBlockNode *bb)
 
void moveDDGedges (Node &root, NodeSet &subgraphNodes, FilteredCDG &filteredCDG)
 
void createJump (BasicBlockNode *from, BasicBlockNode *to, TTAProgram::Terminal *guardReg=NULL, ControlFlowEdge::CFGEdgePredicate predicate=ControlFlowEdge::CFLOW_EDGE_NORMAL)
 
void addLeafEdges (std::vector< BasicBlockNode * > leafs, BasicBlockNode *bb)
 

Private Attributes

const ControlDependenceGraphcdg_
 Stores original control dependence graph.
 
const DataDependenceGraphddg_
 Stores original data dependence graph.
 
NodeentryNode_
 Stores pointer to entry node of the PDG graph.
 
NodeddgEntryNode_
 Stored reference to PDG equivalent of DDG ENTRYNODE.
 
std::vector< std::set< Node * > > strongComponents_
 stores nodes present in each of the found components
 
ControlFlowGraphnewCFG_
 Newly created control flow graph.
 
int insCount_
 Counts new instructions when creating basic blocks.
 
TTAProgram::Programprogram_
 Original Program object, to get instruction reference manager.
 
int wrongCounter_
 

Additional Inherited Members

- Protected Types inherited from BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >
typedef std::set< RemovedEdgeDatum > RemovedEdgeMap
 
typedef boost::adjacency_list< boost::listS, boost::vecS, boost::bidirectionalS, Node *, Edge * > Graph
 Internal graph type, providing actual graph-like operations. This type definition relies on bundled properties of boost library, which need the host compiler to support partial template specialisation.
 
typedef boost::graph_traits< GraphGraphTraits
 Traits characterising the internal graph type.
 
typedef GraphTraits::out_edge_iterator OutEdgeIter
 Output edge iterator type.
 
typedef GraphTraits::in_edge_iterator InEdgeIter
 Input edge iterator type.
 
typedef GraphTraits::edge_iterator EdgeIter
 Iterator type for the list of all edges in the graph.
 
typedef GraphTraits::vertex_iterator NodeIter
 Iterator type for the list of all nodes in the graph.
 
typedef GraphTraits::edge_descriptor EdgeDescriptor
 Type with which edges of the graph are seen internally.
 
typedef GraphTraits::vertex_descriptor NodeDescriptor
 Type with which nodes of the graph are seen internally.
 
typedef hash_map< const Edge *, EdgeDescriptor, GraphHashFunctions > EdgeDescMap
 
typedef hash_map< const Node *, NodeDescriptor, GraphHashFunctions > NodeDescMap
 
typedef std::vector< std::vector< int > > PathCache
 
- Protected Member Functions inherited from BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >
NodetailNode (const Edge &edge, const NodeDescriptor &headNode) const
 
NodeheadNode (const Edge &edge, const NodeDescriptor &tailNode) const
 
virtual void connectNodes (const Node &nTail, const Node &nHead, Edge &e, GraphBase< ProgramDependenceNode, ProgramDependenceEdge > *modifier, bool creatingSG=false)
 
void moveInEdges (const Node &source, const Node &destination, BoostGraph *modifierGraph)
 
virtual void moveOutEdges (const Node &source, const Node &destination, BoostGraph *modifierGraph)
 
virtual void removeNode (Node &node, BoostGraph *modifierGraph)
 
virtual void removeEdge (Edge &e, const ProgramDependenceNode *tailNode, const ProgramDependenceNode *headNode, BoostGraph *modifierGraph=NULL)
 
bool hasEdge (const Node &nTail, const Node &nHead, const Edge &edge) const
 
bool hasEdge (const Edge &edge, const Node *nTail=NULL, const Node *nHead=NULL) const
 
void restoreRemovedEdges (RemovedEdgeMap removedEdges)
 
EdgeDescriptor descriptor (const Edge &e) const
 
NodeDescriptor descriptor (const Node &n) const
 
EdgeDescriptor edgeDescriptor (const NodeDescriptor &tailNode, const Edge &e) const
 
EdgeDescriptor edgeDescriptor (const Edge &e, const NodeDescriptor &headNode) const
 
EdgeDescriptor connectingEdge (const Node &nTail, const Node &nHead) const
 
void replaceNodeWithLastNode (ProgramDependenceNode &dest)
 
void calculatePathLengths () const
 
void calculatePathLengthsFast () const
 
void calculateSinkDistance (const ProgramDependenceNode &node, int len, bool looping=false) const
 
void calculateSourceDistances (const ProgramDependenceNode *startNode=NULL, int startingLength=0, bool looping=false) const
 
void calculatePathLengthsOnConnect (const ProgramDependenceNode &nTail, const ProgramDependenceNode &nHead, ProgramDependenceEdge &e)
 
void sinkDistDecreased (const ProgramDependenceNode &n) const
 
void sourceDistDecreased (const ProgramDependenceNode &n) const
 
virtual int edgeWeight (ProgramDependenceEdge &e, const ProgramDependenceNode &n) const
 
void clearDescriptorCache (EdgeSet edges)
 
void constructSubGraph (BoostGraph &subGraph, NodeSet &nodes)
 
- Protected Member Functions inherited from GraphBase< GraphNode, GraphEdge >
virtual bool hasNode (const Node &) const =0
 
- Protected Attributes inherited from BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >
std::unordered_map< const ProgramDependenceNode *, int > sourceDistances_
 
std::unordered_map< const ProgramDependenceNode *, int > sinkDistances_
 
std::unordered_map< const ProgramDependenceNode *, int > loopingSourceDistances_
 
std::unordered_map< const ProgramDependenceNode *, int > loopingSinkDistances_
 
int height_
 
Graph graph_
 The internal graph structure.
 
EdgeDescMap edgeDescriptors_
 
NodeDescMap nodeDescriptors_
 
BoostGraph< ProgramDependenceNode, ProgramDependenceEdge > * parentGraph_
 
std::vector< BoostGraph< ProgramDependenceNode, ProgramDependenceEdge > * > childGraphs_
 
TCEString name_
 
int sgCounter_
 
std::set< Edge * > ownedEdges_
 
bool allowLoopEdges_
 
PathCachepathCache_
 

Detailed Description

Definition at line 51 of file ProgramDependenceGraph.hh.

Member Typedef Documentation

◆ BBToCD

Definition at line 76 of file ProgramDependenceGraph.hh.

◆ CFGSubgraph

typedef boost::filtered_graph<Graph,BackCFGFilter<Graph> > ProgramDependenceGraph::CFGSubgraph
private

Definition at line 162 of file ProgramDependenceGraph.hh.

◆ Color

typedef boost::associative_property_map<ColorMap> ProgramDependenceGraph::Color
private

Definition at line 116 of file ProgramDependenceGraph.hh.

◆ ColorMap

typedef std::map<NodeDescriptor, boost::default_color_type > ProgramDependenceGraph::ColorMap
private

Storage for color property used by dfs.

Definition at line 115 of file ProgramDependenceGraph.hh.

◆ ControlToProgram

Definition at line 74 of file ProgramDependenceGraph.hh.

◆ DescriptorMap

Storage for relations between nodes.

Definition at line 112 of file ProgramDependenceGraph.hh.

◆ Descriptors

typedef boost::associative_property_map<DescriptorMap> ProgramDependenceGraph::Descriptors
private

Definition at line 113 of file ProgramDependenceGraph.hh.

◆ FilteredCDG

typedef boost::filtered_graph<Graph, CDGFilter<Graph> > ProgramDependenceGraph::FilteredCDG
private

Type of filtered graph with CD edges only.

Definition at line 96 of file ProgramDependenceGraph.hh.

◆ FilteredInEdgeIter

typedef boost::graph_traits<FilteredCDG>::in_edge_iterator ProgramDependenceGraph::FilteredInEdgeIter
private

Few types to work with filtered graph.

Definition at line 99 of file ProgramDependenceGraph.hh.

◆ FilteredInEdgePair

Definition at line 105 of file ProgramDependenceGraph.hh.

◆ FilteredOutEdgeIter

typedef boost::graph_traits<FilteredCDG>::out_edge_iterator ProgramDependenceGraph::FilteredOutEdgeIter
private

Definition at line 101 of file ProgramDependenceGraph.hh.

◆ FilteredOutEdgePair

Definition at line 107 of file ProgramDependenceGraph.hh.

◆ FilteredVertexDescriptor

typedef boost::graph_traits<FilteredCDG>::vertex_descriptor ProgramDependenceGraph::FilteredVertexDescriptor
private

Definition at line 103 of file ProgramDependenceGraph.hh.

◆ MoveNodeToPDGNode

Definition at line 78 of file ProgramDependenceGraph.hh.

◆ MovesInCD

typedef std::map<const ControlDependenceNode*, std::vector<Node*> > ProgramDependenceGraph::MovesInCD
private

Definition at line 80 of file ProgramDependenceGraph.hh.

◆ PDGOrder

typedef boost::associative_property_map<PDGOrderMap> ProgramDependenceGraph::PDGOrder
private

Definition at line 110 of file ProgramDependenceGraph.hh.

◆ PDGOrderMap

typedef std::map<NodeDescriptor, int> ProgramDependenceGraph::PDGOrderMap
private

Stores data to compute post order relation on CDG and strong components.

Definition at line 109 of file ProgramDependenceGraph.hh.

◆ Subgraph

typedef boost::filtered_graph< Graph, BackFilter<Graph>, SubgraphTypeTest<NodeSet, Graph> > ProgramDependenceGraph::Subgraph
private

Definition at line 149 of file ProgramDependenceGraph.hh.

Member Enumeration Documentation

◆ CompareResult

Enumerator
A_BEFORE_B 
B_BEFORE_A 
ANY_ORDER 
UNORDERABLE 
ERROR 

Definition at line 55 of file ProgramDependenceGraph.hh.

55 {
56 A_BEFORE_B, // Subgraph A must be scheduled before subgraph B
57 B_BEFORE_A, // vice verse
58 ANY_ORDER, // Any order is acceptable
59 UNORDERABLE, // Can not be ordered, needs additional predicate
60 ERROR // Relation can not be determined! This is error
61 };

Constructor & Destructor Documentation

◆ ProgramDependenceGraph()

ProgramDependenceGraph::ProgramDependenceGraph ( ControlDependenceGraph cdg,
DataDependenceGraph ddg 
)

Constructor. Build Program Dependence Graph from Control and Data Dependence graphs.

Parameters
cdgControl Dependence Graph of procedure
ddgData Dependence Graph of procedure

Ignore unconditional jumps

Found dummy entry node of ddg, connect it to entry node of pdg as well.

If CDG already has analysis of Region and EEC done, just copy results

Definition at line 93 of file ProgramDependenceGraph.cc.

95 :
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++) {
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 {
169 cNodePNode, tailNode);
171 cNodePNode, headNode);
172 } catch (const Exception& e) {
173 throw InvalidData(
174 __FILE__, __LINE__, __func__, e.errorMessageStack());
175 }
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;
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 }
217 movePD, &ddg.tailNode(edge));
218 if (!MapTools::containsKey(movePD, &ddg.headNode(edge))) {
219 continue;
220 }
222 movePD, &ddg.headNode(edge));
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 {
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 {
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()) {
288 pEdge = new
289 ProgramDependenceEdge(cdg.inEdge(*cNode, j));
290 ProgramDependenceNode* pSource = NULL;
291 try {
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}
#define __func__
#define abortWithError(message)
#define assert(condition)
virtual Node & headNode(const Edge &edge) const
int nodeCount() const
int edgeCount() const
virtual Edge & inEdge(const Node &node, const int index) const
Node & node(const int index) const
virtual const TCEString & name() const
virtual int inDegree(const Node &node) const
ProgramDependenceNode Node
The (base) node type managed by this graph.
Definition BoostGraph.hh:90
virtual Node & tailNode(const Edge &edge) const
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
TTAProgram::Program * program() const
BasicBlockNode * basicBlockNode() const
const BasicBlockNode & getBasicBlockNode(const MoveNode &mn) const
std::string errorMessageStack(bool messagesOnly=false) const
Definition Exception.cc:138
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
bool isMove() const
TTAProgram::Move & move()
Node * ddgEntryNode_
Stored reference to PDG equivalent of DDG ENTRYNODE.
void removeGuardedJump(ControlToProgram &, ProgramDependenceNode &, ControlDependenceNode &)
Node * entryNode_
Stores pointer to entry node of the PDG graph.
int insCount_
Counts new instructions when creating basic blocks.
void copyRegionEECComponent(ControlToProgram &, BBToCD &, MoveNodeToPDGNode &, MovesInCD &)
std::map< const MoveNode *, ProgramDependenceNode *, MoveNode::Comparator > MoveNodeToPDGNode
std::map< const BasicBlockNode *, ControlDependenceNode *, BasicBlockNode::Comparator > BBToCD
std::map< const ControlDependenceNode *, std::vector< Node * > > MovesInCD
const ControlDependenceGraph * cdg_
Stores original control dependence graph.
TTAProgram::Program * program_
Original Program object, to get instruction reference manager.
ProgramDependenceNode & entryNode() const
const DataDependenceGraph * ddg_
Stores original data dependence graph.
std::map< const ControlDependenceNode *, ProgramDependenceNode *, ControlDependenceNode::Comparator > ControlToProgram
bool isJump() const
Definition Move.cc:164

References __func__, abortWithError, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::addNode(), ControlDependenceGraph::analyzed(), assert, ControlDependenceNode::basicBlockNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::connectNodes(), MapTools::containsKey(), copyRegionEECComponent(), ddgEntryNode_, BoostGraph< GraphNode, GraphEdge >::edge(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::edge(), BoostGraph< GraphNode, GraphEdge >::edgeCount(), entryNode(), entryNode_, Exception::errorMessageStack(), DataDependenceGraph::getBasicBlockNode(), BoostGraph< GraphNode, GraphEdge >::headNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::headNode(), BoostGraph< GraphNode, GraphEdge >::inDegree(), BoostGraph< GraphNode, GraphEdge >::inEdge(), ControlDependenceNode::isEntryNode(), TTAProgram::Move::isJump(), ControlDependenceNode::isLastNode(), ControlDependenceNode::isLoopCloseNode(), ControlDependenceNode::isLoopEntryNode(), MoveNode::isMove(), ProgramDependenceNode::isMoveNode(), ProgramDependenceNode::isPredicateMoveNode(), ControlDependenceNode::isRegionNode(), MapTools::keyForValue(), MoveNode::move(), ProgramDependenceNode::moveNode(), BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), ProgramDependenceNode::PDG_NODE_LOOPCLOSE, ProgramDependenceNode::PDG_NODE_LOOPENTRY, ProgramDependenceNode::PDG_NODE_MOVE, ProgramDependenceNode::PDG_NODE_PREDICATE, ProgramDependenceNode::PDG_NODE_REGION, ControlDependenceGraph::program(), program_, removeGuardedJump(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::removeNode(), ProgramDependenceNode::setLastNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::tailNode(), and BoostGraph< GraphNode, GraphEdge >::tailNode().

Here is the call graph for this function:

◆ ~ProgramDependenceGraph()

ProgramDependenceGraph::~ProgramDependenceGraph ( )
virtual

Definition at line 75 of file ProgramDependenceGraph.cc.

75 {
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}
std::vector< std::set< Node * > > strongComponents_
stores nodes present in each of the found components

References BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::nodeCount(), and strongComponents_.

Here is the call graph for this function:

Member Function Documentation

◆ addLeafEdges()

void ProgramDependenceGraph::addLeafEdges ( std::vector< BasicBlockNode * >  leafBlocks,
BasicBlockNode bb 
)
private

Add edges from 'leaf' blocks of a subgraph to the basic block

Parameters
leafBlocksvector of basic blocks to add
bbBasic block to which the edges will point to

One previously tested was predicate or region we have to add edges from all of their leafs to this block

Predicate had only one outgoing edge, we add second with inverse value

Definition at line 1866 of file ProgramDependenceGraph.cc.

1868 {
1869 for (unsigned int i = 0; i < leafBlocks.size(); i++) {
1870 /// One previously tested was predicate or region
1871 /// we have to add edges from all of their leafs to this block
1873 newCFG_->outEdges(*leafBlocks[i]);
1876 /// Predicate had only one outgoing edge, we add second with
1877 /// inverse value
1878 for(ControlFlowGraph::EdgeSet::iterator cfe = edges.begin();
1879 cfe != edges.end(); cfe++) {
1880 if ((*cfe)->isTrueEdge()) {
1882 break;
1883 }
1884 if ((*cfe)->isFalseEdge()) {
1886 break;
1887 }
1888 }
1889 if (newCFG_->connectingEdges(*leafBlocks[i], *bb).size() == 0) {
1890 ControlFlowEdge* edge = new ControlFlowEdge(predicate);
1891 Application::logStream() << (boost::format(
1892 "Adding leaf edge from %s to %s in %s\n")
1893 % leafBlocks[i]->toString() % bb->toString() % name()).str();
1894 newCFG_->connectNodes(*leafBlocks[i], *bb, *edge);
1895 std::cerr << "Adding for leaf edges" << std::endl;
1896 createJump(leafBlocks[i], bb);
1897 }
1898 }
1899 leafBlocks.clear();
1900}
static std::ostream & logStream()
std::string toString() const
EdgeSet connectingEdges(const Node &nTail, const Node &nHead) const
virtual EdgeSet outEdges(const Node &node) const
std::set< GraphEdge *, typename GraphEdge::Comparator > EdgeSet
Definition Graph.hh:54
ControlFlowGraph * newCFG_
Newly created control flow graph.
void createJump(BasicBlockNode *from, BasicBlockNode *to, TTAProgram::Terminal *guardReg=NULL, ControlFlowEdge::CFGEdgePredicate predicate=ControlFlowEdge::CFLOW_EDGE_NORMAL)

References ControlFlowEdge::CFLOW_EDGE_FALSE, ControlFlowEdge::CFLOW_EDGE_NORMAL, ControlFlowEdge::CFLOW_EDGE_TRUE, BoostGraph< GraphNode, GraphEdge >::connectingEdges(), BoostGraph< GraphNode, GraphEdge >::connectNodes(), createJump(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::edge(), Application::logStream(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::name(), newCFG_, BoostGraph< GraphNode, GraphEdge >::outEdges(), and BasicBlockNode::toString().

Referenced by processRegion().

Here is the call graph for this function:

◆ compareSiblings()

ProgramDependenceGraph::CompareResult ProgramDependenceGraph::compareSiblings ( Node a,
Node b 
)
private

Compare sibling nodes and determines their ordering relation based on eec information. In addition, nodes marked as lastNode are always ordered later in case ANY_ORDER is available.

Parameters
aFirst node to compare
bSecond node to compare
Returns
value determining relation

Both a and b are simple statements, order is given by data dependencies no need to test eec info

Find nodes relations in eec

FIXME: Unique region node rule is broken when creating loop entry nodes (removing loop back edge) and creating new region for incoming edges into loop entry - there can be another region which already has same set of dependencies and loop entry was supposed to be child of that, but was not. Problem with detection of subsets of dependencies when creating region nodes!

Definition at line 927 of file ProgramDependenceGraph.cc.

927 {
928 bool AinA = false;
929 bool BinB = false;
930 bool BinA = false;
931 bool AinB = false;
932
933#ifdef AVOID_COMPILER_WARNINGS_REMOVE_THESE_LINES
934 bool extra = false;
935 if (a->isPredicateMoveNode() || b->isPredicateMoveNode()) {
936 extra = true;
937 }
938#endif
939 /// Both a and b are simple statements, order is given by data dependencies
940 /// no need to test eec info
941 if (a->isMoveNode() && b->isMoveNode()
942 && !a->isPredicateMoveNode() && !b->isPredicateMoveNode()) {
943 return ANY_ORDER;
944 }
945 /// Find nodes relations in eec
946 if (AssocTools::containsKey(a->eec(), a)) {
947 AinA = true;
948 }
949 if (AssocTools::containsKey(b->eec(), b)) {
950 BinB = true;
951 }
952 if (AssocTools::containsKey(a->eec(), b)) {
953 BinA = true;
954 }
955 if (AssocTools::containsKey(b->eec(), a)) {
956 AinB = true;
957 }
958 //std::cerr << "AinA=" << AinA << ", BinB=" << BinB <<", AinB=" << AinB
959 // << ", BinA=" << BinA << std::endl;
960 if ((a->isLoopEntryNode() || a->isPredicateMoveNode())
961 && (b->isMoveNode() && !b->isPredicateMoveNode())
962 && AinA == true) {
963 if (a->isLastNode()) {
964 return B_BEFORE_A;
965 }
966 return ANY_ORDER;
967 }
968 if ((b->isLoopEntryNode() || b->isPredicateMoveNode())
969 && (a->isMoveNode() && !a->isPredicateMoveNode())
970 && BinB == true) {
971 if (b->isLastNode()) {
972 return A_BEFORE_B;
973 }
974 return ANY_ORDER;
975 }
976 if ((a->isLoopEntryNode() || a->isPredicateMoveNode())
977 && (b->isLoopEntryNode() || b->isPredicateMoveNode())
978 && AinA == true && BinB == true) {
979 if (a->isLastNode()) {
980 return B_BEFORE_A;
981 }
982 if (b->isLastNode()) {
983 return A_BEFORE_B;
984 }
985 return ANY_ORDER;
986 }
987 if ((a->isLoopEntryNode() || a->isPredicateMoveNode())
988 && (b->isMoveNode() && !b->isPredicateMoveNode())
989 && AinA == false) {
990 return B_BEFORE_A;
991 }
992 if ((b->isLoopEntryNode() || b->isPredicateMoveNode())
993 && (a->isMoveNode() && !a->isPredicateMoveNode())
994 && BinB == false) {
995 return A_BEFORE_B;
996 }
997 if ((a->isLoopEntryNode() || a->isPredicateMoveNode())
998 && (b->isLoopEntryNode() || b->isPredicateMoveNode())
999 && AinA == false && BinB == true) {
1000 return B_BEFORE_A;
1001 }
1002 if ((b->isLoopEntryNode() || b->isPredicateMoveNode())
1003 && (a->isLoopEntryNode() || a->isPredicateMoveNode())
1004 && AinA == true && BinB == false) {
1005 return A_BEFORE_B;
1006 }
1007 if ((a->isLoopEntryNode() || a->isPredicateMoveNode())
1008 && (b->isLoopEntryNode() || b->isPredicateMoveNode())
1009 && AinA == false && BinB == false) {
1010 //std::cerr << "\tUnorderable 1" << std::endl;
1011 return UNORDERABLE;
1012 }
1013 if ((a->isRegionNode() && AinB == true)
1014 && (b->isMoveNode() ||
1015 b->isLoopEntryNode() ||
1016 b->isPredicateMoveNode())){
1017 return B_BEFORE_A;
1018 }
1019 if ((b->isRegionNode() && BinA == true)
1020 && (a->isMoveNode() ||
1021 a->isLoopEntryNode() ||
1022 a->isPredicateMoveNode())){
1023 return A_BEFORE_B;
1024 }
1025 if ((a->isRegionNode() && AinB == false)
1026 && (b->isLoopEntryNode() || b->isPredicateMoveNode())
1027 && AinB == false) {
1028 //std::cerr << "\tUnorderable 2" << std::endl;
1029 return UNORDERABLE;
1030 }
1031 if ((b->isRegionNode() && BinA == false)
1032 && (a->isLoopEntryNode() || a->isPredicateMoveNode())
1033 && BinA == false) {
1034 //std::cerr << "\tUnorderable 3" << std::endl;
1035 return UNORDERABLE;
1036 }
1037 if ((a->isRegionNode() && AinB == false)
1038 && (b->isRegionNode() && BinA == true)) {
1039 return B_BEFORE_A;
1040 }
1041 if ((b->isRegionNode() && BinA == false)
1042 && (a->isRegionNode() && AinB == true)) {
1043 return A_BEFORE_B;
1044 }
1045 if ((a->isRegionNode() && AinB == false)
1046 && (b->isRegionNode() && BinA == false)) {
1047 return UNORDERABLE;
1048 }
1049 if ((a->isLoopCloseNode() && AinB == true)
1050 && (b->isMoveNode() || b->isPredicateMoveNode() || b->isLoopEntryNode()
1051 || b->isRegionNode())) {
1052 return B_BEFORE_A;
1053 }
1054 if ((b->isLoopCloseNode() && BinA == true)
1055 && (a->isMoveNode() || a->isPredicateMoveNode() || a->isLoopEntryNode()
1056 || a->isRegionNode())) {
1057 return A_BEFORE_B;
1058 }
1059 if ((a->isLoopCloseNode() && AinB == false)
1060 && (b->isPredicateMoveNode() || b->isLoopEntryNode()
1061 || b->isRegionNode())) {
1062 //std::cerr << "\tUnorderable 5" << std::endl;
1063 return UNORDERABLE;
1064 }
1065 if ((b->isLoopCloseNode() && BinA == false)
1066 && (a->isPredicateMoveNode() || a->isLoopEntryNode()
1067 || a->isRegionNode())) {
1068 //std::cerr << "\tUnorderable 6" << std::endl;
1069 return UNORDERABLE;
1070 }
1071 /// FIXME:
1072 /// Unique region node rule is broken when creating loop
1073 /// entry nodes (removing loop back edge) and creating new region for
1074 /// incoming edges into loop entry - there can be another region
1075 /// which already has same set of dependencies and loop entry was
1076 /// supposed to be child of that, but was not. Problem with detection
1077 /// of subsets of dependencies when creating region nodes!
1078 if ((a->isRegionNode() && AinB == true)
1079 && (b->isRegionNode() && BinA == true)) {
1080 Application::logStream() << (boost::format(
1081 "Found two regions with identical control dependencies. "
1082 "Known issue with CDG detection not reusing regions.\n")).str();
1083 if (a->isLastNode()) {
1084 return B_BEFORE_A;
1085 }
1086 if (b->isLastNode()) {
1087 return A_BEFORE_B;
1088 }
1089 return ANY_ORDER;
1090 }
1091 return ERROR;
1092}
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)

References A_BEFORE_B, ANY_ORDER, B_BEFORE_A, AssocTools::containsKey(), ProgramDependenceNode::eec(), ERROR, ProgramDependenceNode::isLastNode(), ProgramDependenceNode::isLoopCloseNode(), ProgramDependenceNode::isLoopEntryNode(), ProgramDependenceNode::isMoveNode(), ProgramDependenceNode::isPredicateMoveNode(), ProgramDependenceNode::isRegionNode(), Application::logStream(), and UNORDERABLE.

Referenced by processRegion().

Here is the call graph for this function:

◆ computeEECInfo()

void ProgramDependenceGraph::computeEECInfo ( const PDGOrderMap orderMap,
FilteredCDG filteredCDG 
)
private

Compute the "eec" information for each node of graph. EEC is used to determine order in which sibling subgraphs needs to be scheduled in resulting cfg.

"eec" of node X is set of nodes that will be executed in case any of the nodes in subgraph of X will be executed.

Parameters
orderMappost order map of PDG graph, nodes augmented with "region" information, "eec" information will be added.

eec already exists, skip

Found close node, eec(node) == intersection of all close nodes of same loop region(node) (close node is as leaf node)

Close nodes eec must be empty before we get here

Found leaf node, eec(node) == region(node)

Not a leaf node, eec(x) = intersection(eec(children(x)) \ children(x)

Definition at line 814 of file ProgramDependenceGraph.cc.

816 {
817
818 int mapSize = orderMap.size();
819
820 for (int i = 0; i < mapSize; i++) {
821 NodeDescriptor des =
823 orderMap, i);
824 Node* node = graph_[des];
825 /// eec already exists, skip
826 if (node->eec().size() > 0) {
827 continue;
828 }
829 /// Found close node, eec(node) == intersection of all close
830 /// nodes of same loop region(node) (close node is as leaf node)
831 if (node->isLoopCloseNode() && node->eec().size() == 0) {
832 std::vector<Node*> closeNodes;
833 std::set<Node*> component = strongComponents_[node->component()];
834 // collect all loop close nodes of same loop
835 for (std::set<Node*>::iterator si = component.begin();
836 si != component.end(); si++) {
837 if ((*si)->isLoopCloseNode()) {
838 closeNodes.push_back(*si);
839 } else if ((*si)->isRegionNode()
840 || (*si)->isPredicateMoveNode()) {
841 (*si)->setLastNode();
842 }
843 }
844 Node::NodesInfo finalInfo;
845 Node::NodesInfo storeResult;
846 finalInfo.insert(node->region().begin(),node->region().end());
847 for (unsigned int i = 0; i < closeNodes.size(); i++) {
849 finalInfo, closeNodes[i]->region(), storeResult);
850 finalInfo.swap(storeResult);
851 storeResult.clear();
852 }
853 // add intersection of all region info to each close node in loop
854 for (unsigned j = 0; j < closeNodes.size(); j++) {
855 Node* result = closeNodes[j];
856 /// Close nodes eec must be empty before we get here
857 if(result->eec().size() != 0) {
858 TCEString msg = (boost::format(
859 "Close node %s in %s already has eec!\n")
860 % result->toString() % node->toString()).str();
861 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
862 }
863 for (Node::NodesInfo::iterator k = finalInfo.begin();
864 k != finalInfo.end(); k++) {
865 result->addToEEC(**k);
866 }
867 }
868
869 } else if (boost::out_degree(descriptor(*node), filteredCDG) == 0) {
870 /// Found leaf node, eec(node) == region(node)
871 Node::NodesInfo regionX = node->region();
872 for (Node::NodesInfo::iterator t = regionX.begin();
873 t != regionX.end(); t++) {
874 node->addToEEC( **t);
875 }
876 } else {
877 /// Not a leaf node,
878 /// eec(x) = intersection(eec(children(x)) \ children(x)
879 Node::NodesInfo childNodes;
880 FilteredOutEdgePair edges =
881 boost::out_edges(descriptor(*node), filteredCDG);
882 for (FilteredOutEdgeIter ei = edges.first;
883 ei != edges.second;
884 ++ei) {
885 Node* testedNode = filteredCDG[boost::target(*ei, filteredCDG)];
886 childNodes.insert(testedNode);
887 }
888 Node::NodesInfo finalEEC;
889
890 // Fill in candidate set with data from first successor
891 finalEEC.insert(
892 (*(childNodes.begin()))->eec().begin(),
893 (*(childNodes.begin()))->eec().end());
894 // compute intersection of successors eec
895 for(Node::NodesInfo::iterator j = childNodes.begin();
896 j != childNodes.end(); j++ ) {
897 Node::NodesInfo storeResult;
898 SetTools::intersection(finalEEC, (*j)->eec(), storeResult);
899 finalEEC.swap(storeResult);
900 storeResult.clear();
901 }
902 std::vector<Node*> result(finalEEC.size(), NULL);
903 // compute set difference, returns iterator pointing to
904 // .end() of the result
905 std::vector<Node*>::iterator resultEnd =
906 std::set_difference(finalEEC.begin(), finalEEC.end(),
907 childNodes.begin(), childNodes.end(), result.begin());
908 // push resulting eec into the node eec info
909 for (std::vector<Node*>::iterator t = result.begin();
910 t != resultEnd; t++) {
911 node->addToEEC(**t);
912 }
913 }
914 }
915}
GraphTraits::vertex_descriptor NodeDescriptor
Type with which nodes of the graph are seen internally.
virtual std::string toString() const
Definition GraphNode.cc:61
boost::graph_traits< FilteredCDG >::out_edge_iterator FilteredOutEdgeIter
std::pair< FilteredOutEdgeIter, FilteredOutEdgeIter > FilteredOutEdgePair
std::set< ProgramDependenceNode * > NodesInfo
static void intersection(const std::set< ValueType > &firstContainer, const std::set< ValueType > &secondContainer, std::set< ValueType > &intersection)

References __func__, ProgramDependenceNode::addToEEC(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::descriptor(), ProgramDependenceNode::eec(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::graph_, SetTools::intersection(), MapTools::keyForValue(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node(), strongComponents_, ProgramDependenceNode::toString(), and GraphNode::toString().

Referenced by serializePDG().

Here is the call graph for this function:

◆ computeRegionInfo()

void ProgramDependenceGraph::computeRegionInfo ( const PDGOrderMap orderMap,
FilteredCDG cdg 
)
private

Compute the "region" information for each node of graph. Region is used to compute "eec" to determine order in which sibling subgraphs will be in resulting cfg.

"Region" of node X is set of nodes that will be executed in case is X executed.

Parameters
orderMappost order map of PDG graph, nodes will be augmented with "region" information.
cdgProgram Dependence Graph filtered to us only control dependence edges.

Compute "region" information using reverse post-order processing Node descriptors in filtered graph are identical to original graph we only care about edge filtering here

For non loop entry nodes, simply compute region info and store it in the node

for loop entry node, find all other entry nodes of the same loop (component) final region info will be intersection of region info from all the entry nodes in the same loop it will be same for all the nodes too (they are reachable)

Check if node is loop entry node of tested component

for every entry node of the loop compute region info

Definition at line 742 of file ProgramDependenceGraph.cc.

744 {
745
746 int mapSize = orderMap.size();
747 if (mapSize == 0) {
748 throw ModuleRunTimeError(__FILE__, __LINE__, __func__,
749 "No nodes in CDG graph for " + name() + "!");
750 }
751 /// Compute "region" information using reverse post-order processing
752 /// Node descriptors in filtered graph are identical to original graph
753 /// we only care about edge filtering here
754 for (int i = mapSize -1 ; i >= 0 ; i--) {
755 NodeDescriptor des =
757 Node* node = graph_[des];
758 if (!node->isLoopEntryNode()) {
759 /// For non loop entry nodes, simply compute region info
760 /// and store it in the node
761 Node::NodesInfo finalNodesInfo;
762 regionHelper(node, cdg, finalNodesInfo);
763 for (Node::NodesInfo::iterator k = finalNodesInfo.begin();
764 k != finalNodesInfo.end(); k++) {
765 node->addToRegion(**k);
766 }
767
768 } else if (node->region().size() == 0) {
769 /// for loop entry node, find all other entry nodes
770 /// of the same loop (component)
771 /// final region info will be intersection of region info from
772 /// all the entry nodes in the same loop
773 /// it will be same for all the nodes too (they are reachable)
774 std::vector<Node*> entries;
775 std::set<Node*> component = strongComponents_[node->component()];
776 for (std::set<Node*>::iterator si = component.begin();
777 si != component.end(); si++) {
778 /// Check if node is loop entry node of tested component
779 if ((*si)->isLoopEntryNode(node->component())) {
780 entries.push_back(*si);
781 }
782 }
783 Node::NodesInfo finalNodesInfo;
784 for (unsigned int i = 0; i < entries.size(); i++) {
785 /// for every entry node of the loop compute region info
786 Node* entryNode = entries[i];
787 regionHelper(entryNode, cdg, finalNodesInfo);
788 }
789 for (unsigned j = 0; j < entries.size(); j++) {
790 Node* result = entries[j];
791 for (Node::NodesInfo::iterator k = finalNodesInfo.begin();
792 k != finalNodesInfo.end();
793 k++) {
794 result->addToRegion(**k);
795 }
796 }
797 }
798 }
799}
void regionHelper(Node *node, FilteredCDG &filteredCDG, Node::NodesInfo &finalNodesInfo)
void addToRegion(ProgramDependenceNode &node)

References __func__, ProgramDependenceNode::addToRegion(), entryNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::graph_, MapTools::keyForValue(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::name(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node(), regionHelper(), and strongComponents_.

Referenced by serializePDG().

Here is the call graph for this function:

◆ computeRelations()

void ProgramDependenceGraph::computeRelations ( const PDGOrderMap orderMap,
FilteredCDG filteredCDG 
)
private

Computes relation between every pair of nodes in a graph that has common parent.

Parameters
orderMapPost order map of a graph @parem filteredCDG Filtered PDG with only control dependence edges

Process nodes in post order, guarantees child region/loopEntry/predicate nodes will be processed before their parent

MoveNodes are skipped here, they are always children of region

Definition at line 1452 of file ProgramDependenceGraph.cc.

1454 {
1455
1456 /// Process nodes in post order, guarantees child region/loopEntry/predicate
1457 /// nodes will be processed before their parent
1458 int mapSize = orderMap.size();
1459
1460 cdg_->writeToDotFile(name() + "_originalCDG.dot");
1461
1463 for (int i = 0; i < mapSize; i++) {
1464 NodeDescriptor des =
1466 orderMap, i);
1467 Node* node = graph_[des];
1468 /// MoveNodes are skipped here, they are always children of region
1469 if (node->isRegionNode()
1470 || node->isLoopEntryNode()) {
1471 processRegion(node, filteredCDG);
1472 continue;
1473 }
1474 if (node->isPredicateMoveNode()){
1475 processPredicate(node, filteredCDG);
1476 continue;
1477 }
1478 if (node->isLoopCloseNode()) {
1480 continue;
1481 }
1482 }
1483 newCFG_->writeToDotFile(name() + "_newCFG.dot");
1484 writeToDotFile(name() + "_newPDG.dot");
1485
1486}
virtual void writeToDotFile(const TCEString &fileName) const
void processRegion(Node *region, FilteredCDG &filteredCDG)
void processPredicate(Node *predicate, FilteredCDG &filteredCDG)

References cdg_, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::graph_, MapTools::keyForValue(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::name(), newCFG_, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node(), processLoopClose(), processPredicate(), processRegion(), program_, and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Here is the call graph for this function:

◆ copyRegionEECComponent()

void ProgramDependenceGraph::copyRegionEECComponent ( ControlToProgram cDNodeToPNode,
BBToCD bBlockToCDNode,
MoveNodeToPDGNode ,
MovesInCD moveToCD 
)
private

Copies Region and EEC information from CDG nodes to PDG. Only used if "preprocessing" is done via CDG analysis. Copies also component members.

Parameters
cDNodeToPNodeMap between CDG nodes and PDG nodes
bBlockToCDNodeMap between basic blocks and CDG nodes
moveToPNodeMap between move nodes and their PDG equivalents
moveToCDMap between CDG node and all PDG equivalents of it's content

Find source of region and eec. In case node is move or predicate have to find parent CDG node

No region or eec info in entry

For non basic block/predicate nodes, we copied them so they will also be in 'region' and 'eec'. Set component info for nodes that are part of loop as well

If cdg node is basic block or predicate, all moves inside will be part of same component

If destination in 'region' is CDG node, add it

If destination in 'region' is BB, add all the moves in it

We have node which was in predicate basic block but is not the actual predicate move node. We have to copy "shadow" eec information

any other type of node should have same eec information as it's CDG counterpart or basic block it belonged to

If node was in predicate basic block and is predicate we also test if it is lastNode and set info

Definition at line 1631 of file ProgramDependenceGraph.cc.

1635 {
1636
1637 int componentCount = cdg_->componentCount();
1638 strongComponents_.resize(componentCount);
1639
1640 for (int i = 0; i < nodeCount(); i++) {
1642 ControlDependenceNode* cNode = NULL;
1643
1644 /// Find source of region and eec. In case node is move or predicate
1645 /// have to find parent CDG node
1646 if (node == entryNode_) {
1647 /// No region or eec info in entry
1648 continue;
1649 }
1650 if (node->isRegionNode()
1651 || node->isLoopEntryNode()
1652 || node->isLoopCloseNode()) {
1653 /// For non basic block/predicate nodes, we copied them so
1654 /// they will also be in 'region' and 'eec'.
1655 /// Set component info for nodes that are part of loop as well
1656 cNode = &node->cdgNode();
1657 if (cNode->component() != -1) {
1658 node->setComponent(cNode->component());
1659 strongComponents_[node->component()].insert(node);
1660 }
1661 } else {
1662 const BasicBlockNode* BB =
1663 &ddg_->getBasicBlockNode(node->moveNode());
1664 if (MapTools::containsKey(bBlockToCDNode, BB)) {
1665 cNode =
1667 bBlockToCDNode, BB);
1668 } else {
1669 throw InvalidData(__FILE__, __LINE__, __func__,
1670 "No CD node for basic block!" + BB->toString());
1671 }
1672 /// If cdg node is basic block or predicate, all moves inside
1673 /// will be part of same component
1674 if (cNode->component() != -1) {
1675 std::vector<Node*> nodesInBB = moveToCD[cNode];
1676 int currentComponent = cNode->component();
1677 for (unsigned int i = 0; i < nodesInBB.size(); i++) {
1678 strongComponents_[currentComponent].insert(
1679 nodesInBB[i]);
1680 nodesInBB[i]->setComponent(currentComponent);
1681 }
1682 }
1683 }
1684
1686 for (ControlDependenceNode::NodesInfo::iterator iter = rInfo.begin();
1687 iter != rInfo.end();
1688 iter++) {
1689 /// If destination in 'region' is CDG node, add it
1690 if ((*iter)->isRegionNode()
1691 || (*iter)->isLoopCloseNode()
1692 || (*iter)->isLoopEntryNode()) {
1693 Node* target = cDNodeToPNode[*iter];
1694 node->addToRegion(*target);
1695 } else {
1696 /// If destination in 'region' is BB, add all the moves in it
1697 std::vector<Node*> nodesInBB = moveToCD[*iter];
1698 for (unsigned int i = 0; i < nodesInBB.size(); i++) {
1699 node->addToRegion(*nodesInBB[i]);
1700 }
1701 }
1702 }
1704 if (cNode->isPredicateNode() && !node->isPredicateMoveNode()) {
1705 /// We have node which was in predicate basic block but is not
1706 /// the actual predicate move node.
1707 /// We have to copy "shadow" eec information
1708 eecInfo = cNode->pseudoPredicateEEC();
1709 } else {
1710 /// any other type of node should have same eec information as it's
1711 /// CDG counterpart or basic block it belonged to
1712 eecInfo = cNode->eec();
1713 /// If node was in predicate basic block and is predicate we also
1714 /// test if it is lastNode and set info
1715 if (cNode->isPredicateNode()
1716 && node->isPredicateMoveNode()
1717 && cNode->isLastNode()) {
1718 node->setLastNode();
1719 }
1720 }
1721 for (ControlDependenceNode::NodesInfo::iterator iter =
1722 eecInfo.begin(); iter != eecInfo.end(); iter++) {
1723 if ((*iter)->isRegionNode()
1724 || (*iter)->isLoopCloseNode()
1725 || (*iter)->isLoopEntryNode()) {
1726 Node* target = cDNodeToPNode[*iter];
1727 node->addToEEC(*target);
1728 } else {
1729 std::vector<Node*> nodesInBB = moveToCD[*iter];
1730 for (unsigned int i = 0; i < nodesInBB.size(); i++) {
1731 node->addToEEC(*nodesInBB[i]);
1732 }
1733 }
1734 }
1735 }
1736}
const NodesInfo & pseudoPredicateEEC()
std::set< ControlDependenceNode * > NodesInfo
Storage type for other nodes of same graph needed to define some non graph relations....

References __func__, cdg_, ControlDependenceNode::component(), ControlDependenceGraph::componentCount(), MapTools::containsKey(), ddg_, ControlDependenceNode::eec(), entryNode_, DataDependenceGraph::getBasicBlockNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::graph_, ControlDependenceNode::isLastNode(), ControlDependenceNode::isPredicateNode(), MapTools::keyForValue(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::nodeCount(), ControlDependenceNode::pseudoPredicateEEC(), ControlDependenceNode::region(), strongComponents_, and BasicBlockNode::toString().

Referenced by ProgramDependenceGraph().

Here is the call graph for this function:

◆ createJump()

void ProgramDependenceGraph::createJump ( BasicBlockNode from,
BasicBlockNode to,
TTAProgram::Terminal guardReg = NULL,
ControlFlowEdge::CFGEdgePredicate  predicate = ControlFlowEdge::CFLOW_EDGE_NORMAL 
)
private

If reference already exists, just return it

Definition at line 2003 of file ProgramDependenceGraph.cc.

2007 {
2008 return;
2009 if (from->isNormalBB() && to->isNormalBB()
2010 //&& !from->basicBlock().lastInstruction().hasControlFlowMove()
2011 ) {
2013 Application::logStream() << "\tMove already has CF " <<
2014 from->basicBlock().lastInstruction().toString() << std::endl;
2015 }
2016 Application::logStream() << (boost::format(
2017 "Creating jump from %s to %s\n")
2018 % from->toString() % to->toString()).str();
2021 /// If reference already exists, just return it
2024
2027
2028 TTAProgram::TerminalFUPort* jump1Terminal =
2029 new TTAProgram::TerminalFUPort(*hwOp, 1);
2030
2031 TTAProgram::Terminal* jump0Terminal =
2033
2034 auto jumpMove = std::make_shared<TTAProgram::Move>(
2035 jump0Terminal, jump1Terminal,
2037
2038 if (predicate == ControlFlowEdge::CFLOW_EDGE_TRUE) {
2041 for (int i = 0; i < busNav.count(); i++) {
2042 TTAMachine::Bus* bus = busNav.item(i);
2043 for (int i = 0; i < bus->guardCount(); i++) {
2044 TTAMachine::RegisterGuard* regGuard =
2045 dynamic_cast<TTAMachine::RegisterGuard*>(bus->guard(i));
2046 if (regGuard != NULL &&
2047 regGuard->registerFile() == &guardReg->registerFile() &&
2048 regGuard->registerIndex() == (int)guardReg->index()) {
2049 jumpMove->setGuard(
2050 new TTAProgram::MoveGuard(*regGuard));
2051 break;
2052 }
2053 }
2054 }
2055 } else if (predicate == ControlFlowEdge::CFLOW_EDGE_FALSE) {
2058 for (int i = 0; i < busNav.count(); i++) {
2059 TTAMachine::Bus* bus = busNav.item(i);
2060 for (int i = 0; i < bus->guardCount(); i++) {
2061 TTAMachine::RegisterGuard* regGuard =
2062 dynamic_cast<TTAMachine::RegisterGuard*>(bus->guard(i));
2063 if (regGuard != NULL &&
2064 regGuard->registerFile() == &guardReg->registerFile() &&
2065 regGuard->registerIndex() == (int)guardReg->index() &&
2066 regGuard->isInverted() == true) {
2067 jumpMove->setGuard(
2068 new TTAProgram::MoveGuard(*regGuard));
2069 break;
2070 }
2071 }
2072 }
2073 }
2074
2076 if (inst->moveCount() > 0) {
2077 inst = new TTAProgram::Instruction();
2078 from->basicBlock().add(inst);
2079 }
2080 std::cerr << " before result " << inst->toString() << std::endl;
2081 inst->addMove(jumpMove);
2082 std::cerr << " after result " << inst->toString() << std::endl;
2083 } else {
2084 Application::logStream() << (boost::format(
2085 "Failed to add jump for %s %s, %s, %s\n")
2086 % from->toString() % to->toString() %
2087 from->basicBlock().lastInstruction().toString() %
2088 to->basicBlock().firstInstruction().toString()).str();
2089 }
2090}
TTAProgram::BasicBlock & basicBlock()
bool isNormalBB() const
Guard * guard(int index) const
Definition Bus.cc:456
int guardCount() const
Definition Bus.cc:441
virtual HWOperation * operation(const std::string &name) const
virtual bool isInverted() const
ComponentType * item(int index) const
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
const RegisterFile * registerFile() const
virtual Instruction & firstInstruction() const
virtual void add(Instruction *ins)
virtual Instruction & lastInstruction() const
InstructionReference createReference(Instruction &ins)
std::string toString() const
bool hasControlFlowMove() const
void addMove(std::shared_ptr< Move > move)
InstructionReferenceManager & instructionReferenceManager() const
Definition Program.cc:688
UniversalMachine & universalMachine() const
Definition Program.cc:104
virtual int index() const
Definition Terminal.cc:274
virtual const TTAMachine::RegisterFile & registerFile() const
Definition Terminal.cc:225
TTAMachine::Bus & universalBus() const

References TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), BasicBlockNode::basicBlock(), TTAMachine::Machine::busNavigator(), ControlFlowEdge::CFLOW_EDGE_FALSE, ControlFlowEdge::CFLOW_EDGE_TRUE, TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAProgram::InstructionReferenceManager::createReference(), TTAProgram::CodeSnippet::firstInstruction(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), TTAProgram::Instruction::hasControlFlowMove(), TTAProgram::Terminal::index(), TTAProgram::Program::instructionReferenceManager(), TTAMachine::Guard::isInverted(), BasicBlockNode::isNormalBB(), TTAMachine::Machine::Navigator< ComponentType >::item(), TTAProgram::CodeSnippet::lastInstruction(), Application::logStream(), TTAProgram::Instruction::moveCount(), TTAMachine::FunctionUnit::operation(), program_, TTAMachine::RegisterGuard::registerFile(), TTAProgram::Terminal::registerFile(), TTAMachine::RegisterGuard::registerIndex(), BasicBlockNode::toString(), TTAProgram::Instruction::toString(), UniversalMachine::universalBus(), and TTAProgram::Program::universalMachine().

Referenced by addLeafEdges(), processLoopEntry(), processPredicate(), and processRegion().

Here is the call graph for this function:

◆ detectStrongComponents()

int ProgramDependenceGraph::detectStrongComponents ( PDGOrderMap components,
DescriptorMap roots,
FilteredCDG cdg 
)
private

Detects all strong components of a PDG graph (loops). Strong components are maximal sets of nodes that are reachable from each other. Each node is member of some component. If it is not in loop then node is components of it's own. Augments graph with loop entry and close nodes. Works iteratively, first detects maximal component, then proceeds to ones that are "embedded".

Parameters
componentsAfter return contains for each node number of component to which node belongs
rootsAfter return contains for each node a node that is root of component to which node belongs
Returns
returns number of components in a graph

Will repeat until all the strong components will be found Including weirdly nested :-)

Node count will change with addition of close nodes

If the number of components is identical to number of nodes there are no loops in graph

Add to strong components only those which are loops Store them as Node*, use of descriptors is not possible due to later addition of Nodes which will invalidate descriptors

Detects all loop entry nodes Stores Nodes which are identified as loop entry nodes together with number to which loop they belong

for each entry node, collect edges that points to it from outside the loop, deals only with newly added components

tail of the edge is not inside component it is external edge making this node loop entry

Several nodes points to loop entry node we create dummy region node to collect those edges

Adds close nodes for each loop entry node Node and Edge descriptors are invalidated here!

Create one "close" node for each loop entry

Close node is also part of component

Redirect edges to loop entry from inside the loop to loop close node. Collect edges that needs redirecting

store edges that will have to be moved

Actually redirect edges

Back edge will be added later, after all loops are found

Close node is also added to unfiltered pdg, as well as edges so we can test it directly there and not on filtered graph

In case loop entry has multiple incoming edges outside loop, we add new region to group them together This can be also on original pdg, no need to use filtered version

Creates new artificial region node without equivalent one in CDG

Add edges from close nodes to their respective loop entries

Definition at line 532 of file ProgramDependenceGraph.cc.

535 {
536
537 std::vector<std::pair<Node*, Node*> > backEdges;
538 int componentCount = 0;
539 int currentComponents = 0;
540 int numberOfNodes = 0;
541
542 /// Will repeat until all the strong components will be found
543 /// Including weirdly nested :-)
544 do {
545 PDGOrder componentOrder(components);
546 Descriptors componentRoots(roots);
547 currentComponents = 0;
548 /// Node count will change with addition of close nodes
549 numberOfNodes = boost::num_vertices(cdg);
550 currentComponents = boost::strong_components(
551 cdg, componentOrder, boost::root_map(componentRoots));
552
553 // for each component add vector of nodes that belongs to it
554 std::vector<std::set<Node*> > componentVector;
555 componentVector.resize(componentCount + currentComponents);
556
557 /// If the number of components is identical to number of nodes
558 /// there are no loops in graph
559 if (currentComponents == numberOfNodes) {
560 componentCount = strongComponents_.size();
561 break;
562 }
563
564 /// Add to strong components only those which are loops
565 /// Store them as Node*, use of descriptors is not possible
566 /// due to later addition of Nodes which will invalidate
567 /// descriptors
568 for (PDGOrderMap::iterator iterA = components.begin();
569 iterA != components.end(); iterA ++) {
570 Node* cNode = cdg[(*iterA).first];
571 componentVector[(*iterA).second].insert(cNode);
572 }
573 for (unsigned int i = componentCount; i < componentVector.size(); i++){
574 if (componentVector[i].size() > 1) {
575 std::set<Node*>& vector = componentVector[i];
576 std::set<Node*> ref;
577 int componentsSize = strongComponents_.size();
578 for (std::set<Node*>::iterator iterB = vector.begin();
579 iterB != vector.end();
580 iterB++) {
581 ref.insert(*iterB);
582 // Set component number
583 if ((*iterB)->component() == -1){
584 (*iterB)->setComponent(componentsSize);
585 }
586 }
587 strongComponents_.push_back(ref);
588 }
589 }
590
591 /// Detects all loop entry nodes
592 /// Stores Nodes which are identified as loop entry nodes
593 /// together with number to which loop they belong
594 std::vector<std::pair<Node*,int> > newEntry;
595 /// for each entry node, collect edges that points to it from outside
596 /// the loop, deals only with newly added components
597 std::map<Node*, std::vector<Node*> > incomingToEntry;
598 for (unsigned int i = componentCount;
599 i < strongComponents_.size();
600 i++) {
601 std::set<Node*>& nodes = strongComponents_[i];
602 for (std::set<Node*>::iterator iterD = nodes.begin();
603 iterD != nodes.end();
604 iterD++) {
605
607 vec = descriptor(**iterD);
608 FilteredInEdgePair edges = boost::in_edges(vec, cdg);
609 for (FilteredInEdgeIter ei = edges.first;
610 ei != edges.second;
611 ++ei) {
612
613 Node* testedNode = cdg[boost::source(*ei, cdg)];
614 if (nodes.find(testedNode) == nodes.end()) {
615 /// tail of the edge is not inside component
616 /// it is external edge making this node loop entry
617 if (!(*iterD)->isLoopEntryNode(i)) {
618 (*iterD)->setLoopEntryNode(i);
619 newEntry.push_back(
620 std::pair<Node*,int>(*iterD,i));
621 incomingToEntry[*iterD].push_back(testedNode);
622 } else {
623 /// Several nodes points to loop entry node
624 /// we create dummy region node to collect those
625 /// edges
626 incomingToEntry[*iterD].push_back(testedNode);
627 }
628 }
629 }
630 }
631 }
632
633 /// Adds close nodes for each loop entry node
634 /// Node and Edge descriptors are invalidated here!
635 for (unsigned int j = 0; j < newEntry.size(); j++) {
636 Node* loopNode = newEntry[j].first;
637 std::set<Node*>& nodes =
638 strongComponents_[newEntry[j].second];
639 /// Create one "close" node for each loop entry
640 Node* close = new Node(Node::PDG_NODE_LOOPCLOSE);
641 close->setComponent(newEntry[j].second);
642 addNode(*close);
643
644 /// Close node is also part of component
645 strongComponents_[newEntry[j].second].insert(close);
646
648 vec = descriptor(*loopNode);
649 FilteredInEdgePair edges = boost::in_edges(vec, cdg);
650 std::vector<Edge*> storeEdges;
651 /// Redirect edges to loop entry from inside the loop
652 /// to loop close node. Collect edges that needs redirecting
653 for (FilteredInEdgeIter ei = edges.first;
654 ei != edges.second;
655 ++ei) {
656 Node* sourceNode = cdg[boost::source(*ei, cdg)];
657 if (nodes.find(sourceNode) != nodes.end()){
658 /// store edges that will have to be moved
659 Edge* edge = cdg[*ei];
660 storeEdges.push_back(edge);
661 }
662 }
663 /// Actually redirect edges
664 for (unsigned int counter = 0;
665 counter < storeEdges.size();
666 counter++) {
667 moveInEdge(*loopNode, *close, *storeEdges[counter]);
668 }
669 /// Back edge will be added later, after all loops are found
670 backEdges.push_back(
671 std::pair<Node*, Node*>(close, loopNode));
672
673 /// Close node is also added to unfiltered pdg, as well as edges
674 /// so we can test it directly there and not on filtered graph
675 if (inDegree(*close) == 0) {
676 TCEString msg = "Close node for loop entry node ";
677 msg += loopNode->toString() + " was not connected!";
678 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
679 }
680 /// In case loop entry has multiple incoming edges
681 /// outside loop, we add new region to group them together
682 /// This can be also on original pdg, no need to use filtered
683 /// version
684 std::vector<Node*> tmp =
686 incomingToEntry, loopNode);
687 if (tmp.size() > 1) {
688 /// Creates new artificial region node without equivalent
689 /// one in CDG
690 Node* collect = new Node();
691 addNode(*collect);
692 for (unsigned int i = 0; i < tmp.size(); i++) {
693 Node* input = tmp[i];
694 EdgeDescriptor ed = connectingEdge(*input, *loopNode);
695 Edge* e = graph_[ed];
696 moveInEdge(*loopNode, *collect, *e);
697 }
698 ProgramDependenceEdge* pdgEdge =
700 connectNodes(*collect, *loopNode, *pdgEdge);
701 }
702 }
703 newEntry.clear();
704 componentCount = strongComponents_.size();
705 } while (true);
706
707 /// Add edges from close nodes to their respective loop entries
708 for (unsigned int i = 0; i < backEdges.size(); i++) {
709 ProgramDependenceEdge* pdgEdge =
712 connectNodes(*backEdges[i].first, *backEdges[i].second, *pdgEdge);
713 }
714
715#if 0
716 for (unsigned int i = 0; i < strongComponents_.size() ; i++) {
717 std::cerr << "\tComponent: " << i << std::endl;
718 for (std::set<Node*>::iterator iter = strongComponents_[i].begin();
719 iter != strongComponents_[i].end(); iter++) {
720 std::cerr << "\t\t" << (*iter)->toString() << std::endl;
721 }
722 std::cerr << std::endl;
723 }
724#endif
725 return componentCount;
726}
EdgeDescriptor connectingEdge(const Node &nTail, const Node &nHead) const
GraphTraits::edge_descriptor EdgeDescriptor
Type with which edges of the graph are seen internally.
virtual void moveInEdge(const Node &source, const Node &destination, Edge &edge, const Node *tail=NULL, bool childs=false)
ProgramDependenceEdge Edge
The (base) edge type managed by this graph.
Definition BoostGraph.hh:92
@ PDG_EDGE_LOOP_CLOSE
Indicates Data Dependence Edge from DDG.
boost::graph_traits< FilteredCDG >::in_edge_iterator FilteredInEdgeIter
Few types to work with filtered graph.
boost::graph_traits< FilteredCDG >::vertex_descriptor FilteredVertexDescriptor
std::pair< FilteredInEdgeIter, FilteredInEdgeIter > FilteredInEdgePair
boost::associative_property_map< PDGOrderMap > PDGOrder
boost::associative_property_map< DescriptorMap > Descriptors
void setComponent(int component)
void setLoopEntryNode(int component)

References __func__, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::addNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::connectingEdge(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::connectNodes(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::descriptor(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::edge(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::graph_, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::inDegree(), MapTools::keyForValue(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::moveInEdge(), ProgramDependenceEdge::PDG_EDGE_LOOP_CLOSE, ProgramDependenceNode::PDG_NODE_LOOPCLOSE, ProgramDependenceNode::setComponent(), ProgramDependenceNode::setLoopEntryNode(), strongComponents_, and ProgramDependenceNode::toString().

Referenced by serializePDG().

Here is the call graph for this function:

◆ disassemble()

void ProgramDependenceGraph::disassemble ( ) const

Definition at line 1948 of file ProgramDependenceGraph.cc.

1948 {
1949#if 0
1950 BackCFGFilter<ControlFlowGraph> backCFGFilter(*newCFG_);
1951 /// Create filtered graph
1952 CFGSubgraph sub = CFGSubgraph(*newCFG_, backCFGFilter);
1953 /// Sort nodes of subgraph topologically
1954 std::vector<ControlFlowGraph::NodeDescriptor> sorted;
1955 try {
1956 boost::topological_sort(*newCFG_, std::back_inserter(sorted));
1957 } catch (...) {
1958 Application::logStream() << (boost::format(
1959 "CFG %s can not be topologically sorted\n")
1960 % name()).str();
1961 }
1962 for (std::vector<ControlFlowGraph::NodeDescriptor>::reverse_iterator iter =
1963 sorted.rbegin();
1964 iter != sorted.rend(); iter++) {
1965 BasicBlockNode* node = newCFG_[*iter];
1966 if (node->isNormalBB()) {
1968 POMDIsassembler::disassemble(node->basicBlock());
1969 }
1970 }
1971
1972 Application::logStream() << (boost::format(
1973 "Trying out %s with node count %d\n")
1974 % name() % newCFG_->nodeCount()).str();
1977 TTAProgram::Procedure newProc(name(), space, 0);
1978 Application::logStream() << "Is in program " << newProc.isInProgram() <<
1979 std::endl;
1980 cdg_->program()->addProcedure(&newProc);
1981 newCFG_->copyToProcedure(newProc);
1982 //newCFG_->updateReferencesFromProcToCfg();
1983 Application::logStream() << "Procedure copied" <<
1984 std::endl;
1985 Application::logStream() << " start " << newProc.startAddress().location()
1986 << " end " << newProc.endAddress().location() << std::endl;
1987 //Application::logStream() <<
1988 // POMDisassembler::disassemble(newProc);
1989 cdg_->program()->removeProcedure(newProc);
1990 int count = newProc.instructionCount();
1991 for (int i = 0; i < count; i++) {
1992 Application::logStream() << (boost::format(
1993 "%s\n")
1994 % POMDisassembler::disassemble(newProc.instructionAtIndex(i),1)).str();
1995 }
1996 //ControlFlowGraph testCFG(newProc);
1997 //testCFG.writeToDotFile(name() + "_testCFG.dot");
1998 //delete newCFG_;
1999#endif
2000}
#define sub
void copyToProcedure(TTAProgram::Procedure &proc, TTAProgram::InstructionReferenceManager *irm=NULL)
static std::string disassemble(const TTAProgram::Move &move)
boost::filtered_graph< Graph, BackCFGFilter< Graph > > CFGSubgraph
void removeProcedure(Procedure &proc)
Definition Program.cc:901
void addProcedure(Procedure *proc)
Definition Program.cc:524
TTAMachine::AddressSpace & instructionAddressSpace() const

References TTAProgram::Program::addProcedure(), cdg_, ControlFlowGraph::copyToProcedure(), POMDisassembler::disassemble(), TTAProgram::CodeSnippet::endAddress(), UniversalMachine::instructionAddressSpace(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::CodeSnippet::isInProgram(), TTAProgram::Address::location(), Application::logStream(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::name(), newCFG_, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), ControlDependenceGraph::program(), TTAProgram::Program::removeProcedure(), TTAProgram::CodeSnippet::startAddress(), sub, and TTAProgram::Program::universalMachine().

Here is the call graph for this function:

◆ entryNode()

ProgramDependenceNode & ProgramDependenceGraph::entryNode ( ) const

Returns entry node of the graph.

Returns
Entry node

Definition at line 1099 of file ProgramDependenceGraph.cc.

1099 {
1100 if (entryNode_ == NULL ) {
1101 throw ModuleRunTimeError(
1102 __FILE__, __LINE__, __func__,
1103 "Trying to get entry node before it was defined!");
1104 }
1105 return *entryNode_;
1106}

References __func__, and entryNode_.

Referenced by computeRegionInfo(), ProgramDependenceGraph(), and serializePDG().

◆ moveDDGedges()

void ProgramDependenceGraph::moveDDGedges ( Node root,
NodeSet subgraphNodes,
FilteredCDG filteredCDG 
)
private

Helper method to move/copy DDG edges that connected subraph nodes with rest of the graph to the root node of subgraph

Parameters
rootNodeRoot node of subgraph
subgraphNodesNodes of the subgraph to test
filteredCDGFiltered cdg graph, containing only control dependence nodes

Do not process root of a subtree, it is child of other node and will be processed later

Test if target is region, predicate or loop node, those prefer copies

gets incoming control dependence edges of node more then one edge means node is reachable from several places

Deal with incoming edges

No need to deal with control dependence edges or data dependence that had been "fixed" - meaning they are between nodes of same subtree (including edges between root of subtree and child node)

Edges with identical properties already exists no need to copy or move, just remove edge

Creates copy of edge from outside subgraph to root of the graph

Edge is duplicate of already existing dependence

Moves edge from outside the subgraph to target root

Edge between nodes in subtree

Deal with outgoing edges

No need to deal with control dependence edges or data dependence that had been "fixed" - meaning they are between nodes of same subtree (including edges between root of subtree and child node)

Edges with identical properties already exists no need to copy or move, just remove edge

Creates copy of edge from outside subgraph to root of the graph if such edge does not exists

Edge is duplicate of already existing dependence

Moves edge from outside the subgraph to target root

Edge between nodes in subtree

Definition at line 1498 of file ProgramDependenceGraph.cc.

1501 {
1502
1503 for (NodeSet::iterator iter = subgraphNodes.begin();
1504 iter != subgraphNodes.end();
1505 iter++) {
1506 /// Do not process root of a subtree, it is child of other node
1507 /// and will be processed later
1508 if ((*iter) == &root) {
1509 continue;
1510 }
1511 /// Test if target is region, predicate or loop node,
1512 /// those prefer copies
1513 bool copyInsteadOfMove = false;
1514 if (!(*iter)->isMoveNode()) {
1515 /// gets incoming control dependence edges of node
1516 /// more then one edge means node is reachable from several places
1517 int parentCount = boost::in_degree(descriptor(**iter), filteredCDG);
1518 if (parentCount > 1) {
1519 copyInsteadOfMove = true;
1520 }
1521 }
1522 /// Deal with incoming edges
1523 EdgeSet inputs = inEdges(**iter);
1524 for (EdgeSet::iterator ein = inputs.begin();
1525 ein != inputs.end();
1526 ein++) {
1527 /// No need to deal with control dependence edges or data dependence
1528 /// that had been "fixed" - meaning they are between nodes of same
1529 /// subtree (including edges between root of subtree and child node)
1530 if (!(*ein)->isDataDependence() || (*ein)->fixed()) {
1531 continue;
1532 }
1533 Node* tail = &tailNode(**ein);
1534 if (!AssocTools::containsKey(subgraphNodes, tail)) {
1535 Edge* testedEdge = *ein;
1536 EdgeSet inputEdges = connectingEdges(*tail, root);
1537 bool duplicateEdge = false;
1538 for (EdgeSet::iterator testIter = inputEdges.begin();
1539 testIter != inputEdges.end();
1540 testIter ++) {
1541 if (!(*testIter)->isDataDependence()) {
1542 continue;
1543 }
1544 if ((testedEdge->dataDependenceEdge().dependenceType() ==
1545 (*testIter)->dataDependenceEdge().dependenceType())
1546 &&
1547 (testedEdge->dataDependenceEdge().edgeReason() ==
1548 (*testIter)->dataDependenceEdge().edgeReason())) {
1549 /// Edges with identical properties already exists
1550 /// no need to copy or move, just remove edge
1551 duplicateEdge = true;
1552 }
1553 }
1554 if (copyInsteadOfMove && !duplicateEdge) {
1555 /// Creates copy of edge from outside subgraph
1556 /// to root of the graph
1557 copyInEdge(root, **ein, tail);
1558 } else if (duplicateEdge) {
1559 /// Edge is duplicate of already existing dependence
1560 removeEdge(**ein);
1561 } else {
1562 /// Moves edge from outside the subgraph to target root
1563 moveInEdge(**iter, root, **ein);
1564 }
1565 } else {
1566 /// Edge between nodes in subtree
1567 (*ein)->setFixed();
1568 }
1569 }
1570 /// Deal with outgoing edges
1571 EdgeSet outputs = outEdges(**iter);
1572 for (EdgeSet::iterator eout = outputs.begin();
1573 eout != outputs.end();
1574 eout++) {
1575 /// No need to deal with control dependence edges or data dependence
1576 /// that had been "fixed" - meaning they are between nodes of same
1577 /// subtree (including edges between root of subtree and child node)
1578 if (!(*eout)->isDataDependence() || (*eout)->fixed()) {
1579 continue;
1580 }
1581 Node* head = &headNode(**eout);
1582 if (!AssocTools::containsKey(subgraphNodes, head)) {
1583 Edge* testedEdge = *eout;
1584 EdgeSet outputEdges = connectingEdges(root, *head);
1585 bool duplicateEdge = false;
1586 for (EdgeSet::iterator testIter = outputEdges.begin();
1587 testIter != outputEdges.end();
1588 testIter ++) {
1589 if (!(*testIter)->isDataDependence()) {
1590 continue;
1591 }
1592 if ((testedEdge->dataDependenceEdge().dependenceType() ==
1593 (*testIter)->dataDependenceEdge().dependenceType())
1594 &&
1595 (testedEdge->dataDependenceEdge().edgeReason() ==
1596 (*testIter)->dataDependenceEdge().edgeReason())) {
1597 /// Edges with identical properties already exists
1598 /// no need to copy or move, just remove edge
1599 duplicateEdge = true;
1600 }
1601 }
1602 if (copyInsteadOfMove && !duplicateEdge) {
1603 /// Creates copy of edge from outside subgraph
1604 /// to root of the graph if such edge does not exists
1605 copyOutEdge(root, **eout, head);
1606 } else if (duplicateEdge) {
1607 /// Edge is duplicate of already existing dependence
1608 removeEdge(**eout);
1609 } else {
1610 /// Moves edge from outside the subgraph to target root
1611 moveOutEdge(**iter, root, **eout);
1612 }
1613 } else {
1614 /// Edge between nodes in subtree
1615 (*eout)->setFixed();
1616 }
1617 }
1618 }
1619}
virtual void copyOutEdge(const Node &destination, Edge &edge, const Node *head=NULL)
std::set< ProgramDependenceEdge *, typename GraphEdge::Comparator > EdgeSet
Definition BoostGraph.hh:87
virtual void copyInEdge(const Node &destination, Edge &edge, const Node *tail=NULL)
virtual void moveOutEdge(const Node &source, const Node &destination, Edge &edge, const Node *head=NULL, bool childs=false)
virtual EdgeSet inEdges(const Node &node) const

References BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::connectingEdges(), AssocTools::containsKey(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::copyInEdge(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::copyOutEdge(), ProgramDependenceEdge::dataDependenceEdge(), DataDependenceEdge::dependenceType(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::descriptor(), DataDependenceEdge::edgeReason(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::headNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::inEdges(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::moveInEdge(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::moveOutEdge(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::outEdges(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::removeEdge(), and BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::tailNode().

Referenced by processPredicate(), and processRegion().

Here is the call graph for this function:

◆ processEntry()

void ProgramDependenceGraph::processEntry ( BasicBlockNode firstBB)
private

When entry node is found during serialization, the artificial Entry and Exit nodes are added to CFG. There is added edge from Entry to first BB and All leaf nodes will have edge to the exit.

Definition at line 1744 of file ProgramDependenceGraph.cc.

1744 {
1745 BasicBlockNode* newEntry = new BasicBlockNode(0, 0, true, false);
1746 newCFG_->addNode(*newEntry);
1748 newCFG_->connectNodes(*newEntry, *firstBB, *edge);
1749 newCFG_->addExit();
1750// Application::logStream() << (boost::format(
1751// "Create new Entry %s for %s\n")
1752// % newEntry->toString() % firstBB->toString()).str();
1753}
void addExit(NodeSet &retSourceNodes)

References ControlFlowGraph::addExit(), BoostGraph< GraphNode, GraphEdge >::addNode(), BoostGraph< GraphNode, GraphEdge >::connectNodes(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::edge(), and newCFG_.

Referenced by processRegion().

Here is the call graph for this function:

◆ processLoopClose()

void ProgramDependenceGraph::processLoopClose ( Node node)
private

Add empty instruction, actual jump move will be created when we process corresponding loop entry

Definition at line 1903 of file ProgramDependenceGraph.cc.

1903 {
1905 BasicBlockNode* bb = new BasicBlockNode(*block);
1906 newCFG_->addNode(*bb);
1908 /// Add empty instruction, actual jump move will be created when
1909 /// we process corresponding loop entry
1910 bb->basicBlock().add(newIns);
1911 insCount_++;
1912 node->setNewFirstBB(bb);
1913 /*NodeSet predecessorsNodes = predecessors(*node);
1914 for (NodeSet::iterator iter = predecessorsNodes.begin();
1915 iter != predecessorsNodes.end(); iter++) {
1916 (*iter)->setLastNode();
1917 }*/
1918/* Application::logStream() << (boost::format(
1919 "Creating BB %s for loop close %s")
1920 % bb->toString() % node->toString()).str();*/
1921}

References TTAProgram::CodeSnippet::add(), BoostGraph< GraphNode, GraphEdge >::addNode(), BasicBlockNode::basicBlock(), insCount_, newCFG_, and BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node().

Referenced by computeRelations().

Here is the call graph for this function:

◆ processLoopEntry()

void ProgramDependenceGraph::processLoopEntry ( Node node,
BasicBlockNode bb 
)
private

Add edge from loop close node to corresponding loop entry

Definition at line 1924 of file ProgramDependenceGraph.cc.

1924 {
1925 /// Add edge from loop close node to corresponding loop entry
1926 if (bb == NULL) {
1927 return;
1928 }
1929 NodeSet inputs = predecessors(*node);
1930 for(NodeSet::iterator ni = inputs.begin(); ni != inputs.end();
1931 ni++) {
1932 if((*ni)->isLoopCloseNode()
1933 && (*ni)->newFirstBB() != NULL
1934 && (*ni)->component() == node->component()) {
1935/* Application::logStream() << "Adding loop edge "
1936 << (*ni)->newFirstBB()->toString() << " to "
1937 << bb->toString() << std::endl;*/
1939 edge->setBackEdge();
1940 newCFG_->connectNodes(*(*ni)->newFirstBB(), *bb, *edge);
1941 std::cerr << "Adding for loop entry" << std::endl;
1942 createJump((*ni)->newFirstBB(), bb);
1943 }
1944 }
1945}
std::set< ProgramDependenceNode *, typename GraphNode::Comparator > NodeSet
Definition BoostGraph.hh:86
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const

References BoostGraph< GraphNode, GraphEdge >::connectNodes(), createJump(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::edge(), newCFG_, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node(), and BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::predecessors().

Referenced by processPredicate(), and processRegion().

Here is the call graph for this function:

◆ processPredicate()

void ProgramDependenceGraph::processPredicate ( Node predicate,
FilteredCDG filteredCDG 
)
private

Process predicate node of the graph.

Add edges from predicate to one or two child region nodes and fill in next basic block with last BB of first child region and fall through BB with last BB of second child (if exists), otherwise predicate BB itself. Also moves DDG edges between child nodes and out of subtree to point to predicate for topological sorting of region where predicate itself belongs.

Parameters
predicatePredicate node to process
filteredCDGFiltered graph from where we get child nodes of predicate

Get all child nodes of predicate node

Store all child nodes, we will need to collect all edges to and from subgraph rooted by predicate

Create basic block with predicate, it will be also first to execute

In case one of branches had only single absolute jump to "exit" of procedure, there is no child basic block

One of the outgoing edges is missing, we will have to add edge from predicate itself to next BB

Move/copy edges between nodes "inside" subgraph and nodes outside the subgraph

Definition at line 1768 of file ProgramDependenceGraph.cc.

1770 {
1771
1772 /// Get all child nodes of predicate node
1773 NodeDescriptor nodeDes = descriptor(*predicate);
1774 FilteredOutEdgePair edges = boost::out_edges(nodeDes, filteredCDG);
1775 /// Store all child nodes, we will need to collect all edges
1776 /// to and from subgraph rooted by predicate
1777 NodeSet subgraphNodes;
1778 subgraphNodes.insert(predicate);
1779 /// Create basic block with predicate, it will be also first to
1780 /// execute
1782 BasicBlockNode* bb = new BasicBlockNode(*block);
1783// Application::logStream() << (boost::format(
1784// "Create new Predicate BB %s for %s\n")
1785// % bb->toString() % predicate->toString()).str();
1786
1787 newCFG_->addNode(*bb);
1789 newIns->addMove(predicate->moveNode().movePtr());
1790 TTAProgram::Terminal& guardReg =
1791 predicate->moveNode().move().destination();
1792
1793 bb->basicBlock().add(newIns);
1794 insCount_++;
1795 predicate->setNewFirstBB(bb);
1796
1797 bool hasTrue = false;
1798 bool hasFalse = false;
1799 for (FilteredOutEdgeIter ei1 = edges.first;
1800 ei1 != edges.second;
1801 ++ei1) {
1802 Edge* edge = graph_[*ei1];
1803 if (edge->isArtificialControlDependence()) {
1804 continue;
1805 }
1806 NodeDescriptor des = boost::target(*ei1, filteredCDG);
1807 Node* node = graph_[des];
1808 subgraphNodes.insert(node);
1809
1810 /// In case one of branches had only single
1811 /// absolute jump to "exit" of procedure, there
1812 /// is no child basic block
1813 if(node->newFirstBB() != NULL) {
1814 ControlFlowEdge::CFGEdgePredicate predicateValue =
1816 if (edge->controlDependenceEdge().isTrueEdge()) {
1817 predicateValue = ControlFlowEdge::CFLOW_EDGE_TRUE;
1818 hasTrue = true;
1819 } else {
1820 predicateValue = ControlFlowEdge::CFLOW_EDGE_FALSE;
1821 hasFalse = true;
1822 }
1823 ControlFlowEdge *newEdge = new ControlFlowEdge(predicateValue);
1824/* Application::logStream() << (boost::format(
1825 "Adding edge for predicate %s to %s in %s\n")
1826 % bb->toString() % node->newFirstBB()->toString() % name()).str();*/
1828 *bb, *node->newFirstBB(), *newEdge);
1829 std::cerr << "Adding for predicate" << std::endl;
1830 createJump(bb, node->newFirstBB(), &guardReg, predicateValue);
1831 //predicate->addLeafBlocks(node->leafBlocks());
1832 } else {
1833 if(boost::out_degree(des, filteredCDG) != 0) {
1834 TCEString msg = (boost::format(
1835 "Found a node without first BB set. %s for predicate %s"
1836 " in procedure %s\n")
1837 % node->toString() % predicate->toString() % name()).str();
1838 throw InvalidData(__FILE__, __LINE__, __func__, msg);
1839 }
1840 }
1841 if (node->isLoopCloseNode()) {
1842 assert(node->newFirstBB() != NULL);
1843 //predicate->setLastNode();
1844 }
1845 if (node->isLoopEntryNode()) {
1846 processLoopEntry(node, node->newFirstBB());
1847 }
1848 }
1849 /// One of the outgoing edges is missing, we will have to add edge
1850 /// from predicate itself to next BB
1851 if (!(hasTrue && hasFalse)) {
1852 predicate->addLeafBlock(bb);
1853 }
1854 /// Move/copy edges between nodes "inside" subgraph and nodes outside the
1855 /// subgraph
1856 moveDDGedges(*predicate, subgraphNodes, filteredCDG);
1857}
void moveDDGedges(Node &root, NodeSet &subgraphNodes, FilteredCDG &filteredCDG)
void processLoopEntry(Node *node, BasicBlockNode *bb)

References __func__, TTAProgram::CodeSnippet::add(), ProgramDependenceNode::addLeafBlock(), TTAProgram::Instruction::addMove(), BoostGraph< GraphNode, GraphEdge >::addNode(), assert, BasicBlockNode::basicBlock(), ControlFlowEdge::CFLOW_EDGE_FALSE, ControlFlowEdge::CFLOW_EDGE_NORMAL, ControlFlowEdge::CFLOW_EDGE_TRUE, BoostGraph< GraphNode, GraphEdge >::connectNodes(), createJump(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::descriptor(), TTAProgram::Move::destination(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::edge(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::graph_, insCount_, MoveNode::move(), moveDDGedges(), ProgramDependenceNode::moveNode(), MoveNode::movePtr(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::name(), newCFG_, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node(), processLoopEntry(), ProgramDependenceNode::setNewFirstBB(), ProgramDependenceNode::toString(), and GraphNode::toString().

Referenced by computeRelations().

Here is the call graph for this function:

◆ processRegion()

void ProgramDependenceGraph::processRegion ( Node regionNode,
FilteredCDG filteredCDG 
)
private

"Sorts" all the child nodes of a region in topological order based on their control and data dependencies.

Parameters
regionNodeRegion/Predicate node who's child nodes to process
filteredCDGControl Dependence subraph

Get all child nodes of region node

Store all child nodes, we will need to collect all edges to and from subgraph rooted by region

node1 will be compared against all the other previously untested nodes

Test relation between siblings, should never return ERROR!

Move/copy edges between nodes "inside" subgraph and nodes outside the subgraph

Add actual control dependence edges for serialization

Nodes of subgraph without it's root

No loop close edges or DDG loop edges

Create filtered graph

Sort nodes of subgraph topologically

In case topological sort fails with graph not being DAG Write it out

It is first block so we add it as new first also to parent

There was some previous node tested, we have to add edges

Previously, statements created single basic block so we add edge from that to this one

If previous block ended with call we add CALL type of edge

clear lastBB, the edge was already added

leafs were processed, this node should have some leafs as well

if we got this far, lastBB should be NULL

Accessed node is loop entry, we add edge from corresponding loop close node to it.

We found single statement, time to add it to basic block

Time to create new BB

We just created first BB for children of region so we set it as first BB

Previous BB ended with CALL, so we link it to new one with call edge

Block just created is current lastBB

Leaf blocks were added, we can clear them

Definition at line 1198 of file ProgramDependenceGraph.cc.

1200 {
1201
1202 /// Get all child nodes of region node
1203 NodeDescriptor nodeDes = descriptor(*regionNode);
1204 FilteredOutEdgePair edges = boost::out_edges(nodeDes, filteredCDG);
1205 /// Store all child nodes, we will need to collect all edges
1206 /// to and from subgraph rooted by region
1207 NodeSet subgraphNodes;
1208 subgraphNodes.insert(regionNode);
1209 std::vector<std::pair<Node*, Node*> > newEdges;
1210 std::vector<std::pair<Node*, Node*> > unorderable;
1211 for (FilteredOutEdgeIter ei1 = edges.first;
1212 ei1 != edges.second;
1213 ++ei1) {
1214 NodeDescriptor des = boost::target(*ei1, filteredCDG);
1215 Node* node1 = graph_[des];
1216 subgraphNodes.insert(node1);
1217
1218 /// node1 will be compared against all the other previously untested
1219 /// nodes
1220 FilteredOutEdgeIter ei2 = ei1;
1221 ei2++;
1222 for (; ei2 != edges.second; ++ei2) {
1223 Node* node2 = graph_[boost::target(*ei2, filteredCDG)];
1224 /// Test relation between siblings, should never return ERROR!
1225 CompareResult result = compareSiblings(node1, node2);
1226 switch(result) {
1227 case ERROR:
1228 if(Application::verboseLevel() > 0) {
1229 writeToDotFile(name() + "_pdg_broken.dot");
1230 node1->printRelations();
1231 node2->printRelations();
1232 }
1233 throw ModuleRunTimeError(
1234 __FILE__, __LINE__, __func__,
1235 (boost::format(
1236 "Ordering error for A='%s' and B='%s'")
1237 % node1->toString() % node2->toString()).str());
1238 case A_BEFORE_B:
1239 newEdges.push_back(std::pair<Node*, Node*>(node1, node2));
1240 break;
1241 case B_BEFORE_A:
1242 newEdges.push_back(std::pair<Node*, Node*>(node2, node1));
1243 break;
1244 case UNORDERABLE:
1245 if(Application::verboseLevel() >= 0) {
1246 Application::logStream() << (boost::format(
1247 "Nodes (%s) and (%s) can not "
1248 "be put into any order.\n")
1249 % node1->toString()% node2->toString()).str();
1250 }
1251 unorderable.push_back(
1252 std::pair<Node*, Node*>(node1, node2));
1253 break;
1254 case ANY_ORDER:
1255 break;
1256 }
1257
1258 }
1259 }
1260 /// Move/copy edges between nodes "inside" subgraph and nodes outside the
1261 /// subgraph
1262 moveDDGedges(*regionNode, subgraphNodes, filteredCDG);
1263 /// Add actual control dependence edges for serialization
1264 for (unsigned int i = 0; i < newEdges.size(); i++) {
1266 connectNodes(*newEdges[i].first, *newEdges[i].second, *direction);
1267 }
1268 newEdges.clear();
1269 //return;
1270 /// Nodes of subgraph without it's root
1271 SubgraphTypeTest<NodeSet, Graph> subgraph(
1272 regionNode, subgraphNodes, graph_);
1273 /// No loop close edges or DDG loop edges
1274 BackFilter<Graph> backFilter(graph_);
1275 /// Create filtered graph
1276 Subgraph sub = Subgraph(graph_, backFilter, subgraph);
1277 /// Sort nodes of subgraph topologically
1278 std::vector<NodeDescriptor> sorted;
1279 try {
1280 boost::topological_sort(sub, std::back_inserter(sorted));
1281 } catch (boost::not_a_dag & x) {
1282 /// In case topological sort fails with graph not being DAG
1283 /// Write it out
1284 label_writer<Graph> lb(graph_);
1285 TCEString outName =
1286 name() + Conversion::toString(wrongCounter_) + "_notDAG.dot";
1287 wrongCounter_++;
1288 std::ofstream output(outName.c_str());
1289 boost::write_graphviz(output, sub,lb,lb);
1290
1291 Application::logStream() << (boost::format(
1292 "Topological sort of %s(%s) failed.\n"
1293 "Most likely loop is present.\n")
1294 % name() % regionNode->toString()).str();
1295 return;
1296 } catch (...) {
1297 Application::logStream() << (boost::format(
1298 "Topological sort of %s(%s) failed.\n"
1299 "Most likely loop is present.\n")
1300 % name() % regionNode->toString()).str();
1301 return;
1302 }
1303
1304 BasicBlockNode* lastBB = NULL;
1305 std::vector<BasicBlockNode*> leafBlocks;
1306 bool changeBB = false;
1307
1308 for (std::vector<NodeDescriptor>::reverse_iterator iter = sorted.rbegin();
1309 iter != sorted.rend(); iter++) {
1310 Node* accessedNode = graph_[*iter];
1311 BasicBlockNode* bb = NULL;
1312
1313 if(accessedNode->newFirstBB() != NULL) {
1314 // Child node is region or predicate and already has BBs
1315 // we will just link them
1316 bb = accessedNode->newFirstBB();
1317 if (regionNode->newFirstBB() == NULL) {
1318 assert(leafBlocks.size() == 0 && lastBB == NULL);
1319 /// It is first block so we add it as new first also to parent
1320 regionNode->setNewFirstBB(bb);
1321 }
1322 /// There was some previous node tested, we have to add edges
1323 if (lastBB != NULL) {
1324 assert(leafBlocks.size() == 0);
1325 /// Previously, statements created single basic block
1326 /// so we add edge from that to this one
1327 ControlFlowEdge* edge = NULL;
1328 /// If previous block ended with call we add CALL type of edge
1329 if (changeBB == true) {
1330 changeBB = false;
1331 edge = new
1334 } else {
1335 edge = new ControlFlowEdge();
1336 }
1337/* Application::logStream() << (boost::format(
1338 "Adding edge from lastBB %s to %s in %s\n")
1339 % lastBB->toString() % bb->toString() % name()).str();*/
1340 newCFG_->connectNodes(*lastBB, *bb, *edge);
1341 std::cerr << "Adding for lastBB != NULL" << std::endl;
1342 createJump(lastBB, bb);
1343 /// clear lastBB, the edge was already added
1344/* Application::logStream() << (boost::format(
1345 "\tChanged lastbb from %s to NULL\n")
1346 % lastBB->toString()).str();*/
1347 lastBB = NULL;
1348 leafBlocks.clear();
1349 }
1350/* Application::logStream() << (boost::format(
1351 "\tStart adding leaf blocks for %s in region %s with bb %s\n")
1352 % accessedNode->toString() % regionNode->toString()
1353 % bb->toString()).str();*/
1354 addLeafEdges(leafBlocks, bb);
1355 /// leafs were processed, this node should have some leafs as well
1356 leafBlocks.clear();
1357 leafBlocks = accessedNode->leafBlocks();
1358 /// if we got this far, lastBB should be NULL
1359 assert(lastBB == NULL);
1360 /// Accessed node is loop entry, we add edge from corresponding
1361 /// loop close node to it.
1362 if (accessedNode->isLoopEntryNode()) {
1363 processLoopEntry(accessedNode, bb);
1364 }
1365 } else {
1366 /// We found single statement, time to add it to basic block
1367 if (lastBB == NULL || changeBB == true) {
1368 /// Time to create new BB
1369 TTAProgram::BasicBlock* block =
1371 insCount_++;
1372 bb = new BasicBlockNode(*block);
1373/* Application::logStream() << (boost::format(
1374 "Create new BB %s in %s for %s\n")
1375 % bb->toString() % regionNode->toString() %
1376 accessedNode->toString()).str();*/
1377 newCFG_->addNode(*bb);
1378 if (regionNode->newFirstBB() == NULL) {
1379 /// We just created first BB for children of region
1380 /// so we set it as first BB
1381 regionNode->setNewFirstBB(bb);
1382 }
1383 /// Previous BB ended with CALL, so we link it to new one
1384 /// with call edge
1385 if (changeBB == true && lastBB != NULL) {
1386 changeBB = false;
1390 newCFG_->connectNodes(*lastBB, *bb, *edge);
1391 assert(leafBlocks.size() == 0);
1392 }
1393 /// Block just created is current lastBB
1394/* Application::logStream() << (boost::format(
1395 "\tChanged lastbb to %s\n")
1396 %bb->toString()).str();*/
1397 lastBB = bb;
1398 }
1399 }
1400 if(accessedNode->isMoveNode()
1401 && accessedNode->moveNode().isMove()) {
1402 TTAProgram::Instruction* newIns =
1404 newIns->addMove(accessedNode->moveNode().movePtr());
1405 lastBB->basicBlock().add(newIns);
1406 insCount_++;
1407 if (accessedNode->moveNode().move().isCall()) {
1408 changeBB = true;
1409 }
1410 if (leafBlocks.size() > 0) {
1411/* Application::logStream() << (boost::format(
1412 "\tStart adding leaf blocks: %s in region %s with bb %s\n")
1413 % accessedNode->toString() % regionNode->toString()
1414 % bb->toString()).str();*/
1415 addLeafEdges(leafBlocks, bb);
1416 /// Leaf blocks were added, we can clear them
1417 leafBlocks.clear();
1418 } else {
1419 if (Application::verboseLevel() > 2) {
1421 (boost::format(" Undetected case! %s inside %s\n")
1422 % accessedNode->toString() % regionNode->toString()
1423 ).str();
1424 }
1425 }
1426 }
1427 }
1428 if (leafBlocks.size() > 0) {
1429 regionNode->addLeafBlocks(leafBlocks);
1430 leafBlocks.clear();
1431 }
1432 if (lastBB != NULL) {
1433/* Application::logStream() << (boost::format(
1434 "Add last bb %s as a leaf to %s\n")
1435 % lastBB->toString() % regionNode->toString()).str();*/
1436 regionNode->addLeafBlock(lastBB);
1437 }
1438 if(regionNode == entryNode_) {
1439 processEntry(regionNode->newFirstBB());
1440 }
1441 unorderable.clear();
1442}
static int verboseLevel()
static std::string toString(const T &source)
void processEntry(BasicBlockNode *firstBB)
void addLeafEdges(std::vector< BasicBlockNode * > leafs, BasicBlockNode *bb)
CompareResult compareSiblings(Node *a, Node *b)
boost::filtered_graph< Graph, BackFilter< Graph >, SubgraphTypeTest< NodeSet, Graph > > Subgraph

References __func__, A_BEFORE_B, TTAProgram::CodeSnippet::add(), ProgramDependenceNode::addLeafBlock(), ProgramDependenceNode::addLeafBlocks(), addLeafEdges(), TTAProgram::Instruction::addMove(), BoostGraph< GraphNode, GraphEdge >::addNode(), ANY_ORDER, assert, B_BEFORE_A, BasicBlockNode::basicBlock(), ControlFlowEdge::CFLOW_EDGE_CALL, ControlFlowEdge::CFLOW_EDGE_NORMAL, compareSiblings(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::connectNodes(), BoostGraph< GraphNode, GraphEdge >::connectNodes(), createJump(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::descriptor(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::edge(), entryNode_, ERROR, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::graph_, insCount_, TTAProgram::Move::isCall(), ProgramDependenceNode::isLoopEntryNode(), MoveNode::isMove(), ProgramDependenceNode::isMoveNode(), ProgramDependenceNode::leafBlocks(), Application::logStream(), MoveNode::move(), moveDDGedges(), ProgramDependenceNode::moveNode(), MoveNode::movePtr(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::name(), newCFG_, ProgramDependenceNode::newFirstBB(), ProgramDependenceNode::printRelations(), processEntry(), processLoopEntry(), ProgramDependenceNode::setNewFirstBB(), sub, ProgramDependenceNode::toString(), Conversion::toString(), UNORDERABLE, Application::verboseLevel(), GraphBase< GraphNode, GraphEdge >::writeToDotFile(), and wrongCounter_.

Referenced by computeRelations().

Here is the call graph for this function:

◆ regionHelper()

void ProgramDependenceGraph::regionHelper ( Node node,
FilteredCDG cdg,
Node::NodesInfo finalNodesInfo 
)
private

Helper function to compute actual region information for a node. Called several times for a case when there are loop entry nodes detected.

Parameters
nodeNode for which to compute region info
cdgFiltered PDG graph with only control dependence edges
finalNodesInfostores actual computed region info

Find all incoming control dependence edges

There is no Region info for Entry node

If parent's region is not yet computed (should be btw) compute it before continuing.

region(node,parent) == region(parent) U children(parent)

region(node,parent) == region(parent)

fill in final region info with info from first of parents

region(node) = intersection(region(node,parent(node))) for all parents. finalNodesInfo is already initialized from counter 0

Definition at line 1118 of file ProgramDependenceGraph.cc.

1121 {
1122
1124 std::vector<Node::NodesInfo> tmpResult;
1125 /// Find all incoming control dependence edges
1126 FilteredInEdgePair edges = boost::in_edges(des, cdg);
1127 for (FilteredInEdgeIter ei = edges.first;
1128 ei != edges.second;
1129 ++ei) {
1130 Node* previous = cdg[boost::source(*ei, cdg)];
1131 /// There is no Region info for Entry node
1132 if (previous->isRegionNode()
1133 || previous->isLoopEntryNode()) {
1134 if (previous->region().size() == 0 &&
1135 ! (previous == entryNode_)) {
1136 /// If parent's region is not yet computed (should be btw)
1137 /// compute it before continuing.
1138 Node::NodesInfo addedNodesInfo;
1139 regionHelper(previous, cdg, addedNodesInfo);
1140 for (Node::NodesInfo::iterator k = addedNodesInfo.begin();
1141 k != addedNodesInfo.end();
1142 k++) {
1143 previous->addToRegion(**k);
1144 }
1145
1146/* writeToDotFile(name() + "_broken.dot");
1147 TCEString msg = "Parent " + previous->toString();
1148 msg += " of node " + (*iter)->toString();
1149 msg += " has empty region information!";
1150 msg += " Procedure has " + Conversion::toString(nodeCount());
1151 msg += " nodes.";
1152 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);*/
1153 }
1154 /// region(node,parent) == region(parent) U children(parent)
1155 Node::NodesInfo tmp = previous->region();
1156 FilteredOutEdgePair edges =
1157 boost::out_edges(descriptor(*previous), cdg);
1158 for (FilteredOutEdgeIter ei = edges.first;
1159 ei != edges.second;
1160 ++ei) {
1161 Node* testedNode = cdg[boost::target(*ei, cdg)];
1162 tmp.insert(testedNode);
1163 }
1164 tmpResult.push_back(tmp);
1165 } else if (previous->isPredicateMoveNode()){
1166 /// region(node,parent) == region(parent)
1167 Node::NodesInfo tmp = previous->region();
1168 tmpResult.push_back(tmp);
1169 } else {
1170 assert(previous->isLoopCloseNode());
1171 }
1172 }
1173 /// fill in final region info with info from first of parents
1174 if (tmpResult.size() > 0) {
1175 finalNodesInfo.insert(
1176 tmpResult[0].begin(), tmpResult[0].end());
1177 }
1178 /// region(node) = intersection(region(node,parent(node)))
1179 /// for all parents. finalNodesInfo is already initialized from
1180 /// counter 0
1181 for (unsigned int l = 1; l < tmpResult.size(); l++) {
1182 Node::NodesInfo storeResult;
1184 finalNodesInfo, tmpResult[l], storeResult);
1185 finalNodesInfo.swap(storeResult);
1186 storeResult.clear();
1187 }
1188}

References ProgramDependenceNode::addToRegion(), assert, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::descriptor(), entryNode_, SetTools::intersection(), ProgramDependenceNode::isLoopCloseNode(), ProgramDependenceNode::isLoopEntryNode(), ProgramDependenceNode::isPredicateMoveNode(), ProgramDependenceNode::isRegionNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::node(), ProgramDependenceNode::region(), and regionHelper().

Referenced by computeRegionInfo(), regionHelper(), and serializePDG().

Here is the call graph for this function:

◆ removeGuardedJump()

void ProgramDependenceGraph::removeGuardedJump ( ControlToProgram cToP,
ProgramDependenceNode pNode,
ControlDependenceNode cNode 
)
private

Remove guarded jumps from the graph, makes guard generating operation a predicated node and fixes the true and false edges in case the jump had inverted guard.

Parameters
cToPmapping between Control Dependence nodes of original CDG and newly created Program Dependence nodes in PDG.
pNodeProgram Dependence Node containing guarded jump
cNodeControl Dependence node which included guarded jump in CDG

This used to be error, but now it possible

All incoming control dependence edges into the predicate node are also incoming edges to the guard, since they were in same block in CDG

Definition at line 327 of file ProgramDependenceGraph.cc.

330 {
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()) {
370 ControlDependenceEdge* newEdge = &cdg_->outEdge(cNode, j);;
371 if (isInverted) {
372 newEdge->invertEdgePredicate();
373 }
374 pEdge = new ProgramDependenceEdge(*newEdge);
375 ProgramDependenceNode* pTarget;
376 try {
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}
virtual Edge & outEdge(const Node &node, const int index) const
virtual int outDegree(const Node &node) const
std::string toString() const
bool isInverted() const
Definition MoveGuard.cc:76
MoveGuard & guard() const
Definition Move.cc:345

References __func__, cdg_, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::connectNodes(), Exception::errorMessageStack(), TTAProgram::Move::guard(), BoostGraph< GraphNode, GraphEdge >::headNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::inDegree(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::inEdge(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::inEdges(), ControlDependenceEdge::invertEdgePredicate(), TTAProgram::MoveGuard::isInverted(), ControlDependenceNode::isLoopCloseNode(), ControlDependenceNode::isLoopEntryNode(), ControlDependenceNode::isRegionNode(), MapTools::keyForValue(), Application::logStream(), MoveNode::move(), ProgramDependenceNode::moveNode(), BoostGraph< GraphNode, GraphEdge >::outDegree(), BoostGraph< GraphNode, GraphEdge >::outEdge(), ProgramDependenceNode::setPredicateMoveNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::tailNode(), ProgramDependenceNode::toString(), and Application::verboseLevel().

Referenced by ProgramDependenceGraph().

Here is the call graph for this function:

◆ serializePDG()

bool ProgramDependenceGraph::serializePDG ( )

Performs serialization of ProgramDependenceGraph, turning it into Control Flow Graph.

Returns
ControlFlowGraph representation of PDG
Exceptions
InvalidDatain case serialization of graph is not possible

Created filtered PDG graph containing only control dependence edges

Detect strong components if they were not detected in CDG and transferred

Modifies graph_ with added close nodes and close edges

map to store post order information for all the nodes of a graph

map to store color information during dfs

boost::on_finish_vertex will give us post order numbering

Computes post order of all the nodes in PDG

If not computed on CDG and copied, computes 'region' information for all nodes of a graph

If not computed on CDG and copied, computes 'eec' information for all nodes of a graph

If CDG comes analyzed we need to add region and eec info for dummy ENTRYNODE of DDG. By it's definition, ENTRYNODE is leaf in terms of control dependence, region == eec

Definition at line 401 of file ProgramDependenceGraph.cc.

401 {
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 auto timer = std::chrono::steady_clock::now();
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 = std::chrono::duration_cast<std::chrono::seconds>(
422 std::chrono::steady_clock::now() - timer)
423 .count();
425 Application::logStream() << (boost::format(
426 "\t\tStrong components:%d components, %d minutes and %d seconds.\n")
427 % componentCount % (elapsed/60) % (elapsed%60)).str();
428 }
429 }
430
431 /// map to store post order information for all the nodes of a graph
432 PDGOrderMap lastMap;
433 PDGOrder lastOrder(lastMap);
434 /// map to store color information during dfs
435 ColorMap colorMap;
436 Color colorsDFS(colorMap);
437 int fStamp(-1);
438 /// boost::on_finish_vertex will give us post order numbering
439 boost::time_stamper<PDGOrder, int, boost::on_finish_vertex>
440 lastOrderStamper(lastOrder, fStamp);
441 timer = std::chrono::steady_clock::now(); // restart
442 /// Computes post order of all the nodes in PDG
443 boost::depth_first_visit(
444 filteredCDG, descriptor(entryNode()),
445 boost::make_dfs_visitor(lastOrderStamper), colorsDFS);
446 elapsed = std::chrono::duration_cast<std::chrono::seconds>(
447 std::chrono::steady_clock::now() - timer)
448 .count();
450 Application::logStream() << (boost::format(
451 "\t\tPost order: %d minutes and %d seconds.\n")
452 % (elapsed/60) % (elapsed%60)).str();
453 }
454 /// If not computed on CDG and copied, computes 'region' information for
455 /// all nodes of a graph
456 if (!cdg_->analyzed()) {
457 timer = std::chrono::steady_clock::now(); // restart
458 computeRegionInfo(lastMap, filteredCDG);
459 elapsed = std::chrono::duration_cast<std::chrono::seconds>(
460 std::chrono::steady_clock::now() - timer)
461 .count();
463 Application::logStream() << (boost::format(
464 "\t\tRegion: %d minutes and %d seconds.\n")
465 % (elapsed/60) % (elapsed%60)).str();
466 }
467 /// If not computed on CDG and copied, computes 'eec' information for
468 /// all nodes of a graph
469 timer = std::chrono::steady_clock::now(); // restart
470 computeEECInfo(lastMap, filteredCDG);
471 elapsed = std::chrono::duration_cast<std::chrono::seconds>(
472 std::chrono::steady_clock::now() - timer)
473 .count();
475 Application::logStream() << (boost::format(
476 "\t\tEEC: %d minutes and %d seconds.\n")
477 % (elapsed/60) % (elapsed%60)).str();
478 }
479 }
480
481 timer = std::chrono::steady_clock::now(); // restart
482 /// If CDG comes analyzed we need to add region and eec info for
483 /// dummy ENTRYNODE of DDG. By it's definition, ENTRYNODE is leaf
484 /// in terms of control dependence, region == eec
485 if(cdg_->analyzed() && ddgEntryNode_ != NULL) {
486 Node::NodesInfo finalNodesInfo;
487 regionHelper(ddgEntryNode_, filteredCDG, finalNodesInfo);
488 for (Node::NodesInfo::iterator k = finalNodesInfo.begin();
489 k != finalNodesInfo.end(); k++) {
490 ddgEntryNode_->addToRegion(**k);
491 ddgEntryNode_->addToEEC(**k);
492 }
493 }
494 return true;
495#if 0
496 /// Compute actual relations between sibling nodes. Move Data Dependence
497 /// edges to root's of subgraph if they connect subgraph with outside
498 /// nodes
499 ///computeRelations(lastMap, filteredCDG);
500 elapsed = static_cast<long>(timer.elapsed());
502 Application::logStream() << (boost::format(
503 "\t\tRelations: %d minutes and %d seconds.\n")
504 % (elapsed/60) % (elapsed%60)).str();
505 }
507 Application::logStream() << (boost::format(
508 "Procedure %s has %d nodes and %d edges.\n")
509 % name() % nodeCount() % edgeCount()).str();
510 }
511 //writeToDotFile(name() + "_pdgSerialized.dot");
512 //disassemble();
513 return true;
514#endif
515}
#define DEBUG_LEVEL
void computeEECInfo(const PDGOrderMap &orderMap, FilteredCDG &filteredCDG)
int detectStrongComponents(PDGOrderMap &components, DescriptorMap &roots, FilteredCDG &filteredCDG)
void computeRegionInfo(const PDGOrderMap &orderMap, FilteredCDG &filteredCDG)
std::map< NodeDescriptor, int > PDGOrderMap
Stores data to compute post order relation on CDG and strong components.
std::map< NodeDescriptor, NodeDescriptor > DescriptorMap
Storage for relations between nodes.
boost::associative_property_map< ColorMap > Color
boost::filtered_graph< Graph, CDGFilter< Graph > > FilteredCDG
Type of filtered graph with CD edges only.
std::map< NodeDescriptor, boost::default_color_type > ColorMap
Storage for color property used by dfs.

References ControlDependenceGraph::analyzed(), cdg_, computeEECInfo(), computeRegionInfo(), ddgEntryNode_, DEBUG_LEVEL, BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::descriptor(), detectStrongComponents(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::edgeCount(), entryNode(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::graph_, Application::logStream(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::name(), BoostGraph< ProgramDependenceNode, ProgramDependenceEdge >::nodeCount(), regionHelper(), and Application::verboseLevel().

Here is the call graph for this function:

Member Data Documentation

◆ cdg_

const ControlDependenceGraph* ProgramDependenceGraph::cdg_
private

Stores original control dependence graph.

Definition at line 220 of file ProgramDependenceGraph.hh.

Referenced by computeRelations(), copyRegionEECComponent(), disassemble(), removeGuardedJump(), and serializePDG().

◆ ddg_

const DataDependenceGraph* ProgramDependenceGraph::ddg_
private

Stores original data dependence graph.

Definition at line 222 of file ProgramDependenceGraph.hh.

Referenced by copyRegionEECComponent().

◆ ddgEntryNode_

Node* ProgramDependenceGraph::ddgEntryNode_
private

Stored reference to PDG equivalent of DDG ENTRYNODE.

Definition at line 226 of file ProgramDependenceGraph.hh.

Referenced by ProgramDependenceGraph(), and serializePDG().

◆ entryNode_

Node* ProgramDependenceGraph::entryNode_
private

Stores pointer to entry node of the PDG graph.

Definition at line 224 of file ProgramDependenceGraph.hh.

Referenced by copyRegionEECComponent(), entryNode(), processRegion(), ProgramDependenceGraph(), and regionHelper().

◆ insCount_

int ProgramDependenceGraph::insCount_
private

Counts new instructions when creating basic blocks.

Definition at line 232 of file ProgramDependenceGraph.hh.

Referenced by processLoopClose(), processPredicate(), and processRegion().

◆ newCFG_

ControlFlowGraph* ProgramDependenceGraph::newCFG_
private

◆ program_

TTAProgram::Program* ProgramDependenceGraph::program_
private

Original Program object, to get instruction reference manager.

Definition at line 234 of file ProgramDependenceGraph.hh.

Referenced by computeRelations(), createJump(), and ProgramDependenceGraph().

◆ strongComponents_

std::vector<std::set<Node*> > ProgramDependenceGraph::strongComponents_
private

stores nodes present in each of the found components

Definition at line 228 of file ProgramDependenceGraph.hh.

Referenced by computeEECInfo(), computeRegionInfo(), copyRegionEECComponent(), detectStrongComponents(), and ~ProgramDependenceGraph().

◆ wrongCounter_

int ProgramDependenceGraph::wrongCounter_
private

Definition at line 250 of file ProgramDependenceGraph.hh.

Referenced by processRegion().


The documentation for this class was generated from the following files: