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}, |         .begin{pc}, | ||||||
|         .end{old_block->end}, |         .end{old_block->end}, | ||||||
|         .end_class{old_block->end_class}, |         .end_class{old_block->end_class}, | ||||||
|         .stack{old_block->stack}, |  | ||||||
|         .cond{old_block->cond}, |         .cond{old_block->cond}, | ||||||
|  |         .stack{old_block->stack}, | ||||||
|         .branch_true{old_block->branch_true}, |         .branch_true{old_block->branch_true}, | ||||||
|         .branch_false{old_block->branch_false}, |         .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{ |     *old_block = Block{ | ||||||
|         .begin{old_block->begin}, |         .begin{old_block->begin}, | ||||||
|         .end{pc}, |         .end{pc}, | ||||||
|         .end_class{EndClass::Branch}, |         .end_class{EndClass::Branch}, | ||||||
|         .stack{std::move(old_block->stack)}, |  | ||||||
|         .cond{true}, |         .cond{true}, | ||||||
|  |         .stack{std::move(old_block->stack)}, | ||||||
|         .branch_true{new_block}, |         .branch_true{new_block}, | ||||||
|         .branch_false{nullptr}, |         .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}, |                                          .begin{start_address}, | ||||||
|                                          .end{start_address}, |                                          .end{start_address}, | ||||||
|                                          .end_class{EndClass::Branch}, |                                          .end_class{EndClass::Branch}, | ||||||
|                                          .stack{}, |  | ||||||
|                                          .cond{true}, |                                          .cond{true}, | ||||||
|  |                                          .stack{}, | ||||||
|                                          .branch_true{nullptr}, |                                          .branch_true{nullptr}, | ||||||
|                                          .branch_false{nullptr}, |                                          .branch_false{nullptr}, | ||||||
|  |                                          .function_call{}, | ||||||
|  |                                          .return_block{}, | ||||||
|  |                                          .branch_reg{}, | ||||||
|  |                                          .branch_offset{}, | ||||||
|  |                                          .indirect_branches{}, | ||||||
|                                      })}, |                                      })}, | ||||||
|                                      .stack{}, |                                      .stack{}, | ||||||
|                                  }} {} |                                  }} {} | ||||||
| @@ -351,10 +366,15 @@ void CFG::AnalyzeCondInst(Block* block, FunctionId function_id, Location pc, | |||||||
|         .begin{block->begin.Virtual()}, |         .begin{block->begin.Virtual()}, | ||||||
|         .end{block->begin.Virtual()}, |         .end{block->begin.Virtual()}, | ||||||
|         .end_class{EndClass::Branch}, |         .end_class{EndClass::Branch}, | ||||||
|         .stack{block->stack}, |  | ||||||
|         .cond{cond}, |         .cond{cond}, | ||||||
|  |         .stack{block->stack}, | ||||||
|         .branch_true{conditional_block}, |         .branch_true{conditional_block}, | ||||||
|         .branch_false{nullptr}, |         .branch_false{nullptr}, | ||||||
|  |         .function_call{}, | ||||||
|  |         .return_block{}, | ||||||
|  |         .branch_reg{}, | ||||||
|  |         .branch_offset{}, | ||||||
|  |         .indirect_branches{}, | ||||||
|     }; |     }; | ||||||
|     // Save the contents of the visited block in the conditional block |     // Save the contents of the visited block in the conditional block | ||||||
|     *conditional_block = std::move(*block); |     *conditional_block = std::move(*block); | ||||||
| @@ -502,10 +522,15 @@ Block* CFG::AddLabel(Block* block, Stack stack, Location pc, FunctionId function | |||||||
|         .begin{pc}, |         .begin{pc}, | ||||||
|         .end{pc}, |         .end{pc}, | ||||||
|         .end_class{EndClass::Branch}, |         .end_class{EndClass::Branch}, | ||||||
|         .stack{stack}, |  | ||||||
|         .cond{true}, |         .cond{true}, | ||||||
|  |         .stack{stack}, | ||||||
|         .branch_true{nullptr}, |         .branch_true{nullptr}, | ||||||
|         .branch_false{nullptr}, |         .branch_false{nullptr}, | ||||||
|  |         .function_call{}, | ||||||
|  |         .return_block{}, | ||||||
|  |         .branch_reg{}, | ||||||
|  |         .branch_offset{}, | ||||||
|  |         .indirect_branches{}, | ||||||
|     })}; |     })}; | ||||||
|     function.labels.push_back(Label{ |     function.labels.push_back(Label{ | ||||||
|         .address{pc}, |         .address{pc}, | ||||||
|   | |||||||
| @@ -79,18 +79,14 @@ struct Block : boost::intrusive::set_base_hook< | |||||||
|     Location begin; |     Location begin; | ||||||
|     Location end; |     Location end; | ||||||
|     EndClass end_class; |     EndClass end_class; | ||||||
|     Stack stack; |  | ||||||
|     IR::Condition cond; |     IR::Condition cond; | ||||||
|     union { |     Stack stack; | ||||||
|     Block* branch_true; |     Block* branch_true; | ||||||
|         FunctionId function_call; |  | ||||||
|         IR::Reg branch_reg; |  | ||||||
|     }; |  | ||||||
|     union { |  | ||||||
|     Block* branch_false; |     Block* branch_false; | ||||||
|  |     FunctionId function_call; | ||||||
|     Block* return_block; |     Block* return_block; | ||||||
|  |     IR::Reg branch_reg; | ||||||
|     s32 branch_offset; |     s32 branch_offset; | ||||||
|     }; |  | ||||||
|     std::vector<IndirectBranch> indirect_branches; |     std::vector<IndirectBranch> indirect_branches; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ void RemoveUnreachableBlocks(IR::Program& program) { | |||||||
|     if (program.blocks.size() == program.post_order_blocks.size()) { |     if (program.blocks.size() == program.post_order_blocks.size()) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     const auto begin{std::next(program.blocks.begin())}; |     const auto begin{program.blocks.begin() + 1}; | ||||||
|     const auto end{program.blocks.end()}; |     const auto end{program.blocks.end()}; | ||||||
|     const auto pred{[](IR::Block* block) { return block->ImmediatePredecessors().empty(); }}; |     const auto pred{[](IR::Block* block) { return block->ImmediatePredecessors().empty(); }}; | ||||||
|     program.blocks.erase(std::remove_if(begin, end, pred), end); |     program.blocks.erase(std::remove_if(begin, end, pred), end); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user