ROSE  0.11.145.0
CfgPath.h
1 #ifndef ROSE_BinaryAnalysis_Partitioner2_CfgPath_H
2 #define ROSE_BinaryAnalysis_Partitioner2_CfgPath_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <Rose/BinaryAnalysis/Partitioner2/ControlFlowGraph.h>
7 
8 namespace Rose {
9 namespace BinaryAnalysis {
10 namespace Partitioner2 {
11 
17 class CfgPath {
18 public:
20  typedef std::vector<ControlFlowGraph::ConstEdgeIterator> Edges;
21 
23  typedef std::vector<ControlFlowGraph::ConstVertexIterator> Vertices;
24 
27 
28 private:
30  Edges edges_;
31 
32  // Optional edge ordering information. This vector parallels, "edges_", although it can be smaller if default ordering is
33  // used. Assuming the vectors are the same size, then edgeOrder_[i] contains the back-tracking information for
34  // edges_[i]. If edges_[i] is popped during backtracking and edgeOrder_[i] exists and is not empty, then edges_[i] will be
35  // replaced by edgeOrders_[i].back() and that edge is popped from edgeOrders_[i].
36  std::vector<Edges> edgeOrders_;
37 
38  // Attributes stored at each vertex and edge
39  std::vector<Attributes> vertexAttributes_;
40  std::vector<Attributes> edgeAttributes_;
41 
42 public:
44  CfgPath() {}
45 
47  explicit CfgPath(const ControlFlowGraph::ConstVertexIterator &vertex)
48  : frontVertex_(vertex), vertexAttributes_(1, Attributes()) {}
49 
52  : frontVertex_(edge->source()), edges_(1, edge), vertexAttributes_(2, Attributes()), edgeAttributes_(1, Attributes()) {}
53 
55  void clear() {
56  frontVertex_ = Sawyer::Nothing();
57  edges_.clear();
58  edgeOrders_.clear();
59  vertexAttributes_.clear();
60  edgeAttributes_.clear();
61  }
62 
64  bool isEmpty() const {
65  return !frontVertex_;
66  }
67 
72  bool isConnected() const;
73 
77  size_t nEdges() const {
78  return edges_.size();
79  }
80 
84  size_t nVertices() const {
85  return isEmpty() ? 0 : (1+nEdges());
86  }
87 
91  ControlFlowGraph::ConstVertexIterator frontVertex() const {
92  ASSERT_forbid(isEmpty());
93  return *frontVertex_;
94  }
95 
99  ControlFlowGraph::ConstVertexIterator backVertex() const {
100  ASSERT_forbid(isEmpty());
101  return edges_.empty() ? *frontVertex_ : edges_.back()->target();
102  }
103 
107  const Edges& edges() const {
108  return edges_;
109  }
110 
115  Vertices vertices() const;
116 
122  void pushBack(ControlFlowGraph::ConstEdgeIterator edge);
123 
129  void pushBack(const std::vector<ControlFlowGraph::ConstEdgeIterator> &edges);
130 
139  void pushFront(ControlFlowGraph::ConstEdgeIterator edge);
140 
146  void pushFront(const std::vector<ControlFlowGraph::ConstEdgeIterator> &edges);
147 
153  void popBack();
154 
163  std::vector<ControlFlowGraph::ConstEdgeIterator> backtrack();
164 
173  Attributes& vertexAttributes(size_t);
174  const Attributes& vertexAttributes(size_t) const;
185  Attributes& edgeAttributes(size_t);
186  const Attributes& edgeAttributes(size_t) const;
190  size_t nVisits(const ControlFlowGraph::ConstVertexIterator &vertex) const;
191 
193  size_t nVisits(const ControlFlowGraph::ConstEdgeIterator &edge) const;
194 
201  size_t nCalls(const FunctionPtr&) const;
202  size_t nCalls() const;
211  size_t nReturns(const FunctionPtr&) const;
212  size_t nReturns() const;
223  ssize_t callDepth(const FunctionPtr&) const;
224  ssize_t callDepth() const;
234  size_t maxCallDepth(const FunctionPtr&) const;
235  size_t maxCallDepth() const;
246  std::vector<ControlFlowGraph::ConstEdgeIterator> truncate(const ControlFlowGraph::ConstEdgeIterator&);
247  std::vector<ControlFlowGraph::ConstEdgeIterator> truncate(const CfgConstEdgeSet&);
256  std::pair<size_t /*vertex*/, size_t /*insn*/> lastInsnIndex(SgAsmInstruction*) const;
257 
262  uint64_t hash() const;
263 
269  uint64_t hash(SgAsmInstruction*) const;
270 
272  void print(std::ostream &out) const;
273 };
274 
276 // Functions for operating on paths
278 
287 std::vector<bool>
288 findPathEdges(const ControlFlowGraph &graph,
289  const CfgConstVertexSet &beginVertices,
290  const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
291  const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet(), bool avoidCallsAndReturns = false);
292 std::vector<bool>
293 findPathEdges(const ControlFlowGraph &graph,
294  const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &endVertices,
295  const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
296  const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet(), bool avoidCallsAndReturns = false);
305  const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &endVertices,
306  const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
307  const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet(),
308  bool avoidCallsAndReturns = false);
309 
316  const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &endVertices,
317  const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
318  const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet(),
319  bool avoidCallsAndReturns = false);
320 
328 size_t
329 eraseUnreachablePaths(ControlFlowGraph &graph /*in,out*/, CfgConstVertexSet &beginVertices /*in,out*/,
330  CfgConstVertexSet &endVertices /*in,out*/, CfgVertexMap &vmap /*in,out*/, CfgPath &path /*in,out*/);
331 
347 void
348 findPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths /*out*/, CfgVertexMap &vmap /*out*/,
349  const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &endVertices,
350  const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
351  const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet(),
352  bool avoidCallsAndReturns = false);
353 
368 void
369 findPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths /*out*/, CfgVertexMap &vmap /*out*/,
370  const CfgConstVertexSet &beginVertices,
371  const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
372  const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet(),
373  bool avoidCallsAndReturns = false);
374 
380 void
381 findFunctionPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths /*out*/, CfgVertexMap &vmap /*out*/,
382  const CfgConstVertexSet &beginVertices,
383  const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
384  const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet());
385 void
386 findFunctionPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths /*out*/, CfgVertexMap &vmap /*out*/,
387  const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &endVertices,
388  const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
389  const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet());
399 void
400 findInterFunctionPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths /*out*/, CfgVertexMap &vmap /*out*/,
401  const CfgConstVertexSet &beginVertices,
402  const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
403  const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet());
404 void
405 findInterFunctionPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths /*out*/, CfgVertexMap &vmap /*out*/,
406  const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &endVertices,
407  const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
408  const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet());
440 bool
441 inlineMultipleCallees(ControlFlowGraph &paths /*in,out*/, const ControlFlowGraph::ConstVertexIterator &pathsCallSite,
442  const ControlFlowGraph &cfg, const ControlFlowGraph::ConstVertexIterator &cfgCallSite,
443  const CfgConstVertexSet &cfgAvoidVertices = CfgConstVertexSet(),
444  const CfgConstEdgeSet &cfgAvoidEdges = CfgConstEdgeSet(),
445  std::vector<ControlFlowGraph::ConstVertexIterator> *newEdges = nullptr);
446 bool
447 inlineOneCallee(ControlFlowGraph &paths /*in,out*/, const ControlFlowGraph::ConstVertexIterator &pathsCallSite,
448  const ControlFlowGraph &cfg, const ControlFlowGraph::ConstVertexIterator &cfgCallTarget,
449  const CfgConstVertexSet &cfgAvoidVertices, const CfgConstEdgeSet &cfgAvoidEdges,
450  std::vector<ControlFlowGraph::ConstVertexIterator> *newVertices = nullptr);
468 class Inliner {
469 public:
470 
472  enum HowInline {
476  };
477 
482  size_t maxCallDepth_; // max depth for inlining
483  protected:
484  ShouldInline(): maxCallDepth_(100) {}
485  public:
486  virtual ~ShouldInline() {}
487 
490 
492  static Ptr instance() { return Ptr(new ShouldInline); }
493 
497  size_t maxCallDepth() const { return maxCallDepth_; }
498  void maxCallDepth(size_t n) { maxCallDepth_ = n; }
502  virtual HowInline operator()(const PartitionerConstPtr&, const ControlFlowGraph::ConstEdgeIterator cfgCallEdge,
503  const ControlFlowGraph &paths, const ControlFlowGraph::ConstVertexIterator &pathsCallSite,
504  size_t callDepth);
505  };
506 
507 private:
508  struct CallSite {
509  ControlFlowGraph::ConstVertexIterator pathsVertex;
510  size_t callDepth;
511  CallSite(const ControlFlowGraph::ConstVertexIterator &pathsVertex, size_t callDepth)
512  : pathsVertex(pathsVertex), callDepth(callDepth) {}
513  };
514 
515  ControlFlowGraph paths_; // the resulting paths graph
516  CfgVertexMap vmap_; // relates CFG vertices to paths graph vertices
517  CfgConstVertexSet pathsBeginVertices_; // vertices where traversal starts
518  CfgConstVertexSet pathsEndVertices_; // vertices where traversal ends
519  std::list<CallSite> workList_; // call sites to be processed
520  ShouldInline::Ptr shouldInline_; // user predicate for whether to inline a call
521 
522 public:
527  : shouldInline_(ShouldInline::instance()) {}
528 
535  ShouldInline::Ptr shouldInline() const { return shouldInline_; }
536  void shouldInline(const ShouldInline::Ptr &p) { shouldInline_ = p; }
547  void inlinePaths(const PartitionerConstPtr &partitioner, const CfgConstVertexSet &cfgBeginVertices,
548  const CfgConstVertexSet &cfgEndVertices, const CfgConstVertexSet &cfgAvoidVertices,
549  const CfgConstEdgeSet &cfgAvoidEdges);
550 
554  const ControlFlowGraph& paths() const { return paths_; }
555 
560  const CfgConstVertexSet& pathsBeginVertices() const { return pathsBeginVertices_; }
561 
566  const CfgConstVertexSet& pathsEndVertices() const { return pathsEndVertices_; }
567 
568 private:
569  void reset(const PartitionerConstPtr &partitioner, const CfgConstVertexSet &cfgBeginVertices,
570  const CfgConstVertexSet &cfgEndVertices, const CfgConstVertexSet &cfgAvoidVertices,
571  const CfgConstEdgeSet &cfgAvoidEdges);
572 
573  // Returns true if pathVertex is a function call. Does so by consulting the corresponding vertex in the partitioner's
574  // global CFG.
575  static bool isFunctionCall(const PartitionerConstPtr&, const ControlFlowGraph::ConstVertexIterator &pathVertex);
576 
577  // Convert a path vertex to the corresponding vertex in the partitioner's global CFG.
578  static ControlFlowGraph::ConstVertexIterator pathToCfg(const PartitionerConstPtr &partitioner,
579  const ControlFlowGraph::ConstVertexIterator &pathVertex);
580 
581  // Convert global CFG vertices to paths graph vertices. */
582  static CfgConstVertexSet cfgToPaths(const CfgConstVertexSet &vertices, const CfgVertexMap &vmap);
583 };
584 
585 std::ostream& operator<<(std::ostream &out, const CfgPath &path);
586 
587 } // namespace
588 } // namespace
589 } // namespace
590 
591 #endif
592 #endif
std::vector< ControlFlowGraph::ConstVertexIterator > Vertices
Stack of vertices.
Definition: CfgPath.h:23
static Ptr instance()
Factory class method.
Definition: CfgPath.h:492
CfgPath(const ControlFlowGraph::ConstVertexIterator &vertex)
Construct a path having only a starting vertex.
Definition: CfgPath.h:47
HowInline
What action to take for inlining.
Definition: CfgPath.h:472
size_t nVertices() const
Number of vertices in a path.
Definition: CfgPath.h:84
ControlFlowGraph::ConstVertexIterator frontVertex() const
Returns the vertex where the path starts.
Definition: CfgPath.h:91
size_t nEdges() const
Number of edges in a path.
Definition: CfgPath.h:77
Base class for machine instructions.
size_t maxCallDepth() const
Maximum call depth.
std::vector< ControlFlowGraph::ConstEdgeIterator > Edges
Stack of inter-connected edges.
Definition: CfgPath.h:20
Holds a value or nothing.
Definition: Optional.h:49
bool isConnected() const
Verify that path edges are connected.
size_t nVisits(const ControlFlowGraph::ConstVertexIterator &vertex) const
Number of times vertex appears in path.
Sawyer::Container::Graph< CfgVertex, CfgEdge > ControlFlowGraph
Control flow graph.
bool inlineOneCallee(ControlFlowGraph &paths, const ControlFlowGraph::ConstVertexIterator &pathsCallSite, const ControlFlowGraph &cfg, const ControlFlowGraph::ConstVertexIterator &cfgCallTarget, const CfgConstVertexSet &cfgAvoidVertices, const CfgConstEdgeSet &cfgAvoidEdges, std::vector< ControlFlowGraph::ConstVertexIterator > *newVertices=nullptr)
Inline a function at the specified call site.
const CfgConstVertexSet & pathsEndVertices() const
Paths end vertices.
Definition: CfgPath.h:566
void popBack()
Erase the final edge from a path.
Main namespace for the ROSE library.
Sawyer::Container::GraphIteratorSet< ControlFlowGraph::ConstVertexIterator > CfgConstVertexSet
Set of CFG vertex pointers.
uint64_t hash() const
Hash the path.
std::vector< bool > findPathEdges(const ControlFlowGraph &graph, const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &avoidVertices=CfgConstVertexSet(), const CfgConstEdgeSet &avoidEdges=CfgConstEdgeSet(), bool avoidCallsAndReturns=false)
Finds edges that can be part of some path.
Sawyer::Attribute::Storage< Sawyer::SingleThreadedTag > Attributes
Stores user-defined attributes.
Definition: CfgPath.h:26
void inlinePaths(const PartitionerConstPtr &partitioner, const CfgConstVertexSet &cfgBeginVertices, const CfgConstVertexSet &cfgEndVertices, const CfgConstVertexSet &cfgAvoidVertices, const CfgConstEdgeSet &cfgAvoidEdges)
Construct a CFG with inlined functions.
void clear()
Makes this path empty.
Definition: CfgPath.h:55
std::pair< size_t, size_t > lastInsnIndex(SgAsmInstruction *) const
Find indices of last vertex and instruction.
Predicate to determine whether inlining should be performed.
Definition: CfgPath.h:481
Do not inline anything for this call.
Definition: CfgPath.h:473
size_t maxCallDepth() const
Property: maximum call depth.
Definition: CfgPath.h:497
A path through a control flow graph.
Definition: CfgPath.h:17
Attributes & edgeAttributes(size_t)
User-defined attributes for the nth edge.
void pushBack(ControlFlowGraph::ConstEdgeIterator edge)
Append a new edge to the end of the path.
virtual HowInline operator()(const PartitionerConstPtr &, const ControlFlowGraph::ConstEdgeIterator cfgCallEdge, const ControlFlowGraph &paths, const ControlFlowGraph::ConstVertexIterator &pathsCallSite, size_t callDepth)
Whether to inline a function.
ShouldInline::Ptr shouldInline() const
Property: inline predicate.
Definition: CfgPath.h:535
void shouldInline(const ShouldInline::Ptr &p)
Property: inline predicate.
Definition: CfgPath.h:536
void findPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths, CfgVertexMap &vmap, const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &endVertices, const CfgConstVertexSet &avoidVertices=CfgConstVertexSet(), const CfgConstEdgeSet &avoidEdges=CfgConstEdgeSet(), bool avoidCallsAndReturns=false)
Compute all paths.
CfgConstEdgeSet findPathUnreachableEdges(const ControlFlowGraph &graph, const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &endVertices, const CfgConstVertexSet &avoidVertices=CfgConstVertexSet(), const CfgConstEdgeSet &avoidEdges=CfgConstEdgeSet(), bool avoidCallsAndReturns=false)
Find edges that are unreachable.
bool inlineMultipleCallees(ControlFlowGraph &paths, const ControlFlowGraph::ConstVertexIterator &pathsCallSite, const ControlFlowGraph &cfg, const ControlFlowGraph::ConstVertexIterator &cfgCallSite, const CfgConstVertexSet &cfgAvoidVertices=CfgConstVertexSet(), const CfgConstEdgeSet &cfgAvoidEdges=CfgConstEdgeSet(), std::vector< ControlFlowGraph::ConstVertexIterator > *newEdges=nullptr)
Inline a function at the specified call site.
const CfgConstVertexSet & pathsBeginVertices() const
Paths begin vertices.
Definition: CfgPath.h:560
Attributes & vertexAttributes(size_t)
User-defined attributes for the nth vertex.
Base class for reference counted objects.
Definition: SharedObject.h:64
ControlFlowGraph::ConstVertexIterator backVertex() const
Returns the vertex where the path ends.
Definition: CfgPath.h:99
Sawyer::SharedPointer< ShouldInline > Ptr
Shared ownership pointer to a predicate object.
Definition: CfgPath.h:489
Bidirectional edge node iterator.
Definition: Graph.h:945
std::vector< ControlFlowGraph::ConstEdgeIterator > truncate(const ControlFlowGraph::ConstEdgeIterator &)
Truncate the path.
CfgPath(const ControlFlowGraph::ConstEdgeIterator &edge)
Construct a path given an initial edge.
Definition: CfgPath.h:51
Sawyer::Container::GraphIteratorBiMap< ControlFlowGraph::ConstVertexIterator, ControlFlowGraph::ConstVertexIterator > CfgVertexMap
Map vertices from one CFG to another CFG and vice versa.
void findInterFunctionPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths, CfgVertexMap &vmap, const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &avoidVertices=CfgConstVertexSet(), const CfgConstEdgeSet &avoidEdges=CfgConstEdgeSet())
Compute all paths across function calls and returns.
CfgPath()
Construct an empty path.
Definition: CfgPath.h:44
ssize_t callDepth() const
Call depth.
std::vector< ControlFlowGraph::ConstEdgeIterator > backtrack()
Backtrack to next path.
Add a V_USER_DEFINED vertex for this call.
Definition: CfgPath.h:475
Vertices vertices() const
Return all the vertices in a path.
size_t nCalls() const
Number of function calls.
size_t eraseUnreachablePaths(ControlFlowGraph &graph, CfgConstVertexSet &beginVertices, CfgConstVertexSet &endVertices, CfgVertexMap &vmap, CfgPath &path)
Remove edges and vertices that cannot be on the paths.
API and storage for attributes.
Definition: Attribute.h:215
void print(std::ostream &out) const
Print the path.
const ControlFlowGraph & paths() const
Resulting paths graph.
Definition: CfgPath.h:554
CfgConstEdgeSet findPathReachableEdges(const ControlFlowGraph &graph, const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &endVertices, const CfgConstVertexSet &avoidVertices=CfgConstVertexSet(), const CfgConstEdgeSet &avoidEdges=CfgConstEdgeSet(), bool avoidCallsAndReturns=false)
Find edges that are reachable.
Represents no value.
Definition: Optional.h:32
Sawyer::Container::GraphIteratorSet< ControlFlowGraph::ConstEdgeIterator > CfgConstEdgeSet
Set of CFG edge pointers.
void findFunctionPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths, CfgVertexMap &vmap, const CfgConstVertexSet &beginVertices, const CfgConstVertexSet &avoidVertices=CfgConstVertexSet(), const CfgConstEdgeSet &avoidEdges=CfgConstEdgeSet())
Compute all paths within one function.
size_t nReturns() const
Number of function returns.
bool isEmpty() const
Determine if a path is empty.
Definition: CfgPath.h:64
void pushFront(ControlFlowGraph::ConstEdgeIterator edge)
Insert a new edge to the front of the path.
const Edges & edges() const
Returns all the edges in a path.
Definition: CfgPath.h:107
void maxCallDepth(size_t n)
Property: maximum call depth.
Definition: CfgPath.h:498