Files
clang-r547379/include/llvm/CodeGen/MachinePassManager.h
Ryan Prichard 6024e5c395 Update prebuilt Clang to r547379 (20.0.0).
clang 20.0.0 (based on r547379) from build 12806354.

Bug: http://b/379133546
Test: N/A
Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b

Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
2025-11-26 14:59:46 -05:00

242 lines
8.9 KiB
C++

//===- PassManager.h --- Pass management for CodeGen ------------*- 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 header defines the pass manager interface for codegen. The codegen
// pipeline consists of only machine function passes. There is no container
// relationship between IR module/function and machine function in terms of pass
// manager organization. So there is no need for adaptor classes (for example
// ModuleToMachineFunctionAdaptor). Since invalidation could only happen among
// machine function passes, there is no proxy classes to handle cross-IR-unit
// invalidation. IR analysis results are provided for machine function passes by
// their respective analysis managers such as ModuleAnalysisManager and
// FunctionAnalysisManager.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H
#define LLVM_CODEGEN_MACHINEPASSMANAGER_H
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PassManagerInternal.h"
#include "llvm/Support/Error.h"
namespace llvm {
class Module;
class Function;
class MachineFunction;
extern template class AnalysisManager<MachineFunction>;
using MachineFunctionAnalysisManager = AnalysisManager<MachineFunction>;
/// An RAII based helper class to modify MachineFunctionProperties when running
/// pass. Define a MFPropsModifier in PassT::run to set
/// MachineFunctionProperties properly.
template <typename PassT> class MFPropsModifier {
public:
MFPropsModifier(PassT &P_, MachineFunction &MF_) : P(P_), MF(MF_) {
auto &MFProps = MF.getProperties();
#ifndef NDEBUG
if constexpr (has_get_required_properties_v<PassT>) {
auto &MFProps = MF.getProperties();
auto RequiredProperties = P.getRequiredProperties();
if (!MFProps.verifyRequiredProperties(RequiredProperties)) {
errs() << "MachineFunctionProperties required by " << PassT::name()
<< " pass are not met by function " << MF.getName() << ".\n"
<< "Required properties: ";
RequiredProperties.print(errs());
errs() << "\nCurrent properties: ";
MFProps.print(errs());
errs() << '\n';
report_fatal_error("MachineFunctionProperties check failed");
}
}
#endif // NDEBUG
if constexpr (has_get_cleared_properties_v<PassT>)
MFProps.reset(P.getClearedProperties());
}
~MFPropsModifier() {
if constexpr (has_get_set_properties_v<PassT>) {
auto &MFProps = MF.getProperties();
MFProps.set(P.getSetProperties());
}
}
private:
PassT &P;
MachineFunction &MF;
template <typename T>
using has_get_required_properties_t =
decltype(std::declval<T &>().getRequiredProperties());
template <typename T>
using has_get_set_properties_t =
decltype(std::declval<T &>().getSetProperties());
template <typename T>
using has_get_cleared_properties_t =
decltype(std::declval<T &>().getClearedProperties());
template <typename T>
static constexpr bool has_get_required_properties_v =
is_detected<has_get_required_properties_t, T>::value;
template <typename T>
static constexpr bool has_get_set_properties_v =
is_detected<has_get_set_properties_t, T>::value;
template <typename T>
static constexpr bool has_get_cleared_properties_v =
is_detected<has_get_cleared_properties_t, T>::value;
};
// Additional deduction guide to suppress warning.
template <typename PassT>
MFPropsModifier(PassT &P, MachineFunction &MF) -> MFPropsModifier<PassT>;
using MachineFunctionAnalysisManagerModuleProxy =
InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Module>;
template <>
bool MachineFunctionAnalysisManagerModuleProxy::Result::invalidate(
Module &M, const PreservedAnalyses &PA,
ModuleAnalysisManager::Invalidator &Inv);
extern template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager,
Module>;
using MachineFunctionAnalysisManagerFunctionProxy =
InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Function>;
template <>
bool MachineFunctionAnalysisManagerFunctionProxy::Result::invalidate(
Function &F, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv);
extern template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager,
Function>;
extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
MachineFunction>;
/// Provide the \c ModuleAnalysisManager to \c Function proxy.
using ModuleAnalysisManagerMachineFunctionProxy =
OuterAnalysisManagerProxy<ModuleAnalysisManager, MachineFunction>;
class FunctionAnalysisManagerMachineFunctionProxy
: public AnalysisInfoMixin<FunctionAnalysisManagerMachineFunctionProxy> {
public:
class Result {
public:
explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {
// We have to null out the analysis manager in the moved-from state
// because we are taking ownership of the responsibilty to clear the
// analysis state.
Arg.FAM = nullptr;
}
Result &operator=(Result &&RHS) {
FAM = RHS.FAM;
// We have to null out the analysis manager in the moved-from state
// because we are taking ownership of the responsibilty to clear the
// analysis state.
RHS.FAM = nullptr;
return *this;
}
/// Accessor for the analysis manager.
FunctionAnalysisManager &getManager() { return *FAM; }
/// Handler for invalidation of the outer IR unit, \c IRUnitT.
///
/// If the proxy analysis itself is not preserved, we assume that the set of
/// inner IR objects contained in IRUnit may have changed. In this case,
/// we have to call \c clear() on the inner analysis manager, as it may now
/// have stale pointers to its inner IR objects.
///
/// Regardless of whether the proxy analysis is marked as preserved, all of
/// the analyses in the inner analysis manager are potentially invalidated
/// based on the set of preserved analyses.
bool invalidate(MachineFunction &IR, const PreservedAnalyses &PA,
MachineFunctionAnalysisManager::Invalidator &Inv);
private:
FunctionAnalysisManager *FAM;
};
explicit FunctionAnalysisManagerMachineFunctionProxy(
FunctionAnalysisManager &FAM)
: FAM(&FAM) {}
/// Run the analysis pass and create our proxy result object.
///
/// This doesn't do any interesting work; it is primarily used to insert our
/// proxy result object into the outer analysis cache so that we can proxy
/// invalidation to the inner analysis manager.
Result run(MachineFunction &, MachineFunctionAnalysisManager &) {
return Result(*FAM);
}
static AnalysisKey Key;
private:
FunctionAnalysisManager *FAM;
};
class FunctionToMachineFunctionPassAdaptor
: public PassInfoMixin<FunctionToMachineFunctionPassAdaptor> {
public:
using PassConceptT =
detail::PassConcept<MachineFunction, MachineFunctionAnalysisManager>;
explicit FunctionToMachineFunctionPassAdaptor(
std::unique_ptr<PassConceptT> Pass)
: Pass(std::move(Pass)) {}
/// Runs the function pass across every function in the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
void printPipeline(raw_ostream &OS,
function_ref<StringRef(StringRef)> MapClassName2PassName);
static bool isRequired() { return true; }
private:
std::unique_ptr<PassConceptT> Pass;
};
template <typename MachineFunctionPassT>
FunctionToMachineFunctionPassAdaptor
createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
using PassModelT = detail::PassModel<MachineFunction, MachineFunctionPassT,
MachineFunctionAnalysisManager>;
// Do not use make_unique, it causes too many template instantiations,
// causing terrible compile times.
return FunctionToMachineFunctionPassAdaptor(
std::unique_ptr<FunctionToMachineFunctionPassAdaptor::PassConceptT>(
new PassModelT(std::forward<MachineFunctionPassT>(Pass))));
}
template <>
PreservedAnalyses
PassManager<MachineFunction>::run(MachineFunction &,
AnalysisManager<MachineFunction> &);
extern template class PassManager<MachineFunction>;
/// Convenience typedef for a pass manager over functions.
using MachineFunctionPassManager = PassManager<MachineFunction>;
/// Returns the minimum set of Analyses that all machine function passes must
/// preserve.
PreservedAnalyses getMachineFunctionPassPreservedAnalyses();
} // end namespace llvm
#endif // LLVM_CODEGEN_MACHINEPASSMANAGER_H