summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/ir/value.h
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-04-21 00:35:47 -0300
committerGravatar ameerj2021-07-22 21:51:28 -0400
commit050e81500c002f304d581f28700de549b828a2bc (patch)
tree906868122c08a0771987e6953c096476c0ebc277 /src/shader_recompiler/frontend/ir/value.h
parentshader: Move siblings check to a separate function and comment them out (diff)
downloadyuzu-050e81500c002f304d581f28700de549b828a2bc.tar.gz
yuzu-050e81500c002f304d581f28700de549b828a2bc.tar.xz
yuzu-050e81500c002f304d581f28700de549b828a2bc.zip
shader: Move microinstruction header to the value header
Diffstat (limited to 'src/shader_recompiler/frontend/ir/value.h')
-rw-r--r--src/shader_recompiler/frontend/ir/value.h151
1 files changed, 150 insertions, 1 deletions
diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h
index 303745563..d90a68b37 100644
--- a/src/shader_recompiler/frontend/ir/value.h
+++ b/src/shader_recompiler/frontend/ir/value.h
@@ -4,19 +4,34 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
8#include <cstring>
9#include <memory>
10#include <type_traits>
11#include <utility>
12#include <vector>
13
14#include <boost/container/small_vector.hpp>
15#include <boost/intrusive/list.hpp>
16
17#include "common/bit_cast.h"
7#include "common/common_types.h" 18#include "common/common_types.h"
8#include "shader_recompiler/exception.h" 19#include "shader_recompiler/exception.h"
9#include "shader_recompiler/frontend/ir/attribute.h" 20#include "shader_recompiler/frontend/ir/attribute.h"
21#include "shader_recompiler/frontend/ir/opcodes.h"
22#include "shader_recompiler/frontend/ir/patch.h"
10#include "shader_recompiler/frontend/ir/pred.h" 23#include "shader_recompiler/frontend/ir/pred.h"
11#include "shader_recompiler/frontend/ir/reg.h" 24#include "shader_recompiler/frontend/ir/reg.h"
12#include "shader_recompiler/frontend/ir/patch.h"
13#include "shader_recompiler/frontend/ir/type.h" 25#include "shader_recompiler/frontend/ir/type.h"
26#include "shader_recompiler/frontend/ir/value.h"
14 27
15namespace Shader::IR { 28namespace Shader::IR {
16 29
17class Block; 30class Block;
18class Inst; 31class Inst;
19 32
33struct AssociatedInsts;
34
20class Value { 35class Value {
21public: 36public:
22 Value() noexcept : type{IR::Type::Void}, inst{nullptr} {} 37 Value() noexcept : type{IR::Type::Void}, inst{nullptr} {}
@@ -101,6 +116,140 @@ public:
101 explicit TypedValue(IR::Inst* inst_) : TypedValue(Value(inst_)) {} 116 explicit TypedValue(IR::Inst* inst_) : TypedValue(Value(inst_)) {}
102}; 117};
103 118
119class Inst : public boost::intrusive::list_base_hook<> {
120public:
121 explicit Inst(IR::Opcode op_, u32 flags_) noexcept;
122 ~Inst();
123
124 Inst& operator=(const Inst&) = delete;
125 Inst(const Inst&) = delete;
126
127 Inst& operator=(Inst&&) = delete;
128 Inst(Inst&&) = delete;
129
130 /// Get the number of uses this instruction has.
131 [[nodiscard]] int UseCount() const noexcept {
132 return use_count;
133 }
134
135 /// Determines whether this instruction has uses or not.
136 [[nodiscard]] bool HasUses() const noexcept {
137 return use_count > 0;
138 }
139
140 /// Get the opcode this microinstruction represents.
141 [[nodiscard]] IR::Opcode GetOpcode() const noexcept {
142 return op;
143 }
144
145 /// Determines if there is a pseudo-operation associated with this instruction.
146 [[nodiscard]] bool HasAssociatedPseudoOperation() const noexcept {
147 return associated_insts != nullptr;
148 }
149
150 /// Determines whether or not this instruction may have side effects.
151 [[nodiscard]] bool MayHaveSideEffects() const noexcept;
152
153 /// Determines whether or not this instruction is a pseudo-instruction.
154 /// Pseudo-instructions depend on their parent instructions for their semantics.
155 [[nodiscard]] bool IsPseudoInstruction() const noexcept;
156
157 /// Determines if all arguments of this instruction are immediates.
158 [[nodiscard]] bool AreAllArgsImmediates() const;
159
160 /// Gets a pseudo-operation associated with this instruction
161 [[nodiscard]] Inst* GetAssociatedPseudoOperation(IR::Opcode opcode);
162
163 /// Get the type this instruction returns.
164 [[nodiscard]] IR::Type Type() const;
165
166 /// Get the number of arguments this instruction has.
167 [[nodiscard]] size_t NumArgs() const {
168 return op == IR::Opcode::Phi ? phi_args.size() : NumArgsOf(op);
169 }
170
171 /// Get the value of a given argument index.
172 [[nodiscard]] Value Arg(size_t index) const noexcept {
173 if (op == IR::Opcode::Phi) {
174 return phi_args[index].second;
175 } else {
176 return args[index];
177 }
178 }
179
180 /// Set the value of a given argument index.
181 void SetArg(size_t index, Value value);
182
183 /// Get a pointer to the block of a phi argument.
184 [[nodiscard]] Block* PhiBlock(size_t index) const;
185 /// Add phi operand to a phi instruction.
186 void AddPhiOperand(Block* predecessor, const Value& value);
187
188 void Invalidate();
189 void ClearArgs();
190
191 void ReplaceUsesWith(Value replacement);
192
193 void ReplaceOpcode(IR::Opcode opcode);
194
195 template <typename FlagsType>
196 requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>)
197 [[nodiscard]] FlagsType Flags() const noexcept {
198 FlagsType ret;
199 std::memcpy(reinterpret_cast<char*>(&ret), &flags, sizeof(ret));
200 return ret;
201 }
202
203 template <typename FlagsType>
204 requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>)
205 [[nodiscard]] void SetFlags(FlagsType value) noexcept {
206 std::memcpy(&flags, &value, sizeof(value));
207 }
208
209 /// Intrusively store the host definition of this instruction.
210 template <typename DefinitionType>
211 void SetDefinition(DefinitionType def) {
212 definition = Common::BitCast<u32>(def);
213 }
214
215 /// Return the intrusively stored host definition of this instruction.
216 template <typename DefinitionType>
217 [[nodiscard]] DefinitionType Definition() const noexcept {
218 return Common::BitCast<DefinitionType>(definition);
219 }
220
221private:
222 struct NonTriviallyDummy {
223 NonTriviallyDummy() noexcept {}
224 };
225
226 void Use(const Value& value);
227 void UndoUse(const Value& value);
228
229 IR::Opcode op{};
230 int use_count{};
231 u32 flags{};
232 u32 definition{};
233 union {
234 NonTriviallyDummy dummy{};
235 boost::container::small_vector<std::pair<Block*, Value>, 2> phi_args;
236 std::array<Value, 5> args;
237 };
238 std::unique_ptr<AssociatedInsts> associated_insts;
239};
240static_assert(sizeof(Inst) <= 128, "Inst size unintentionally increased");
241
242struct AssociatedInsts {
243 union {
244 Inst* in_bounds_inst;
245 Inst* sparse_inst;
246 Inst* zero_inst{};
247 };
248 Inst* sign_inst{};
249 Inst* carry_inst{};
250 Inst* overflow_inst{};
251};
252
104using U1 = TypedValue<Type::U1>; 253using U1 = TypedValue<Type::U1>;
105using U8 = TypedValue<Type::U8>; 254using U8 = TypedValue<Type::U8>;
106using U16 = TypedValue<Type::U16>; 255using U16 = TypedValue<Type::U16>;