diff options
Diffstat (limited to '')
-rw-r--r-- | src/shader_recompiler/frontend/ir/microinstruction.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index 3dfa5a880..97e2bf6af 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp @@ -6,6 +6,7 @@ #include <memory> #include "shader_recompiler/exception.h" +#include "shader_recompiler/frontend/ir/basic_block.h" #include "shader_recompiler/frontend/ir/type.h" #include "shader_recompiler/frontend/ir/value.h" @@ -46,6 +47,17 @@ Inst::Inst(IR::Opcode op_, u32 flags_) noexcept : op{op_}, flags{flags_} { } } +Inst::Inst(const Inst& base) : op{base.op}, flags{base.flags} { + if (base.op == Opcode::Phi) { + throw NotImplementedException("Copying phi node"); + } + std::construct_at(&args); + const size_t num_args{base.NumArgs()}; + for (size_t index = 0; index < num_args; ++index) { + SetArg(index, base.Arg(index)); + } +} + Inst::~Inst() { if (op == Opcode::Phi) { std::destroy_at(&phi_args); @@ -253,6 +265,10 @@ Inst* Inst::GetAssociatedPseudoOperation(IR::Opcode opcode) { } IR::Type Inst::Type() const { + if (op == IR::Opcode::Phi) { + // The type of a phi node is stored in its flags + return Flags<IR::Type>(); + } return TypeOf(op); } @@ -291,6 +307,16 @@ void Inst::AddPhiOperand(Block* predecessor, const Value& value) { phi_args.emplace_back(predecessor, value); } +void Inst::OrderPhiArgs() { + if (op != Opcode::Phi) { + throw LogicError("{} is not a Phi instruction", op); + } + std::sort(phi_args.begin(), phi_args.end(), + [](const std::pair<Block*, Value>& a, const std::pair<Block*, Value>& b) { + return a.first->GetOrder() < b.first->GetOrder(); + }); +} + void Inst::Invalidate() { ClearArgs(); ReplaceOpcode(Opcode::Void); |