yuzu-emu
/
yuzu-android
Archived
1
0
Fork 0

glasm: Fix aliased bitcasts ref counting

This commit is contained in:
ReinUsesLisp 2021-05-17 19:24:09 -03:00 committed by ameerj
parent f1b334b9f9
commit fb3ba62b3a
3 changed files with 42 additions and 13 deletions

View File

@ -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) {

View File

@ -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

View File

@ -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;