Răsfoiți Sursa

shader: Fix indirect branches to scheduler instructions

ReinUsesLisp 5 ani în urmă
părinte
comite
b0d5572abf

+ 6 - 3
src/shader_recompiler/frontend/maxwell/control_flow.cpp

@@ -434,7 +434,10 @@ CFG::AnalysisState CFG::AnalyzeBRX(Block* block, Location pc, Instruction inst,
     block->indirect_branches.reserve(targets.size());
     block->indirect_branches.reserve(targets.size());
     for (const u32 target : targets) {
     for (const u32 target : targets) {
         Block* const branch{AddLabel(block, block->stack, target, function_id)};
         Block* const branch{AddLabel(block, block->stack, target, function_id)};
-        block->indirect_branches.push_back(branch);
+        block->indirect_branches.push_back({
+            .block{branch},
+            .address{target},
+        });
     }
     }
     block->cond = IR::Condition{true};
     block->cond = IR::Condition{true};
     block->end = pc + 1;
     block->end = pc + 1;
@@ -530,8 +533,8 @@ std::string CFG::Dot() const {
                 }
                 }
                 break;
                 break;
             case EndClass::IndirectBranch:
             case EndClass::IndirectBranch:
-                for (Block* const branch : block.indirect_branches) {
-                    add_branch(branch, false);
+                for (const IndirectBranch& branch : block.indirect_branches) {
+                    add_branch(branch.block, false);
                 }
                 }
                 break;
                 break;
             case EndClass::Call:
             case EndClass::Call:

+ 8 - 1
src/shader_recompiler/frontend/maxwell/control_flow.h

@@ -22,6 +22,8 @@
 
 
 namespace Shader::Maxwell::Flow {
 namespace Shader::Maxwell::Flow {
 
 
+struct Block;
+
 using FunctionId = size_t;
 using FunctionId = size_t;
 
 
 enum class EndClass {
 enum class EndClass {
@@ -60,6 +62,11 @@ private:
     boost::container::small_vector<StackEntry, 3> entries;
     boost::container::small_vector<StackEntry, 3> entries;
 };
 };
 
 
+struct IndirectBranch {
+    Block* block;
+    u32 address;
+};
+
 struct Block : boost::intrusive::set_base_hook<
 struct Block : boost::intrusive::set_base_hook<
                    // Normal link is ~2.5% faster compared to safe link
                    // Normal link is ~2.5% faster compared to safe link
                    boost::intrusive::link_mode<boost::intrusive::normal_link>> {
                    boost::intrusive::link_mode<boost::intrusive::normal_link>> {
@@ -84,7 +91,7 @@ struct Block : boost::intrusive::set_base_hook<
         Block* return_block;
         Block* return_block;
         s32 branch_offset;
         s32 branch_offset;
     };
     };
-    std::vector<Block*> indirect_branches;
+    std::vector<IndirectBranch> indirect_branches;
 };
 };
 
 
 struct Label {
 struct Label {

+ 3 - 3
src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp

@@ -446,9 +446,9 @@ private:
             case Flow::EndClass::IndirectBranch:
             case Flow::EndClass::IndirectBranch:
                 root.insert(ip, *pool.Create(SetIndirectBranchVariable{}, block.branch_reg,
                 root.insert(ip, *pool.Create(SetIndirectBranchVariable{}, block.branch_reg,
                                              block.branch_offset));
                                              block.branch_offset));
-                for (Flow::Block* const branch : block.indirect_branches) {
-                    const Node indirect_label{local_labels.at(branch)};
-                    Statement* cond{pool.Create(IndirectBranchCond{}, branch->begin.Offset())};
+                for (const Flow::IndirectBranch& indirect : block.indirect_branches) {
+                    const Node indirect_label{local_labels.at(indirect.block)};
+                    Statement* cond{pool.Create(IndirectBranchCond{}, indirect.address)};
                     Statement* goto_stmt{pool.Create(Goto{}, cond, indirect_label, &root_stmt)};
                     Statement* goto_stmt{pool.Create(Goto{}, cond, indirect_label, &root_stmt)};
                     gotos.push_back(root.insert(ip, *goto_stmt));
                     gotos.push_back(root.insert(ip, *goto_stmt));
                 }
                 }