ROSE 2.1.0
Loading...
Searching...
No Matches
FlowGraphInterface.h
1#ifndef ROSE_FlowGraphInterface_H
2#define ROSE_FlowGraphInterface_H
3
4#include <RoseFirst.h>
5
6#include <vector>
7#include <functional>
8#include <boost/range/iterator_range.hpp>
9
10namespace Rose{
11namespace FlowGraphInterface {
12
13enum MutationSupportOption { None, NodeInsertion, EdgeInsertion, NodeDeletion, EdgeDeletion};
14
16 int t_;
17 public:
18 bool operator == (const TraversalSupportOption& t1) const { return t_ == t1.t_; }
19 // Below are possible options of node traversals supported by a graph.
20 static constexpr auto ENTRY_NODES_TRAVERSAL = 1;
21 static constexpr auto EXIT_NODES_TRAVERSAL = 2;
22 static constexpr auto INTERNAL_NODES_TRAVERSAL = 4;
23 static constexpr auto OUT_EDGES_TRAVERSAL = 8;
24 static constexpr auto IN_EDGES_TRAVERSAL = 16;
25 static constexpr auto ALL_NODES_OUT_EDGES_TRAVERSAL = ENTRY_NODES_TRAVERSAL + EXIT_NODES_TRAVERSAL + INTERNAL_NODES_TRAVERSAL + OUT_EDGES_TRAVERSAL;
26 static constexpr auto ALL_NODES_IN_EDGES_TRAVERSAL = ENTRY_NODES_TRAVERSAL + EXIT_NODES_TRAVERSAL + INTERNAL_NODES_TRAVERSAL + IN_EDGES_TRAVERSAL;
27 // Below are examples of definition different combinations of traversals supported.
28 // In essence, combine all supported traversal options via the | or + operator.
29 static constexpr auto BOUNDARY_NODES_TRAVERSAL=ENTRY_NODES_TRAVERSAL | EXIT_NODES_TRAVERSAL;
30
31 TraversalSupportOption(int t = ALL_NODES_OUT_EDGES_TRAVERSAL) : t_(t) {}
32 bool isIncludedTraversal(int t) const { return t_ & t; }
33 bool isTraversal(int t) const { return t_ == t; }
34
35 template <class Iterator>
36 auto traversalSupportFilter() const // optional: -> std::function<bool(EdgeIterator)>
37 {
38 return [this](Iterator it) -> bool
39 {
40 return isIncludedTraversal(it->traversal_kind());
41 };
42 }
43};
44
45 template<class T>
46 auto
47 noFilter() // optional: -> std::function<bool(T)>
48 {
49 return [](T) -> bool { return true; };
50 }
51
52
53
54// Provide an interface for traversing nodes in a directed graph.
55// Node: content of the nodes; NodeIterator: key to access nodes of the graph.
56// Edge traversal is not supported directly here and is provided in FlowGraphNode
57// DONE: make the names more consistent (with vs without Type at the end): renamed types to options, support,etc.
58template <class NodeIterator, class EdgeIterator,
59 class NodeCollection=boost::iterator_range<NodeIterator>,
60 class EdgeCollection=boost::iterator_range<EdgeIterator>>
62 public:
63 using NodeCollectionType = NodeCollection;
64 using EdgeCollectionType = EdgeCollection;
65
66 using NodePredicate = std::function<bool(NodeIterator)>;
67 using EdgePredicate = std::function<bool(EdgeIterator)>;
68
69 // Return all the nodes that meet the given predicate.
70 // If the requested traversal is not supported, return a pair of empty iterators.
71 virtual NodeCollection getNodes(NodePredicate = noFilter<NodeIterator>() ) const = 0;
72
73 // Return all the edges that meet the given predicate.
74 // If the requested traversal is not supported, return a pair of empty iterators.
75 virtual EdgeCollection getEdges(EdgePredicate = noFilter<EdgeIterator>()) const = 0;
76
77 // Assume each edge is directed and has a single source and a single target.
78 virtual NodeIterator edgeSource(const EdgeIterator& p) const = 0;
79 virtual NodeIterator edgeTarget(const EdgeIterator& p) const = 0;
80
81 // Returns edges connected to the given node filtered by the given traversal support.
82 // If the requested traversal is not supported, return a pair of empty iterators.
83 virtual EdgeCollection getEdgesFrom(const NodeIterator&, EdgePredicate = noFilter<EdgeIterator>()) const { assert("Error: outgoing edge traversal not supported!"); return EdgeCollection(); }
84 virtual EdgeCollection getEdgesTo(const NodeIterator&, EdgePredicate = noFilter<EdgeIterator>()) const { assert("Error: incomng edge traversal not supported!"); return EdgeCollection(); }
85
86 virtual enum MutationSupportOption allowMutationDuringTraversal() const { return MutationSupportOption::None; }
87 virtual TraversalSupportOption getTraversalSupport() const { return TraversalSupportOption(); }
88};
89
90// Maybe add a template parameter to represent what type of iterator invalidation. Instantiate EdgeIterator with void if not need it.
91template <class NodeInfo, class EdgeInfo, class NodeIterator, class EdgeIterator>
93 public:
94 // For correctness, the underlying implementation must ensure the returned NodeIterator object
95 // is not invalidated after more nodes are added into the graph via additional calls of addNode.
96 // Returning a NodeIterator value instead of const NodeIterator&
97 virtual NodeIterator addNode(const NodeInfo& node) = 0;
98
99 // It may happen The Edgeterator stays valid only if no additional node or edge is added.
100 virtual EdgeIterator addEdge(const NodeIterator& p1, const NodeIterator& p2, const EdgeInfo& t) = 0;
101
102 // TODO: What about iterators being invalidated while creating. Documentation. Add API to specify whether an iterator is still valid?
103};
104
105
106class SgNode;
107
108// Control flows can be traversed forward (outgoing) or backward (incoming), with each edge conditioned with the boolean value of the conditional branch.
109template <class NodeIterator, class EdgeIterator,
110 class NodeInfo=std::vector<SgNode*>, class EdgeInfo=TraversalSupportOption,
111 class NodeCollection=boost::iterator_range<NodeIterator>,
112 class EdgeCollection=boost::iterator_range<EdgeIterator>>
114 public FlowGraphAccessInterface<NodeIterator,EdgeIterator,NodeCollection,EdgeCollection>,
115 public FlowGraphCreateInterface<NodeInfo,EdgeInfo,NodeIterator,EdgeIterator> {
116 public:
117 using NodeCollectionType = NodeCollection;
118 using EdgeCollectionType = EdgeCollection;
119 virtual const NodeInfo& dereferenceNode(const NodeIterator& p) const = 0;
120 virtual const EdgeInfo& dereferenceEdge(const EdgeIterator& p) const = 0;
121};
122
123
124// Data flows can be speculative (maybe_flow, which depends on runtime values), or non-speculative (must_flow, which does not depend on runtime info). It can flow from a definition to a use of a memory store (DEF_USE_FLOW), from a use to a definition (USE_DEF_FLOW, which is the reverse of DEF_USE_FLOW), or from a use to a memory whose value is computed by combining all the incoming used values (USE_JOIN_FLOW).
125template <class NodeIterator, class EdgeIterator,
126 class NodeInfo=SgNode*, class EdgeInfo=TraversalSupportOption,
127 class NodeCollection=boost::iterator_range<NodeIterator>,
128 class EdgeCollection=boost::iterator_range<EdgeIterator>>
130 public FlowGraphAccessInterface<NodeIterator, EdgeIterator, NodeCollection, EdgeCollection>,
131 public FlowGraphCreateInterface<NodeInfo, EdgeInfo, NodeIterator, EdgeIterator> {
132 public:
133 using NodeCollectionType = NodeCollection;
134 using EdgeCollectionType = EdgeCollection;
135 virtual const NodeInfo& dereferenceNode(const NodeIterator& p) const = 0;
136 virtual const EdgeInfo& dereferenceEdge(const EdgeIterator& p) const = 0;
137};
138
139}; // namespace FlowGraphInterface
140}; // namespace Rose
141
142#endif
This class represents the base class for all IR nodes within Sage III.
The ROSE library.