1 #ifndef ROSE_Partitioner2_Utility_H
2 #define ROSE_Partitioner2_Utility_H
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
7 #include <Partitioner2/AddressUsageMap.h>
8 #include <Partitioner2/BasicBlock.h>
9 #include <Partitioner2/DataBlock.h>
10 #include <Partitioner2/Function.h>
12 #include "Diagnostics.h"
19 namespace Partitioner2 {
22 void initDiagnostics();
28 bool sortByExpression(
const BasicBlock::Successor&,
const BasicBlock::Successor&);
32 template<
class Container,
class Comparator>
34 isSorted(
const Container &container, Comparator sorted,
bool distinct=
true) {
35 typename Container::const_iterator current = container.begin();
36 if (current!=container.end()) {
37 typename Container::const_iterator next = current;
38 while (++next != container.end()) {
39 if ((distinct && !sorted(*current, *next)) || sorted(*next, *current))
47 template<
class Container,
class Value,
class Comparator>
48 typename Container::const_iterator
49 lowerBound(
const Container &container,
const Value &item, Comparator cmp) {
50 return std::lower_bound(container.begin(), container.end(), item, cmp);
52 template<
class Container,
class Value,
class Comparator>
53 typename Container::iterator
54 lowerBound(Container &container,
const Value &item, Comparator cmp) {
55 return std::lower_bound(container.begin(), container.end(), item, cmp);
59 template<
class Value,
class Comparator>
61 equalUnique(
const Value &a,
const Value &b, Comparator cmp) {
62 return !cmp(a, b) && !cmp(b, a);
66 template<
class Container,
class Value,
class Comparator>
68 insertUnique(Container &container,
const Value &item, Comparator cmp) {
69 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
70 typename Container::iterator lb = lowerBound(container, item, cmp);
71 if (lb==container.end() || !equalUnique(*lb, item, cmp)) {
72 container.insert(lb, item);
73 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
80 template<
class Container,
class Value,
class Comparator>
82 replaceOrInsert(Container &container,
const Value &item, Comparator cmp) {
83 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
84 typename Container::iterator lb = lowerBound(container, item, cmp);
85 if (lb == container.end() || !equalUnique(*lb, item, cmp)) {
86 container.insert(lb, item);
90 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
94 template<
class Container,
class Value,
class Comparator>
96 eraseUnique(Container &container,
const Value &item, Comparator cmp) {
97 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
98 typename Container::iterator lb = lowerBound(container, item, cmp);
99 if (lb!=container.end() && equalUnique(*lb, item, cmp)) {
107 template<
class Container,
class Value,
class Comparator>
109 existsUnique(
const Container &container,
const Value &item, Comparator cmp) {
112 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
113 typename Container::const_iterator lb = lowerBound(container, item, cmp);
114 if (lb==container.end() || cmp(*lb, item) || cmp(item, *lb))
120 template<
class Container,
class Value,
class Comparator>
122 getUnique(
const Container &container,
const Value &item, Comparator cmp) {
125 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
126 typename Container::const_iterator lb = lowerBound(container, item, cmp);
127 if (lb==container.end() || cmp(*lb, item) || cmp(item, *lb))
132 template<
class Container,
class Comparator>
134 isSupersetUnique(
const Container &sup,
const Container &sub, Comparator lessThan) {
135 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(sup, lessThan,
true));
136 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(sub, lessThan,
true));
137 typename Container::const_iterator isup = sup.begin(), isub = sub.begin();
138 while (isup != sup.end() && isub != sub.end()) {
139 while (isup != sup.end() && lessThan(*isup, *isub))
141 if (isup == sup.end() || lessThan(*isub, *isup))
145 return isub == sub.end();
148 std::ostream& operator<<(std::ostream&,
const AddressUser&);
149 std::ostream& operator<<(std::ostream&,
const AddressUsers&);
150 std::ostream& operator<<(std::ostream&,
const AddressUsageMap&);
171 static Ptr instance() {
179 static std::string docString();
224 Trigger(
size_t nSkip,
size_t nTimes): nCalls_(0) {
244 size_t nCalls()
const {
return nCalls_; }
const ValueSaver::Ptr valueSaver() const
Property: functor responsible for saving a parsed value in user storage.
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< DataBlock > Ptr
Shared pointer to a data block.
Parse an address interval.
A collection of related switch declarations.
Represents a synthesized function.
size_t nCalls() const
Number of times called.
bool isContaining(const Interval &other) const
Containment predicate.
Main namespace for the ROSE library.
Sawyer::SharedPointer< AddressIntervalParser > Ptr
Shared-ownership pointer to an AddressIntervalParser.
static Interval baseSize(rose_addr_t lo, rose_addr_t size)
Construct an interval from one endpoint and a size.
size_t serialNumber()
Return the next serial number.
Information about a parsed switch value.
Trigger based on number of times called.
static std::string docString()
Documentation for command-line switches.
bool isArmed() const
True if trigger is armed.
Trigger()
Trigger armed for single call.
Sawyer::SharedPointer< BasicBlock > Ptr
Shared pointer to a basic block.
static Sawyer::CommandLine::SwitchGroup switches(Settings &)
Command-line switches to initialize settings.
Position within a command-line.
Base class parsing a value from input.
T greatest() const
Returns upper limit.
static Trigger always()
Armed to always trigger.
static Trigger never()
Armed to never trigger.
FunctionPtr Ptr
Shared-ownership pointer for function.
bool shouldTrigger()
Increment calls and return true if triggering.
static Trigger once()
Armed for one call.
void reset()
Reset number of calls to zero.
static AddressInterval parse(const char *input, const char **rest)
Parse an interval from a C string.
Trigger(size_t nSkip, size_t nTimes)
Armed for triggering after nSkip calls but not more than nTimes times.