forked from suyu/suyu
video_core/control_flow: Use std::move where applicable
Results in less work being done where avoidable.
This commit is contained in:
parent
e7b39f47f8
commit
56bc11d952
1 changed files with 15 additions and 10 deletions
|
@ -371,10 +371,11 @@ bool TryQuery(CFGRebuildState& state) {
|
||||||
if (state.queries.empty()) {
|
if (state.queries.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Query& q = state.queries.front();
|
Query& q = state.queries.front();
|
||||||
const u32 block_index = state.registered[q.address];
|
const u32 block_index = state.registered[q.address];
|
||||||
BlockInfo& block = state.block_info[block_index];
|
BlockInfo& block = state.block_info[block_index];
|
||||||
// If the block is visted, check if the stacks match, else gather the ssy/pbk
|
// If the block is visited, check if the stacks match, else gather the ssy/pbk
|
||||||
// labels into the current stack and look if the branch at the end of the block
|
// labels into the current stack and look if the branch at the end of the block
|
||||||
// consumes a label. Schedule new queries accordingly
|
// consumes a label. Schedule new queries accordingly
|
||||||
if (block.visited) {
|
if (block.visited) {
|
||||||
|
@ -385,7 +386,8 @@ bool TryQuery(CFGRebuildState& state) {
|
||||||
return all_okay;
|
return all_okay;
|
||||||
}
|
}
|
||||||
block.visited = true;
|
block.visited = true;
|
||||||
state.stacks[q.address] = BlockStack{q};
|
state.stacks.insert_or_assign(q.address, BlockStack{q});
|
||||||
|
|
||||||
Query q2(q);
|
Query q2(q);
|
||||||
state.queries.pop_front();
|
state.queries.pop_front();
|
||||||
gather_labels(q2.ssy_stack, state.ssy_labels, block);
|
gather_labels(q2.ssy_stack, state.ssy_labels, block);
|
||||||
|
@ -394,6 +396,7 @@ bool TryQuery(CFGRebuildState& state) {
|
||||||
q2.address = block.end + 1;
|
q2.address = block.end + 1;
|
||||||
state.queries.push_back(q2);
|
state.queries.push_back(q2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Query conditional_query{q2};
|
Query conditional_query{q2};
|
||||||
if (block.branch.is_sync) {
|
if (block.branch.is_sync) {
|
||||||
if (block.branch.address == unassigned_branch) {
|
if (block.branch.address == unassigned_branch) {
|
||||||
|
@ -408,7 +411,7 @@ bool TryQuery(CFGRebuildState& state) {
|
||||||
conditional_query.pbk_stack.pop();
|
conditional_query.pbk_stack.pop();
|
||||||
}
|
}
|
||||||
conditional_query.address = block.branch.address;
|
conditional_query.address = block.branch.address;
|
||||||
state.queries.push_back(conditional_query);
|
state.queries.push_back(std::move(conditional_query));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
@ -416,6 +419,7 @@ bool TryQuery(CFGRebuildState& state) {
|
||||||
std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
|
std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
|
||||||
std::size_t program_size, u32 start_address) {
|
std::size_t program_size, u32 start_address) {
|
||||||
CFGRebuildState state{program_code, program_size, start_address};
|
CFGRebuildState state{program_code, program_size, start_address};
|
||||||
|
|
||||||
// Inspect Code and generate blocks
|
// Inspect Code and generate blocks
|
||||||
state.labels.clear();
|
state.labels.clear();
|
||||||
state.labels.emplace(start_address);
|
state.labels.emplace(start_address);
|
||||||
|
@ -425,10 +429,9 @@ std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decompile Stacks
|
// Decompile Stacks
|
||||||
Query start_query{};
|
state.queries.push_back(Query{state.start, {}, {}});
|
||||||
start_query.address = state.start;
|
|
||||||
state.queries.push_back(start_query);
|
|
||||||
bool decompiled = true;
|
bool decompiled = true;
|
||||||
while (!state.queries.empty()) {
|
while (!state.queries.empty()) {
|
||||||
if (!TryQuery(state)) {
|
if (!TryQuery(state)) {
|
||||||
|
@ -436,14 +439,15 @@ std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort and organize results
|
// Sort and organize results
|
||||||
std::sort(state.block_info.begin(), state.block_info.end(),
|
std::sort(state.block_info.begin(), state.block_info.end(),
|
||||||
[](const BlockInfo& a, const BlockInfo& b) -> bool { return a.start < b.start; });
|
[](const BlockInfo& a, const BlockInfo& b) { return a.start < b.start; });
|
||||||
ShaderCharacteristics result_out{};
|
ShaderCharacteristics result_out{};
|
||||||
result_out.decompilable = decompiled;
|
result_out.decompilable = decompiled;
|
||||||
result_out.start = start_address;
|
result_out.start = start_address;
|
||||||
result_out.end = start_address;
|
result_out.end = start_address;
|
||||||
for (auto& block : state.block_info) {
|
for (const auto& block : state.block_info) {
|
||||||
ShaderBlock new_block{};
|
ShaderBlock new_block{};
|
||||||
new_block.start = block.start;
|
new_block.start = block.start;
|
||||||
new_block.end = block.end;
|
new_block.end = block.end;
|
||||||
|
@ -458,8 +462,9 @@ std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
|
||||||
}
|
}
|
||||||
if (result_out.decompilable) {
|
if (result_out.decompilable) {
|
||||||
result_out.labels = std::move(state.labels);
|
result_out.labels = std::move(state.labels);
|
||||||
return {result_out};
|
return {std::move(result_out)};
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's not decompilable, merge the unlabelled blocks together
|
// If it's not decompilable, merge the unlabelled blocks together
|
||||||
auto back = result_out.blocks.begin();
|
auto back = result_out.blocks.begin();
|
||||||
auto next = std::next(back);
|
auto next = std::next(back);
|
||||||
|
@ -472,6 +477,6 @@ std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
|
||||||
back = next;
|
back = next;
|
||||||
++next;
|
++next;
|
||||||
}
|
}
|
||||||
return {result_out};
|
return {std::move(result_out)};
|
||||||
}
|
}
|
||||||
} // namespace VideoCommon::Shader
|
} // namespace VideoCommon::Shader
|
||||||
|
|
Loading…
Reference in a new issue