From 29c24de8901db652b65fba9c45406fb879709df3 Mon Sep 17 00:00:00 2001 From: Ruben van Meerten Date: Tue, 23 Jul 2024 12:32:29 +0200 Subject: [PATCH] Renames the InitMemoryPass to FinalizeMemoryInfo, moves the addFunctions() from the linearMemoryHelper after the computing of constant offsets --- .../{MemoryInit.h => FinalizeMemoryInfo.h} | 2 +- llvm/include/llvm/Cheerp/LinearMemoryHelper.h | 7 +- llvm/lib/CheerpUtils/CMakeLists.txt | 2 +- llvm/lib/CheerpUtils/FinalizeMemoryInfo.cpp | 77 +++++++++++++++++++ llvm/lib/CheerpUtils/MemoryInit.cpp | 55 ------------- .../Target/WebAssembly/CheerpWritePass.cpp | 16 +--- 6 files changed, 86 insertions(+), 73 deletions(-) rename llvm/include/llvm/Cheerp/{MemoryInit.h => FinalizeMemoryInfo.h} (89%) create mode 100644 llvm/lib/CheerpUtils/FinalizeMemoryInfo.cpp delete mode 100644 llvm/lib/CheerpUtils/MemoryInit.cpp diff --git a/llvm/include/llvm/Cheerp/MemoryInit.h b/llvm/include/llvm/Cheerp/FinalizeMemoryInfo.h similarity index 89% rename from llvm/include/llvm/Cheerp/MemoryInit.h rename to llvm/include/llvm/Cheerp/FinalizeMemoryInfo.h index e67afec22dd2..d3309cc0ecb3 100644 --- a/llvm/include/llvm/Cheerp/MemoryInit.h +++ b/llvm/include/llvm/Cheerp/FinalizeMemoryInfo.h @@ -19,7 +19,7 @@ namespace cheerp using namespace llvm; -class MemoryInitPass : public PassInfoMixin { +class FinalizeMemoryInfoPass : public PassInfoMixin { private: public: diff --git a/llvm/include/llvm/Cheerp/LinearMemoryHelper.h b/llvm/include/llvm/Cheerp/LinearMemoryHelper.h index 95a68beeab7e..a1388e04e5e0 100644 --- a/llvm/include/llvm/Cheerp/LinearMemoryHelper.h +++ b/llvm/include/llvm/Cheerp/LinearMemoryHelper.h @@ -198,16 +198,17 @@ class LinearMemoryHelper this->module = &module; globalDeps = GDA; builtinIds.fill(std::numeric_limits::max()); - addFunctions(); addStack(); addGlobals(); checkMemorySize(); addMemoryInfo(); - populateGlobalData(); return false; } + void addFunctions(); + void populateGlobalData(); + uint32_t getGlobalVariableAddress(const llvm::GlobalVariable* G) const; const llvm::GlobalVariable* getGlobalVariableFromAddress(llvm::Value* C) const; uint32_t getFunctionAddress(const llvm::Function* F) const; @@ -392,11 +393,9 @@ class LinearMemoryHelper void setGlobalPtrIfPresent(llvm::StringRef name, uint32_t ptr); void addGlobals(); - void addFunctions(); void addStack(); void addMemoryInfo(); void checkMemorySize(); - void populateGlobalData(); llvm::Module* module; GlobalDepsAnalyzer* globalDeps; diff --git a/llvm/lib/CheerpUtils/CMakeLists.txt b/llvm/lib/CheerpUtils/CMakeLists.txt index 1df346213e4c..c98f81d57803 100644 --- a/llvm/lib/CheerpUtils/CMakeLists.txt +++ b/llvm/lib/CheerpUtils/CMakeLists.txt @@ -32,7 +32,7 @@ add_llvm_component_library(LLVMCheerpUtils SIMDTransform.cpp BitCastLowering.cpp JSStringLiteralLowering.cpp - MemoryInit.cpp + FinalizeMemoryInfo.cpp CheerpLowerAtomic.cpp JsExport.cpp ) diff --git a/llvm/lib/CheerpUtils/FinalizeMemoryInfo.cpp b/llvm/lib/CheerpUtils/FinalizeMemoryInfo.cpp new file mode 100644 index 000000000000..b66301298d34 --- /dev/null +++ b/llvm/lib/CheerpUtils/FinalizeMemoryInfo.cpp @@ -0,0 +1,77 @@ +//===-- MemoryInit.cpp - Populate the __memory_init function with init intrinsics------===// +// +// Cheerp: The C++ compiler for the Web +// +// This file is distributed under the Apache License v2.0 with LLVM Exceptions. +// See LICENSE.TXT for details. +// +// Copyright 2022-2023 Leaning Technologies +// +//===----------------------------------------------------------------------===// + +#include "llvm/Cheerp/FinalizeMemoryInfo.h" +#include "llvm/Cheerp/LinearMemoryHelper.h" +#include "llvm/Cheerp/AllocaMerging.h" +#include "llvm/Cheerp/Registerize.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Intrinsics.h" + +using namespace llvm; + +namespace cheerp +{ + +PreservedAnalyses FinalizeMemoryInfoPass::run(Module& M, ModuleAnalysisManager& MAM) +{ + PointerAnalyzer &PA = MAM.getResult(M); + Registerize ®isterize = MAM.getResult(M); + LinearMemoryHelper &linearHelper = MAM.getResult(M); + AllocaStoresExtractor &allocaStoresExtractor = MAM.getResult(M); + + PA.fullResolve(); + PA.computeConstantOffsets(M); + linearHelper.addFunctions(); + linearHelper.populateGlobalData(); + + if (LinearOutput == LinearOutputTy::Wasm) + { + Function* initFunc = M.getFunction("__memory_init"); + if (!initFunc) + { + // We print a warning and return. This is to satisfy some llvm tests. + llvm::errs() << "warning: __memory_init function point not found\n"; + return PreservedAnalyses::all(); + } + if (!initFunc->empty()) + llvm::report_fatal_error("__memory_init function already has a body."); + + BasicBlock* Entry = BasicBlock::Create(M.getContext(), "entry", initFunc); + IRBuilder<> Builder(Entry); + + // Loop over the chunks and populate the function. + Function* memoryInit = Intrinsic::getDeclaration(&M, Intrinsic::cheerp_memory_init); + Function* dataDrop = Intrinsic::getDeclaration(&M, Intrinsic::cheerp_data_drop); + + uint32_t amountOfChunks = linearHelper.getAmountChunks(); + for (uint32_t i = 0; i < amountOfChunks; i++) + { + auto chunk = linearHelper.getGlobalDataChunk(i); + Builder.CreateCall(memoryInit, {Builder.getInt32(i), Builder.getInt32(chunk.address), Builder.getInt32(0), Builder.getInt32(chunk.view.size())}); + Builder.CreateCall(dataDrop, {Builder.getInt32(i)}); + } + + Builder.CreateRetVoid(); + } + + // Destroy the stores here, we need them to properly compute the pointer kinds, but we want to optimize them away before registerize + allocaStoresExtractor.unlinkStores(); + + registerize.assignRegisters(M, PA); + #ifdef REGISTERIZE_STATS + cheerp::reportRegisterizeStatistics(); + #endif + + return PreservedAnalyses::all(); +} + +} diff --git a/llvm/lib/CheerpUtils/MemoryInit.cpp b/llvm/lib/CheerpUtils/MemoryInit.cpp deleted file mode 100644 index ea75f6244128..000000000000 --- a/llvm/lib/CheerpUtils/MemoryInit.cpp +++ /dev/null @@ -1,55 +0,0 @@ -//===-- MemoryInit.cpp - Populate the __memory_init function with init intrinsics------===// -// -// Cheerp: The C++ compiler for the Web -// -// This file is distributed under the Apache License v2.0 with LLVM Exceptions. -// See LICENSE.TXT for details. -// -// Copyright 2022-2023 Leaning Technologies -// -//===----------------------------------------------------------------------===// - -#include "llvm/Cheerp/MemoryInit.h" -#include "llvm/Cheerp/LinearMemoryHelper.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Intrinsics.h" - -using namespace llvm; - -namespace cheerp -{ - -PreservedAnalyses MemoryInitPass::run(Module& M, ModuleAnalysisManager& MAM) -{ - cheerp::LinearMemoryHelper& linearHelper = MAM.getResult(M); - - Function* initFunc = M.getFunction("__memory_init"); - if (!initFunc) - { - // We print a warning and return. This is to satisfy some llvm tests. - llvm::errs() << "warning: __memory_init function point not found\n"; - return PreservedAnalyses::all(); - } - if (!initFunc->empty()) - llvm::report_fatal_error("__memory_init function already has a body."); - - BasicBlock* Entry = BasicBlock::Create(M.getContext(), "entry", initFunc); - IRBuilder<> Builder(Entry); - - // Loop over the chunks and populate the function. - Function* memoryInit = Intrinsic::getDeclaration(&M, Intrinsic::cheerp_memory_init); - Function* dataDrop = Intrinsic::getDeclaration(&M, Intrinsic::cheerp_data_drop); - - uint32_t amountOfChunks = linearHelper.getAmountChunks(); - for (uint32_t i = 0; i < amountOfChunks; i++) - { - auto chunk = linearHelper.getGlobalDataChunk(i); - Builder.CreateCall(memoryInit, {Builder.getInt32(i), Builder.getInt32(chunk.address), Builder.getInt32(0), Builder.getInt32(chunk.view.size())}); - Builder.CreateCall(dataDrop, {Builder.getInt32(i)}); - } - - Builder.CreateRetVoid(); - return PreservedAnalyses::all(); -} - -} diff --git a/llvm/lib/Target/WebAssembly/CheerpWritePass.cpp b/llvm/lib/Target/WebAssembly/CheerpWritePass.cpp index a11c7bcfca12..cdf6f79b5080 100644 --- a/llvm/lib/Target/WebAssembly/CheerpWritePass.cpp +++ b/llvm/lib/Target/WebAssembly/CheerpWritePass.cpp @@ -14,7 +14,7 @@ #include "llvm/Cheerp/DTSWriter.h" #include "llvm/Cheerp/I64Lowering.h" #include "llvm/Cheerp/JSStringLiteralLowering.h" -#include "llvm/Cheerp/MemoryInit.h" +#include "llvm/Cheerp/FinalizeMemoryInfo.h" #include "llvm/Cheerp/PassRegistry.h" #include "llvm/Cheerp/PassUtility.h" #include "llvm/Cheerp/SIMDLowering.h" @@ -60,15 +60,6 @@ PreservedAnalyses cheerp::CheerpWritePassImpl::run(Module& M, ModuleAnalysisMana return PreservedAnalyses::none(); } } - PA.fullResolve(); - PA.computeConstantOffsets(M); - // Destroy the stores here, we need them to properly compute the pointer kinds, but we want to optimize them away before registerize - allocaStoresExtractor.unlinkStores(); - - registerize.assignRegisters(M, PA); -#ifdef REGISTERIZE_STATS - cheerp::reportRegisterizeStatistics(); -#endif Triple TargetTriple(M.getTargetTriple()); bool WasmOnly = TargetTriple.getOS() == Triple::WASI; @@ -261,8 +252,6 @@ bool CheerpWritePass::runOnModule(Module& M) MPM.addPass(createModuleToFunctionPassAdaptor(cheerp::PreserveCheerpAnalysisPassWrapper())); MPM.addPass(cheerp::RegisterizePass(!NoJavaScriptMathFround, LinearOutput == Wasm)); MPM.addPass(cheerp::LinearMemoryHelperPass(cheerp::LinearMemoryHelperInitializer({functionAddressMode, CheerpHeapSize, CheerpStackSize, CheerpStackOffset, growMem, hasAsmjsMem}))); - if (LinearOutput == LinearOutputTy::Wasm) - MPM.addPass(cheerp::MemoryInitPass()); MPM.addPass(cheerp::ConstantExprLoweringPass()); MPM.addPass(cheerp::PointerAnalyzerPass()); MPM.addPass(cheerp::DelayInstsPass()); @@ -275,6 +264,9 @@ bool CheerpWritePass::runOnModule(Module& M) // Keep this pass last, it is going to remove stores to memory from the LLVM visible code, so further optimizing afterwards will break MPM.addPass(cheerp::AllocaStoresExtractorPass()); + // This pass needs to be ran after the AllocaStoresExtractorPass and does not do any optimizing. + MPM.addPass(cheerp::FinalizeMemoryInfoPass()); + MPM.addPass(cheerp::CheerpWritePassImpl(Out, TM)); // Now that we have all the passes ready, run them.