diff --git a/llvm/include/llvm/CodeGen/PassManager.h b/llvm/include/llvm/CodeGen/PassManager.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/CodeGen/PassManager.h @@ -0,0 +1,133 @@ +//===- PassManager.h ---------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// Interface for the pass manager functionality used for CodeGen. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_PASS_MANAGER_H +#define LLVM_CODEGEN_PASS_MANAGER_H + +#include "llvm/Analysis/OptimizationRemarkEmitter.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/PassManagerInternal.h" + +namespace llvm { +using namespace ore; + +/// Convenience typedef for the MachineFunction analysis manager. +using MachineFunctionAnalysisManager = AnalysisManager; +/// Convenience typedef for a pass manager over functions. +using MachineFunctionPassManager = PassManager; + +using MachineFunctionAnalysisManagerFunctionProxy = + InnerAnalysisManagerProxy; + +using FunctionAnalysisManagerMachineFunctionProxy = + OuterAnalysisManagerProxy; + +template +class FunctionToMachineFunctionPassAdaptor + : public PassInfoMixin> { +public: + explicit FunctionToMachineFunctionPassAdaptor(MachineFunctionPassT Pass) + : Pass(std::move(Pass)) {} + + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) { + PreservedAnalyses PA = PreservedAnalyses::all(); + + // Do not codegen any 'available_externally' functions at all, they have + // definitions outside the translation unit. + if (F.hasAvailableExternallyLinkage()) + return PA; + + MachineFunctionAnalysisManager &MFAM = + AM.getResult(F) + .getManager(); + + MachineModuleInfo *MMI = + AM.getResult(F) + .getManager() + .getCachedResult(*F.getParent()); + MachineFunction &MF = MMI->getOrCreateMachineFunction(F); + + // Collect the MI count of the function before the pass. + unsigned CountBefore, CountAfter; + + // Check if the user asked for size remarks. + bool ShouldEmitSizeRemarks = + F.getParent()->shouldEmitInstrCountChangedRemark(); + + // If we want size remarks, collect the number of MachineInstrs in our + // MachineFunction before the pass runs. + if (ShouldEmitSizeRemarks) + CountBefore = MF.getInstructionCount(); + + // Request PassInstrumentation from analysis manager, will use it to run + // instrumenting callbacks for the passes later. + // TODO PASS INSTRUMENTATION + // PassInstrumentation PI = AM.getResult(F); + + // if (PI.runBeforePass(Pass, MF)) + // PA = Pass.run(MF, MFAM); + + // PI.runAfterPass(Pass, MF); + + Pass.run(MF, MFAM); + + if (ShouldEmitSizeRemarks) { + // We wanted size remarks. Check if there was a change to the number of + // MachineInstrs in the module. Emit a remark if there was a change. + CountAfter = MF.getInstructionCount(); + if (CountBefore != CountAfter) { + MachineOptimizationRemarkEmitter MORE(MF, nullptr); + MORE.emit([&]() { + int64_t Delta = static_cast(CountAfter) - + static_cast(CountBefore); + MachineOptimizationRemarkAnalysis R( + "size-info", "FunctionMISizeChange", + MF.getFunction().getSubprogram(), &MF.front()); + R << NV("Pass", getTypeName()) + << ": Function: " << NV("Function", F.getName()) << ": " + << "MI Instruction count changed from " + << NV("MIInstrsBefore", CountBefore) << " to " + << NV("MIInstrsAfter", CountAfter) + << "; Delta: " << NV("Delta", Delta); + return R; + }); + } + } + + // The FunctionAnalysisManagerModuleProxy is preserved because (we assume) + // the function passes we ran didn't add or remove any functions. + // + // We also preserve all analyses on Machine Functions, because we did all + // the invalidation we needed to do above. + PA.preserveSet>(); + PA.preserve(); + assert(PA.areAllPreserved()); + return PA; + } + +private: + MachineFunctionPassT Pass; +}; + +template +FunctionToMachineFunctionPassAdaptor +createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT Pass) { + return FunctionToMachineFunctionPassAdaptor( + std::move(Pass)); +} + +} // end namespace llvm + +#endif // LLVM_CODEGEN_PASS_MANAGER_H diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -100,6 +100,7 @@ MacroFusion.cpp OptimizePHIs.cpp ParallelCG.cpp + PassManager.cpp PeepholeOptimizer.cpp PHIElimination.cpp PHIEliminationUtils.cpp diff --git a/llvm/lib/CodeGen/PassManager.cpp b/llvm/lib/CodeGen/PassManager.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/CodeGen/PassManager.cpp @@ -0,0 +1,34 @@ +//===-- PassManager.cpp -------------------------------------------===// +// +// 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 file contains the pass management machinery for machine functions. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/PassManager.h" + +using namespace llvm; + +namespace llvm { +template class AllAnalysesOn; +template class AnalysisManager; +template class PassManager; +template class InnerAnalysisManagerProxy; +template class OuterAnalysisManagerProxy; + +template <> +bool MachineFunctionAnalysisManagerFunctionProxy::Result::invalidate( + Function &F, const PreservedAnalyses &PA, + FunctionAnalysisManager::Invalidator &Inv) { + // Just assume that all proxies are valid for the time being until we run into + // trouble. Return false to indicate that this result is still a valid proxy. + return false; +} +} // namespace llvm diff --git a/llvm/tools/llc/CMakeLists.txt b/llvm/tools/llc/CMakeLists.txt --- a/llvm/tools/llc/CMakeLists.txt +++ b/llvm/tools/llc/CMakeLists.txt @@ -17,6 +17,7 @@ Target TransformUtils Vectorize + Passes ) # Support plugins. diff --git a/llvm/tools/llc/LLVMBuild.txt b/llvm/tools/llc/LLVMBuild.txt --- a/llvm/tools/llc/LLVMBuild.txt +++ b/llvm/tools/llc/LLVMBuild.txt @@ -18,4 +18,4 @@ type = Tool name = llc parent = Tools -required_libraries = AsmParser BitReader IRReader MIRParser TransformUtils Scalar Vectorize all-targets +required_libraries = AsmParser BitReader IRReader MIRParser TransformUtils Scalar Vectorize Passes all-targets