diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-11-01 15:19:47 -0500 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-11-01 15:19:47 -0500 |
| commit | e23b0f2fab9014225486beebd82fab8dbc0fe14c (patch) | |
| tree | 3297c6c501f02851387fa8dc64b8f6e2760a1521 /src/shader_recompiler/ir_opt/texture_pass.cpp | |
| parent | 561f87abec2f76b3ca40c59277752ed4d3b6bf16 (diff) | |
shader: keep the handle slot map thread-local instead of a pointer to it
BuildHandleProgram stored the address of its outermost call's local map
in a thread_local pointer for the nested calls, which GCC 15 rejects
with -Werror=dangling-pointer. The map itself is thread_local now, and
a depth counter tells the outermost call to clear it.
Diffstat (limited to 'src/shader_recompiler/ir_opt/texture_pass.cpp')
| -rw-r--r-- | src/shader_recompiler/ir_opt/texture_pass.cpp | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index f413cf108a..8a72f565dc 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp @@ -436,8 +436,10 @@ bool IsUndefined(IR::Opcode opcode) { opcode == IR::Opcode::UndefU64; } -// Values already emitted by the program being built, by the slot that keeps them. -thread_local std::unordered_map<const IR::Inst*, u32>* g_handle_slots{}; +// Values already emitted by the program being built, by the slot that keeps them, and how deep +// in nested BuildHandleProgram calls the build is. +thread_local std::unordered_map<const IR::Inst*, u32> g_handle_slots; +thread_local int g_handle_depth{}; bool BuildHandleNode(const IR::Value& value, std::vector<u32>& code, int& budget, const IR::Block* block); @@ -448,14 +450,13 @@ bool BuildHandleProgram(const IR::Value& value, std::vector<u32>& code, int& bud if (value.IsImmediate()) { return BuildHandleNode(value, code, budget, block); } - std::unordered_map<const IR::Inst*, u32> local_slots; - const bool outermost = g_handle_slots == nullptr; + const bool outermost = g_handle_depth++ == 0; if (outermost) { - g_handle_slots = &local_slots; + g_handle_slots.clear(); } const IR::Inst* const inst{value.InstRecursive()}; bool result; - if (const auto it = g_handle_slots->find(inst); it != g_handle_slots->end()) { + if (const auto it = g_handle_slots.find(inst); it != g_handle_slots.end()) { if (it->second == ~0U) { // Reached again while building it: a loop carries the value, which no single // evaluation can give. @@ -467,23 +468,24 @@ bool BuildHandleProgram(const IR::Value& value, std::vector<u32>& code, int& bud result = true; } } else { - g_handle_slots->emplace(inst, ~0U); + g_handle_slots.emplace(inst, ~0U); const size_t start = code.size(); result = BuildHandleNode(value, code, budget, block); - g_handle_slots->erase(inst); + g_handle_slots.erase(inst); if (!result) { code.resize(start); } - if (result && inst->UseCount() > 1 && g_handle_slots->size() < 256) { + if (result && inst->UseCount() > 1 && g_handle_slots.size() < 256) { const u32 slot = static_cast<u32>( - std::ranges::count_if(*g_handle_slots, [](const auto& entry) { return entry.second != ~0U; })); - g_handle_slots->emplace(inst, slot); + std::ranges::count_if(g_handle_slots, [](const auto& entry) { return entry.second != ~0U; })); + g_handle_slots.emplace(inst, slot); code.push_back(static_cast<u32>(Op::Tee)); code.push_back(slot); } } + --g_handle_depth; if (outermost) { - g_handle_slots = nullptr; + g_handle_slots.clear(); } return result; } |
