glasm: Fix aliased bitcasts ref counting
This commit is contained in:
		| @@ -12,12 +12,10 @@ static void Alias(IR::Inst& inst, const IR::Value& value) { | ||||
|     if (value.IsImmediate()) { | ||||
|         return; | ||||
|     } | ||||
|     IR::Inst* const value_inst{value.InstRecursive()}; | ||||
|     if (inst.GetOpcode() == IR::Opcode::Identity) { | ||||
|         value_inst->DestructiveAddUsage(inst.UseCount()); | ||||
|         value_inst->DestructiveRemoveUsage(); | ||||
|     } | ||||
|     inst.SetDefinition(value_inst->Definition<Id>()); | ||||
|     IR::Inst& value_inst{RegAlloc::AliasInst(*value.Inst())}; | ||||
|     value_inst.DestructiveAddUsage(inst.UseCount()); | ||||
|     value_inst.DestructiveRemoveUsage(); | ||||
|     inst.SetDefinition(value_inst.Definition<Id>()); | ||||
| } | ||||
|  | ||||
| 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) { | ||||
|     inst.DestructiveRemoveUsage(); | ||||
|     if (!inst.HasUses()) { | ||||
|         Free(inst.Definition<Id>()); | ||||
|     IR::Inst& value_inst{AliasInst(inst)}; | ||||
|     value_inst.DestructiveRemoveUsage(); | ||||
|     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) { | ||||
|     inst.DestructiveRemoveUsage(); | ||||
|     if (!inst.HasUses()) { | ||||
|         Free(inst.Definition<Id>()); | ||||
|     } | ||||
|     Unref(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 | ||||
|   | ||||
| @@ -126,6 +126,12 @@ public: | ||||
|         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: | ||||
|     static constexpr size_t NUM_REGS = 4096; | ||||
|     static constexpr size_t NUM_ELEMENTS = 4; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user