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>
16namespace BinaryAnalysis {
17namespace Partitioner2 {
26bool sortByExpression(
const BasicBlockSuccessor&,
const BasicBlockSuccessor&);
30template<
class Container,
class Comparator>
32isSorted(
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))
45template<
class Container,
class Value,
class Comparator>
46typename Container::const_iterator
47lowerBound(
const Container &container,
const Value &item, Comparator cmp) {
48 return std::lower_bound(container.begin(), container.end(), item, cmp);
50template<
class Container,
class Value,
class Comparator>
51typename Container::iterator
52lowerBound(Container &container,
const Value &item, Comparator cmp) {
53 return std::lower_bound(container.begin(), container.end(), item, cmp);
57template<
class Value,
class Comparator>
59equalUnique(
const Value &a,
const Value &b, Comparator cmp) {
60 return !cmp(a, b) && !cmp(b, a);
64template<
class Container,
class Value,
class Comparator>
66insertUnique(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));
78template<
class Container,
class Value,
class Comparator>
80replaceOrInsert(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));
92template<
class Container,
class Value,
class Comparator>
94eraseUnique(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)) {
105template<
class Container,
class Value,
class Comparator>
107existsUnique(
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))
118template<
class Container,
class Value,
class Comparator>
120getUnique(
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))
131template<
class Container,
class Value,
class Comparator>
133getOrInsertUnique(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));
145template<
class Container,
class Comparator>
147isSupersetUnique(
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();
161std::ostream& operator<<(std::ostream&,
const AddressUser&);
162std::ostream& operator<<(std::ostream&,
const AddressUsers&);
163std::ostream& operator<<(std::ostream&,
const AddressUsageMap&);
224 Trigger(
size_t nSkip,
size_t nTimes): nCalls_(0) {
244 size_t nCalls()
const {
return nCalls_; }
Parse an address interval.
static Ptr instance(const Sawyer::CommandLine::ValueSaver::Ptr &valueSaver)
Allocating constructor.
static std::string docString()
Runtime documentation.
Sawyer::SharedPointer< AddressIntervalParser > Ptr
Shared-ownership pointer to an AddressIntervalParser.
static Ptr instance()
Default allocating constructor.
Trigger based on number of times called.
static Sawyer::CommandLine::SwitchGroup switches(Settings &)
Command-line switches to initialize settings.
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.
Trigger(const Settings &settings)
Armed for triggering when number of calls falls within when.
bool isArmed() const
True if trigger is armed.
static Trigger once()
Armed for one call.
static std::string docString()
Documentation for command-line switches.
bool shouldTrigger()
Increment calls and return true if triggering.
static Trigger never()
Armed to never trigger.
size_t nCalls() const
Number of times called.
static Trigger always()
Armed to always trigger.
Trigger()
Trigger armed for single call.
A collection of related switch declarations.
const ValueSaver::Ptr valueSaver() const
Property: functor responsible for saving a parsed value in user storage.
T greatest() const
Returns upper limit.
static Interval baseSize(Address lo, Address size)
Construct an interval from one endpoint and a size.
bool contains(const Interval &other) const
Containment predicate.
bool isEmpty() const
True if interval is empty.
Holds a value or nothing.
Represents a synthesized function.
Base class for machine instructions.
bool hasCallReturnEdges(const ControlFlowGraph::ConstVertexIterator &)
Test whether vertex has at least one call-return edge.
Sawyer::SharedPointer< Function > FunctionPtr
Shared-ownership pointer for Function.
boost::logic::tribool hasAnyCalleeReturn(const PartitionerConstPtr &, const ControlFlowGraph::ConstVertexIterator &)
May-return status for function callees.
size_t serialNumber()
Return the next serial number.
Sawyer::SharedPointer< DataBlock > DataBlockPtr
Shared-ownership pointer for DataBlock.
Sawyer::SharedPointer< BasicBlock > BasicBlockPtr
Shared-ownersip pointer for BasicBlock.
void initDiagnostics()
Initialize diagnostics.
ROSE_DLL_API Sawyer::Message::Facility mlog
Diagnostic facility for the ROSE library as a whole.