diff options
-rw-r--r-- | llvm/include/llvm/InitializePasses.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/Transforms/IPO/MergeFunctions.h | 32 | ||||
-rw-r--r-- | llvm/lib/Passes/PassBuilder.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Passes/PassRegistry.def | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/IPO.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/MergeFunctions.cpp | 47 | ||||
-rw-r--r-- | llvm/test/Transforms/MergeFunc/merge-block-address.ll | 1 |
7 files changed, 70 insertions, 16 deletions
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 831c6882b4a..a5e1310e28b 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -288,7 +288,7 @@ void initializeMemoryDependenceWrapperPassPass(PassRegistry&); void initializeMemorySSAPrinterLegacyPassPass(PassRegistry&); void initializeMemorySSAWrapperPassPass(PassRegistry&); void initializeMemorySanitizerLegacyPassPass(PassRegistry&); -void initializeMergeFunctionsPass(PassRegistry&); +void initializeMergeFunctionsLegacyPassPass(PassRegistry&); void initializeMergeICmpsLegacyPassPass(PassRegistry &); void initializeMergedLoadStoreMotionLegacyPassPass(PassRegistry&); void initializeMetaRenamerPass(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/IPO/MergeFunctions.h b/llvm/include/llvm/Transforms/IPO/MergeFunctions.h new file mode 100644 index 00000000000..822f0fd9918 --- /dev/null +++ b/llvm/include/llvm/Transforms/IPO/MergeFunctions.h @@ -0,0 +1,32 @@ +//===- MergeFunctions.h - Merge Identical Functions -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This pass transforms simple global variables that never have their address +// taken. If obviously true, it marks read/write globals as constant, deletes +// variables only stored to, etc. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_IPO_MERGEFUNCTIONS_H +#define LLVM_TRANSFORMS_IPO_MERGEFUNCTIONS_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class Module; + +/// Merge identical functions. +class MergeFunctionsPass : public PassInfoMixin<MergeFunctionsPass> { +public: + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); +}; + +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_IPO_MERGEFUNCTIONS_H diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index b05ee0537eb..53b7db8689c 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -86,6 +86,7 @@ #include "llvm/Transforms/IPO/Inliner.h" #include "llvm/Transforms/IPO/Internalize.h" #include "llvm/Transforms/IPO/LowerTypeTests.h" +#include "llvm/Transforms/IPO/MergeFunctions.h" #include "llvm/Transforms/IPO/PartialInlining.h" #include "llvm/Transforms/IPO/SCCP.h" #include "llvm/Transforms/IPO/SampleProfile.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 3efb57cd358..355dd6f9681 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -64,6 +64,7 @@ MODULE_PASS("internalize", InternalizePass()) MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass()) MODULE_PASS("ipsccp", IPSCCPPass()) MODULE_PASS("lowertypetests", LowerTypeTestsPass(nullptr, nullptr)) +MODULE_PASS("mergefunc", MergeFunctionsPass()) MODULE_PASS("name-anon-globals", NameAnonGlobalPass()) MODULE_PASS("no-op-module", NoOpModulePass()) MODULE_PASS("partial-inliner", PartialInlinerPass()) diff --git a/llvm/lib/Transforms/IPO/IPO.cpp b/llvm/lib/Transforms/IPO/IPO.cpp index bddf7521159..8a15800cbdb 100644 --- a/llvm/lib/Transforms/IPO/IPO.cpp +++ b/llvm/lib/Transforms/IPO/IPO.cpp @@ -43,7 +43,7 @@ void llvm::initializeIPO(PassRegistry &Registry) { initializeBlockExtractorPass(Registry); initializeSingleLoopExtractorPass(Registry); initializeLowerTypeTestsPass(Registry); - initializeMergeFunctionsPass(Registry); + initializeMergeFunctionsLegacyPassPass(Registry); initializePartialInlinerLegacyPassPass(Registry); initializeAttributorLegacyPassPass(Registry); initializePostOrderFunctionAttrsLegacyPassPass(Registry); diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp index a702de03e46..06d2a2f3194 100644 --- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp +++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp @@ -122,6 +122,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/MergeFunctions.h" #include "llvm/Transforms/Utils/FunctionComparator.h" #include <algorithm> #include <cassert> @@ -196,16 +197,12 @@ public: /// by considering all pointer types to be equivalent. Once identified, /// MergeFunctions will fold them by replacing a call to one to a call to a /// bitcast of the other. -class MergeFunctions : public ModulePass { +class MergeFunctions { public: - static char ID; - - MergeFunctions() - : ModulePass(ID), FnTree(FunctionNodeCmp(&GlobalNumbers)) { - initializeMergeFunctionsPass(*PassRegistry::getPassRegistry()); + MergeFunctions() : FnTree(FunctionNodeCmp(&GlobalNumbers)) { } - bool runOnModule(Module &M) override; + bool runOnModule(Module &M); private: // The function comparison operator is provided here so that FunctionNodes do @@ -298,14 +295,39 @@ private: DenseMap<AssertingVH<Function>, FnTreeType::iterator> FNodesInTree; }; -} // end anonymous namespace +class MergeFunctionsLegacyPass : public ModulePass { +public: + static char ID; -char MergeFunctions::ID = 0; + MergeFunctionsLegacyPass(): ModulePass(ID) { + initializeMergeFunctionsLegacyPassPass(*PassRegistry::getPassRegistry()); + } -INITIALIZE_PASS(MergeFunctions, "mergefunc", "Merge Functions", false, false) + bool runOnModule(Module &M) override { + if (skipModule(M)) + return false; + + MergeFunctions MF; + return MF.runOnModule(M); + } +}; + +} // end anonymous namespace + +char MergeFunctionsLegacyPass::ID = 0; +INITIALIZE_PASS(MergeFunctionsLegacyPass, "mergefunc", + "Merge Functions", false, false) ModulePass *llvm::createMergeFunctionsPass() { - return new MergeFunctions(); + return new MergeFunctionsLegacyPass(); +} + +PreservedAnalyses MergeFunctionsPass::run(Module &M, + ModuleAnalysisManager &AM) { + MergeFunctions MF; + if (!MF.runOnModule(M)) + return PreservedAnalyses::all(); + return PreservedAnalyses::none(); } #ifndef NDEBUG @@ -387,9 +409,6 @@ static bool isEligibleForMerging(Function &F) { } bool MergeFunctions::runOnModule(Module &M) { - if (skipModule(M)) - return false; - bool Changed = false; // All functions in the module, ordered by hash. Functions with a unique diff --git a/llvm/test/Transforms/MergeFunc/merge-block-address.ll b/llvm/test/Transforms/MergeFunc/merge-block-address.ll index 4ce13e5da87..d2340a77caf 100644 --- a/llvm/test/Transforms/MergeFunc/merge-block-address.ll +++ b/llvm/test/Transforms/MergeFunc/merge-block-address.ll @@ -1,4 +1,5 @@ ; RUN: opt -S -mergefunc < %s | FileCheck %s +; RUN: opt -S -passes=mergefunc < %s | FileCheck %s ; These two functions are identical. The basic block labels are the same, and ; induce the same CFG. We are testing that block addresses within different |