+ changed = true;
+ }
+ }
+
+ for (unsigned i = 0; i < barrier_count; i++) {
+ changed |= barrier_imm[i].combine(other->barrier_imm[i]);
+ changed |= other->barrier_events[i] & ~barrier_events[i];
+ barrier_events[i] |= other->barrier_events[i];
+ }
+
+ /* these are used for statistics, so don't update "changed" */
+ for (unsigned i = 0; i < num_counters; i++) {
+ for (std::pair<Instruction *, unsigned> instr : other->unwaited_instrs[i]) {
+ auto pos = unwaited_instrs[i].find(instr.first);
+ if (pos == unwaited_instrs[i].end())
+ unwaited_instrs[i].insert(instr);
+ else
+ pos->second = std::min(pos->second, instr.second);
+ }
+ /* don't use a foreach loop to avoid copies */
+ for (auto it = other->reg_instrs[i].begin(); it != other->reg_instrs[i].end(); ++it)
+ reg_instrs[i][it->first].insert(it->second.begin(), it->second.end());
+ }
+
+ return changed;
+ }
+
+ void wait_and_remove_from_entry(PhysReg reg, wait_entry& entry, counter_type counter) {
+ if (collect_statistics && (entry.counters & counter)) {
+ unsigned counter_idx = ffs(counter) - 1;
+ for (Instruction *instr : reg_instrs[counter_idx][reg]) {
+ auto pos = unwaited_instrs[counter_idx].find(instr);
+ if (pos == unwaited_instrs[counter_idx].end())
+ continue;
+
+ unsigned distance = pos->second;
+ unsigned events = entry.events & get_events_for_counter(counter);
+ while (events) {
+ unsigned event_idx = u_bit_scan(&events);
+ wait_distances[event_idx].push_back(distance);
+ }
+
+ unwaited_instrs[counter_idx].erase(instr);
+ }
+ reg_instrs[counter_idx][reg].clear();