Просмотр исходного кода

shader: Add copy constructor to instructions

ReinUsesLisp 5 лет назад
Родитель
Сommit
c892359d1b

+ 5 - 0
src/shader_recompiler/frontend/ir/basic_block.cpp

@@ -22,6 +22,11 @@ void Block::AppendNewInst(Opcode op, std::initializer_list<Value> args) {
     PrependNewInst(end(), op, args);
 }
 
+Block::iterator Block::PrependNewInst(iterator insertion_point, const Inst& base_inst) {
+    Inst* const inst{inst_pool->Create(base_inst)};
+    return instructions.insert(insertion_point, *inst);
+}
+
 Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode op,
                                       std::initializer_list<Value> args, u32 flags) {
     Inst* const inst{inst_pool->Create(op, flags)};

+ 3 - 0
src/shader_recompiler/frontend/ir/basic_block.h

@@ -40,6 +40,9 @@ public:
     /// Appends a new instruction to the end of this basic block.
     void AppendNewInst(Opcode op, std::initializer_list<Value> args);
 
+    /// Prepends a copy of an instruction to this basic block before the insertion point.
+    iterator PrependNewInst(iterator insertion_point, const Inst& base_inst);
+
     /// Prepends a new instruction to this basic block before the insertion point.
     iterator PrependNewInst(iterator insertion_point, Opcode op,
                             std::initializer_list<Value> args = {}, u32 flags = 0);

+ 11 - 0
src/shader_recompiler/frontend/ir/microinstruction.cpp

@@ -47,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);

+ 1 - 1
src/shader_recompiler/frontend/ir/value.h

@@ -116,10 +116,10 @@ public:
 class Inst : public boost::intrusive::list_base_hook<> {
 public:
     explicit Inst(IR::Opcode op_, u32 flags_) noexcept;
+    explicit Inst(const Inst& base);
     ~Inst();
 
     Inst& operator=(const Inst&) = delete;
-    Inst(const Inst&) = delete;
 
     Inst& operator=(Inst&&) = delete;
     Inst(Inst&&) = delete;