From e7c6045a03584ac5cd93e9030cdf4f47867f9ee3 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 27 Jun 2019 09:24:40 -0400 Subject: [PATCH] control_flow: Correct block breaking algorithm. --- src/video_core/shader/control_flow.cpp | 34 +++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp index bdf9d4dd4..fdcc970ff 100644 --- a/src/video_core/shader/control_flow.cpp +++ b/src/video_core/shader/control_flow.cpp @@ -75,19 +75,17 @@ struct CFGRebuildState { enum class BlockCollision : u32 { None, Found, Inside }; -std::pair::iterator> TryGetBlock(CFGRebuildState& state, - u32 address) { - auto it = state.block_info.begin(); - while (it != state.block_info.end()) { - if (it->start == address) { - return {BlockCollision::Found, it}; +std::pair TryGetBlock(CFGRebuildState& state, u32 address) { + const auto& blocks = state.block_info; + for (u32 index = 0; index < blocks.size(); index++) { + if (blocks[index].start == address) { + return {BlockCollision::Found, index}; } - if (it->IsInside(address)) { - return {BlockCollision::Inside, it}; + if (blocks[index].IsInside(address)) { + return {BlockCollision::Inside, index}; } - it++; } - return {BlockCollision::None, it}; + return {BlockCollision::None, -1}; } struct ParseInfo { @@ -318,24 +316,26 @@ bool TryInspectAddress(CFGRebuildState& state) { if (state.inspect_queries.empty()) { return false; } + const u32 address = state.inspect_queries.front(); state.inspect_queries.pop_front(); - const auto search_result = TryGetBlock(state, address); - switch (search_result.first) { + const auto [result, block_index] = TryGetBlock(state, address); + switch (result) { case BlockCollision::Found: { return true; } case BlockCollision::Inside: { // This case is the tricky one: // We need to Split the block in 2 sepparate blocks - const auto it = search_result.second; - BlockInfo& block_info = CreateBlockInfo(state, address, it->end); - it->end = address - 1; - block_info.branch = it->branch; + const u32 end = state.block_info[block_index].end; + BlockInfo& new_block = CreateBlockInfo(state, address, end); + BlockInfo& current_block = state.block_info[block_index]; + current_block.end = address - 1; + new_block.branch = current_block.branch; BlockBranchInfo forward_branch{}; forward_branch.address = address; forward_branch.ignore = true; - it->branch = forward_branch; + current_block.branch = forward_branch; return true; } default: