From f646e541d6ee93b40dcfd193042d7b5ececeb7c4 Mon Sep 17 00:00:00 2001 From: Dong Wang Date: Tue, 28 Nov 2023 13:56:01 +0800 Subject: [PATCH] Deduplicate constant data tables A constant data is assigned to different variables several times, then we will create multiple globalVariables, which causes the constant data is repeated in the .rodata section with different names. Like this: .rodata (size = 1344 bytes) __unnamed_3 (offset = 0 size = 448 hash = 0xB186021131D03E38) (offset = 0 size = 0 hash = 0x071E967D705FB008) 0:3F1FE7C0 3F0B1A4C 3F53F141 00000000 BE095BFF BF71E3A8 3F745048 00000000 32:3EC6833C BEDE978D 3F1520B0 00000000 3DF8572A BE45729B 3E693F29 00000000 ... __unnamed_2 (offset = 448 size = 448 hash = 0xB186021131D03E38) 448:3F1FE7C0 3F0B1A4C 3F53F141 00000000 BE095BFF BF71E3A8 3F745048 00000000 480:3EC6833C BEDE978D 3F1520B0 00000000 3DF8572A BE45729B 3E693F29 00000000 ... __unnamed_1 (offset = 896 size = 448 hash = 0xB186021131D03E38) 896:3F1FE7C0 3F0B1A4C 3F53F141 00000000 BE095BFF BF71E3A8 3F745048 00000000 928:3EC6833C BEDE978D 3F1520B0 00000000 3DF8572A BE45729B 3E693F29 00000000 ... For the globalVariable that the initialization values are the same, we should treat them as the same variable. --- llpc/lower/llpcSpirvLowerConstImmediateStore.cpp | 16 ++++++++++++---- llpc/lower/llpcSpirvLowerConstImmediateStore.h | 2 ++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/llpc/lower/llpcSpirvLowerConstImmediateStore.cpp b/llpc/lower/llpcSpirvLowerConstImmediateStore.cpp index a4fe78af1b..e9a5f5f05b 100644 --- a/llpc/lower/llpcSpirvLowerConstImmediateStore.cpp +++ b/llpc/lower/llpcSpirvLowerConstImmediateStore.cpp @@ -59,6 +59,7 @@ PreservedAnalyses SpirvLowerConstImmediateStore::run(Module &module, ModuleAnaly // Process "alloca" instructions to see if they can be optimized to a read-only global // variable. bool changed = false; + m_allocToGlobals.clear(); for (auto &func : module.functions()) { if (!func.empty()) { if (processAllocaInsts(&func)) @@ -222,10 +223,17 @@ bool SpirvLowerConstImmediateStore::tryProcessAlloca(AllocaInst *allocaInst) { } // Step 3: Create the global variable and replace the alloca - auto global = new GlobalVariable(*m_module, allocatedTy, - true, // isConstant - GlobalValue::InternalLinkage, initializer, "", nullptr, GlobalValue::NotThreadLocal, - SPIRAS_Constant); + GlobalVariable *global = nullptr; + auto iter = m_allocToGlobals.find(initializer); + if (iter == m_allocToGlobals.end()) { + global = new GlobalVariable(*m_module, allocatedTy, + true, // isConstant + GlobalValue::InternalLinkage, initializer, "", nullptr, GlobalValue::NotThreadLocal, + SPIRAS_Constant); + m_allocToGlobals[initializer] = global; + } else { + global = iter->second; + } global->takeName(allocaInst); for (Use &use : llvm::make_early_inc_range(allocaInst->uses())) diff --git a/llpc/lower/llpcSpirvLowerConstImmediateStore.h b/llpc/lower/llpcSpirvLowerConstImmediateStore.h index db38ce5b38..9dc51158c3 100644 --- a/llpc/lower/llpcSpirvLowerConstImmediateStore.h +++ b/llpc/lower/llpcSpirvLowerConstImmediateStore.h @@ -51,6 +51,8 @@ class SpirvLowerConstImmediateStore : public SpirvLower, public llvm::PassInfoMi private: bool processAllocaInsts(llvm::Function *func); bool tryProcessAlloca(llvm::AllocaInst *allocaInst); + + llvm::DenseMap m_allocToGlobals; }; } // namespace Llpc