shader: Fix indirect branches to scheduler instructions

This commit is contained in:
ReinUsesLisp 2021-03-29 22:13:37 -03:00 committed by ameerj
parent 55b960a20f
commit b0d5572abf
3 changed files with 17 additions and 7 deletions

View file

@ -434,7 +434,10 @@ CFG::AnalysisState CFG::AnalyzeBRX(Block* block, Location pc, Instruction inst,
block->indirect_branches.reserve(targets.size()); block->indirect_branches.reserve(targets.size());
for (const u32 target : targets) { for (const u32 target : targets) {
Block* const branch{AddLabel(block, block->stack, target, function_id)}; 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->cond = IR::Condition{true};
block->end = pc + 1; block->end = pc + 1;
@ -530,8 +533,8 @@ std::string CFG::Dot() const {
} }
break; break;
case EndClass::IndirectBranch: case EndClass::IndirectBranch:
for (Block* const branch : block.indirect_branches) { for (const IndirectBranch& branch : block.indirect_branches) {
add_branch(branch, false); add_branch(branch.block, false);
} }
break; break;
case EndClass::Call: case EndClass::Call:

View file

@ -22,6 +22,8 @@
namespace Shader::Maxwell::Flow { namespace Shader::Maxwell::Flow {
struct Block;
using FunctionId = size_t; using FunctionId = size_t;
enum class EndClass { enum class EndClass {
@ -60,6 +62,11 @@ private:
boost::container::small_vector<StackEntry, 3> entries; boost::container::small_vector<StackEntry, 3> entries;
}; };
struct IndirectBranch {
Block* block;
u32 address;
};
struct Block : boost::intrusive::set_base_hook< struct Block : boost::intrusive::set_base_hook<
// Normal link is ~2.5% faster compared to safe link // Normal link is ~2.5% faster compared to safe link
boost::intrusive::link_mode<boost::intrusive::normal_link>> { boost::intrusive::link_mode<boost::intrusive::normal_link>> {
@ -84,7 +91,7 @@ struct Block : boost::intrusive::set_base_hook<
Block* return_block; Block* return_block;
s32 branch_offset; s32 branch_offset;
}; };
std::vector<Block*> indirect_branches; std::vector<IndirectBranch> indirect_branches;
}; };
struct Label { struct Label {

View file

@ -446,9 +446,9 @@ private:
case Flow::EndClass::IndirectBranch: case Flow::EndClass::IndirectBranch:
root.insert(ip, *pool.Create(SetIndirectBranchVariable{}, block.branch_reg, root.insert(ip, *pool.Create(SetIndirectBranchVariable{}, block.branch_reg,
block.branch_offset)); block.branch_offset));
for (Flow::Block* const branch : block.indirect_branches) { for (const Flow::IndirectBranch& indirect : block.indirect_branches) {
const Node indirect_label{local_labels.at(branch)}; const Node indirect_label{local_labels.at(indirect.block)};
Statement* cond{pool.Create(IndirectBranchCond{}, branch->begin.Offset())}; Statement* cond{pool.Create(IndirectBranchCond{}, indirect.address)};
Statement* goto_stmt{pool.Create(Goto{}, cond, indirect_label, &root_stmt)}; Statement* goto_stmt{pool.Create(Goto{}, cond, indirect_label, &root_stmt)};
gotos.push_back(root.insert(ip, *goto_stmt)); gotos.push_back(root.insert(ip, *goto_stmt));
} }