summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/ir/basic_block.h
diff options
context:
space:
mode:
authorGravatar bunnei2021-07-25 11:39:04 -0700
committerGravatar GitHub2021-07-25 11:39:04 -0700
commit98b26b6e126d4775fdf3f773fe8a8ac808a8ff8f (patch)
tree816faa96c2c4d291825063433331a8ea4b3d08f1 /src/shader_recompiler/frontend/ir/basic_block.h
parentMerge pull request #6699 from lat9nq/common-threads (diff)
parentshader: Support out of bound local memory reads and immediate writes (diff)
downloadyuzu-98b26b6e126d4775fdf3f773fe8a8ac808a8ff8f.tar.gz
yuzu-98b26b6e126d4775fdf3f773fe8a8ac808a8ff8f.tar.xz
yuzu-98b26b6e126d4775fdf3f773fe8a8ac808a8ff8f.zip
Merge pull request #6585 from ameerj/hades
Shader Decompiler Rewrite
Diffstat (limited to 'src/shader_recompiler/frontend/ir/basic_block.h')
-rw-r--r--src/shader_recompiler/frontend/ir/basic_block.h185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/ir/basic_block.h b/src/shader_recompiler/frontend/ir/basic_block.h
new file mode 100644
index 000000000..7e134b4c7
--- /dev/null
+++ b/src/shader_recompiler/frontend/ir/basic_block.h
@@ -0,0 +1,185 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <initializer_list>
8#include <map>
9#include <span>
10#include <vector>
11
12#include <boost/intrusive/list.hpp>
13
14#include "common/bit_cast.h"
15#include "common/common_types.h"
16#include "shader_recompiler/frontend/ir/condition.h"
17#include "shader_recompiler/frontend/ir/value.h"
18#include "shader_recompiler/object_pool.h"
19
20namespace Shader::IR {
21
22class Block {
23public:
24 using InstructionList = boost::intrusive::list<Inst>;
25 using size_type = InstructionList::size_type;
26 using iterator = InstructionList::iterator;
27 using const_iterator = InstructionList::const_iterator;
28 using reverse_iterator = InstructionList::reverse_iterator;
29 using const_reverse_iterator = InstructionList::const_reverse_iterator;
30
31 explicit Block(ObjectPool<Inst>& inst_pool_);
32 ~Block();
33
34 Block(const Block&) = delete;
35 Block& operator=(const Block&) = delete;
36
37 Block(Block&&) = default;
38 Block& operator=(Block&&) = default;
39
40 /// Appends a new instruction to the end of this basic block.
41 void AppendNewInst(Opcode op, std::initializer_list<Value> args);
42
43 /// Prepends a new instruction to this basic block before the insertion point.
44 iterator PrependNewInst(iterator insertion_point, Opcode op,
45 std::initializer_list<Value> args = {}, u32 flags = 0);
46
47 /// Adds a new branch to this basic block.
48 void AddBranch(Block* block);
49
50 /// Gets a mutable reference to the instruction list for this basic block.
51 [[nodiscard]] InstructionList& Instructions() noexcept {
52 return instructions;
53 }
54 /// Gets an immutable reference to the instruction list for this basic block.
55 [[nodiscard]] const InstructionList& Instructions() const noexcept {
56 return instructions;
57 }
58
59 /// Gets an immutable span to the immediate predecessors.
60 [[nodiscard]] std::span<Block* const> ImmPredecessors() const noexcept {
61 return imm_predecessors;
62 }
63 /// Gets an immutable span to the immediate successors.
64 [[nodiscard]] std::span<Block* const> ImmSuccessors() const noexcept {
65 return imm_successors;
66 }
67
68 /// Intrusively store the host definition of this instruction.
69 template <typename DefinitionType>
70 void SetDefinition(DefinitionType def) {
71 definition = Common::BitCast<u32>(def);
72 }
73
74 /// Return the intrusively stored host definition of this instruction.
75 template <typename DefinitionType>
76 [[nodiscard]] DefinitionType Definition() const noexcept {
77 return Common::BitCast<DefinitionType>(definition);
78 }
79
80 void SetSsaRegValue(IR::Reg reg, const Value& value) noexcept {
81 ssa_reg_values[RegIndex(reg)] = value;
82 }
83 const Value& SsaRegValue(IR::Reg reg) const noexcept {
84 return ssa_reg_values[RegIndex(reg)];
85 }
86
87 void SsaSeal() noexcept {
88 is_ssa_sealed = true;
89 }
90 [[nodiscard]] bool IsSsaSealed() const noexcept {
91 return is_ssa_sealed;
92 }
93
94 [[nodiscard]] bool empty() const {
95 return instructions.empty();
96 }
97 [[nodiscard]] size_type size() const {
98 return instructions.size();
99 }
100
101 [[nodiscard]] Inst& front() {
102 return instructions.front();
103 }
104 [[nodiscard]] const Inst& front() const {
105 return instructions.front();
106 }
107
108 [[nodiscard]] Inst& back() {
109 return instructions.back();
110 }
111 [[nodiscard]] const Inst& back() const {
112 return instructions.back();
113 }
114
115 [[nodiscard]] iterator begin() {
116 return instructions.begin();
117 }
118 [[nodiscard]] const_iterator begin() const {
119 return instructions.begin();
120 }
121 [[nodiscard]] iterator end() {
122 return instructions.end();
123 }
124 [[nodiscard]] const_iterator end() const {
125 return instructions.end();
126 }
127
128 [[nodiscard]] reverse_iterator rbegin() {
129 return instructions.rbegin();
130 }
131 [[nodiscard]] const_reverse_iterator rbegin() const {
132 return instructions.rbegin();
133 }
134 [[nodiscard]] reverse_iterator rend() {
135 return instructions.rend();
136 }
137 [[nodiscard]] const_reverse_iterator rend() const {
138 return instructions.rend();
139 }
140
141 [[nodiscard]] const_iterator cbegin() const {
142 return instructions.cbegin();
143 }
144 [[nodiscard]] const_iterator cend() const {
145 return instructions.cend();
146 }
147
148 [[nodiscard]] const_reverse_iterator crbegin() const {
149 return instructions.crbegin();
150 }
151 [[nodiscard]] const_reverse_iterator crend() const {
152 return instructions.crend();
153 }
154
155private:
156 /// Memory pool for instruction list
157 ObjectPool<Inst>* inst_pool;
158
159 /// List of instructions in this block
160 InstructionList instructions;
161
162 /// Block immediate predecessors
163 std::vector<Block*> imm_predecessors;
164 /// Block immediate successors
165 std::vector<Block*> imm_successors;
166
167 /// Intrusively store the value of a register in the block.
168 std::array<Value, NUM_REGS> ssa_reg_values;
169 /// Intrusively store if the block is sealed in the SSA pass.
170 bool is_ssa_sealed{false};
171
172 /// Intrusively stored host definition of this block.
173 u32 definition{};
174};
175
176using BlockList = std::vector<Block*>;
177
178[[nodiscard]] std::string DumpBlock(const Block& block);
179
180[[nodiscard]] std::string DumpBlock(const Block& block,
181 const std::map<const Block*, size_t>& block_to_index,
182 std::map<const Inst*, size_t>& inst_to_index,
183 size_t& inst_index);
184
185} // namespace Shader::IR