summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/ir/basic_block.h
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-02-11 16:39:06 -0300
committerGravatar ameerj2021-07-22 21:51:22 -0400
commit9170200a11715d131645d1ffb92e86e6ef0d7e88 (patch)
tree6c6f84c38a9b59d023ecb09c0737ea56da166b64 /src/shader_recompiler/frontend/ir/basic_block.h
parentspirv: Initial SPIR-V support (diff)
downloadyuzu-9170200a11715d131645d1ffb92e86e6ef0d7e88.tar.gz
yuzu-9170200a11715d131645d1ffb92e86e6ef0d7e88.tar.xz
yuzu-9170200a11715d131645d1ffb92e86e6ef0d7e88.zip
shader: Initial implementation of an AST
Diffstat (limited to 'src/shader_recompiler/frontend/ir/basic_block.h')
-rw-r--r--src/shader_recompiler/frontend/ir/basic_block.h40
1 files changed, 36 insertions, 4 deletions
diff --git a/src/shader_recompiler/frontend/ir/basic_block.h b/src/shader_recompiler/frontend/ir/basic_block.h
index ec3ad6263..3205705e7 100644
--- a/src/shader_recompiler/frontend/ir/basic_block.h
+++ b/src/shader_recompiler/frontend/ir/basic_block.h
@@ -11,7 +11,9 @@
11 11
12#include <boost/intrusive/list.hpp> 12#include <boost/intrusive/list.hpp>
13 13
14#include "shader_recompiler/frontend/ir/condition.h"
14#include "shader_recompiler/frontend/ir/microinstruction.h" 15#include "shader_recompiler/frontend/ir/microinstruction.h"
16#include "shader_recompiler/frontend/ir/value.h"
15#include "shader_recompiler/object_pool.h" 17#include "shader_recompiler/object_pool.h"
16 18
17namespace Shader::IR { 19namespace Shader::IR {
@@ -26,6 +28,7 @@ public:
26 using const_reverse_iterator = InstructionList::const_reverse_iterator; 28 using const_reverse_iterator = InstructionList::const_reverse_iterator;
27 29
28 explicit Block(ObjectPool<Inst>& inst_pool_, u32 begin, u32 end); 30 explicit Block(ObjectPool<Inst>& inst_pool_, u32 begin, u32 end);
31 explicit Block(ObjectPool<Inst>& inst_pool_);
29 ~Block(); 32 ~Block();
30 33
31 Block(const Block&) = delete; 34 Block(const Block&) = delete;
@@ -41,9 +44,15 @@ public:
41 iterator PrependNewInst(iterator insertion_point, Opcode op, 44 iterator PrependNewInst(iterator insertion_point, Opcode op,
42 std::initializer_list<Value> args = {}, u64 flags = 0); 45 std::initializer_list<Value> args = {}, u64 flags = 0);
43 46
44 /// Adds a new immediate predecessor to the basic block. 47 /// Set the branches to jump to when all instructions have executed.
45 void AddImmediatePredecessor(IR::Block* immediate_predecessor); 48 void SetBranches(Condition cond, Block* branch_true, Block* branch_false);
49 /// Set the branch to unconditionally jump to when all instructions have executed.
50 void SetBranch(Block* branch);
51 /// Mark the block as a return block.
52 void SetReturn();
46 53
54 /// Returns true when the block does not implement any guest instructions directly.
55 [[nodiscard]] bool IsVirtual() const noexcept;
47 /// Gets the starting location of this basic block. 56 /// Gets the starting location of this basic block.
48 [[nodiscard]] u32 LocationBegin() const noexcept; 57 [[nodiscard]] u32 LocationBegin() const noexcept;
49 /// Gets the end location for this basic block. 58 /// Gets the end location for this basic block.
@@ -54,8 +63,23 @@ public:
54 /// Gets an immutable reference to the instruction list for this basic block. 63 /// Gets an immutable reference to the instruction list for this basic block.
55 [[nodiscard]] const InstructionList& Instructions() const noexcept; 64 [[nodiscard]] const InstructionList& Instructions() const noexcept;
56 65
66 /// Adds a new immediate predecessor to this basic block.
67 void AddImmediatePredecessor(Block* block);
57 /// Gets an immutable span to the immediate predecessors. 68 /// Gets an immutable span to the immediate predecessors.
58 [[nodiscard]] std::span<IR::Block* const> ImmediatePredecessors() const noexcept; 69 [[nodiscard]] std::span<Block* const> ImmediatePredecessors() const noexcept;
70
71 [[nodiscard]] Condition BranchCondition() const noexcept {
72 return branch_cond;
73 }
74 [[nodiscard]] bool IsTerminationBlock() const noexcept {
75 return !branch_true && !branch_false;
76 }
77 [[nodiscard]] Block* TrueBranch() const noexcept {
78 return branch_true;
79 }
80 [[nodiscard]] Block* FalseBranch() const noexcept {
81 return branch_false;
82 }
59 83
60 [[nodiscard]] bool empty() const { 84 [[nodiscard]] bool empty() const {
61 return instructions.empty(); 85 return instructions.empty();
@@ -129,10 +153,18 @@ private:
129 /// List of instructions in this block 153 /// List of instructions in this block
130 InstructionList instructions; 154 InstructionList instructions;
131 155
156 /// Condition to choose the branch to take
157 Condition branch_cond{true};
158 /// Block to jump into when the branch condition evaluates as true
159 Block* branch_true{nullptr};
160 /// Block to jump into when the branch condition evaluates as false
161 Block* branch_false{nullptr};
132 /// Block immediate predecessors 162 /// Block immediate predecessors
133 std::vector<IR::Block*> imm_predecessors; 163 std::vector<Block*> imm_predecessors;
134}; 164};
135 165
166using BlockList = std::vector<Block*>;
167
136[[nodiscard]] std::string DumpBlock(const Block& block); 168[[nodiscard]] std::string DumpBlock(const Block& block);
137 169
138[[nodiscard]] std::string DumpBlock(const Block& block, 170[[nodiscard]] std::string DumpBlock(const Block& block,