summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/frontend/ir
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/ir')
-rw-r--r--src/shader_recompiler/frontend/ir/abstract_syntax_list.h56
-rw-r--r--src/shader_recompiler/frontend/ir/basic_block.cpp56
-rw-r--r--src/shader_recompiler/frontend/ir/basic_block.h51
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp60
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h11
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.cpp11
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.h1
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc21
-rw-r--r--src/shader_recompiler/frontend/ir/post_order.cpp36
-rw-r--r--src/shader_recompiler/frontend/ir/post_order.h3
-rw-r--r--src/shader_recompiler/frontend/ir/program.h4
-rw-r--r--src/shader_recompiler/frontend/ir/type.h49
-rw-r--r--src/shader_recompiler/frontend/ir/value.cpp8
-rw-r--r--src/shader_recompiler/frontend/ir/value.h9
14 files changed, 151 insertions, 225 deletions
diff --git a/src/shader_recompiler/frontend/ir/abstract_syntax_list.h b/src/shader_recompiler/frontend/ir/abstract_syntax_list.h
new file mode 100644
index 000000000..1366414c2
--- /dev/null
+++ b/src/shader_recompiler/frontend/ir/abstract_syntax_list.h
@@ -0,0 +1,56 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <vector>
+
+#include "shader_recompiler/frontend/ir/value.h"
+
+namespace Shader::IR {
+
+class Block;
+
+struct AbstractSyntaxNode {
+ enum class Type {
+ Block,
+ If,
+ EndIf,
+ Loop,
+ Repeat,
+ Break,
+ Return,
+ Unreachable,
+ };
+ Type type{};
+ union {
+ Block* block{};
+ struct {
+ U1 cond;
+ Block* body;
+ Block* merge;
+ } if_node;
+ struct {
+ Block* merge;
+ } end_if;
+ struct {
+ Block* body;
+ Block* continue_block;
+ Block* merge;
+ } loop;
+ struct {
+ U1 cond;
+ Block* loop_header;
+ Block* merge;
+ } repeat;
+ struct {
+ U1 cond;
+ Block* merge;
+ Block* skip;
+ } break_node;
+ };
+};
+using AbstractSyntaxList = std::vector<AbstractSyntaxNode>;
+
+} // namespace Shader::IR
diff --git a/src/shader_recompiler/frontend/ir/basic_block.cpp b/src/shader_recompiler/frontend/ir/basic_block.cpp
index f92fc2571..7c08b25ce 100644
--- a/src/shader_recompiler/frontend/ir/basic_block.cpp
+++ b/src/shader_recompiler/frontend/ir/basic_block.cpp
@@ -14,10 +14,7 @@
namespace Shader::IR {
-Block::Block(ObjectPool<Inst>& inst_pool_, u32 begin, u32 end)
- : inst_pool{&inst_pool_}, location_begin{begin}, location_end{end} {}
-
-Block::Block(ObjectPool<Inst>& inst_pool_) : Block{inst_pool_, 0, 0} {}
+Block::Block(ObjectPool<Inst>& inst_pool_) : inst_pool{&inst_pool_} {}
Block::~Block() = default;
@@ -40,39 +37,15 @@ Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode op,
return result_it;
}
-void Block::SetBranches(Condition cond, Block* branch_true_, Block* branch_false_) {
- branch_cond = cond;
- branch_true = branch_true_;
- branch_false = branch_false_;
-}
-
-void Block::SetBranch(Block* branch) {
- branch_cond = Condition{true};
- branch_true = branch;
-}
-
-void Block::SetReturn() {
- branch_cond = Condition{true};
- branch_true = nullptr;
- branch_false = nullptr;
-}
-
-bool Block::IsVirtual() const noexcept {
- return location_begin == location_end;
-}
-
-u32 Block::LocationBegin() const noexcept {
- return location_begin;
-}
-
-u32 Block::LocationEnd() const noexcept {
- return location_end;
-}
-
-void Block::AddImmediatePredecessor(Block* block) {
- if (std::ranges::find(imm_predecessors, block) == imm_predecessors.end()) {
- imm_predecessors.push_back(block);
+void Block::AddBranch(Block* block) {
+ if (std::ranges::find(imm_successors, block) != imm_successors.end()) {
+ throw LogicError("Successor already inserted");
+ }
+ if (std::ranges::find(block->imm_predecessors, this) != block->imm_predecessors.end()) {
+ throw LogicError("Predecessor already inserted");
}
+ imm_successors.push_back(block);
+ block->imm_predecessors.push_back(this);
}
static std::string BlockToIndex(const std::map<const Block*, size_t>& block_to_index,
@@ -92,15 +65,11 @@ static size_t InstIndex(std::map<const Inst*, size_t>& inst_to_index, size_t& in
return it->second;
}
-static std::string ArgToIndex(const std::map<const Block*, size_t>& block_to_index,
- std::map<const Inst*, size_t>& inst_to_index, size_t& inst_index,
+static std::string ArgToIndex(std::map<const Inst*, size_t>& inst_to_index, size_t& inst_index,
const Value& arg) {
if (arg.IsEmpty()) {
return "<null>";
}
- if (arg.IsLabel()) {
- return BlockToIndex(block_to_index, arg.Label());
- }
if (!arg.IsImmediate() || arg.IsIdentity()) {
return fmt::format("%{}", InstIndex(inst_to_index, inst_index, arg.Inst()));
}
@@ -140,8 +109,7 @@ std::string DumpBlock(const Block& block, const std::map<const Block*, size_t>&
if (const auto it{block_to_index.find(&block)}; it != block_to_index.end()) {
ret += fmt::format(" ${}", it->second);
}
- ret += fmt::format(": begin={:04x} end={:04x}\n", block.LocationBegin(), block.LocationEnd());
-
+ ret += '\n';
for (const Inst& inst : block) {
const Opcode op{inst.GetOpcode()};
ret += fmt::format("[{:016x}] ", reinterpret_cast<u64>(&inst));
@@ -153,7 +121,7 @@ std::string DumpBlock(const Block& block, const std::map<const Block*, size_t>&
const size_t arg_count{inst.NumArgs()};
for (size_t arg_index = 0; arg_index < arg_count; ++arg_index) {
const Value arg{inst.Arg(arg_index)};
- const std::string arg_str{ArgToIndex(block_to_index, inst_to_index, inst_index, arg)};
+ const std::string arg_str{ArgToIndex(inst_to_index, inst_index, arg)};
ret += arg_index != 0 ? ", " : " ";
if (op == Opcode::Phi) {
ret += fmt::format("[ {}, {} ]", arg_str,
diff --git a/src/shader_recompiler/frontend/ir/basic_block.h b/src/shader_recompiler/frontend/ir/basic_block.h
index 0b0c97af6..7e134b4c7 100644
--- a/src/shader_recompiler/frontend/ir/basic_block.h
+++ b/src/shader_recompiler/frontend/ir/basic_block.h
@@ -12,6 +12,7 @@
#include <boost/intrusive/list.hpp>
#include "common/bit_cast.h"
+#include "common/common_types.h"
#include "shader_recompiler/frontend/ir/condition.h"
#include "shader_recompiler/frontend/ir/value.h"
#include "shader_recompiler/object_pool.h"
@@ -27,7 +28,6 @@ public:
using reverse_iterator = InstructionList::reverse_iterator;
using const_reverse_iterator = InstructionList::const_reverse_iterator;
- explicit Block(ObjectPool<Inst>& inst_pool_, u32 begin, u32 end);
explicit Block(ObjectPool<Inst>& inst_pool_);
~Block();
@@ -44,22 +44,8 @@ public:
iterator PrependNewInst(iterator insertion_point, Opcode op,
std::initializer_list<Value> args = {}, u32 flags = 0);
- /// Set the branches to jump to when all instructions have executed.
- void SetBranches(Condition cond, Block* branch_true, Block* branch_false);
- /// Set the branch to unconditionally jump to when all instructions have executed.
- void SetBranch(Block* branch);
- /// Mark the block as a return block.
- void SetReturn();
-
- /// Returns true when the block does not implement any guest instructions directly.
- [[nodiscard]] bool IsVirtual() const noexcept;
- /// Gets the starting location of this basic block.
- [[nodiscard]] u32 LocationBegin() const noexcept;
- /// Gets the end location for this basic block.
- [[nodiscard]] u32 LocationEnd() const noexcept;
-
- /// Adds a new immediate predecessor to this basic block.
- void AddImmediatePredecessor(Block* block);
+ /// Adds a new branch to this basic block.
+ void AddBranch(Block* block);
/// Gets a mutable reference to the instruction list for this basic block.
[[nodiscard]] InstructionList& Instructions() noexcept {
@@ -71,9 +57,13 @@ public:
}
/// Gets an immutable span to the immediate predecessors.
- [[nodiscard]] std::span<Block* const> ImmediatePredecessors() const noexcept {
+ [[nodiscard]] std::span<Block* const> ImmPredecessors() const noexcept {
return imm_predecessors;
}
+ /// Gets an immutable span to the immediate successors.
+ [[nodiscard]] std::span<Block* const> ImmSuccessors() const noexcept {
+ return imm_successors;
+ }
/// Intrusively store the host definition of this instruction.
template <typename DefinitionType>
@@ -87,19 +77,6 @@ public:
return Common::BitCast<DefinitionType>(definition);
}
- [[nodiscard]] Condition BranchCondition() const noexcept {
- return branch_cond;
- }
- [[nodiscard]] bool IsTerminationBlock() const noexcept {
- return !branch_true && !branch_false;
- }
- [[nodiscard]] Block* TrueBranch() const noexcept {
- return branch_true;
- }
- [[nodiscard]] Block* FalseBranch() const noexcept {
- return branch_false;
- }
-
void SetSsaRegValue(IR::Reg reg, const Value& value) noexcept {
ssa_reg_values[RegIndex(reg)] = value;
}
@@ -178,22 +155,14 @@ public:
private:
/// Memory pool for instruction list
ObjectPool<Inst>* inst_pool;
- /// Starting location of this block
- u32 location_begin;
- /// End location of this block
- u32 location_end;
/// List of instructions in this block
InstructionList instructions;
- /// Condition to choose the branch to take
- Condition branch_cond{true};
- /// Block to jump into when the branch condition evaluates as true
- Block* branch_true{nullptr};
- /// Block to jump into when the branch condition evaluates as false
- Block* branch_false{nullptr};
/// Block immediate predecessors
std::vector<Block*> imm_predecessors;
+ /// Block immediate successors
+ std::vector<Block*> imm_successors;
/// Intrusively store the value of a register in the block.
std::array<Value, NUM_REGS> ssa_reg_values;
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index ce6c9af07..eb45aa477 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -61,25 +61,28 @@ F64 IREmitter::Imm64(f64 value) const {
return F64{Value{value}};
}
-void IREmitter::Branch(Block* label) {
- label->AddImmediatePredecessor(block);
- block->SetBranch(label);
- Inst(Opcode::Branch, label);
+void IREmitter::Prologue() {
+ Inst(Opcode::Prologue);
}
-void IREmitter::BranchConditional(const U1& condition, Block* true_label, Block* false_label) {
- block->SetBranches(IR::Condition{true}, true_label, false_label);
- true_label->AddImmediatePredecessor(block);
- false_label->AddImmediatePredecessor(block);
- Inst(Opcode::BranchConditional, condition, true_label, false_label);
+void IREmitter::Epilogue() {
+ Inst(Opcode::Epilogue);
}
-void IREmitter::LoopMerge(Block* merge_block, Block* continue_target) {
- Inst(Opcode::LoopMerge, merge_block, continue_target);
+void IREmitter::BranchConditionRef(const U1& cond) {
+ Inst(Opcode::BranchConditionRef, cond);
}
-void IREmitter::SelectionMerge(Block* merge_block) {
- Inst(Opcode::SelectionMerge, merge_block);
+void IREmitter::DemoteToHelperInvocation() {
+ Inst(Opcode::DemoteToHelperInvocation);
+}
+
+void IREmitter::EmitVertex(const U32& stream) {
+ Inst(Opcode::EmitVertex, stream);
+}
+
+void IREmitter::EndPrimitive(const U32& stream) {
+ Inst(Opcode::EndPrimitive, stream);
}
void IREmitter::Barrier() {
@@ -94,37 +97,6 @@ void IREmitter::DeviceMemoryBarrier() {
Inst(Opcode::DeviceMemoryBarrier);
}
-void IREmitter::Return() {
- block->SetReturn();
- Inst(Opcode::Return);
-}
-
-void IREmitter::Unreachable() {
- Inst(Opcode::Unreachable);
-}
-
-void IREmitter::DemoteToHelperInvocation(Block* continue_label) {
- block->SetBranch(continue_label);
- continue_label->AddImmediatePredecessor(block);
- Inst(Opcode::DemoteToHelperInvocation, continue_label);
-}
-
-void IREmitter::Prologue() {
- Inst(Opcode::Prologue);
-}
-
-void IREmitter::Epilogue() {
- Inst(Opcode::Epilogue);
-}
-
-void IREmitter::EmitVertex(const U32& stream) {
- Inst(Opcode::EmitVertex, stream);
-}
-
-void IREmitter::EndPrimitive(const U32& stream) {
- Inst(Opcode::EndPrimitive, stream);
-}
-
U32 IREmitter::GetReg(IR::Reg reg) {
return Inst<U32>(Opcode::GetRegister, reg);
}
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index fd41b7e89..7a83c33d3 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -32,17 +32,10 @@ public:
[[nodiscard]] U64 Imm64(s64 value) const;
[[nodiscard]] F64 Imm64(f64 value) const;
- void Branch(Block* label);
- void BranchConditional(const U1& condition, Block* true_label, Block* false_label);
- void LoopMerge(Block* merge_block, Block* continue_target);
- void SelectionMerge(Block* merge_block);
- void Return();
- void Unreachable();
- void DemoteToHelperInvocation(Block* continue_label);
-
void Prologue();
void Epilogue();
-
+ void BranchConditionRef(const U1& cond);
+ void DemoteToHelperInvocation();
void EmitVertex(const U32& stream);
void EndPrimitive(const U32& stream);
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp
index 616ef17d4..364574240 100644
--- a/src/shader_recompiler/frontend/ir/microinstruction.cpp
+++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp
@@ -56,19 +56,14 @@ Inst::~Inst() {
bool Inst::MayHaveSideEffects() const noexcept {
switch (op) {
- case Opcode::Branch:
- case Opcode::BranchConditional:
- case Opcode::LoopMerge:
- case Opcode::SelectionMerge:
- case Opcode::Return:
+ case Opcode::Prologue:
+ case Opcode::Epilogue:
+ case Opcode::BranchConditionRef:
case Opcode::Join:
- case Opcode::Unreachable:
case Opcode::DemoteToHelperInvocation:
case Opcode::Barrier:
case Opcode::WorkgroupMemoryBarrier:
case Opcode::DeviceMemoryBarrier:
- case Opcode::Prologue:
- case Opcode::Epilogue:
case Opcode::EmitVertex:
case Opcode::EndPrimitive:
case Opcode::SetAttribute:
diff --git a/src/shader_recompiler/frontend/ir/opcodes.h b/src/shader_recompiler/frontend/ir/opcodes.h
index 2b9c0ed8c..56b001902 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.h
+++ b/src/shader_recompiler/frontend/ir/opcodes.h
@@ -30,7 +30,6 @@ struct OpcodeMeta {
// using enum Type;
constexpr Type Void{Type::Void};
constexpr Type Opaque{Type::Opaque};
-constexpr Type Label{Type::Label};
constexpr Type Reg{Type::Reg};
constexpr Type Pred{Type::Pred};
constexpr Type Attribute{Type::Attribute};
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index 9165421f8..75ddb6b6f 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -7,27 +7,20 @@ OPCODE(Phi, Opaque,
OPCODE(Identity, Opaque, Opaque, )
OPCODE(Void, Void, )
-// Control flow
-OPCODE(Branch, Void, Label, )
-OPCODE(BranchConditional, Void, U1, Label, Label, )
-OPCODE(LoopMerge, Void, Label, Label, )
-OPCODE(SelectionMerge, Void, Label, )
-OPCODE(Return, Void, )
+// Special operations
+OPCODE(Prologue, Void, )
+OPCODE(Epilogue, Void, )
+OPCODE(BranchConditionRef, Void, U1, )
OPCODE(Join, Void, )
-OPCODE(Unreachable, Void, )
-OPCODE(DemoteToHelperInvocation, Void, Label, )
+OPCODE(DemoteToHelperInvocation, Void, )
+OPCODE(EmitVertex, Void, U32, )
+OPCODE(EndPrimitive, Void, U32, )
// Barriers
OPCODE(Barrier, Void, )
OPCODE(WorkgroupMemoryBarrier, Void, )
OPCODE(DeviceMemoryBarrier, Void, )
-// Special operations
-OPCODE(Prologue, Void, )
-OPCODE(Epilogue, Void, )
-OPCODE(EmitVertex, Void, U32, )
-OPCODE(EndPrimitive, Void, U32, )
-
// Context getters/setters
OPCODE(GetRegister, U32, Reg, )
OPCODE(SetRegister, Void, Reg, U32, )
diff --git a/src/shader_recompiler/frontend/ir/post_order.cpp b/src/shader_recompiler/frontend/ir/post_order.cpp
index 8709a2ea1..1a28df7fb 100644
--- a/src/shader_recompiler/frontend/ir/post_order.cpp
+++ b/src/shader_recompiler/frontend/ir/post_order.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
+
#include <boost/container/flat_set.hpp>
#include <boost/container/small_vector.hpp>
@@ -10,35 +12,31 @@
namespace Shader::IR {
-BlockList PostOrder(const BlockList& blocks) {
+BlockList PostOrder(const AbstractSyntaxNode& root) {
boost::container::small_vector<Block*, 16> block_stack;
boost::container::flat_set<Block*> visited;
-
BlockList post_order_blocks;
- post_order_blocks.reserve(blocks.size());
- Block* const first_block{blocks.front()};
+ if (root.type != AbstractSyntaxNode::Type::Block) {
+ throw LogicError("First node in abstract syntax list root is not a block");
+ }
+ Block* const first_block{root.block};
visited.insert(first_block);
block_stack.push_back(first_block);
- const auto visit_branch = [&](Block* block, Block* branch) {
- if (!branch) {
- return false;
- }
- if (!visited.insert(branch).second) {
- return false;
- }
- // Calling push_back twice is faster than insert on MSVC
- block_stack.push_back(block);
- block_stack.push_back(branch);
- return true;
- };
while (!block_stack.empty()) {
Block* const block{block_stack.back()};
+ const auto visit{[&](Block* branch) {
+ if (!visited.insert(branch).second) {
+ return false;
+ }
+ // Calling push_back twice is faster than insert on MSVC
+ block_stack.push_back(block);
+ block_stack.push_back(branch);
+ return true;
+ }};
block_stack.pop_back();
-
- if (!visit_branch(block, block->TrueBranch()) &&
- !visit_branch(block, block->FalseBranch())) {
+ if (std::ranges::none_of(block->ImmSuccessors(), visit)) {
post_order_blocks.push_back(block);
}
}
diff --git a/src/shader_recompiler/frontend/ir/post_order.h b/src/shader_recompiler/frontend/ir/post_order.h
index 30137ff57..58a0467a0 100644
--- a/src/shader_recompiler/frontend/ir/post_order.h
+++ b/src/shader_recompiler/frontend/ir/post_order.h
@@ -5,9 +5,10 @@
#pragma once
#include "shader_recompiler/frontend/ir/basic_block.h"
+#include "shader_recompiler/frontend/ir/abstract_syntax_list.h"
namespace Shader::IR {
-BlockList PostOrder(const BlockList& blocks);
+BlockList PostOrder(const AbstractSyntaxNode& root);
} // namespace Shader::IR
diff --git a/src/shader_recompiler/frontend/ir/program.h b/src/shader_recompiler/frontend/ir/program.h
index 51e1a8c77..9ede5b48d 100644
--- a/src/shader_recompiler/frontend/ir/program.h
+++ b/src/shader_recompiler/frontend/ir/program.h
@@ -7,8 +7,7 @@
#include <array>
#include <string>
-#include <boost/container/small_vector.hpp>
-
+#include "shader_recompiler/frontend/ir/abstract_syntax_list.h"
#include "shader_recompiler/frontend/ir/basic_block.h"
#include "shader_recompiler/program_header.h"
#include "shader_recompiler/shader_info.h"
@@ -17,6 +16,7 @@
namespace Shader::IR {
struct Program {
+ AbstractSyntaxList syntax_list;
BlockList blocks;
BlockList post_order_blocks;
Info info;
diff --git a/src/shader_recompiler/frontend/ir/type.h b/src/shader_recompiler/frontend/ir/type.h
index 8b3b33852..294b230c4 100644
--- a/src/shader_recompiler/frontend/ir/type.h
+++ b/src/shader_recompiler/frontend/ir/type.h
@@ -16,31 +16,30 @@ namespace Shader::IR {
enum class Type {
Void = 0,
Opaque = 1 << 0,
- Label = 1 << 1,
- Reg = 1 << 2,
- Pred = 1 << 3,
- Attribute = 1 << 4,
- Patch = 1 << 5,
- U1 = 1 << 6,
- U8 = 1 << 7,
- U16 = 1 << 8,
- U32 = 1 << 9,
- U64 = 1 << 10,
- F16 = 1 << 11,
- F32 = 1 << 12,
- F64 = 1 << 13,
- U32x2 = 1 << 14,
- U32x3 = 1 << 15,
- U32x4 = 1 << 16,
- F16x2 = 1 << 17,
- F16x3 = 1 << 18,
- F16x4 = 1 << 19,
- F32x2 = 1 << 20,
- F32x3 = 1 << 21,
- F32x4 = 1 << 22,
- F64x2 = 1 << 23,
- F64x3 = 1 << 24,
- F64x4 = 1 << 25,
+ Reg = 1 << 1,
+ Pred = 1 << 2,
+ Attribute = 1 << 3,
+ Patch = 1 << 4,
+ U1 = 1 << 5,
+ U8 = 1 << 6,
+ U16 = 1 << 7,
+ U32 = 1 << 8,
+ U64 = 1 << 9,
+ F16 = 1 << 10,
+ F32 = 1 << 11,
+ F64 = 1 << 12,
+ U32x2 = 1 << 13,
+ U32x3 = 1 << 14,
+ U32x4 = 1 << 15,
+ F16x2 = 1 << 16,
+ F16x3 = 1 << 17,
+ F16x4 = 1 << 18,
+ F32x2 = 1 << 19,
+ F32x3 = 1 << 20,
+ F32x4 = 1 << 21,
+ F64x2 = 1 << 22,
+ F64x3 = 1 << 23,
+ F64x4 = 1 << 24,
};
DECLARE_ENUM_FLAG_OPERATORS(Type)
diff --git a/src/shader_recompiler/frontend/ir/value.cpp b/src/shader_recompiler/frontend/ir/value.cpp
index b962f170d..d365ea1bc 100644
--- a/src/shader_recompiler/frontend/ir/value.cpp
+++ b/src/shader_recompiler/frontend/ir/value.cpp
@@ -9,8 +9,6 @@ namespace Shader::IR {
Value::Value(IR::Inst* value) noexcept : type{Type::Opaque}, inst{value} {}
-Value::Value(IR::Block* value) noexcept : type{Type::Label}, label{value} {}
-
Value::Value(IR::Reg value) noexcept : type{Type::Reg}, reg{value} {}
Value::Value(IR::Pred value) noexcept : type{Type::Pred}, pred{value} {}
@@ -33,10 +31,6 @@ Value::Value(u64 value) noexcept : type{Type::U64}, imm_u64{value} {}
Value::Value(f64 value) noexcept : type{Type::F64}, imm_f64{value} {}
-bool Value::IsLabel() const noexcept {
- return type == Type::Label;
-}
-
IR::Type Value::Type() const noexcept {
if (IsPhi()) {
// The type of a phi node is stored in its flags
@@ -60,8 +54,6 @@ bool Value::operator==(const Value& other) const {
return true;
case Type::Opaque:
return inst == other.inst;
- case Type::Label:
- return label == other.label;
case Type::Reg:
return reg == other.reg;
case Type::Pred:
diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h
index beaf149f3..2ce49f953 100644
--- a/src/shader_recompiler/frontend/ir/value.h
+++ b/src/shader_recompiler/frontend/ir/value.h
@@ -37,7 +37,6 @@ class Value {
public:
Value() noexcept = default;
explicit Value(IR::Inst* value) noexcept;
- explicit Value(IR::Block* value) noexcept;
explicit Value(IR::Reg value) noexcept;
explicit Value(IR::Pred value) noexcept;
explicit Value(IR::Attribute value) noexcept;
@@ -54,11 +53,9 @@ public:
[[nodiscard]] bool IsPhi() const noexcept;
[[nodiscard]] bool IsEmpty() const noexcept;
[[nodiscard]] bool IsImmediate() const noexcept;
- [[nodiscard]] bool IsLabel() const noexcept;
[[nodiscard]] IR::Type Type() const noexcept;
[[nodiscard]] IR::Inst* Inst() const;
- [[nodiscard]] IR::Block* Label() const;
[[nodiscard]] IR::Inst* InstRecursive() const;
[[nodiscard]] IR::Value Resolve() const;
[[nodiscard]] IR::Reg Reg() const;
@@ -80,7 +77,6 @@ private:
IR::Type type{};
union {
IR::Inst* inst{};
- IR::Block* label;
IR::Reg reg;
IR::Pred pred;
IR::Attribute attribute;
@@ -304,11 +300,6 @@ inline IR::Inst* Value::Inst() const {
return inst;
}
-inline IR::Block* Value::Label() const {
- DEBUG_ASSERT(type == Type::Label);
- return label;
-}
-
inline IR::Inst* Value::InstRecursive() const {
DEBUG_ASSERT(type == Type::Opaque);
if (IsIdentity()) {