1 #ifndef ROSE_BinaryAnalysis_Partitioner2_Utility_H
2 #define ROSE_BinaryAnalysis_Partitioner2_Utility_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 #include <Rose/BinaryAnalysis/Partitioner2/BasicTypes.h>
7 #include <Rose/BinaryAnalysis/Partitioner2/Function.h>
8 #include <Rose/CommandLine/IntervalParser.h>
10 #include <Rose/Diagnostics.h>
16 namespace BinaryAnalysis {
17 namespace Partitioner2 {
26 bool sortByExpression(
const BasicBlockSuccessor&,
const BasicBlockSuccessor&);
30 template<
class Container,
class Comparator>
32 isSorted(
const Container &container, Comparator sorted,
bool distinct=
true) {
33 typename Container::const_iterator current = container.begin();
34 if (current!=container.end()) {
35 typename Container::const_iterator next = current;
36 while (++next != container.end()) {
37 if ((distinct && !sorted(*current, *next)) || sorted(*next, *current))
45 template<
class Container,
class Value,
class Comparator>
46 typename Container::const_iterator
47 lowerBound(
const Container &container,
const Value &item, Comparator cmp) {
48 return std::lower_bound(container.begin(), container.end(), item, cmp);
50 template<
class Container,
class Value,
class Comparator>
51 typename Container::iterator
52 lowerBound(Container &container,
const Value &item, Comparator cmp) {
53 return std::lower_bound(container.begin(), container.end(), item, cmp);
57 template<
class Value,
class Comparator>
59 equalUnique(
const Value &a,
const Value &b, Comparator cmp) {
60 return !cmp(a, b) && !cmp(b, a);
64 template<
class Container,
class Value,
class Comparator>
66 insertUnique(Container &container,
const Value &item, Comparator cmp) {
67 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
68 typename Container::iterator lb = lowerBound(container, item, cmp);
69 if (lb==container.end() || !equalUnique(*lb, item, cmp)) {
70 container.insert(lb, item);
71 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
78 template<
class Container,
class Value,
class Comparator>
80 replaceOrInsert(Container &container,
const Value &item, Comparator cmp) {
81 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
82 typename Container::iterator lb = lowerBound(container, item, cmp);
83 if (lb == container.end() || !equalUnique(*lb, item, cmp)) {
84 container.insert(lb, item);
88 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
92 template<
class Container,
class Value,
class Comparator>
94 eraseUnique(Container &container,
const Value &item, Comparator cmp) {
95 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
96 typename Container::iterator lb = lowerBound(container, item, cmp);
97 if (lb!=container.end() && equalUnique(*lb, item, cmp)) {
105 template<
class Container,
class Value,
class Comparator>
107 existsUnique(
const Container &container,
const Value &item, Comparator cmp) {
110 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
111 typename Container::const_iterator lb = lowerBound(container, item, cmp);
112 if (lb==container.end() || cmp(*lb, item) || cmp(item, *lb))
118 template<
class Container,
class Value,
class Comparator>
120 getUnique(
const Container &container,
const Value &item, Comparator cmp) {
123 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
124 typename Container::const_iterator lb = lowerBound(container, item, cmp);
125 if (lb==container.end() || cmp(*lb, item) || cmp(item, *lb))
131 template<
class Container,
class Value,
class Comparator>
133 getOrInsertUnique(Container &container,
const Value &item, Comparator cmp) {
134 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
135 typename Container::iterator lb = lowerBound(container, item, cmp);
136 if (lb != container.end() && equalUnique(*lb, item, cmp)) {
139 container.insert(lb, item);
140 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
145 template<
class Container,
class Comparator>
147 isSupersetUnique(
const Container &sup,
const Container &sub, Comparator lessThan) {
148 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(sup, lessThan,
true));
149 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(sub, lessThan,
true));
150 typename Container::const_iterator isup = sup.begin(),
isub = sub.begin();
151 while (isup != sup.end() &&
isub != sub.end()) {
152 while (isup != sup.end() && lessThan(*isup, *isub))
154 if (isup == sup.end() || lessThan(*isub, *isup))
158 return isub == sub.end();
161 std::ostream& operator<<(std::ostream&,
const AddressUser&);
162 std::ostream& operator<<(std::ostream&,
const AddressUsers&);
163 std::ostream& operator<<(std::ostream&,
const AddressUsageMap&);
181 :
Super(valueSaver) {}
224 Trigger(
size_t nSkip,
size_t nTimes): nCalls_(0) {
244 size_t nCalls()
const {
return nCalls_; }
262 boost::logic::tribool
const ValueSaver::Ptr valueSaver() const
Property: functor responsible for saving a parsed value in user storage.
static Ptr instance()
Default allocating constructor.
bool isEmpty() const
True if interval is empty.
Trigger(const Settings &settings)
Armed for triggering when number of calls falls within when.
Base class for machine instructions.
Sawyer::SharedPointer< AddressIntervalParser > Ptr
Shared-ownership pointer to an AddressIntervalParser.
ROSE_DLL_API Sawyer::Message::Facility mlog
Diagnostic facility for the ROSE library as a whole.
Parse an address interval.
A collection of related switch declarations.
Represents a synthesized function.
size_t nCalls() const
Number of times called.
Main namespace for the ROSE library.
static Interval baseSize(rose_addr_t lo, rose_addr_t size)
Construct an interval from one endpoint and a size.
Sawyer::SharedPointer< Function > FunctionPtr
Shared-ownership pointer for Function.
Sawyer::SharedPointer< BasicBlock > BasicBlockPtr
Shared-ownersip pointer for BasicBlock.
bool contains(const Interval &other) const
Containment predicate.
size_t serialNumber()
Return the next serial number.
Trigger based on number of times called.
Sawyer::SharedPointer< const Partitioner > PartitionerConstPtr
Shared-ownership pointer for Partitioner.
static std::string docString()
Documentation for command-line switches.
bool isArmed() const
True if trigger is armed.
Trigger()
Trigger armed for single call.
static Ptr instance(const Sawyer::CommandLine::ValueSaver::Ptr &valueSaver)
Allocating constructor.
bool hasCallReturnEdges(const ControlFlowGraph::ConstVertexIterator &)
Test whether vertex has at least one call-return edge.
boost::logic::tribool hasAnyCalleeReturn(const PartitionerConstPtr &, const ControlFlowGraph::ConstVertexIterator &)
May-return status for function callees.
void initDiagnostics()
Initialize diagnostics.
static Sawyer::CommandLine::SwitchGroup switches(Settings &)
Command-line switches to initialize settings.
static std::string docString()
Runtime documentation.
Sawyer::SharedPointer< DataBlock > DataBlockPtr
Shared-ownership pointer for DataBlock.
T greatest() const
Returns upper limit.
static Trigger always()
Armed to always trigger.
static Trigger never()
Armed to never trigger.
bool shouldTrigger()
Increment calls and return true if triggering.
static Trigger once()
Armed for one call.
void reset()
Reset number of calls to zero.
Trigger(size_t nSkip, size_t nTimes)
Armed for triggering after nSkip calls but not more than nTimes times.