From 6cee2dc0bda731355ee56c610c62b988e4bd3280 Mon Sep 17 00:00:00 2001 From: Senaxx Date: Tue, 27 Oct 2026 06:24:26 +0100 Subject: [PATCH] shader: inline the hot IR operand accessors --- src/graphics/shader/recompiler/ir/Value.cpp | 63 --------------------- src/graphics/shader/recompiler/ir/Value.h | 52 +++++++++++++++-- 2 files changed, 46 insertions(+), 69 deletions(-) diff --git a/src/graphics/shader/recompiler/ir/Value.cpp b/src/graphics/shader/recompiler/ir/Value.cpp index 425eda5e0..f6b33dc33 100644 --- a/src/graphics/shader/recompiler/ir/Value.cpp +++ b/src/graphics/shader/recompiler/ir/Value.cpp @@ -25,22 +25,6 @@ Value Value::F32(float value) { return Value(Type::F32, std::bit_cast(value)); } -bool Value::IsEmpty() const { - return type == Type::Void; -} - -bool Value::IsImmediate() const { - return type != Type::Opaque; -} - -bool Value::IsIdentity() const { - return type == Type::Opaque && inst->GetOpcode() == ValueOpcode::Identity; -} - -bool Value::IsPhi() const { - return type == Type::Opaque && inst->GetOpcode() == ValueOpcode::Phi; -} - Type Value::GetType() const { if (IsPhi()) { return inst->Flags(); @@ -56,19 +40,6 @@ Inst* Value::Instruction() const { return inst; } -Inst* Value::TryInstruction() const { - return type == Type::Opaque ? inst : nullptr; -} - -Inst* Value::ResolveInstruction() const { - EXIT_IF(type != Type::Opaque); - return IsIdentity() ? inst->Arg(0).ResolveInstruction() : inst; -} - -Value Value::Resolve() const { - return IsIdentity() ? inst->Arg(0).Resolve() : *this; -} - ScalarReg Value::ScalarRegister() const { EXIT_IF(type != Type::ScalarReg); return scalar_reg; @@ -94,11 +65,6 @@ uint16_t Value::U16() const { return imm_u16; } -uint32_t Value::U32() const { - EXIT_IF(type != Type::U32); - return imm_u32; -} - uint64_t Value::U64() const { EXIT_IF(type != Type::U64); return imm_u64; @@ -152,10 +118,6 @@ Inst::~Inst() { ClearArgs(); } -ValueOpcode Inst::GetOpcode() const { - return opcode; -} - Type Inst::GetType() const { if (opcode == ValueOpcode::Phi) { return static_cast(flags); @@ -178,40 +140,15 @@ size_t Inst::UseCount() const { return uses.size(); } -size_t Inst::NumArgs() const { - return num_args == PhiArity ? phi_args.size() : num_args; -} - size_t Inst::NumPhiBlocks() const { return num_args == PhiArity ? phi_args.size() : 0; } -template -auto& Inst::ArgSlot(Self& self, size_t index) { - EXIT_IF(index >= self.NumArgs()); - if (self.num_args <= InlineArity) { - return self.fixed_args[index]; - } - return self.num_args == PhiArity ? self.phi_args[index].second : self.large_args[index]; -} - -Value Inst::Arg(size_t index) const { - return ArgSlot(*this, index); -} - Block* Inst::PhiBlock(size_t index) const { EXIT_IF(opcode != ValueOpcode::Phi || index >= phi_args.size()); return phi_args[index].first; } -Block* Inst::Parent() const { - return parent; -} - -const std::vector& Inst::Uses() const { - return uses; -} - void Inst::SetParent(Block* block) { parent = block; } diff --git a/src/graphics/shader/recompiler/ir/Value.h b/src/graphics/shader/recompiler/ir/Value.h index 1bfef0598..5caae4e48 100644 --- a/src/graphics/shader/recompiler/ir/Value.h +++ b/src/graphics/shader/recompiler/ir/Value.h @@ -33,14 +33,14 @@ public: static Value F16(uint16_t bits); static Value F32(float value); - [[nodiscard]] bool IsEmpty() const; - [[nodiscard]] bool IsImmediate() const; + [[nodiscard]] bool IsEmpty() const { return type == Type::Void; } + [[nodiscard]] bool IsImmediate() const { return type != Type::Opaque; } [[nodiscard]] bool IsIdentity() const; [[nodiscard]] bool IsPhi() const; [[nodiscard]] Type GetType() const; [[nodiscard]] Inst* Instruction() const; - [[nodiscard]] Inst* TryInstruction() const; + [[nodiscard]] Inst* TryInstruction() const { return type == Type::Opaque ? inst : nullptr; } [[nodiscard]] Inst* ResolveInstruction() const; [[nodiscard]] Value Resolve() const; [[nodiscard]] ScalarReg ScalarRegister() const; @@ -112,7 +112,7 @@ public: Inst(Inst&&) = delete; Inst& operator=(Inst&&) = delete; - [[nodiscard]] ValueOpcode GetOpcode() const; + [[nodiscard]] ValueOpcode GetOpcode() const { return opcode; } [[nodiscard]] Type GetType() const; [[nodiscard]] bool MayHaveSideEffects() const; [[nodiscard]] bool HasUses() const; @@ -121,8 +121,8 @@ public: [[nodiscard]] size_t NumPhiBlocks() const; [[nodiscard]] Value Arg(size_t index) const; [[nodiscard]] Block* PhiBlock(size_t index) const; - [[nodiscard]] Block* Parent() const; - [[nodiscard]] const std::vector& Uses() const; + [[nodiscard]] Block* Parent() const { return parent; } + [[nodiscard]] const std::vector& Uses() const { return uses; } // SRT walker output index, assigned by the resource plan that owns this instruction. [[nodiscard]] uint32_t WalkOutput() const { return walk_output; } void SetWalkOutput(uint32_t index) const { walk_output = index; } @@ -185,4 +185,44 @@ private: static_assert(sizeof(Inst) <= 120, "Inst operand and backend storage unintentionally increased"); +// Called per operand by the IR passes and the resource walker; inline, as the build has no LTO. +inline bool Value::IsIdentity() const { + return type == Type::Opaque && inst->GetOpcode() == ValueOpcode::Identity; +} + +inline bool Value::IsPhi() const { + return type == Type::Opaque && inst->GetOpcode() == ValueOpcode::Phi; +} + +inline Inst* Value::ResolveInstruction() const { + EXIT_IF(type != Type::Opaque); + return IsIdentity() ? inst->Arg(0).ResolveInstruction() : inst; +} + +inline Value Value::Resolve() const { + return IsIdentity() ? inst->Arg(0).Resolve() : *this; +} + +inline uint32_t Value::U32() const { + EXIT_IF(type != Type::U32); + return imm_u32; +} + +inline size_t Inst::NumArgs() const { + return num_args == PhiArity ? phi_args.size() : num_args; +} + +template +auto& Inst::ArgSlot(Self& self, size_t index) { + EXIT_IF(index >= self.NumArgs()); + if (self.num_args <= InlineArity) { + return self.fixed_args[index]; + } + return self.num_args == PhiArity ? self.phi_args[index].second : self.large_args[index]; +} + +inline Value Inst::Arg(size_t index) const { + return ArgSlot(*this, index); +} + } // namespace Libs::Graphics::ShaderRecompiler::IR