shader: Fix splits on blocks using indirect branches
This commit is contained in:
parent
ffca21487f
commit
9e6fe430bd
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue