Skip to content

Commit 93f68c4

Browse files
committed
[CodeGen] Support MachineFunctionProperties in PassConcept
1 parent 3ed98cb commit 93f68c4

File tree

6 files changed

+185
-24
lines changed

6 files changed

+185
-24
lines changed

llvm/include/llvm/CodeGen/MachinePassManager.h

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,13 @@
2525

2626
#include "llvm/ADT/FunctionExtras.h"
2727
#include "llvm/ADT/SmallVector.h"
28+
#include "llvm/CodeGen/MachinePassManagerInternal.h"
2829
#include "llvm/IR/PassManager.h"
2930
#include "llvm/Support/Error.h"
3031

3132
#include <map>
3233

3334
namespace llvm {
34-
class Module;
35-
class Function;
36-
class MachineFunction;
3735

3836
extern template class AnalysisManager<MachineFunction>;
3937

@@ -43,7 +41,28 @@ extern template class AnalysisManager<MachineFunction>;
4341
/// automatically mixes in \c PassInfoMixin.
4442
template <typename DerivedT>
4543
struct MachinePassInfoMixin : public PassInfoMixin<DerivedT> {
46-
// TODO: Add MachineFunctionProperties support.
44+
static MachineFunctionProperties getRequiredProperties() {
45+
return MachineFunctionProperties();
46+
}
47+
static MachineFunctionProperties getSetProperties() {
48+
return MachineFunctionProperties();
49+
}
50+
static MachineFunctionProperties getClearedProperties() {
51+
return MachineFunctionProperties();
52+
}
53+
};
54+
55+
/// A CRTP mix-in that provides informational APIs needed for MachineFunction
56+
/// analysis passes. See also \c PassInfoMixin.
57+
template <typename DerivedT>
58+
struct MachineFunctionAnalysisInfoMixin
59+
: public MachinePassInfoMixin<DerivedT> {
60+
static AnalysisKey *ID() {
61+
static_assert(
62+
std::is_base_of<MachineFunctionAnalysisInfoMixin, DerivedT>::value,
63+
"Must pass the derived type as the template argument!");
64+
return &DerivedT::Key;
65+
}
4766
};
4867

4968
/// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
@@ -170,6 +189,17 @@ class MachineFunctionPassManager
170189
addRunOnModule<PassT>(P);
171190
}
172191

192+
// Avoid diamond problem.
193+
static MachineFunctionProperties getRequiredProperties() {
194+
return MachineFunctionProperties();
195+
}
196+
static MachineFunctionProperties getSetProperties() {
197+
return MachineFunctionProperties();
198+
}
199+
static MachineFunctionProperties getClearedProperties() {
200+
return MachineFunctionProperties();
201+
}
202+
173203
private:
174204
template <typename PassT>
175205
using has_init_t = decltype(std::declval<PassT &>().doInitialization(
@@ -183,9 +213,7 @@ class MachineFunctionPassManager
183213
template <typename PassT>
184214
std::enable_if_t<is_detected<has_init_t, PassT>::value>
185215
addDoInitialization(PassConceptT *Pass) {
186-
using PassModelT =
187-
detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
188-
MachineFunctionAnalysisManager>;
216+
using PassModelT = detail::MachinePassModel<PassT>;
189217
auto *P = static_cast<PassModelT *>(Pass);
190218
InitializationFuncs.emplace_back(
191219
[=](Module &M, MachineFunctionAnalysisManager &MFAM) {
@@ -205,9 +233,7 @@ class MachineFunctionPassManager
205233
template <typename PassT>
206234
std::enable_if_t<is_detected<has_fini_t, PassT>::value>
207235
addDoFinalization(PassConceptT *Pass) {
208-
using PassModelT =
209-
detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
210-
MachineFunctionAnalysisManager>;
236+
using PassModelT = detail::MachinePassModel<PassT>;
211237
auto *P = static_cast<PassModelT *>(Pass);
212238
FinalizationFuncs.emplace_back(
213239
[=](Module &M, MachineFunctionAnalysisManager &MFAM) {
@@ -236,9 +262,7 @@ class MachineFunctionPassManager
236262
"machine module pass needs to define machine function pass "
237263
"api. sorry.");
238264

239-
using PassModelT =
240-
detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
241-
MachineFunctionAnalysisManager>;
265+
using PassModelT = detail::MachinePassModel<PassT>;
242266
auto *P = static_cast<PassModelT *>(Pass);
243267
MachineModulePasses.emplace(
244268
Passes.size() - 1,
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//===- MachinePassManagerInternal.h --------------------------- -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
/// \file
9+
///
10+
/// This header provides internal APIs and implementation details used by the
11+
/// pass management interfaces exposed in MachinePassManager.h. Most of them are
12+
/// copied from PassManagerInternal.h.
13+
/// See also PassManagerInternal.h.
14+
///
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef LLVM_CODEGEN_MACHINEPASSMANAGERINTERNAL_H
18+
#define LLVM_CODEGEN_MACHINEPASSMANAGERINTERNAL_H
19+
20+
#include "llvm/CodeGen/MachineFunction.h"
21+
#include "llvm/IR/PassManager.h"
22+
23+
namespace llvm {
24+
25+
class MachineFunctionAnalysisManager;
26+
27+
using MachinePassConcept =
28+
detail::PassConcept<MachineFunction, MachineFunctionAnalysisManager>;
29+
30+
namespace detail {
31+
32+
/// Template for the abstract base class used to dispatch
33+
/// polymorphically over pass objects. See also \c PassConcept.
34+
template <>
35+
struct PassConcept<MachineFunction, MachineFunctionAnalysisManager>
36+
: public PassConceptBase<MachineFunction, MachineFunctionAnalysisManager> {
37+
/// MachineFunction Properties.
38+
PassConcept(MachineFunctionProperties RequiredProperties,
39+
MachineFunctionProperties SetProperties,
40+
MachineFunctionProperties ClearedProperties)
41+
: RequiredProperties(RequiredProperties), SetProperties(SetProperties),
42+
ClearedProperties(ClearedProperties) {}
43+
44+
MachineFunctionProperties RequiredProperties;
45+
MachineFunctionProperties SetProperties;
46+
MachineFunctionProperties ClearedProperties;
47+
};
48+
49+
template <typename IRUnitT, typename PassT, typename PreservedAnalysesT,
50+
typename AnalysisManagerT, typename... ExtraArgTs>
51+
template <typename MachineFunctionT, typename>
52+
PassModel<IRUnitT, PassT, PreservedAnalysesT, AnalysisManagerT, ExtraArgTs...>::
53+
PassModel(PassT Pass, MachineFunctionProperties RequiredProperties,
54+
MachineFunctionProperties SetProperties,
55+
MachineFunctionProperties ClearedProperties)
56+
: PassConcept<MachineFunction, MachineFunctionAnalysisManager>(
57+
RequiredProperties, SetProperties, ClearedProperties),
58+
Pass(std::move(Pass)) {}
59+
60+
template <typename PassT>
61+
using MachinePassModel = PassModel<MachineFunction, PassT, PreservedAnalyses,
62+
MachineFunctionAnalysisManager>;
63+
64+
} // namespace detail
65+
66+
} // namespace llvm
67+
68+
#endif // LLVM_CODEGEN_MACHINEPASSMANAGERINTERNAL_H

llvm/include/llvm/IR/PassManager.h

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,13 @@ class PassManager : public PassInfoMixin<
576576
ExtraArgTs...>;
577577
// Do not use make_unique or emplace_back, they cause too many template
578578
// instantiations, causing terrible compile times.
579-
Passes.push_back(std::unique_ptr<PassConceptT>(
580-
new PassModelT(std::forward<PassT>(Pass))));
579+
if constexpr (std::is_same_v<IRUnitT, MachineFunction>)
580+
Passes.push_back(std::unique_ptr<PassConceptT>(new PassModelT(
581+
std::forward<PassT>(Pass), PassT::getRequiredProperties(),
582+
PassT::getSetProperties(), PassT::getClearedProperties())));
583+
else
584+
Passes.push_back(std::unique_ptr<PassConceptT>(
585+
new PassModelT(std::forward<PassT>(Pass))));
581586
}
582587

583588
/// When adding a pass manager pass that has the same type as this pass
@@ -1292,9 +1297,33 @@ struct RequireAnalysisPass
12921297
OS << "require<" << PassName << '>';
12931298
}
12941299
static bool isRequired() { return true; }
1300+
1301+
template <typename MachineFunctionT = IRUnitT,
1302+
typename MachineFunctionPropertiesT = MachineFunctionProperties,
1303+
typename = std::enable_if_t<
1304+
std::is_same_v<MachineFunctionT, MachineFunction>>>
1305+
static MachineFunctionPropertiesT getRequiredProperties() {
1306+
return MachineFunctionPropertiesT();
1307+
}
1308+
template <typename MachineFunctionT = IRUnitT,
1309+
typename MachineFunctionPropertiesT = MachineFunctionProperties,
1310+
typename = std::enable_if_t<
1311+
std::is_same_v<MachineFunctionT, MachineFunction>>>
1312+
static MachineFunctionPropertiesT getSetProperties() {
1313+
return MachineFunctionPropertiesT();
1314+
}
1315+
template <typename MachineFunctionT = IRUnitT,
1316+
typename MachineFunctionPropertiesT = MachineFunctionProperties,
1317+
typename = std::enable_if_t<
1318+
std::is_same_v<MachineFunctionT, MachineFunction>>>
1319+
static MachineFunctionPropertiesT getClearedProperties() {
1320+
return MachineFunctionPropertiesT();
1321+
}
12951322
};
12961323

1297-
/// A no-op pass template which simply forces a specific analysis result
1324+
template <typename DerivedT> struct MachineFunctionAnalysisInfoMixin;
1325+
1326+
/// A no-op IR pass template which simply forces a specific analysis result
12981327
/// to be invalidated.
12991328
template <typename AnalysisT>
13001329
struct InvalidateAnalysisPass
@@ -1317,6 +1346,31 @@ struct InvalidateAnalysisPass
13171346
auto PassName = MapClassName2PassName(ClassName);
13181347
OS << "invalidate<" << PassName << '>';
13191348
}
1349+
1350+
template <typename MachineFunctionPropertiesT = MachineFunctionProperties,
1351+
typename MachineFunctionAnalysisT = AnalysisT,
1352+
typename = std::enable_if_t<std::is_base_of_v<
1353+
MachineFunctionAnalysisInfoMixin<MachineFunctionAnalysisT>,
1354+
MachineFunctionAnalysisT>>>
1355+
static MachineFunctionPropertiesT getRequiredProperties() {
1356+
return MachineFunctionPropertiesT();
1357+
}
1358+
template <typename MachineFunctionPropertiesT = MachineFunctionProperties,
1359+
typename MachineFunctionAnalysisT = AnalysisT,
1360+
typename = std::enable_if_t<std::is_base_of_v<
1361+
MachineFunctionAnalysisInfoMixin<MachineFunctionAnalysisT>,
1362+
MachineFunctionAnalysisT>>>
1363+
static MachineFunctionPropertiesT getSetProperties() {
1364+
return MachineFunctionPropertiesT();
1365+
}
1366+
template <typename MachineFunctionPropertiesT = MachineFunctionProperties,
1367+
typename MachineFunctionAnalysisT = AnalysisT,
1368+
typename = std::enable_if_t<std::is_base_of_v<
1369+
MachineFunctionAnalysisInfoMixin<MachineFunctionAnalysisT>,
1370+
MachineFunctionAnalysisT>>>
1371+
static MachineFunctionPropertiesT getClearedProperties() {
1372+
return MachineFunctionPropertiesT();
1373+
}
13201374
};
13211375

13221376
/// A utility pass that does nothing, but preserves no analyses.

llvm/include/llvm/IR/PassManagerInternal.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,18 @@ namespace llvm {
2828
template <typename IRUnitT> class AllAnalysesOn;
2929
template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
3030
class PreservedAnalyses;
31+
class MachineFunction;
32+
class MachineFunctionProperties;
3133

3234
// Implementation details of the pass manager interfaces.
3335
namespace detail {
3436

3537
/// Template for the abstract base class used to dispatch
3638
/// polymorphically over pass objects.
3739
template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
38-
struct PassConcept {
40+
struct PassConceptBase {
3941
// Boiler plate necessary for the container of derived classes.
40-
virtual ~PassConcept() = default;
42+
virtual ~PassConceptBase() = default;
4143

4244
/// The polymorphic API which runs the pass over a given IR entity.
4345
///
@@ -60,6 +62,10 @@ struct PassConcept {
6062
virtual bool isRequired() const = 0;
6163
};
6264

65+
template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
66+
struct PassConcept
67+
: public PassConceptBase<IRUnitT, AnalysisManagerT, ExtraArgTs...> {};
68+
6369
/// A template wrapper used to implement the polymorphic API.
6470
///
6571
/// Can be instantiated for any object which provides a \c run method accepting
@@ -69,6 +75,13 @@ template <typename IRUnitT, typename PassT, typename PreservedAnalysesT,
6975
typename AnalysisManagerT, typename... ExtraArgTs>
7076
struct PassModel : PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...> {
7177
explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
78+
79+
template <typename MachineFunctionT = IRUnitT,
80+
typename = std::enable_if_t<
81+
std::is_same_v<MachineFunctionT, MachineFunction>>>
82+
explicit PassModel(PassT Pass, MachineFunctionProperties RequiredProperties,
83+
MachineFunctionProperties SetProperties,
84+
MachineFunctionProperties ClearedProperties);
7285
// We have to explicitly define all the special member functions because MSVC
7386
// refuses to generate them.
7487
PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}

llvm/unittests/CodeGen/PassManagerTest.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {
5252
AnalysisKey TestFunctionAnalysis::Key;
5353

5454
class TestMachineFunctionAnalysis
55-
: public AnalysisInfoMixin<TestMachineFunctionAnalysis> {
55+
: public MachineFunctionAnalysisInfoMixin<TestMachineFunctionAnalysis> {
5656
public:
5757
struct Result {
5858
Result(int Count) : InstructionCount(Count) {}
@@ -70,7 +70,7 @@ class TestMachineFunctionAnalysis
7070
}
7171

7272
private:
73-
friend AnalysisInfoMixin<TestMachineFunctionAnalysis>;
73+
friend MachineFunctionAnalysisInfoMixin<TestMachineFunctionAnalysis>;
7474
static AnalysisKey Key;
7575
};
7676

@@ -79,7 +79,8 @@ AnalysisKey TestMachineFunctionAnalysis::Key;
7979
const std::string DoInitErrMsg = "doInitialization failed";
8080
const std::string DoFinalErrMsg = "doFinalization failed";
8181

82-
struct TestMachineFunctionPass : public PassInfoMixin<TestMachineFunctionPass> {
82+
struct TestMachineFunctionPass
83+
: public MachinePassInfoMixin<TestMachineFunctionPass> {
8384
TestMachineFunctionPass(int &Count, std::vector<int> &BeforeInitialization,
8485
std::vector<int> &BeforeFinalization,
8586
std::vector<int> &MachineFunctionPassCount)
@@ -139,7 +140,8 @@ struct TestMachineFunctionPass : public PassInfoMixin<TestMachineFunctionPass> {
139140
std::vector<int> &MachineFunctionPassCount;
140141
};
141142

142-
struct TestMachineModulePass : public PassInfoMixin<TestMachineModulePass> {
143+
struct TestMachineModulePass
144+
: public MachinePassInfoMixin<TestMachineModulePass> {
143145
TestMachineModulePass(int &Count, std::vector<int> &MachineModulePassCount)
144146
: Count(Count), MachineModulePassCount(MachineModulePassCount) {}
145147

llvm/unittests/MIR/PassBuilderCallbacksTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ struct MockPassInstrumentationCallbacks {
174174

175175
template <typename DerivedT> class MockAnalysisHandleBase {
176176
public:
177-
class Analysis : public AnalysisInfoMixin<Analysis> {
178-
friend AnalysisInfoMixin<Analysis>;
177+
class Analysis : public MachineFunctionAnalysisInfoMixin<Analysis> {
178+
friend MachineFunctionAnalysisInfoMixin<Analysis>;
179179
friend MockAnalysisHandleBase;
180180
static AnalysisKey Key;
181181

0 commit comments

Comments
 (0)