16#include <llvm/ADT/APInt.h>
28 return rewrite(e, arrays, idx_valIdx);
34 std::vector<ref<Expr>> eqExprs;
36 for (
auto &element : arrays) {
37 const Array *arr = element.first;
38 std::vector<ref<Expr>> indexes = element.second;
43 assert((idxt_v.
getWidth() % element.first->range == 0) &&
44 "Read is not aligned");
47 if (
auto e = idxt_v.
getMul()) {
52 auto ce = dyn_cast<ConstantExpr>(e);
53 assert(ce &&
"Not a constant expression");
55 llvm::APInt val = ce->getAPValue();
56 uint64_t mulVal = val.getZExtValue();
59 if (width == 1 && mulVal > 1)
63 for (std::vector<
ref<Expr>>::const_iterator index_it = indexes.begin();
64 index_it != indexes.end(); ++index_it) {
65 if (idx_valIdx.find((*index_it)) == idx_valIdx.end()) {
68 auto opt_indexes = idx_valIdx.at((*index_it));
69 if (opt_indexes.empty()) {
72 }
else if (opt_indexes.size() == 1) {
75 eqExprs.push_back(
createEqExpr((*index_it), opt_indexes[0]));
77 Expr::Width idxWidth = (*index_it).get()->getWidth();
80 for (
auto &vals : opt_indexes) {
81 auto ce = dyn_cast<ConstantExpr>(vals);
82 llvm::APInt v = ce->getAPValue();
83 ba.
set(v.getZExtValue() / width);
86 if (set > 0 && set < arr->size / width)
88 ((float)set / (
float)(arr->
size / width)) > 0.5 ? true :
false;
90 for (
unsigned i = 0; i < arr->
size / width; ++i) {
91 if ((!invert && ba.
get(i)) || (invert && !ba.
get(i))) {
111 if ((arr->
size / width) - start == 1) {
118 ((arr->
size / width) - 1) * width, idxWidth);
125 if (eqExprs.empty()) {
127 }
else if (eqExprs.size() == 1) {
128 if (isa<AndExpr>(eqExprs[0])) {
129 return EqExpr::alloc(
139 return EqExpr::alloc(
145 const std::vector<
ref<Expr>>::const_iterator begin,
146 const std::vector<
ref<Expr>>::const_iterator end) {
147 if (begin + 2 == end) {
148 return OrExpr::alloc(ZExtExpr::alloc((*begin),
Expr::Int32),
151 return OrExpr::alloc(ZExtExpr::alloc((*begin),
Expr::Int32),
158 return EqExpr::alloc(valIndex, index);
164 return AndExpr::alloc(UleExpr::alloc(valStart, index),
165 UleExpr::alloc(index, valEnd));
static ref< ConstantExpr > create(uint64_t v, Width w)
static ref< ConstantExpr > alloc(const llvm::APInt &v)
static ref< Expr > createRangeExpr(const ref< Expr > &index, const ref< Expr > &valStart, const ref< Expr > &valEnd)
static ref< Expr > concatenateOrExpr(const std::vector< ref< Expr > >::const_iterator begin, const std::vector< ref< Expr > >::const_iterator end)
static ref< Expr > rewrite(const ref< Expr > &e, const array2idx_ty &arrays, const mapIndexOptimizedExpr_ty &idx_valIdx)
static ref< Expr > createEqExpr(const ref< Expr > &index, const ref< Expr > &valIndex)
ref< Expr > visit(const ref< Expr > &e)
unsigned Width
The type of an expression is simply its width, in bits.
static ref< Expr > alloc(const ref< Expr > &e)
std::map< ref< Expr >, std::vector< ref< Expr > > > mapIndexOptimizedExpr_ty
std::map< const Array *, std::vector< ref< Expr > > > array2idx_ty