std::string Compiler::gen_access_string()

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();
}