diff options
| author | 2021-02-11 16:39:06 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:22 -0400 | |
| commit | 9170200a11715d131645d1ffb92e86e6ef0d7e88 (patch) | |
| tree | 6c6f84c38a9b59d023ecb09c0737ea56da166b64 /src/shader_recompiler/frontend/ir/basic_block.h | |
| parent | spirv: Initial SPIR-V support (diff) | |
| download | yuzu-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.h | 40 |
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 | ||
| 17 | namespace Shader::IR { | 19 | namespace 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 | ||
| 166 | using 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, |