63template <
typename Signature>
66template <
typename R,
typename... Args>
72 typename = std::enable_if_t<
74 std::is_invocable_r_v<
R, F &, Args...>>>
76 : invoke_(&function_ref::call<std::remove_reference_t<F>>),
77 ctx_(
const_cast<void *
>(
static_cast<const void *
>(std::addressof(fn))))
83 if constexpr (std::is_void_v<R>)
84 invoke_(ctx_, std::forward<Args>(args)...);
86 return invoke_(ctx_, std::forward<Args>(args)...);
91 static R call(
void *p, Args... args)
93 if constexpr (std::is_void_v<R>)
94 (*
static_cast<F *
>(p))(std::forward<Args>(args)...);
96 return (*
static_cast<F *
>(p))(std::forward<Args>(args)...);
99 R (*invoke_)(
void *, Args...);
113 seed ^= std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
153 explicit make_tag() =
default;
161 ptr_->
refcount.fetch_add(1, std::memory_order_relaxed);
164 template <
class U,
class... Args>
165 friend irep_container<typename U::base_type>
make_irep(Args &&...args);
177 ptr_->refcount.fetch_add(1, std::memory_order_relaxed);
190 irep_container &
operator=(
const irep_container &ref)
noexcept
203 T *new_ptr = ref.ptr_;
205 new_ptr->refcount.fetch_add(1, std::memory_order_relaxed);
212 irep_container &
operator=(irep_container &&ref)
noexcept
219 T *new_ptr = ref.ptr_;
240 [[nodiscard]]
const T *
get() const noexcept
256 ptr_->crc_val.store(0, std::memory_order_relaxed);
276 explicit operator bool() const noexcept
278 return ptr_ !=
nullptr;
294 if (ptr_->refcount.load(std::memory_order_acquire) == 1)
297 *
this = ptr_->clone();
300 friend void swap(irep_container &a, irep_container &b)
noexcept
307 void swap(irep_container &b)
noexcept
315 const T *foo =
get();
316 return foo->simplify();
321 const T *foo =
get();
326 size_t cached = foo->crc_val.load(std::memory_order_acquire); cached != 0)
345 friend bool operator==(
const irep_container &a,
const irep_container &b)
356 friend bool operator!=(
const irep_container &a,
const irep_container &b)
361 friend bool operator<(
const irep_container &a,
const irep_container &b)
374 friend bool operator<=(
const irep_container &a,
const irep_container &b)
379 friend bool operator>=(
const irep_container &a,
const irep_container &b)
384 friend bool operator>(
const irep_container &a,
const irep_container &b)
395 return a.ptr_ == b.ptr_;
402 void release() noexcept
406 unsigned int prev = ptr_->refcount.fetch_sub(1, std::memory_order_release);
412 std::atomic_thread_fence(std::memory_order_acquire);
422 ptr_->clear_writer();
450template <
class T,
class... Args>
451inline irep_container<typename T::base_type>
make_irep(Args &&...args)
453 using container_t = irep_container<typename T::base_type>;
455 new T(std::forward<Args>(args)...),
typename container_t::make_tag{});
514 auto h = std::hash<std::thread::id>{}(std::this_thread::get_id());
517 return h == 0 ? 1 :
static_cast<std::uintptr_t
>(h);
523 std::uintptr_t prev =
writer_thread.load(std::memory_order_acquire);
533 prev, me, std::memory_order_release, std::memory_order_acquire))
538 "irep2 single-writer contract violated: a second thread tried to "
539 "mutate a node already being mutated by another thread");
561#define IREP2_TYPE(kind, pretty) kind##_id,
574 const char *
what() const noexcept
576 return "symbolic type encountered";
631 std::string
pretty(
unsigned int indent = 0)
const;
678 template <
typename T>
685 template <
typename T>
734#define IREP2_EXPR(kind, pretty) kind##_id,
781 std::string
pretty(
unsigned int indent = 0)
const;
892 template <
typename T>
899 template <
typename T>
918 return exp.get() ==
nullptr;
934 return a.
get() == b.
get();
939 return t.
get() ==
nullptr;
1032template <
class C,
class M>
1038template <
class C,
class M>
1048template <
class K, std::
size_t I>
1051 using P = std::remove_cvref_t<decltype(std::get<I>(K::fields))>;
1053 if constexpr (std::is_same_v<class_t, K>)
1059template <
class K, std::size_t... Is>
1065template <
class K, std::size_t... Is>
1071 std::remove_cvref_t<
decltype(std::get<Is>(K::fields))>>::class_t,
1075 ... + std::size_t{0});
1090template <
class K,
class =
void>
1098 std::void_t<decltype(K::excluded_field_bytes)>>
1100 static constexpr std::size_t
value = K::excluded_field_bytes;
1113 using fields_t = std::remove_cv_t<
decltype(K::fields)>;
1114 constexpr std::size_t derived_storage =
sizeof(K) -
1115 sizeof(
typename K::base_type) -
1118 std::make_index_sequence<std::tuple_size_v<fields_t>>{});
1119 return derived_storage - covered <
alignof(K);
1128 using fields_t = std::remove_cv_t<
decltype(K::fields)>;
1130 std::make_index_sequence<std::tuple_size_v<fields_t>>{});
1138 "irep2 kind invariant: fields tuple does not cover the derived class "
1139 "storage. Either add the missing member pointer to the kind's "
1140 "`fields = std::make_tuple(...)`, or — if the member is intentionally "
1141 "excluded from cmp/crc/hash — list every non-excluded member explicitly "
1142 "and document the omission.");
1145 "irep2 kind invariant: this kind has more derived-class field entries "
1146 "than esbmct::num_type_fields. Either bump num_type_fields and the "
1147 "corresponding field_names[] arrays, or replace the fixed-size array "
1148 "with one sized by std::tuple_size_v<decltype(fields)>.");
1185 using std::logic_error::logic_error;
1201template <
typename Derived>
1205 const char *target_name)
1209 return static_cast<Derived &
>(t);
1212template <
typename Derived>
1216 const char *target_name)
1220 return static_cast<const Derived &
>(t);
1223template <
typename Derived>
1227 const char *target_name)
1229 if (e.expr_id != expected)
1231 return static_cast<Derived &
>(e);
1234template <
typename Derived>
1238 const char *target_name)
1240 if (e.expr_id != expected)
1242 return static_cast<const Derived &
>(e);
static float R(float z)
Definition acosf.c:26
R operator()(Args... args) const
Definition irep2.h:81
function_ref(F &&fn) noexcept
Definition irep2.h:75
Type-erased callable reference: non-owning, two pointers wide, no heap allocation.
Definition irep2.h:64
Base class for all expressions.
Definition irep2.h:725
void foreach_operand_impl_const(const_op_delegate &expr) const
Definition irep2_expr.cpp:684
expr2t base_type
Definition irep2.h:759
list_of_memberst tostring(unsigned int indent) const
Convert fields of subclasses to a string representation.
Definition irep2_expr.cpp:636
void Foreach_operand(T &&t)
Definition irep2.h:900
const expr2tc * get_sub_expr(size_t idx) const
Fetch a sub-operand.
Definition irep2_expr.cpp:652
bool cmp(const expr2t &ref) const
Structural comparison.
Definition irep2_expr.cpp:414
bool operator<(const expr2t &ref) const
Definition irep2_expr.cpp:71
std::string pretty(unsigned int indent=0) const
Produce textual representation of this expr.
Definition irep2_expr.cpp:81
expr2tc clone() const
Definition irep2_expr.cpp:455
DUMP_METHOD void dump() const
Write textual representation of this object to stdout.
Definition irep2_expr.cpp:92
expr2t(const type2tc &type, expr_ids id)
Primary constructor.
Definition irep2_expr.cpp:49
bool operator==(const expr2t &ref) const
Definition irep2_expr.cpp:61
std::atomic< size_t > crc_val
Definition irep2.h:913
virtual ~expr2t()=default
expr_ids
Enumeration identifying each sort of expr.
Definition irep2.h:730
@ end_expr_id
Definition irep2.h:901
const expr_ids expr_id
Instance of expr_ids recording tihs exprs type.
Definition irep2.h:907
void foreach_operand(T &&t) const
Indirect, abstract operand iteration.
Definition irep2.h:893
esbmct::function_ref< void(const expr2tc &)> const_op_delegate
Definition irep2.h:741
void foreach_operand_impl(op_delegate &expr)
Definition irep2_expr.cpp:700
virtual expr2tc do_simplify() const
expr-specific simplification methods.
Definition expr_simplifier.cpp:17
esbmct::function_ref< void(expr2tc &)> op_delegate
Definition irep2.h:742
bool operator!=(const expr2t &ref) const
Definition irep2_expr.cpp:66
int lt(const expr2t &ref) const
Trinary structural ordering.
Definition irep2_expr.cpp:438
const type2tc type
Type of this expr.
Definition irep2.h:910
size_t crc() const
Calculate a hash/digest of the current expr.
Definition irep2_crc.cpp:290
expr2tc container_type
Definition irep2.h:758
expr2tc with_type(const type2tc &new_type) const
Build a fresh expression of the same kind and field values as this one, but with a different type.
Definition irep2_expr.cpp:613
expr2tc simplify() const
Simplify an expression.
Definition expr_simplifier.cpp:40
size_t get_num_sub_exprs() const
Count the number of sub-exprs there are.
Definition irep2_expr.cpp:668
static std::uintptr_t current_thread_tag() noexcept
Definition irep2.h:512
std::atomic< std::uintptr_t > writer_thread
Definition irep2.h:510
irep2t(const irep2t &) noexcept
Definition irep2.h:482
irep2t() noexcept
Definition irep2.h:470
void clear_writer() const noexcept
Definition irep2.h:542
virtual ~irep2t()=default
irep2t & operator=(const irep2t &)=delete
std::atomic< unsigned int > refcount
Definition irep2.h:495
void mark_writer() const noexcept
Definition irep2.h:520
Reference counted container for irep2 nodes.
Definition irep2.h:144
size_t crc() const
Definition irep2.h:319
void reset() noexcept
Definition irep2.h:281
T * operator->()
Definition irep2.h:271
friend bool operator==(const irep_container &a, const irep_container &b)
Definition irep2.h:345
irep_container & operator=(const irep_container &ref) noexcept
Definition irep2.h:190
irep_container(const irep_container &ref) noexcept
Definition irep2.h:174
friend bool operator<(const irep_container &a, const irep_container &b)
Definition irep2.h:361
irep_container(irep_container &&ref) noexcept
Definition irep2.h:180
friend bool operator<=(const irep_container &a, const irep_container &b)
Definition irep2.h:374
friend bool operator>(const irep_container &a, const irep_container &b)
Definition irep2.h:384
~irep_container()
Definition irep2.h:185
irep_container simplify() const
Definition irep2.h:313
irep_container & operator=(irep_container &&ref) noexcept
Definition irep2.h:212
const T & operator*() const noexcept
Definition irep2.h:230
const T * get() const noexcept
Definition irep2.h:240
const T * operator->() const noexcept
Definition irep2.h:235
friend bool operator!=(const irep_container &a, const irep_container &b)
Definition irep2.h:356
T * get()
Definition irep2.h:251
T & operator*()
Definition irep2.h:266
void swap(irep_container &b) noexcept
Definition irep2.h:307
friend irep_container< typename U::base_type > make_irep(Args &&...args)
Allocate a fresh irep2 node and adopt it into an irep_container.
Definition irep2.h:451
friend bool operator>=(const irep_container &a, const irep_container &b)
Definition irep2.h:379
friend void swap(irep_container &a, irep_container &b) noexcept
Definition irep2.h:300
void detach()
Definition irep2.h:287
constexpr irep_container() noexcept
Definition irep2.h:170
Symbolic type exception class.
Definition irep2.h:572
const char * what() const noexcept
Definition irep2.h:574
Base class for all types.
Definition irep2.h:554
type2tc container_type
Definition irep2.h:602
void Foreach_subtype(T &&t)
Definition irep2.h:686
esbmct::function_ref< void(type2tc &)> subtype_delegate
Definition irep2.h:586
unsigned int get_width() const
Fetch bit width of this type.
Definition irep2_type.cpp:352
type2tc clone() const
Clone method.
Definition irep2_type.cpp:288
esbmct::function_ref< void(const type2tc &)> const_subtype_delegate
Definition irep2.h:585
bool operator!=(const type2t &ref) const
Definition irep2_type.cpp:90
void foreach_subtype_impl(subtype_delegate &t)
Definition irep2_type.cpp:336
void foreach_subtype_impl_const(const_subtype_delegate &t) const
Definition irep2_type.cpp:319
bool operator<(const type2t &ref) const
Definition irep2_type.cpp:95
type_ids
Enumeration identifying each sort of type.
Definition irep2.h:560
@ end_type_id
Definition irep2.h:599
type2t base_type
Definition irep2.h:603
std::string pretty(unsigned int indent=0) const
Produce a human-readable string representation of type.
Definition irep2_type.cpp:100
bool operator==(const type2t &ref) const
Definition irep2_type.cpp:85
size_t crc() const
Produce a checksum/hash of the current object.
Definition irep2_crc.cpp:295
type2t(type_ids id)
Primary constructor.
Definition irep2_type.cpp:72
int lt(const type2t &ref) const
Trinary structural ordering.
Definition irep2_type.cpp:270
DUMP_METHOD void dump() const
Dump object string representation to stdout.
Definition irep2_type.cpp:110
void foreach_subtype(T &&t) const
Definition irep2.h:679
std::atomic< size_t > crc_val
Definition irep2.h:701
virtual ~type2t()=default
list_of_memberst tostring(unsigned int indent) const
Extract a list of members from type as strings.
Definition irep2_type.cpp:303
bool cmp(const type2t &ref) const
Structural comparison.
Definition irep2_type.cpp:252
const type_ids type_id
Instance of type_ids recording this types type.
Definition irep2.h:693
#define DUMP_METHOD
Definition compiler_defs.h:97
#define T
Definition exp2f.c:24
#define C
Definition exp2f.c:25
double exp(double x)
Definition exp.c:84
@ raw
No normalisation. Baseline for the measurement.
Definition fingerprint.h:18
void irep2_bad_family_cast(unsigned actual, const char *accessor)
Definition irep2_type.cpp:61
std::ostream & operator<<(std::ostream &out, const expr2tc &a)
Definition irep2.h:1154
std::list< member_entryt > list_of_memberst
Definition irep2.h:459
irep_container< typename T::base_type > make_irep(Args &&...args)
Allocate a fresh irep2 node and adopt it into an irep_container.
Definition irep2.h:451
Derived & irep2_checked_expr_cast(expr2t &e, expr2t::expr_ids expected, const char *target_name)
Definition irep2.h:1224
irep_container< type2t > type2tc
Definition irep2.h:430
bool is_nil_expr(const expr2tc &exp)
Definition irep2.h:916
Derived & irep2_checked_type_cast(type2t &t, type2t::type_ids expected, const char *target_name)
Definition irep2.h:1202
std::size_t hash_value(const expr2tc &expr)
Definition irep2.h:943
std::pair< std::string, std::string > member_entryt
Definition irep2.h:458
irep_container< expr2t > expr2tc
Definition irep2.h:431
bool is_nil_type(const type2tc &t)
Definition irep2.h:937
bool same_pointer(const irep_container< T > &a, const irep_container< T > &b)
Node-identity test: true iff a and b refer to the very same hash-consed node.
Definition irep2.h:932
void irep2_bad_expr_cast(unsigned actual, unsigned expected, const char *target)
Definition irep2_expr.cpp:33
std::string get_expr_id(const expr2t &expr)
Fetch string identifier for an expression.
Definition irep2_expr.cpp:76
void irep2_bad_type_cast(unsigned actual, unsigned expected, const char *target)
Definition irep2_type.cpp:41
std::string get_type_id(const type2t &type)
Fetch identifying name for a type.
Definition irep2_type.cpp:36
Containers and field-walking infrastructure for irep2 nodes.
Definition esbmc_internal_cpp.h:3
constexpr std::size_t count_derived_field_entries(std::index_sequence< Is... >)
Definition irep2.h:1066
constexpr std::size_t derived_field_count()
Definition irep2.h:1126
constexpr bool assert_kind_invariants()
Definition irep2.h:1134
constexpr std::size_t sum_derived_field_sizes(std::index_sequence< Is... >)
Definition irep2.h:1060
constexpr bool fields_cover_class()
Definition irep2.h:1111
void hash_combine(std::size_t &seed, const T &v)
Mix a value into a running hash seed.
Definition irep2.h:111
constexpr std::size_t nth_field_size_in_derived()
Definition irep2.h:1049
const unsigned int num_type_fields
Maximum number of fields to support in expr2t subclasses.
Definition irep2.h:998
Definition exception.cpp:51
#define bool
Definition stdbool.h:9
static constexpr std::size_t value
Definition irep2.h:1100
static constexpr std::size_t value
Definition irep2.h:1093
M member_t
Definition irep2.h:1036
C class_t
Definition irep2.h:1035
C class_t
Definition irep2.h:1041
M member_t
Definition irep2.h:1042
size_t operator()(const expr2tc &ref) const
Definition irep2.h:1162
size_t operator()(const type2tc &ref) const
Definition irep2.h:1170