diff options
Diffstat (limited to 'src/shader_recompiler/frontend')
3 files changed, 17 insertions, 7 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/control_flow.cpp b/src/shader_recompiler/frontend/maxwell/control_flow.cpp index 1e9b8e426..784f9df8a 100644 --- a/src/shader_recompiler/frontend/maxwell/control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/control_flow.cpp | |||
| @@ -434,7 +434,10 @@ CFG::AnalysisState CFG::AnalyzeBRX(Block* block, Location pc, Instruction inst, | |||
| 434 | block->indirect_branches.reserve(targets.size()); | 434 | block->indirect_branches.reserve(targets.size()); |
| 435 | for (const u32 target : targets) { | 435 | for (const u32 target : targets) { |
| 436 | Block* const branch{AddLabel(block, block->stack, target, function_id)}; | 436 | Block* const branch{AddLabel(block, block->stack, target, function_id)}; |
| 437 | block->indirect_branches.push_back(branch); | 437 | block->indirect_branches.push_back({ |
| 438 | .block{branch}, | ||
| 439 | .address{target}, | ||
| 440 | }); | ||
| 438 | } | 441 | } |
| 439 | block->cond = IR::Condition{true}; | 442 | block->cond = IR::Condition{true}; |
| 440 | block->end = pc + 1; | 443 | block->end = pc + 1; |
| @@ -530,8 +533,8 @@ std::string CFG::Dot() const { | |||
| 530 | } | 533 | } |
| 531 | break; | 534 | break; |
| 532 | case EndClass::IndirectBranch: | 535 | case EndClass::IndirectBranch: |
| 533 | for (Block* const branch : block.indirect_branches) { | 536 | for (const IndirectBranch& branch : block.indirect_branches) { |
| 534 | add_branch(branch, false); | 537 | add_branch(branch.block, false); |
| 535 | } | 538 | } |
| 536 | break; | 539 | break; |
| 537 | case EndClass::Call: | 540 | case EndClass::Call: |
diff --git a/src/shader_recompiler/frontend/maxwell/control_flow.h b/src/shader_recompiler/frontend/maxwell/control_flow.h index 1e05fcb97..a8c90d27a 100644 --- a/src/shader_recompiler/frontend/maxwell/control_flow.h +++ b/src/shader_recompiler/frontend/maxwell/control_flow.h | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | 22 | ||
| 23 | namespace Shader::Maxwell::Flow { | 23 | namespace Shader::Maxwell::Flow { |
| 24 | 24 | ||
| 25 | struct Block; | ||
| 26 | |||
| 25 | using FunctionId = size_t; | 27 | using FunctionId = size_t; |
| 26 | 28 | ||
| 27 | enum class EndClass { | 29 | enum class EndClass { |
| @@ -60,6 +62,11 @@ private: | |||
| 60 | boost::container::small_vector<StackEntry, 3> entries; | 62 | boost::container::small_vector<StackEntry, 3> entries; |
| 61 | }; | 63 | }; |
| 62 | 64 | ||
| 65 | struct IndirectBranch { | ||
| 66 | Block* block; | ||
| 67 | u32 address; | ||
| 68 | }; | ||
| 69 | |||
| 63 | struct Block : boost::intrusive::set_base_hook< | 70 | struct Block : boost::intrusive::set_base_hook< |
| 64 | // Normal link is ~2.5% faster compared to safe link | 71 | // Normal link is ~2.5% faster compared to safe link |
| 65 | boost::intrusive::link_mode<boost::intrusive::normal_link>> { | 72 | boost::intrusive::link_mode<boost::intrusive::normal_link>> { |
| @@ -84,7 +91,7 @@ struct Block : boost::intrusive::set_base_hook< | |||
| 84 | Block* return_block; | 91 | Block* return_block; |
| 85 | s32 branch_offset; | 92 | s32 branch_offset; |
| 86 | }; | 93 | }; |
| 87 | std::vector<Block*> indirect_branches; | 94 | std::vector<IndirectBranch> indirect_branches; |
| 88 | }; | 95 | }; |
| 89 | 96 | ||
| 90 | struct Label { | 97 | struct Label { |
diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index a6e55f61e..c804c2a8e 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | |||
| @@ -446,9 +446,9 @@ private: | |||
| 446 | case Flow::EndClass::IndirectBranch: | 446 | case Flow::EndClass::IndirectBranch: |
| 447 | root.insert(ip, *pool.Create(SetIndirectBranchVariable{}, block.branch_reg, | 447 | root.insert(ip, *pool.Create(SetIndirectBranchVariable{}, block.branch_reg, |
| 448 | block.branch_offset)); | 448 | block.branch_offset)); |
| 449 | for (Flow::Block* const branch : block.indirect_branches) { | 449 | for (const Flow::IndirectBranch& indirect : block.indirect_branches) { |
| 450 | const Node indirect_label{local_labels.at(branch)}; | 450 | const Node indirect_label{local_labels.at(indirect.block)}; |
| 451 | Statement* cond{pool.Create(IndirectBranchCond{}, branch->begin.Offset())}; | 451 | Statement* cond{pool.Create(IndirectBranchCond{}, indirect.address)}; |
| 452 | Statement* goto_stmt{pool.Create(Goto{}, cond, indirect_label, &root_stmt)}; | 452 | Statement* goto_stmt{pool.Create(Goto{}, cond, indirect_label, &root_stmt)}; |
| 453 | gotos.push_back(root.insert(ip, *goto_stmt)); | 453 | gotos.push_back(root.insert(ip, *goto_stmt)); |
| 454 | } | 454 | } |