shader: inline the hot IR operand accessors

This commit is contained in:
Senaxx authored and nmzik committed 2026-10-27 07:04:38 +01:00
1 parent a526a8b9c9
commit 6cee2dc0bd
2 files changed
+46 -69

No files matched your search

@@ -25,22 +25,6 @@ Value Value::F32(float value) {
return Value(Type::F32, std::bit_cast<uint32_t>(value)); return Value(Type::F32, std::bit_cast<uint32_t>(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 { Type Value::GetType() const {
if (IsPhi()) { if (IsPhi()) {
return inst->Flags<Type>(); return inst->Flags<Type>();
@@ -56,19 +40,6 @@ Inst* Value::Instruction() const {
return inst; 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 { ScalarReg Value::ScalarRegister() const {
EXIT_IF(type != Type::ScalarReg); EXIT_IF(type != Type::ScalarReg);
return scalar_reg; return scalar_reg;
@@ -94,11 +65,6 @@ uint16_t Value::U16() const {
return imm_u16; return imm_u16;
} }
uint32_t Value::U32() const {
EXIT_IF(type != Type::U32);
return imm_u32;
}
uint64_t Value::U64() const { uint64_t Value::U64() const {
EXIT_IF(type != Type::U64); EXIT_IF(type != Type::U64);
return imm_u64; return imm_u64;
@@ -152,10 +118,6 @@ Inst::~Inst() {
ClearArgs(); ClearArgs();
} }
ValueOpcode Inst::GetOpcode() const {
return opcode;
}
Type Inst::GetType() const { Type Inst::GetType() const {
if (opcode == ValueOpcode::Phi) { if (opcode == ValueOpcode::Phi) {
return static_cast<Type>(flags); return static_cast<Type>(flags);
@@ -178,40 +140,15 @@ size_t Inst::UseCount() const {
return uses.size(); return uses.size();
} }
size_t Inst::NumArgs() const {
return num_args == PhiArity ? phi_args.size() : num_args;
}
size_t Inst::NumPhiBlocks() const { size_t Inst::NumPhiBlocks() const {
return num_args == PhiArity ? phi_args.size() : 0; return num_args == PhiArity ? phi_args.size() : 0;
} }
template <typename Self>
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 { Block* Inst::PhiBlock(size_t index) const {
EXIT_IF(opcode != ValueOpcode::Phi || index >= phi_args.size()); EXIT_IF(opcode != ValueOpcode::Phi || index >= phi_args.size());
return phi_args[index].first; return phi_args[index].first;
} }
Block* Inst::Parent() const {
return parent;
}
const std::vector<Use>& Inst::Uses() const {
return uses;
}
void Inst::SetParent(Block* block) { void Inst::SetParent(Block* block) {
parent = block; parent = block;
} }
+46 -6
View File
@@ -33,14 +33,14 @@ public:
static Value F16(uint16_t bits); static Value F16(uint16_t bits);
static Value F32(float value); static Value F32(float value);
[[nodiscard]] bool IsEmpty() const; [[nodiscard]] bool IsEmpty() const { return type == Type::Void; }
[[nodiscard]] bool IsImmediate() const; [[nodiscard]] bool IsImmediate() const { return type != Type::Opaque; }
[[nodiscard]] bool IsIdentity() const; [[nodiscard]] bool IsIdentity() const;
[[nodiscard]] bool IsPhi() const; [[nodiscard]] bool IsPhi() const;
[[nodiscard]] Type GetType() const; [[nodiscard]] Type GetType() const;
[[nodiscard]] Inst* Instruction() const; [[nodiscard]] Inst* Instruction() const;
[[nodiscard]] Inst* TryInstruction() const; [[nodiscard]] Inst* TryInstruction() const { return type == Type::Opaque ? inst : nullptr; }
[[nodiscard]] Inst* ResolveInstruction() const; [[nodiscard]] Inst* ResolveInstruction() const;
[[nodiscard]] Value Resolve() const; [[nodiscard]] Value Resolve() const;
[[nodiscard]] ScalarReg ScalarRegister() const; [[nodiscard]] ScalarReg ScalarRegister() const;
@@ -112,7 +112,7 @@ public:
Inst(Inst&&) = delete; Inst(Inst&&) = delete;
Inst& operator=(Inst&&) = delete; Inst& operator=(Inst&&) = delete;
[[nodiscard]] ValueOpcode GetOpcode() const; [[nodiscard]] ValueOpcode GetOpcode() const { return opcode; }
[[nodiscard]] Type GetType() const; [[nodiscard]] Type GetType() const;
[[nodiscard]] bool MayHaveSideEffects() const; [[nodiscard]] bool MayHaveSideEffects() const;
[[nodiscard]] bool HasUses() const; [[nodiscard]] bool HasUses() const;
@@ -121,8 +121,8 @@ public:
[[nodiscard]] size_t NumPhiBlocks() const; [[nodiscard]] size_t NumPhiBlocks() const;
[[nodiscard]] Value Arg(size_t index) const; [[nodiscard]] Value Arg(size_t index) const;
[[nodiscard]] Block* PhiBlock(size_t index) const; [[nodiscard]] Block* PhiBlock(size_t index) const;
[[nodiscard]] Block* Parent() const; [[nodiscard]] Block* Parent() const { return parent; }
[[nodiscard]] const std::vector<Use>& Uses() const; [[nodiscard]] const std::vector<Use>& Uses() const { return uses; }
// SRT walker output index, assigned by the resource plan that owns this instruction. // SRT walker output index, assigned by the resource plan that owns this instruction.
[[nodiscard]] uint32_t WalkOutput() const { return walk_output; } [[nodiscard]] uint32_t WalkOutput() const { return walk_output; }
void SetWalkOutput(uint32_t index) const { walk_output = index; } 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"); 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 <typename Self>
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 } // namespace Libs::Graphics::ShaderRecompiler::IR