shader: Fix splits on blocks using indirect branches
This commit is contained in:
		| @@ -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}, | ||||
|   | ||||
| @@ -79,18 +79,14 @@ struct Block : boost::intrusive::set_base_hook< | ||||
|     Location begin; | ||||
|     Location end; | ||||
|     EndClass end_class; | ||||
|     Stack stack; | ||||
|     IR::Condition cond; | ||||
|     union { | ||||
|     Stack stack; | ||||
|     Block* branch_true; | ||||
|         FunctionId function_call; | ||||
|         IR::Reg branch_reg; | ||||
|     }; | ||||
|     union { | ||||
|     Block* branch_false; | ||||
|     FunctionId function_call; | ||||
|     Block* return_block; | ||||
|     IR::Reg branch_reg; | ||||
|     s32 branch_offset; | ||||
|     }; | ||||
|     std::vector<IndirectBranch> indirect_branches; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user