shader: Fix indirect branches to scheduler instructions
This commit is contained in:
		| @@ -434,7 +434,10 @@ CFG::AnalysisState CFG::AnalyzeBRX(Block* block, Location pc, Instruction inst, | ||||
|     block->indirect_branches.reserve(targets.size()); | ||||
|     for (const u32 target : targets) { | ||||
|         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->end = pc + 1; | ||||
| @@ -530,8 +533,8 @@ std::string CFG::Dot() const { | ||||
|                 } | ||||
|                 break; | ||||
|             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; | ||||
|             case EndClass::Call: | ||||
|   | ||||
| @@ -22,6 +22,8 @@ | ||||
|  | ||||
| namespace Shader::Maxwell::Flow { | ||||
|  | ||||
| struct Block; | ||||
|  | ||||
| using FunctionId = size_t; | ||||
|  | ||||
| enum class EndClass { | ||||
| @@ -60,6 +62,11 @@ private: | ||||
|     boost::container::small_vector<StackEntry, 3> entries; | ||||
| }; | ||||
|  | ||||
| struct IndirectBranch { | ||||
|     Block* block; | ||||
|     u32 address; | ||||
| }; | ||||
|  | ||||
| struct Block : boost::intrusive::set_base_hook< | ||||
|                    // Normal link is ~2.5% faster compared to safe link | ||||
|                    boost::intrusive::link_mode<boost::intrusive::normal_link>> { | ||||
| @@ -84,7 +91,7 @@ struct Block : boost::intrusive::set_base_hook< | ||||
|         Block* return_block; | ||||
|         s32 branch_offset; | ||||
|     }; | ||||
|     std::vector<Block*> indirect_branches; | ||||
|     std::vector<IndirectBranch> indirect_branches; | ||||
| }; | ||||
|  | ||||
| struct Label { | ||||
|   | ||||
| @@ -446,9 +446,9 @@ private: | ||||
|             case Flow::EndClass::IndirectBranch: | ||||
|                 root.insert(ip, *pool.Create(SetIndirectBranchVariable{}, block.branch_reg, | ||||
|                                              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)}; | ||||
|                     gotos.push_back(root.insert(ip, *goto_stmt)); | ||||
|                 } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user