فهرست منبع

shader: Fix splits on blocks using indirect branches

ReinUsesLisp 5 سال پیش
والد
کامیت
9e6fe430bd

+ 30 - 5
src/shader_recompiler/frontend/maxwell/control_flow.cpp

@@ -45,19 +45,29 @@ void Split(Block* old_block, Block* new_block, Location pc) {
         .begin{pc},
         .end{old_block->end},
         .end_class{old_block->end_class},
-        .stack{old_block->stack},
         .cond{old_block->cond},
+        .stack{old_block->stack},
         .branch_true{old_block->branch_true},
         .branch_false{old_block->branch_false},
+        .function_call{old_block->function_call},
+        .return_block{old_block->return_block},
+        .branch_reg{old_block->branch_reg},
+        .branch_offset{old_block->branch_offset},
+        .indirect_branches{std::move(old_block->indirect_branches)},
     };
     *old_block = Block{
         .begin{old_block->begin},
         .end{pc},
         .end_class{EndClass::Branch},
-        .stack{std::move(old_block->stack)},
         .cond{true},
+        .stack{std::move(old_block->stack)},
         .branch_true{new_block},
         .branch_false{nullptr},
+        .function_call{},
+        .return_block{},
+        .branch_reg{},
+        .branch_offset{},
+        .indirect_branches{},
     };
 }
 
@@ -173,10 +183,15 @@ Function::Function(ObjectPool<Block>& block_pool, Location start_address)
                                          .begin{start_address},
                                          .end{start_address},
                                          .end_class{EndClass::Branch},
-                                         .stack{},
                                          .cond{true},
+                                         .stack{},
                                          .branch_true{nullptr},
                                          .branch_false{nullptr},
+                                         .function_call{},
+                                         .return_block{},
+                                         .branch_reg{},
+                                         .branch_offset{},
+                                         .indirect_branches{},
                                      })},
                                      .stack{},
                                  }} {}
@@ -351,10 +366,15 @@ void CFG::AnalyzeCondInst(Block* block, FunctionId function_id, Location pc,
         .begin{block->begin.Virtual()},
         .end{block->begin.Virtual()},
         .end_class{EndClass::Branch},
-        .stack{block->stack},
         .cond{cond},
+        .stack{block->stack},
         .branch_true{conditional_block},
         .branch_false{nullptr},
+        .function_call{},
+        .return_block{},
+        .branch_reg{},
+        .branch_offset{},
+        .indirect_branches{},
     };
     // Save the contents of the visited block in the conditional block
     *conditional_block = std::move(*block);
@@ -502,10 +522,15 @@ Block* CFG::AddLabel(Block* block, Stack stack, Location pc, FunctionId function
         .begin{pc},
         .end{pc},
         .end_class{EndClass::Branch},
-        .stack{stack},
         .cond{true},
+        .stack{stack},
         .branch_true{nullptr},
         .branch_false{nullptr},
+        .function_call{},
+        .return_block{},
+        .branch_reg{},
+        .branch_offset{},
+        .indirect_branches{},
     })};
     function.labels.push_back(Label{
         .address{pc},

+ 7 - 11
src/shader_recompiler/frontend/maxwell/control_flow.h

@@ -79,18 +79,14 @@ struct Block : boost::intrusive::set_base_hook<
     Location begin;
     Location end;
     EndClass end_class;
-    Stack stack;
     IR::Condition cond;
-    union {
-        Block* branch_true;
-        FunctionId function_call;
-        IR::Reg branch_reg;
-    };
-    union {
-        Block* branch_false;
-        Block* return_block;
-        s32 branch_offset;
-    };
+    Stack stack;
+    Block* branch_true;
+    Block* branch_false;
+    FunctionId function_call;
+    Block* return_block;
+    IR::Reg branch_reg;
+    s32 branch_offset;
     std::vector<IndirectBranch> indirect_branches;
 };
 

+ 1 - 1
src/shader_recompiler/frontend/maxwell/program.cpp

@@ -21,7 +21,7 @@ void RemoveUnreachableBlocks(IR::Program& program) {
     if (program.blocks.size() == program.post_order_blocks.size()) {
         return;
     }
-    const auto begin{std::next(program.blocks.begin())};
+    const auto begin{program.blocks.begin() + 1};
     const auto end{program.blocks.end()};
     const auto pred{[](IR::Block* block) { return block->ImmediatePredecessors().empty(); }};
     program.blocks.erase(std::remove_if(begin, end, pred), end);