ROSE 0.11.145.147
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
8namespace Rose {
9namespace BinaryAnalysis {
10namespace Partitioner2 {
11
17class CfgPath {
18public:
20 typedef std::vector<ControlFlowGraph::ConstEdgeIterator> Edges;
21
23 typedef std::vector<ControlFlowGraph::ConstVertexIterator> Vertices;
24
27
28private:
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
42public:
45
47 explicit CfgPath(const ControlFlowGraph::ConstVertexIterator &vertex)
48 : frontVertex_(vertex), vertexAttributes_(1, Attributes()) {}
49
51 explicit CfgPath(const ControlFlowGraph::ConstEdgeIterator &edge)
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
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
174 const Attributes& vertexAttributes(size_t) const;
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
287std::vector<bool>
289 const CfgConstVertexSet &beginVertices,
290 const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
291 const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet(), bool avoidCallsAndReturns = false);
292std::vector<bool>
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
328size_t
329eraseUnreachablePaths(ControlFlowGraph &graph /*in,out*/, CfgConstVertexSet &beginVertices /*in,out*/,
330 CfgConstVertexSet &endVertices /*in,out*/, CfgVertexMap &vmap /*in,out*/, CfgPath &path /*in,out*/);
331
347void
348findPaths(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
368void
369findPaths(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
380void
381findFunctionPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths /*out*/, CfgVertexMap &vmap /*out*/,
382 const CfgConstVertexSet &beginVertices,
383 const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
384 const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet());
385void
386findFunctionPaths(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());
399void
400findInterFunctionPaths(const ControlFlowGraph &srcCfg, ControlFlowGraph &paths /*out*/, CfgVertexMap &vmap /*out*/,
401 const CfgConstVertexSet &beginVertices,
402 const CfgConstVertexSet &avoidVertices = CfgConstVertexSet(),
403 const CfgConstEdgeSet &avoidEdges = CfgConstEdgeSet());
404void
405findInterFunctionPaths(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());
440bool
441inlineMultipleCallees(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);
446bool
447inlineOneCallee(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);
468class Inliner {
469public:
470
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
507private:
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
522public:
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
568private:
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
585std::ostream& operator<<(std::ostream &out, const CfgPath &path);
586
587} // namespace
588} // namespace
589} // namespace
590
591#endif
592#endif
A path through a control flow graph.
Definition CfgPath.h:17
std::pair< size_t, size_t > lastInsnIndex(SgAsmInstruction *) const
Find indices of last vertex and instruction.
CfgPath()
Construct an empty path.
Definition CfgPath.h:44
void popBack()
Erase the final edge from a path.
size_t maxCallDepth(const FunctionPtr &) const
Maximum call depth.
uint64_t hash(SgAsmInstruction *) const
Hash part of a path,.
size_t nVisits(const ControlFlowGraph::ConstVertexIterator &vertex) const
Number of times vertex appears in path.
std::vector< ControlFlowGraph::ConstEdgeIterator > truncate(const CfgConstEdgeSet &)
Truncate the path.
size_t maxCallDepth() const
Maximum call depth.
uint64_t hash() const
Hash the path.
const Edges & edges() const
Returns all the edges in a path.
Definition CfgPath.h:107
Vertices vertices() const
Return all the vertices in a path.
size_t nCalls() const
Number of function calls.
void clear()
Makes this path empty.
Definition CfgPath.h:55
const Attributes & edgeAttributes(size_t) const
User-defined attributes for the nth edge.
Attributes & edgeAttributes(size_t)
User-defined attributes for the nth edge.
std::vector< ControlFlowGraph::ConstEdgeIterator > truncate(const ControlFlowGraph::ConstEdgeIterator &)
Truncate the path.
ControlFlowGraph::ConstVertexIterator backVertex() const
Returns the vertex where the path ends.
Definition CfgPath.h:99
size_t nReturns() const
Number of function returns.
ControlFlowGraph::ConstVertexIterator frontVertex() const
Returns the vertex where the path starts.
Definition CfgPath.h:91
void pushBack(ControlFlowGraph::ConstEdgeIterator edge)
Append a new edge to the end of the path.
const Attributes & vertexAttributes(size_t) const
User-defined attributes for the nth vertex.
CfgPath(const ControlFlowGraph::ConstVertexIterator &vertex)
Construct a path having only a starting vertex.
Definition CfgPath.h:47
Attributes & vertexAttributes(size_t)
User-defined attributes for the nth vertex.
std::vector< ControlFlowGraph::ConstEdgeIterator > Edges
Stack of inter-connected edges.
Definition CfgPath.h:20
std::vector< ControlFlowGraph::ConstVertexIterator > Vertices
Stack of vertices.
Definition CfgPath.h:23
std::vector< ControlFlowGraph::ConstEdgeIterator > backtrack()
Backtrack to next path.
ssize_t callDepth() const
Call depth.
Sawyer::Attribute::Storage< Sawyer::SingleThreadedTag > Attributes
Stores user-defined attributes.
Definition CfgPath.h:26
void pushBack(const std::vector< ControlFlowGraph::ConstEdgeIterator > &edges)
Append a new edge to the end of the path.
bool isConnected() const
Verify that path edges are connected.
size_t nReturns(const FunctionPtr &) const
Number of function returns.
size_t nVisits(const ControlFlowGraph::ConstEdgeIterator &edge) const
Number of times edge appears in path.
size_t nCalls(const FunctionPtr &) const
Number of function calls.
void pushFront(ControlFlowGraph::ConstEdgeIterator edge)
Insert a new edge to the front of the path.
size_t nEdges() const
Number of edges in a path.
Definition CfgPath.h:77
bool isEmpty() const
Determine if a path is empty.
Definition CfgPath.h:64
ssize_t callDepth(const FunctionPtr &) const
Call depth.
void pushFront(const std::vector< ControlFlowGraph::ConstEdgeIterator > &edges)
Insert a new edge to the front of the path.
CfgPath(const ControlFlowGraph::ConstEdgeIterator &edge)
Construct a path given an initial edge.
Definition CfgPath.h:51
size_t nVertices() const
Number of vertices in a path.
Definition CfgPath.h:84
void print(std::ostream &out) const
Print the path.
Predicate to determine whether inlining should be performed.
Definition CfgPath.h:481
Sawyer::SharedPointer< ShouldInline > Ptr
Shared ownership pointer to a predicate object.
Definition CfgPath.h:489
void maxCallDepth(size_t n)
Property: maximum call depth.
Definition CfgPath.h:498
virtual HowInline operator()(const PartitionerConstPtr &, const ControlFlowGraph::ConstEdgeIterator cfgCallEdge, const ControlFlowGraph &paths, const ControlFlowGraph::ConstVertexIterator &pathsCallSite, size_t callDepth)
Whether to inline a function.
size_t maxCallDepth() const
Property: maximum call depth.
Definition CfgPath.h:497
ShouldInline::Ptr shouldInline() const
Property: inline predicate.
Definition CfgPath.h:535
HowInline
What action to take for inlining.
Definition CfgPath.h:472
@ INLINE_NORMAL
Normal inlining for this call.
Definition CfgPath.h:474
@ INLINE_USER
Add a V_USER_DEFINED vertex for this call.
Definition CfgPath.h:475
@ INLINE_NONE
Do not inline anything for this call.
Definition CfgPath.h:473
void inlinePaths(const PartitionerConstPtr &partitioner, const CfgConstVertexSet &cfgBeginVertices, const CfgConstVertexSet &cfgEndVertices, const CfgConstVertexSet &cfgAvoidVertices, const CfgConstEdgeSet &cfgAvoidEdges)
Construct a CFG with inlined functions.
const ControlFlowGraph & paths() const
Resulting paths graph.
Definition CfgPath.h:554
const CfgConstVertexSet & pathsEndVertices() const
Paths end vertices.
Definition CfgPath.h:566
void shouldInline(const ShouldInline::Ptr &p)
Property: inline predicate.
Definition CfgPath.h:536
const CfgConstVertexSet & pathsBeginVertices() const
Paths begin vertices.
Definition CfgPath.h:560
API and storage for attributes.
Definition Attribute.h:215
Represents no value.
Definition Optional.h:36
Holds a value or nothing.
Definition Optional.h:56
Base class for reference counted objects.
Base class for machine instructions.
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.
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.
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.
Sawyer::Container::GraphIteratorBiMap< ControlFlowGraph::ConstVertexIterator, ControlFlowGraph::ConstVertexIterator > CfgVertexMap
Map vertices from one CFG to another CFG and vice versa.
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.
Sawyer::Container::Graph< CfgVertex, CfgEdge > ControlFlowGraph
Control flow graph.
Sawyer::Container::GraphIteratorSet< ControlFlowGraph::ConstEdgeIterator > CfgConstEdgeSet
Set of CFG edge pointers.
size_t eraseUnreachablePaths(ControlFlowGraph &graph, CfgConstVertexSet &beginVertices, CfgConstVertexSet &endVertices, CfgVertexMap &vmap, CfgPath &path)
Remove edges and vertices that cannot be on the 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.
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.
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.
Sawyer::Container::GraphIteratorSet< ControlFlowGraph::ConstVertexIterator > CfgConstVertexSet
Set of CFG vertex pointers.
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.
The ROSE library.