}
/* else: merge block */
- std::set<Temp> partial_spills;
+ std::map<Temp, bool> partial_spills;
/* keep variables spilled on all incoming paths */
for (const std::pair<const Temp, std::pair<uint32_t, uint32_t>>& pair : next_use_distances) {
break;
}
if (!ctx.spills_exit[pred_idx].count(pair.first)) {
+ partial_spills.emplace(pair.first, false);
if (!remat)
spill = false;
} else {
- partial_spills.insert(pair.first);
+ partial_spills[pair.first] = true;
/* it might be that on one incoming path, the variable has a different spill_id, but
* add_couple_code() will take care of that. */
spill_id = ctx.spills_exit[pred_idx][pair.first];
spilled_registers += phi->definitions[0].getTemp();
} else {
/* Phis might increase the register pressure. */
- partial_spills.insert(phi->definitions[0].getTemp());
+ partial_spills[phi->definitions[0].getTemp()] = true;
}
}
while (reg_pressure.exceeds(ctx.target_pressure)) {
assert(!partial_spills.empty());
- std::set<Temp>::iterator it = partial_spills.begin();
+ std::map<Temp, bool>::iterator it = partial_spills.begin();
Temp to_spill = Temp();
+ bool is_spilled_or_phi = false;
unsigned distance = 0;
RegType type = reg_pressure.vgpr > ctx.target_pressure.vgpr ? RegType::vgpr : RegType::sgpr;
while (it != partial_spills.end()) {
- assert(!ctx.spills_entry[block_idx].count(*it));
-
- if (it->type() == type && next_use_distances.at(*it).second > distance) {
- distance = next_use_distances.at(*it).second;
- to_spill = *it;
+ assert(!ctx.spills_entry[block_idx].count(it->first));
+
+ if (it->first.type() == type && ((it->second && !is_spilled_or_phi) ||
+ (it->second == is_spilled_or_phi &&
+ next_use_distances.at(it->first).second > distance))) {
+ distance = next_use_distances.at(it->first).second;
+ to_spill = it->first;
+ is_spilled_or_phi = it->second;
}
++it;
}