From 3cc627a2e7b5ac92720bff9c05f3f3038030cd98 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 2 Oct 2024 11:46:56 -0400 Subject: [PATCH] ConstProp: don't pool with a hash table hash tables have high overhead! but individual blocks are small, so the quadratic search is _much_ faster in practice. knocks 8% off node. Signed-off-by: Alyssa Rosenzweig --- .../Source/Interface/IR/Passes/ConstProp.cpp | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp b/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp index 8cfe155709..5e01f845d2 100644 --- a/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp +++ b/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp @@ -75,8 +75,6 @@ class ConstProp final : public FEXCore::IR::Pass { void HandleConstantPools(IREmitter* IREmit, const IRListView& CurrentIR); void ConstantPropagation(IREmitter* IREmit, const IRListView& CurrentIR, Ref CodeNode, IROp_Header* IROp); - fextl::unordered_map ConstPool; - bool SupportsTSOImm9 {}; const FEXCore::CPUIDEmu* CPUID; @@ -144,23 +142,42 @@ void ConstProp::HandleConstantPools(IREmitter* IREmit, const IRListView& Current // don't have constants leftover after all inlining. fextl::vector Remap {}; + struct Entry { + int64_t Value; + Ref R; + }; + + + fextl::vector Pool {}; + for (auto [BlockNode, BlockIROp] : CurrentIR.GetBlocks()) { + Pool.clear(); + for (auto [CodeNode, IROp] : CurrentIR.GetCode(BlockNode)) { if (IROp->Op == OP_CONSTANT) { auto Op = IROp->C(); - auto it = ConstPool.find(Op->Constant); - - if (it != ConstPool.end()) { - uint32_t Value = CurrentIR.GetID(CodeNode).Value; - LOGMAN_THROW_A_FMT(Value < SSACount, "def not yet remapped"); - - if (Remap.empty()) { - Remap.resize(SSACount, NULL); + bool Found = false; + + // Search for the constant. This is O(n^2) but n is small since it's + // local and most constants are inlined. In practice, it ends up much + // faster than a hash table. + for (auto K : Pool) { + if (K.Value == Op->Constant) { + uint32_t Value = CurrentIR.GetID(CodeNode).Value; + LOGMAN_THROW_A_FMT(Value < SSACount, "def not yet remapped"); + + if (Remap.empty()) { + Remap.resize(SSACount, NULL); + } + + Remap[Value] = K.R; + Found = true; + break; } + } - Remap[Value] = it->second; - } else { - ConstPool[Op->Constant] = CodeNode; + if (!Found) { + Pool.push_back({.Value = Op->Constant, .R = CodeNode}); } } else if (!Remap.empty()) { const uint8_t NumArgs = IR::GetArgs(IROp->Op); @@ -179,7 +196,6 @@ void ConstProp::HandleConstantPools(IREmitter* IREmit, const IRListView& Current } } } - ConstPool.clear(); } }