in src/core/compile.cpp [1141:1225]
std::string Compiler::gen_access_string(IR::NodeRef node_ref,
LoopTree::TreeRef ref) const {
std::stringstream ss;
auto acc = gen_access(node_ref, ref);
auto info = gen_idx_info(ref, acc);
if (info.maxes.size()) {
ss << "(";
std::unordered_map<int, std::string> bound_strings;
std::vector<LoopTree::TreeRef> ref_idxs;
auto p = lt.parent(ref);
while (p != -1) {
ref_idxs.emplace_back(p);
p = lt.parent(p);
}
std::reverse(ref_idxs.begin(), ref_idxs.end());
for (auto i = 0; i < info.strides.size(); ++i) {
auto bound_idx = info.idxs[i];
if (bound_idx == -1) {
continue;
}
auto stride = info.strides[i];
if (stride < 1) {
continue;
}
if (bound_strings[bound_idx].size()) {
bound_strings[bound_idx] += " + ";
}
bound_strings[bound_idx] += "i_" + std::to_string(ref_idxs.at(i));
if (stride > 1) {
bound_strings[bound_idx] += " * " + std::to_string(stride);
}
}
bool emitted = false;
ss << "(";
for (const auto &p : bound_strings) {
if (emitted) {
ss << " && ";
}
ss << "(" << p.second << " < " << info.maxes.at(p.first) << ") && ";
ss << "(" << p.second << " >= " << info.mins.at(p.first) << ")";
emitted = true;
}
ss << ") ? ";
}
if (acc.alloc.size() > 1 || is_input_output(acc.alloc.node_ref)) {
ss << "((float*)memory[" << acc.alloc.mem_idx << "])";
ss << "[";
auto p = lt.parent(ref);
auto i = 1;
bool emitted = false;
while (p != acc.alloc.lca) {
auto stride = info.strides[info.strides.size() - i];
if (stride > 0) {
if (emitted) {
ss << " + ";
} else {
emitted = true;
}
ss << "i_" << p;
if (stride > 1) {
ss << " * " << stride;
}
}
p = lt.parent(p);
i++;
};
if (acc.total_offset) {
ss << " + " << acc.total_offset;
}
// input/output could be a single integer (should be rare)
if (acc.alloc.size() == 1 && emitted == false) {
ss << 0;
}
ss << "]";
} else {
ss << "v" << acc.alloc.mem_idx;
}
if (info.maxes.size()) {
ss << " : " << 0 << ")";
}
return ss.str();
}