3
0
Fork 0
forked from suyu/suyu

shader_ir: Remove unnecessary constructors and use optional for ScanFlow result

This commit is contained in:
Fernando Sahmkow 2019-06-25 20:40:38 -04:00 committed by FernandoS27
parent 01b21ee1e8
commit d45fed3030
3 changed files with 17 additions and 28 deletions

View file

@ -29,10 +29,6 @@ struct ControlStack {
std::array<u32, stack_fixed_size> stack{}; std::array<u32, stack_fixed_size> stack{};
u32 index{}; u32 index{};
ControlStack() {}
ControlStack(const ControlStack& cp) = default;
bool Compare(const ControlStack& cs) const { bool Compare(const ControlStack& cs) const {
if (index != cs.index) { if (index != cs.index) {
return false; return false;
@ -75,8 +71,6 @@ struct ControlStack {
}; };
struct Query { struct Query {
Query() {}
Query(const Query& q) = default;
u32 address{}; u32 address{};
ControlStack ssy_stack{}; ControlStack ssy_stack{};
ControlStack pbk_stack{}; ControlStack pbk_stack{};
@ -91,8 +85,6 @@ struct BlockStack {
}; };
struct BlockBranchInfo { struct BlockBranchInfo {
BlockBranchInfo() = default;
BlockBranchInfo(const BlockBranchInfo& b) = default;
Condition condition{}; Condition condition{};
s32 address{exit_branch}; s32 address{exit_branch};
bool kill{}; bool kill{};
@ -102,7 +94,6 @@ struct BlockBranchInfo {
}; };
struct BlockInfo { struct BlockInfo {
BlockInfo() = default;
u32 start{}; u32 start{};
u32 end{}; u32 end{};
bool visited{}; bool visited{};
@ -454,8 +445,8 @@ bool TryQuery(CFGRebuildState& state) {
return true; return true;
} }
bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_address, std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size,
ShaderCharacteristics& result_out) { u32 start_address) {
CFGRebuildState state{program_code, program_size}; CFGRebuildState state{program_code, program_size};
// Inspect Code and generate blocks // Inspect Code and generate blocks
state.labels.clear(); state.labels.clear();
@ -463,7 +454,7 @@ bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_addre
state.inspect_queries.push_back(start_address); state.inspect_queries.push_back(start_address);
while (!state.inspect_queries.empty()) { while (!state.inspect_queries.empty()) {
if (!TryInspectAddress(state)) { if (!TryInspectAddress(state)) {
return false; return {};
} }
} }
// Decompile Stacks // Decompile Stacks
@ -480,7 +471,7 @@ bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_addre
// 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) -> bool { return a.start < b.start; });
result_out.blocks.clear(); 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;
@ -499,7 +490,7 @@ bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_addre
} }
if (result_out.decompilable) { if (result_out.decompilable) {
result_out.labels = std::move(state.labels); result_out.labels = std::move(state.labels);
return true; return {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();
@ -513,6 +504,6 @@ bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_addre
back = next; back = next;
next++; next++;
} }
return true; return {result_out};
} }
} // namespace VideoCommon::Shader } // namespace VideoCommon::Shader

View file

@ -32,8 +32,6 @@ struct Condition {
}; };
struct ShaderBlock { struct ShaderBlock {
ShaderBlock() = default;
ShaderBlock(const ShaderBlock& sb) = default;
u32 start{}; u32 start{};
u32 end{}; u32 end{};
bool ignore_branch{}; bool ignore_branch{};
@ -44,7 +42,7 @@ struct ShaderBlock {
bool operator==(const Branch& b) const { bool operator==(const Branch& b) const {
return std::tie(cond, kills, address) == std::tie(b.cond, b.kills, b.address); return std::tie(cond, kills, address) == std::tie(b.cond, b.kills, b.address);
} }
} branch; } branch{};
bool operator==(const ShaderBlock& sb) const { bool operator==(const ShaderBlock& sb) const {
return std::tie(start, end, ignore_branch, branch) == return std::tie(start, end, ignore_branch, branch) ==
std::tie(sb.start, sb.end, sb.ignore_branch, sb.branch); std::tie(sb.start, sb.end, sb.ignore_branch, sb.branch);
@ -52,14 +50,14 @@ struct ShaderBlock {
}; };
struct ShaderCharacteristics { struct ShaderCharacteristics {
std::list<ShaderBlock> blocks; std::list<ShaderBlock> blocks{};
bool decompilable{}; bool decompilable{};
u32 start; u32 start{};
u32 end; u32 end{};
std::unordered_set<u32> labels{}; std::unordered_set<u32> labels{};
}; };
bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_address, std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size,
ShaderCharacteristics& result_out); u32 start_address);
} // namespace VideoCommon::Shader } // namespace VideoCommon::Shader

View file

@ -39,9 +39,9 @@ void ShaderIR::Decode() {
std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header));
disable_flow_stack = false; disable_flow_stack = false;
ShaderCharacteristics shader_info{}; const auto info = ScanFlow(program_code, program_code.size(), main_offset);
bool can_proceed = ScanFlow(program_code, program_code.size(), main_offset, shader_info); if (info) {
if (can_proceed) { const auto& shader_info = *info;
coverage_begin = shader_info.start; coverage_begin = shader_info.start;
coverage_end = shader_info.end; coverage_end = shader_info.end;
if (shader_info.decompilable) { if (shader_info.decompilable) {
@ -52,7 +52,7 @@ void ShaderIR::Decode() {
} }
basic_blocks.insert({label, nodes}); basic_blocks.insert({label, nodes});
}); });
std::list<ShaderBlock>& blocks = shader_info.blocks; const auto& blocks = shader_info.blocks;
NodeBlock current_block; NodeBlock current_block;
u32 current_label = exit_branch; u32 current_label = exit_branch;
for (auto& block : blocks) { for (auto& block : blocks) {
@ -82,7 +82,7 @@ void ShaderIR::Decode() {
// Now we need to deal with an undecompilable shader. We need to brute force // Now we need to deal with an undecompilable shader. We need to brute force
// a shader that captures every position. // a shader that captures every position.
coverage_begin = shader_info.start; coverage_begin = main_offset;
const u32 shader_end = static_cast<u32>(program_size / sizeof(u64)); const u32 shader_end = static_cast<u32>(program_size / sizeof(u64));
coverage_end = shader_end; coverage_end = shader_end;
for (u32 label = main_offset; label < shader_end; label++) { for (u32 label = main_offset; label < shader_end; label++) {