summaryrefslogtreecommitdiff
path: root/src/abstract_hardware_model.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/abstract_hardware_model.h')
-rw-r--r--src/abstract_hardware_model.h105
1 files changed, 104 insertions, 1 deletions
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 1e3c94e..1a42657 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -1119,6 +1119,20 @@ enum divergence_support_t {
const unsigned MAX_ACCESSES_PER_INSN_PER_THREAD = 8;
+// Mixed-space MEM co-issue (v2): per-lane address storage for a shared-
+// memory coissuer set. Captured at co_issue_warp time BEFORE temp_inst
+// dies, so later per-set bank conflict recomputes can run against each
+// set's own per-lane addresses without colliding on the composite's
+// m_per_scalar_thread (which is keyed by thread-in-warp and would be
+// overwritten across inter-warp coissuers).
+struct simd_set_addr_entry {
+ new_addr_type memreqaddr[MAX_ACCESSES_PER_INSN_PER_THREAD];
+ simd_set_addr_entry() {
+ for (unsigned i = 0; i < MAX_ACCESSES_PER_INSN_PER_THREAD; i++)
+ memreqaddr[i] = 0;
+ }
+};
+
// SIMD lane partitioning: per-set execution data
struct simd_set_info {
unsigned set_id; // Set index (0 to num_sets-1)
@@ -1131,13 +1145,29 @@ struct simd_set_info {
bool valid; // Whether this set has any active threads
const inst_t *source_inst; // Pointer to static decoded instruction (for MIMD)
+ // Mixed-space MEM co-issue (v2): per-set shared state.
+ // Populated only when source_inst's space is shared/sstarr; otherwise
+ // unused. `cycles` is the set's bank-conflict depth (modelled per-set
+ // in shared_cycle). `per_thread_addrs` is the captured per-lane
+ // memreqaddr for this set.
+ unsigned cycles;
+ std::vector<simd_set_addr_entry> per_thread_addrs;
+
simd_set_info()
: set_id(0), warp_id(0), split_id((unsigned)-1),
- num_active_threads(0), valid(false), source_inst(NULL) {
+ num_active_threads(0), valid(false), source_inst(NULL), cycles(0) {
set_active_mask.reset();
active_mask_in_warp.reset();
for (unsigned i = 0; i < MAX_WARP_SIZE; i++) thread_ids[i] = 0;
}
+
+ // Mirror of warp_inst_t::has_dispatch_delay / dispatch_delay, but
+ // per-set. Used by the per-set shared_cycle path in ldst_unit.
+ bool has_dispatch_delay() const { return cycles > 0; }
+ bool dispatch_delay() {
+ if (cycles > 0) cycles--;
+ return cycles > 0;
+ }
};
class warp_inst_t : public inst_t {
@@ -1205,8 +1235,68 @@ class warp_inst_t : public inst_t {
const std::vector<simd_set_info> &get_simd_sets() const {
return m_simd_sets;
}
+ // Mixed-space MEM co-issue (v2): mutable accessor for capture path.
+ std::vector<simd_set_info> &get_simd_sets_mutable() { return m_simd_sets; }
unsigned num_active_simd_sets() const;
+
+ // Mixed-space MEM co-issue (v2): space-bucket classification. "shared
+ // bucket" = shared_space/sstarr_space; "global bucket" =
+ // global/local/param_local.
+ static bool is_shared_bucket_space(enum _memory_space_t t) {
+ return t == shared_space || t == sstarr_space;
+ }
+ static bool is_global_bucket_space(enum _memory_space_t t) {
+ return t == global_space || t == local_space || t == param_space_local;
+ }
+ // A composite has a shared/global "subcomposite" if any valid simd_set
+ // (including the primary set when source_inst==NULL) has a source space
+ // in that bucket. Primary set's space is the composite's own `space`.
+ bool has_shared_subcomposite() const {
+ for (unsigned s = 0; s < m_simd_sets.size(); s++) {
+ if (!m_simd_sets[s].valid) continue;
+ enum _memory_space_t sp = (m_simd_sets[s].source_inst == NULL)
+ ? space.get_type()
+ : m_simd_sets[s].source_inst->space.get_type();
+ if (is_shared_bucket_space(sp)) return true;
+ }
+ return false;
+ }
+ bool has_global_subcomposite() const {
+ for (unsigned s = 0; s < m_simd_sets.size(); s++) {
+ if (!m_simd_sets[s].valid) continue;
+ enum _memory_space_t sp = (m_simd_sets[s].source_inst == NULL)
+ ? space.get_type()
+ : m_simd_sets[s].source_inst->space.get_type();
+ if (is_global_bucket_space(sp)) return true;
+ }
+ return false;
+ }
+ bool is_mixed_space_composite() const {
+ return has_shared_subcomposite() && has_global_subcomposite();
+ }
bool has_simd_sets() const { return !m_simd_sets.empty(); }
+
+ // Mixed-space MEM co-issue (v2): copy this instruction's per-lane
+ // memreqaddr entries into `set.per_thread_addrs`, and copy this
+ // instruction's bank-conflict `cycles` into `set.cycles`. Used by
+ // co_issue_warp for SHARED coissuer sets BEFORE temp_inst dies, so
+ // later per-set bank-conflict re-checks can read each set's own
+ // addresses without colliding on the composite's m_per_scalar_thread.
+ void capture_per_set_shared_state(simd_set_info &set,
+ unsigned set_width) const {
+ set.cycles = cycles;
+ if (!m_per_scalar_thread_valid) return;
+ set.per_thread_addrs.assign(set_width, simd_set_addr_entry());
+ for (unsigned lane = 0; lane < set_width; lane++) {
+ if (!set.set_active_mask.test(lane)) continue;
+ unsigned t = set.thread_ids[lane];
+ if (t >= m_per_scalar_thread.size()) continue;
+ for (unsigned i = 0; i < MAX_ACCESSES_PER_INSN_PER_THREAD; i++) {
+ set.per_thread_addrs[lane].memreqaddr[i] =
+ m_per_scalar_thread[t].memreqaddr[i];
+ }
+ }
+ }
void merge_simd_sets(const std::vector<simd_set_info> &other_sets);
void set_source_inst_on_sets(const inst_t *src);
void set_split_id_on_sets(unsigned split_id);
@@ -1408,6 +1498,19 @@ class warp_inst_t : public inst_t {
bool m_is_depbar;
unsigned int m_depbar_group_no;
+
+ // Mixed-space MEM co-issue (Option A / Stage 6): tracks whether the
+ // shared-source scoreboards of this MIXED composite have already been
+ // released via the early-release path in ldst_unit::cycle. Set once;
+ // checked by both the early-release path (to avoid re-release as
+ // shared_cycle keeps returning true) and by the final mixed-retire
+ // (to avoid double-releasing shared sources at dispatch_reg clear).
+ // Default false. Only meaningful for mixed composites.
+ public:
+ bool shared_side_released() const { return m_shared_side_released; }
+ void set_shared_side_released(bool v) { m_shared_side_released = v; }
+ private:
+ bool m_shared_side_released = false;
};
void move_warp(warp_inst_t *&dst, warp_inst_t *&src);