mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-27 09:12:46 +01:00
glasm: Fix aliased bitcasts ref counting
This commit is contained in:
parent
f1b334b9f9
commit
fb3ba62b3a
3 changed files with 42 additions and 13 deletions
|
@ -12,12 +12,10 @@ static void Alias(IR::Inst& inst, const IR::Value& value) {
|
||||||
if (value.IsImmediate()) {
|
if (value.IsImmediate()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IR::Inst* const value_inst{value.InstRecursive()};
|
IR::Inst& value_inst{RegAlloc::AliasInst(*value.Inst())};
|
||||||
if (inst.GetOpcode() == IR::Opcode::Identity) {
|
value_inst.DestructiveAddUsage(inst.UseCount());
|
||||||
value_inst->DestructiveAddUsage(inst.UseCount());
|
value_inst.DestructiveRemoveUsage();
|
||||||
value_inst->DestructiveRemoveUsage();
|
inst.SetDefinition(value_inst.Definition<Id>());
|
||||||
}
|
|
||||||
inst.SetDefinition(value_inst->Definition<Id>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) {
|
void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) {
|
||||||
|
|
|
@ -30,9 +30,10 @@ Value RegAlloc::Consume(const IR::Value& value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegAlloc::Unref(IR::Inst& inst) {
|
void RegAlloc::Unref(IR::Inst& inst) {
|
||||||
inst.DestructiveRemoveUsage();
|
IR::Inst& value_inst{AliasInst(inst)};
|
||||||
if (!inst.HasUses()) {
|
value_inst.DestructiveRemoveUsage();
|
||||||
Free(inst.Definition<Id>());
|
if (!value_inst.HasUses()) {
|
||||||
|
Free(value_inst.Definition<Id>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,10 +100,7 @@ Value RegAlloc::PeekInst(IR::Inst& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Value RegAlloc::ConsumeInst(IR::Inst& inst) {
|
Value RegAlloc::ConsumeInst(IR::Inst& inst) {
|
||||||
inst.DestructiveRemoveUsage();
|
Unref(inst);
|
||||||
if (!inst.HasUses()) {
|
|
||||||
Free(inst.Definition<Id>());
|
|
||||||
}
|
|
||||||
return PeekInst(inst);
|
return PeekInst(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,4 +136,31 @@ void RegAlloc::Free(Id id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static*/ bool RegAlloc::IsAliased(const IR::Inst& inst) {
|
||||||
|
switch (inst.GetOpcode()) {
|
||||||
|
case IR::Opcode::Identity:
|
||||||
|
case IR::Opcode::BitCastU16F16:
|
||||||
|
case IR::Opcode::BitCastU32F32:
|
||||||
|
case IR::Opcode::BitCastU64F64:
|
||||||
|
case IR::Opcode::BitCastF16U16:
|
||||||
|
case IR::Opcode::BitCastF32U32:
|
||||||
|
case IR::Opcode::BitCastF64U64:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ IR::Inst& RegAlloc::AliasInst(IR::Inst& inst) {
|
||||||
|
IR::Inst* it{&inst};
|
||||||
|
while (IsAliased(*it)) {
|
||||||
|
const IR::Value arg{it->Arg(0)};
|
||||||
|
if (arg.IsImmediate()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
it = arg.InstRecursive();
|
||||||
|
}
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Shader::Backend::GLASM
|
} // namespace Shader::Backend::GLASM
|
||||||
|
|
|
@ -126,6 +126,12 @@ public:
|
||||||
return num_used_long_registers;
|
return num_used_long_registers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the instruction is expected to be aliased to another
|
||||||
|
static bool IsAliased(const IR::Inst& inst);
|
||||||
|
|
||||||
|
/// Returns the underlying value out of an alias sequence
|
||||||
|
static IR::Inst& AliasInst(IR::Inst& inst);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t NUM_REGS = 4096;
|
static constexpr size_t NUM_REGS = 4096;
|
||||||
static constexpr size_t NUM_ELEMENTS = 4;
|
static constexpr size_t NUM_ELEMENTS = 4;
|
||||||
|
|
Loading…
Reference in a new issue