diff --git a/src/amd/compiler/aco_spill.cpp b/src/amd/compiler/aco_spill.cpp index 0926508555f..1404d90a02c 100644 --- a/src/amd/compiler/aco_spill.cpp +++ b/src/amd/compiler/aco_spill.cpp @@ -602,12 +602,10 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in) ctx.ssa_infos[op.tempId()].num_uses--; } - /* if the phi is not spilled, add to instructions */ + /* The phi is not spilled */ if (!phi->definitions[0].isTemp() || - !ctx.spills_entry[block_idx].count(phi->definitions[0].getTemp())) { - instructions.emplace_back(std::move(phi)); + !ctx.spills_entry[block_idx].count(phi->definitions[0].getTemp())) continue; - } Block::edge_vec& preds = phi->opcode == aco_opcode::p_phi ? block->logical_preds : block->linear_preds; @@ -619,10 +617,11 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in) unsigned pred_idx = preds[i]; Operand spill_op = phi->operands[i]; + phi->operands[i] = Operand(phi->definitions[0].regClass()); if (spill_op.isTemp()) { - assert(phi->operands[i].isKill()); - Temp var = phi->operands[i].getTemp(); + assert(spill_op.isKill()); + Temp var = spill_op.getTemp(); std::map::iterator rename_it = ctx.renames[pred_idx].find(var); /* prevent the defining instruction from being DCE'd if it could be rematerialized */ @@ -637,6 +636,13 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in) continue; } + /* If the phi operand has the same name as the definition, + * add to predecessor's spilled variables, so that it gets + * skipped in the loop below. + */ + if (var == phi->definitions[0].getTemp()) + ctx.spills_exit[pred_idx][var] = def_spill_id; + /* rename if necessary */ if (rename_it != ctx.renames[pred_idx].end()) { spill_op.setTemp(rename_it->second); @@ -660,17 +666,7 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in) pred.instructions[idx]->opcode != aco_opcode::p_logical_end); std::vector>::iterator it = std::next(pred.instructions.begin(), idx); pred.instructions.insert(it, std::move(spill)); - - /* If the phi operand has the same name as the definition, - * add to predecessor's spilled variables, so that it gets - * skipped in the loop below. - */ - if (spill_op.isTemp() && phi->operands[i].getTemp() == phi->definitions[0].getTemp()) - ctx.spills_exit[pred_idx][phi->operands[i].getTemp()] = def_spill_id; } - - /* remove phi from instructions */ - phi.reset(); } /* iterate all (other) spilled variables for which to spill at the predecessor */ @@ -733,10 +729,14 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in) } /* iterate phis for which operands to reload */ - for (aco_ptr& phi : instructions) { - assert(phi->opcode == aco_opcode::p_phi || phi->opcode == aco_opcode::p_linear_phi); + for (aco_ptr& phi : block->instructions) { + if (!is_phi(phi)) + break; + assert(!phi->definitions[0].isTemp() || - !ctx.spills_entry[block_idx].count(phi->definitions[0].getTemp())); + !ctx.spills_entry[block_idx].count(phi->definitions[0].getTemp()) || + std::all_of(phi->operands.begin(), phi->operands.end(), + [](Operand op) { return op.isUndefined(); })); Block::edge_vec& preds = phi->opcode == aco_opcode::p_phi ? block->logical_preds : block->linear_preds; @@ -872,33 +872,15 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in) phi->operands[i] = Operand(tmp); } phi->definitions[0] = Definition(rename); - instructions.emplace_back(std::move(phi)); + block->instructions.insert(block->instructions.begin(), std::move(phi)); + ctx.program->live.register_demand[block->index].insert( + ctx.program->live.register_demand[block->index].begin(), block->live_in_demand); } /* the variable was renamed: add new name to renames */ if (!(rename == Temp() || rename == var)) ctx.renames[block_idx][var] = rename; } - - /* combine phis with instructions */ - unsigned idx = 0; - while (!block->instructions[idx]) { - idx++; - } - - if (!ctx.processed[block_idx]) { - assert(!(block->kind & block_kind_loop_header)); - std::vector& register_demand = - ctx.program->live.register_demand[block->index]; - register_demand.erase(register_demand.begin(), register_demand.begin() + idx); - register_demand.insert(register_demand.begin(), instructions.size(), block->live_in_demand); - } - - std::vector>::iterator start = std::next(block->instructions.begin(), idx); - instructions.insert( - instructions.end(), std::move_iterator>::iterator>(start), - std::move_iterator>::iterator>(block->instructions.end())); - block->instructions = std::move(instructions); } void