Skip to content

[CodeGen][NewPM] Extract MachineFunctionProperties modification part to an RAII class #94854

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 35 additions & 50 deletions llvm/include/llvm/CodeGen/MachinePassManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,35 +36,20 @@ class MachineFunction;
extern template class AnalysisManager<MachineFunction>;
using MachineFunctionAnalysisManager = AnalysisManager<MachineFunction>;

namespace detail {

template <typename PassT>
struct MachinePassModel
: PassModel<MachineFunction, PassT, MachineFunctionAnalysisManager> {
explicit MachinePassModel(PassT &&Pass)
: PassModel<MachineFunction, PassT, MachineFunctionAnalysisManager>(
std::move(Pass)) {}

friend void swap(MachinePassModel &LHS, MachinePassModel &RHS) {
using std::swap;
swap(LHS.Pass, RHS.Pass);
}

MachinePassModel &operator=(MachinePassModel RHS) {
swap(*this, RHS);
return *this;
}

MachinePassModel &operator=(const MachinePassModel &) = delete;
PreservedAnalyses run(MachineFunction &IR,
MachineFunctionAnalysisManager &AM) override {
/// 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 (is_detected<has_get_required_properties_t, PassT>::value) {
auto &MFProps = IR.getProperties();
auto RequiredProperties = this->Pass.getRequiredProperties();
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 " << IR.getName() << ".\n"
<< " pass are not met by function " << MF.getName() << ".\n"
<< "Required properties: ";
RequiredProperties.print(errs());
errs() << "\nCurrent properties: ";
Expand All @@ -73,18 +58,22 @@ struct MachinePassModel
report_fatal_error("MachineFunctionProperties check failed");
}
}
#endif

auto PA = this->Pass.run(IR, AM);
#endif // NDEBUG
if constexpr (has_get_cleared_properties_v<PassT>)
MFProps.reset(P.getClearedProperties());
}

if constexpr (is_detected<has_get_set_properties_t, PassT>::value)
IR.getProperties().set(this->Pass.getSetProperties());
if constexpr (is_detected<has_get_cleared_properties_t, PassT>::value)
IR.getProperties().reset(this->Pass.getClearedProperties());
return PA;
~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());
Expand All @@ -96,8 +85,19 @@ struct MachinePassModel
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;
};
} // namespace detail

using MachineFunctionAnalysisManagerModuleProxy =
InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Module>;
Expand Down Expand Up @@ -219,21 +219,6 @@ createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
new PassModelT(std::forward<MachineFunctionPassT>(Pass))));
}

template <>
template <typename PassT>
void PassManager<MachineFunction>::addPass(PassT &&Pass) {
using MachinePassModelT = detail::MachinePassModel<PassT>;
// Do not use make_unique or emplace_back, they cause too many template
// instantiations, causing terrible compile times.
if constexpr (std::is_same_v<PassT, PassManager<MachineFunction>>) {
for (auto &P : Pass.Passes)
Passes.push_back(std::move(P));
} else {
Passes.push_back(std::unique_ptr<MachinePassModelT>(
new MachinePassModelT(std::forward<PassT>(Pass))));
}
}

template <>
PreservedAnalyses
PassManager<MachineFunction>::run(MachineFunction &,
Expand Down
35 changes: 19 additions & 16 deletions llvm/include/llvm/IR/PassManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,24 +245,27 @@ class PassManager : public PassInfoMixin<
return PA;
}

// FIXME: Revert to enable_if style when gcc >= 11.1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://www.llvm.org/docs/GettingStarted.html#getting-a-modern-host-c-toolchain says we still support some gcc <11 (this should be a separate PR anyway)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was introduced in b361b53 to distinguish machine function passes and ir passes. MachinePassModel is removed now, so we can revert to enable_if form.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah sorry, I was mixing up enable_if_t and enable_if

template <typename PassT> LLVM_ATTRIBUTE_MINSIZE void addPass(PassT &&Pass) {
template <typename PassT>
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v<PassT, PassManager>>
addPass(PassT &&Pass) {
using PassModelT =
detail::PassModel<IRUnitT, PassT, AnalysisManagerT, ExtraArgTs...>;
if constexpr (!std::is_same_v<PassT, PassManager>) {
// Do not use make_unique or emplace_back, they cause too many template
// instantiations, causing terrible compile times.
Passes.push_back(std::unique_ptr<PassConceptT>(
new PassModelT(std::forward<PassT>(Pass))));
} else {
/// When adding a pass manager pass that has the same type as this pass
/// manager, simply move the passes over. This is because we don't have
/// use cases rely on executing nested pass managers. Doing this could
/// reduce implementation complexity and avoid potential invalidation
/// issues that may happen with nested pass managers of the same type.
for (auto &P : Pass.Passes)
Passes.push_back(std::move(P));
}
// Do not use make_unique or emplace_back, they cause too many template
// instantiations, causing terrible compile times.
Passes.push_back(std::unique_ptr<PassConceptT>(
new PassModelT(std::forward<PassT>(Pass))));
}

/// When adding a pass manager pass that has the same type as this pass
/// manager, simply move the passes over. This is because we don't have
/// use cases rely on executing nested pass managers. Doing this could
/// reduce implementation complexity and avoid potential invalidation
/// issues that may happen with nested pass managers of the same type.
template <typename PassT>
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<std::is_same_v<PassT, PassManager>>
addPass(PassT &&Pass) {
for (auto &P : Pass.Passes)
Passes.push_back(std::move(P));
}

/// Returns if the pass manager contains any passes.
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/RegAllocFast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1790,6 +1790,7 @@ bool RegAllocFastImpl::runOnMachineFunction(MachineFunction &MF) {

PreservedAnalyses RegAllocFastPass::run(MachineFunction &MF,
MachineFunctionAnalysisManager &) {
MFPropsModifier _(*this, MF);
RegAllocFastImpl Impl(Opts.Filter, Opts.ClearVRegs);
bool Changed = Impl.runOnMachineFunction(MF);
if (!Changed)
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,8 @@ class TriggerVerifierErrorPass
class RequireAllMachineFunctionPropertiesPass
: public PassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
public:
PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) {
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
MFPropsModifier _(*this, MF);
return PreservedAnalyses::none();
}

Expand Down
Loading