From e7c6045a03584ac5cd93e9030cdf4f47867f9ee3 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow <fsahmkow27@gmail.com>
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 bdf9d4dd43..fdcc970ff8 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<BlockCollision, std::vector<BlockInfo>::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<BlockCollision, u32> 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:
-- 
GitLab