mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 06:58:05 +02:00
aco/ra: Handle temps fixed to different regs in different operands
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29576>
This commit is contained in:
parent
7a4775b396
commit
b8bcc8e5c5
1 changed files with 45 additions and 3 deletions
|
|
@ -2103,6 +2103,7 @@ handle_fixed_operands(ra_ctx& ctx, RegisterFile& register_file,
|
|||
|
||||
RegisterFile tmp_file(register_file);
|
||||
|
||||
BITSET_DECLARE(live_reg_assigned, 128) = {0};
|
||||
BITSET_DECLARE(mask, 128) = {0};
|
||||
|
||||
for (unsigned i = 0; i < instr->operands.size(); i++) {
|
||||
|
|
@ -2113,6 +2114,47 @@ handle_fixed_operands(ra_ctx& ctx, RegisterFile& register_file,
|
|||
|
||||
assert(op.isTemp());
|
||||
PhysReg src = ctx.assignments[op.tempId()].reg;
|
||||
if (!BITSET_TEST(live_reg_assigned, i) && !op.isKill()) {
|
||||
/* Figure out which register the temp will continue living in after the instruction. */
|
||||
PhysReg live_reg = op.physReg();
|
||||
bool found = false;
|
||||
for (unsigned j = i; j < instr->operands.size(); ++j) {
|
||||
const Operand& op2 = instr->operands[j];
|
||||
if (!op2.isPrecolored() || op2.tempId() != op.tempId())
|
||||
continue;
|
||||
|
||||
/* Don't consider registers interfering with definitions - we'd have to immediately copy
|
||||
* the temporary somewhere else to make space for the interfering definition.
|
||||
*/
|
||||
if (op2.isClobbered())
|
||||
continue;
|
||||
|
||||
/* Choose the first register that doesn't interfere with definitions. If the temp can
|
||||
* continue residing in the same register it's currently in, just choose that.
|
||||
*/
|
||||
if (!found || op2.physReg() == src) {
|
||||
live_reg = op2.physReg();
|
||||
found = true;
|
||||
if (op2.physReg() == src)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned j = i; j < instr->operands.size(); ++j) {
|
||||
if (!instr->operands[j].isPrecolored() || instr->operands[j].tempId() != op.tempId())
|
||||
continue;
|
||||
|
||||
/* Fix up operand kill flags according to the live_reg choice we made. */
|
||||
if (instr->operands[j].physReg() == live_reg) {
|
||||
instr->operands[j].setCopyKill(false);
|
||||
instr->operands[j].setKill(false);
|
||||
} else {
|
||||
instr->operands[j].setCopyKill(true);
|
||||
}
|
||||
BITSET_SET(live_reg_assigned, j);
|
||||
}
|
||||
}
|
||||
|
||||
adjust_max_used_regs(ctx, op.regClass(), op.physReg());
|
||||
|
||||
if (op.physReg() == src) {
|
||||
|
|
@ -2124,15 +2166,15 @@ handle_fixed_operands(ra_ctx& ctx, RegisterFile& register_file,
|
|||
assert(std::none_of(parallelcopy.begin(), parallelcopy.end(),
|
||||
[&](auto copy) { return copy.def.physReg() == op.physReg(); }));
|
||||
|
||||
/* clear from register_file so fixed operands are not collected be collect_vars() */
|
||||
tmp_file.clear(src, op.regClass()); // TODO: try to avoid moving block vars to src
|
||||
/* clear from register_file so fixed operands are not collected by collect_vars() */
|
||||
tmp_file.clear(src, op.regClass());
|
||||
|
||||
BITSET_SET(mask, i);
|
||||
|
||||
Operand pc_op(instr->operands[i].getTemp());
|
||||
pc_op.setFixed(src);
|
||||
Definition pc_def = Definition(op.physReg(), pc_op.regClass());
|
||||
parallelcopy.emplace_back(pc_op, pc_def);
|
||||
parallelcopy.emplace_back(pc_op, pc_def, op.isCopyKill());
|
||||
}
|
||||
|
||||
if (BITSET_IS_EMPTY(mask))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue