From c1ba685d9c9b9ca9e8c479c52097adf943e804eb Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 7 May 2021 06:31:30 -0300 Subject: glasm: Changes to GLASM register allocator and emit context --- .../backend/glasm/emit_context.cpp | 8 +++-- src/shader_recompiler/backend/glasm/emit_context.h | 27 ++++++++++++++-- src/shader_recompiler/backend/glasm/reg_alloc.cpp | 37 ++++++++++++---------- src/shader_recompiler/backend/glasm/reg_alloc.h | 18 ++++++++--- 4 files changed, 64 insertions(+), 26 deletions(-) diff --git a/src/shader_recompiler/backend/glasm/emit_context.cpp b/src/shader_recompiler/backend/glasm/emit_context.cpp index 02c4d8a5d..b4db4ff8f 100644 --- a/src/shader_recompiler/backend/glasm/emit_context.cpp +++ b/src/shader_recompiler/backend/glasm/emit_context.cpp @@ -2,6 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma once +#include "shader_recompiler/backend/glasm/emit_context.h" -#include "shader_recompiler/backend/glasm/emit_context.h" \ No newline at end of file +namespace Shader::Backend::GLASM { + +EmitContext::EmitContext() = default; + +} // namespace Shader::Backend::GLASM diff --git a/src/shader_recompiler/backend/glasm/emit_context.h b/src/shader_recompiler/backend/glasm/emit_context.h index ae91069c8..cf66619de 100644 --- a/src/shader_recompiler/backend/glasm/emit_context.h +++ b/src/shader_recompiler/backend/glasm/emit_context.h @@ -5,17 +5,38 @@ #pragma once #include +#include + +#include #include "shader_recompiler/backend/glasm/reg_alloc.h" +namespace Shader::IR { +class Inst; +} + namespace Shader::Backend::GLASM { class EmitContext { public: - std::string code; - RegAlloc reg_alloc; + explicit EmitContext(); -private: + template + void Add(const char* fmt, IR::Inst& inst, Args&&... args) { + code += fmt::format(fmt, reg_alloc.Define(inst), std::forward(args)...); + // TODO: Remove this + code += '\n'; + } + + template + void Add(const char* fmt, Args&&... args) { + code += fmt::format(fmt, std::forward(args)...); + // TODO: Remove this + code += '\n'; + } + + std::string code; + RegAlloc reg_alloc{*this}; }; } // namespace Shader::Backend::GLASM diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.cpp b/src/shader_recompiler/backend/glasm/reg_alloc.cpp index 0460a394b..55e8107e9 100644 --- a/src/shader_recompiler/backend/glasm/reg_alloc.cpp +++ b/src/shader_recompiler/backend/glasm/reg_alloc.cpp @@ -3,18 +3,16 @@ // Refer to the license.txt file included. #include -#include #include +#include "shader_recompiler/backend/glasm/emit_context.h" #include "shader_recompiler/backend/glasm/reg_alloc.h" #include "shader_recompiler/exception.h" #include "shader_recompiler/frontend/ir/value.h" namespace Shader::Backend::GLASM { namespace { -constexpr std::string_view SWIZZLE = "xyzw"; - std::string Representation(Id id) { if (id.is_condition_code != 0) { throw NotImplementedException("Condition code"); @@ -22,27 +20,36 @@ std::string Representation(Id id) { if (id.is_spill != 0) { throw NotImplementedException("Spilling"); } - const u32 num_elements{id.num_elements_minus_one + 1}; const u32 index{static_cast(id.index)}; - if (num_elements == 4) { - return fmt::format("R{}", index); - } else { - return fmt::format("R{}.{}", index, SWIZZLE.substr(id.base_element, num_elements)); + return fmt::format("R{}.x", index); +} + +std::string ImmValue(const IR::Value& value) { + switch (value.Type()) { + case IR::Type::U1: + return value.U1() ? "-1" : "0"; + case IR::Type::U32: + return fmt::format("{}", value.U32()); + case IR::Type::F32: + return fmt::format("{}", value.F32()); + default: + throw NotImplementedException("Immediate type", value.Type()); } } } // Anonymous namespace -std::string RegAlloc::Define(IR::Inst& inst, u32 num_elements, u32 alignment) { - const Id id{Alloc(num_elements, alignment)}; +std::string RegAlloc::Define(IR::Inst& inst) { + const Id id{Alloc()}; inst.SetDefinition(id); return Representation(id); } std::string RegAlloc::Consume(const IR::Value& value) { - if (!value.IsImmediate()) { - return Consume(*value.Inst()); + if (value.IsImmediate()) { + return ImmValue(value); + } else { + return Consume(*value.InstRecursive()); } - throw NotImplementedException("Immediate loading"); } std::string RegAlloc::Consume(IR::Inst& inst) { @@ -54,7 +61,7 @@ std::string RegAlloc::Consume(IR::Inst& inst) { return Representation(inst.Definition()); } -Id RegAlloc::Alloc(u32 num_elements, [[maybe_unused]] u32 alignment) { +Id RegAlloc::Alloc() { for (size_t reg = 0; reg < NUM_REGS; ++reg) { if (register_use[reg]) { continue; @@ -62,8 +69,6 @@ Id RegAlloc::Alloc(u32 num_elements, [[maybe_unused]] u32 alignment) { num_used_registers = std::max(num_used_registers, reg + 1); register_use[reg] = true; return Id{ - .base_element = 0, - .num_elements_minus_one = num_elements - 1, .index = static_cast(reg), .is_spill = 0, .is_condition_code = 0, diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.h b/src/shader_recompiler/backend/glasm/reg_alloc.h index 46018b0c2..83d728d20 100644 --- a/src/shader_recompiler/backend/glasm/reg_alloc.h +++ b/src/shader_recompiler/backend/glasm/reg_alloc.h @@ -15,27 +15,35 @@ class Value; namespace Shader::Backend::GLASM { +class EmitContext; + struct Id { - u32 base_element : 2; - u32 num_elements_minus_one : 2; - u32 index : 26; + u32 index : 30; u32 is_spill : 1; u32 is_condition_code : 1; }; class RegAlloc { public: - std::string Define(IR::Inst& inst, u32 num_elements = 1, u32 alignment = 1); + RegAlloc(EmitContext& ctx_) : ctx{ctx_} {} + + std::string Define(IR::Inst& inst); std::string Consume(const IR::Value& value); + [[nodiscard]] size_t NumUsedRegisters() const noexcept { + return num_used_registers; + } + private: static constexpr size_t NUM_REGS = 4096; static constexpr size_t NUM_ELEMENTS = 4; + EmitContext& ctx; + std::string Consume(IR::Inst& inst); - Id Alloc(u32 num_elements, u32 alignment); + Id Alloc(); void Free(Id id); -- cgit v1.2.3