aco: introduce new Operand flag 'Clobbered'

This flag indicates that the Operand's register gets clobbered by the instruction.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30299>
This commit is contained in:
Daniel Schürmann 2024-07-04 09:42:16 +02:00 committed by Marge Bot
parent 1c14013b9e
commit 5a6fa8a8eb
2 changed files with 24 additions and 4 deletions

View file

@ -459,8 +459,8 @@ class Operand final {
public:
constexpr Operand()
: reg_(PhysReg{128}), isTemp_(false), isFixed_(true), isConstant_(false), isKill_(false),
isUndef_(true), isFirstKill_(false), constSize(0), isLateKill_(false), is16bit_(false),
is24bit_(false), signext(false)
isUndef_(true), isFirstKill_(false), constSize(0), isLateKill_(false), isClobbered_(false),
is16bit_(false), is24bit_(false), signext(false)
{}
explicit Operand(Temp r) noexcept
@ -805,6 +805,10 @@ public:
constexpr bool isLateKill() const noexcept { return isLateKill_; }
/* Indicates that the Operand's register gets clobbered by the instruction. */
constexpr void setClobbered(bool flag) noexcept { isClobbered_ = flag; }
constexpr bool isClobbered() const noexcept { return isClobbered_; }
constexpr void setKill(bool flag) noexcept
{
isKill_ = flag;
@ -874,6 +878,7 @@ private:
uint8_t isFirstKill_ : 1;
uint8_t constSize : 2;
uint8_t isLateKill_ : 1;
uint8_t isClobbered_ : 1;
uint8_t is16bit_ : 1;
uint8_t is24bit_ : 1;
uint8_t signext : 1;

View file

@ -237,6 +237,11 @@ process_live_temps_per_block(live_ctx& ctx, Block* block)
insn->operands[1].setLateKill(true);
}
/* Check if a definition clobbers some operand */
int op_idx = get_op_fixed_to_def(insn);
if (op_idx != -1)
insn->operands[op_idx].setClobbered(true);
/* we need to do this in a separate loop because the next one can
* setKill() for several operands at once and we don't want to
* overwrite that in a later iteration */
@ -256,8 +261,18 @@ process_live_temps_per_block(live_ctx& ctx, Block* block)
Operand& operand = insn->operands[i];
if (!operand.isTemp())
continue;
if (operand.isFixed() && operand.physReg() == vcc)
ctx.program->needs_vcc = true;
if (operand.isFixed() && ctx.program->progress < CompilationProgress::after_ra) {
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)
{
return def.isFixed() &&
def.physReg() + def.size() > operand.physReg() &&
operand.physReg() + operand.size() > def.physReg();
}))
operand.setClobbered(true);
}
const Temp temp = operand.getTemp();
if (operand.isKill())