mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 22:30:11 +01:00
aco: introduce Operand flag 'CopyKill'
This flag indicates that the Operand must be copied in order to satisfy register constraints. The copy is immediately killed by the instruction. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30299>
This commit is contained in:
parent
91f65d5935
commit
dfc13fcf9f
2 changed files with 33 additions and 4 deletions
|
|
@ -460,7 +460,7 @@ public:
|
|||
constexpr Operand()
|
||||
: reg_(PhysReg{128}), isTemp_(false), isFixed_(true), isConstant_(false), isKill_(false),
|
||||
isUndef_(true), isFirstKill_(false), constSize(0), isLateKill_(false), isClobbered_(false),
|
||||
is16bit_(false), is24bit_(false), signext(false)
|
||||
isCopyKill_(false), is16bit_(false), is24bit_(false), signext(false)
|
||||
{}
|
||||
|
||||
explicit Operand(Temp r) noexcept
|
||||
|
|
@ -809,11 +809,24 @@ public:
|
|||
constexpr void setClobbered(bool flag) noexcept { isClobbered_ = flag; }
|
||||
constexpr bool isClobbered() const noexcept { return isClobbered_; }
|
||||
|
||||
/* Indicates that the Operand must be copied in order to satisfy register
|
||||
* constraints. The copy is immediately killed by the instruction.
|
||||
*/
|
||||
constexpr void setCopyKill(bool flag) noexcept
|
||||
{
|
||||
isCopyKill_ = flag;
|
||||
if (flag)
|
||||
setKill(flag);
|
||||
}
|
||||
constexpr bool isCopyKill() const noexcept { return isCopyKill_; }
|
||||
|
||||
constexpr void setKill(bool flag) noexcept
|
||||
{
|
||||
isKill_ = flag;
|
||||
if (!flag)
|
||||
if (!flag) {
|
||||
setFirstKill(false);
|
||||
setCopyKill(false);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool isKill() const noexcept { return isKill_ || isFirstKill(); }
|
||||
|
|
@ -879,6 +892,7 @@ private:
|
|||
uint8_t constSize : 2;
|
||||
uint8_t isLateKill_ : 1;
|
||||
uint8_t isClobbered_ : 1;
|
||||
uint8_t isCopyKill_ : 1;
|
||||
uint8_t is16bit_ : 1;
|
||||
uint8_t is24bit_ : 1;
|
||||
uint8_t signext : 1;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ get_temp_registers(Instruction* instr)
|
|||
}
|
||||
|
||||
for (Operand op : instr->operands) {
|
||||
if (op.isFirstKill()) {
|
||||
if (op.isFirstKill() || op.isCopyKill()) {
|
||||
demand_before += op.getTemp();
|
||||
if (op.isLateKill())
|
||||
demand_after += op.getTemp();
|
||||
|
|
@ -252,8 +252,12 @@ process_live_temps_per_block(live_ctx& ctx, Block* block)
|
|||
Operand& operand = insn->operands[i];
|
||||
if (!operand.isTemp())
|
||||
continue;
|
||||
|
||||
const Temp temp = operand.getTemp();
|
||||
if (operand.isFixed() && ctx.program->progress < CompilationProgress::after_ra) {
|
||||
assert(!operand.isLateKill());
|
||||
ctx.program->needs_vcc |= operand.physReg() == vcc;
|
||||
|
||||
/* Check if this operand gets overwritten by a precolored definition. */
|
||||
if (std::any_of(insn->definitions.begin(), insn->definitions.end(),
|
||||
[=](Definition def)
|
||||
|
|
@ -263,8 +267,19 @@ process_live_temps_per_block(live_ctx& ctx, Block* block)
|
|||
operand.physReg() + operand.size() > def.physReg();
|
||||
}))
|
||||
operand.setClobbered(true);
|
||||
|
||||
/* Check if this temp is fixed to a different register as well.
|
||||
* This assumes that operands of one instruction are not precolored twice to
|
||||
* the same register. In this case, register pressure might be overestimated.
|
||||
*/
|
||||
for (unsigned j = i + 1; !operand.isCopyKill() && j < insn->operands.size(); ++j) {
|
||||
if (insn->operands[j].isTemp() && insn->operands[j].getTemp() == temp &&
|
||||
insn->operands[j].isFixed()) {
|
||||
operand_demand += temp;
|
||||
insn->operands[j].setCopyKill(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
const Temp temp = operand.getTemp();
|
||||
|
||||
if (operand.isKill())
|
||||
continue;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue