Skip to content

Commit f3ccf25

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

File tree

6 files changed

+197
-24
lines changed

6 files changed

+197
-24
lines changed

llvm/include/llvm/CodeGen/MachinePassManager.h

Lines changed: 40 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,31 @@ 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+
// MachineFunctionProperties support
45+
static MachineFunctionProperties getRequiredProperties() {
46+
return MachineFunctionProperties();
47+
}
48+
49+
static MachineFunctionProperties getSetProperties() {
50+
return MachineFunctionProperties();
51+
}
52+
53+
static MachineFunctionProperties getClearedProperties() {
54+
return MachineFunctionProperties();
55+
}
56+
};
57+
58+
/// A CRTP mix-in that provides informational APIs needed for MachineFunction
59+
/// analysis passes. See also \c PassInfoMixin.
60+
template <typename DerivedT>
61+
struct MachineFunctionAnalysisInfoMixin
62+
: public MachinePassInfoMixin<DerivedT> {
63+
static AnalysisKey *ID() {
64+
static_assert(
65+
std::is_base_of<MachineFunctionAnalysisInfoMixin, DerivedT>::value,
66+
"Must pass the derived type as the template argument!");
67+
return &DerivedT::Key;
68+
}
4769
};
4870

4971
/// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
@@ -170,6 +192,17 @@ class MachineFunctionPassManager
170192
addRunOnModule<PassT>(P);
171193
}
172194

195+
// Avoid diamond problem.
196+
static MachineFunctionProperties getRequiredProperties() {
197+
return MachineFunctionProperties();
198+
}
199+
static MachineFunctionProperties getSetProperties() {
200+
return MachineFunctionProperties();
201+
}
202+
static MachineFunctionProperties getClearedProperties() {
203+
return MachineFunctionProperties();
204+
}
205+
173206
private:
174207
template <typename PassT>
175208
using has_init_t = decltype(std::declval<PassT &>().doInitialization(
@@ -183,9 +216,7 @@ class MachineFunctionPassManager
183216
template <typename PassT>
184217
std::enable_if_t<is_detected<has_init_t, PassT>::value>
185218
addDoInitialization(PassConceptT *Pass) {
186-
using PassModelT =
187-
detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
188-
MachineFunctionAnalysisManager>;
219+
using PassModelT = detail::MachinePassModel<PassT>;
189220
auto *P = static_cast<PassModelT *>(Pass);
190221
InitializationFuncs.emplace_back(
191222
[=](Module &M, MachineFunctionAnalysisManager &MFAM) {
@@ -205,9 +236,7 @@ class MachineFunctionPassManager
205236
template <typename PassT>
206237
std::enable_if_t<is_detected<has_fini_t, PassT>::value>
207238
addDoFinalization(PassConceptT *Pass) {
208-
using PassModelT =
209-
detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
210-
MachineFunctionAnalysisManager>;
239+
using PassModelT = detail::MachinePassModel<PassT>;
211240
auto *P = static_cast<PassModelT *>(Pass);
212241
FinalizationFuncs.emplace_back(
213242
[=](Module &M, MachineFunctionAnalysisManager &MFAM) {
@@ -236,9 +265,7 @@ class MachineFunctionPassManager
236265
"machine module pass needs to define machine function pass "
237266
"api. sorry.");
238267

239-
using PassModelT =
240-
detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
241-
MachineFunctionAnalysisManager>;
268+
using PassModelT = detail::MachinePassModel<PassT>;
242269
auto *P = static_cast<PassModelT *>(Pass);
243270
MachineModulePasses.emplace(
244271
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: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,14 @@ 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))));
586+
}
581587
}
582588

583589
/// When adding a pass manager pass that has the same type as this pass
@@ -1292,9 +1298,37 @@ struct RequireAnalysisPass
12921298
OS << "require<" << PassName << '>';
12931299
}
12941300
static bool isRequired() { return true; }
1301+
1302+
// MachineFunctionPass interface, define Define these separately to prevent
1303+
// dependency on CodeGen
1304+
template <typename MachineFunctionT = IRUnitT,
1305+
typename MachineFunctionPropertiesT = MachineFunctionProperties,
1306+
typename = std::enable_if_t<
1307+
std::is_same_v<MachineFunctionT, MachineFunction>>>
1308+
static MachineFunctionPropertiesT getRequiredProperties() {
1309+
return MachineFunctionPropertiesT();
1310+
}
1311+
1312+
template <typename MachineFunctionT = IRUnitT,
1313+
typename MachineFunctionPropertiesT = MachineFunctionProperties,
1314+
typename = std::enable_if_t<
1315+
std::is_same_v<MachineFunctionT, MachineFunction>>>
1316+
static MachineFunctionPropertiesT getSetProperties() {
1317+
return MachineFunctionPropertiesT();
1318+
}
1319+
1320+
template <typename MachineFunctionT = IRUnitT,
1321+
typename MachineFunctionPropertiesT = MachineFunctionProperties,
1322+
typename = std::enable_if_t<
1323+
std::is_same_v<MachineFunctionT, MachineFunction>>>
1324+
static MachineFunctionPropertiesT getClearedProperties() {
1325+
return MachineFunctionPropertiesT();
1326+
}
12951327
};
12961328

1297-
/// A no-op pass template which simply forces a specific analysis result
1329+
template <typename DerivedT> struct MachineFunctionAnalysisInfoMixin;
1330+
1331+
/// A no-op IR pass template which simply forces a specific analysis result
12981332
/// to be invalidated.
12991333
template <typename AnalysisT>
13001334
struct InvalidateAnalysisPass
@@ -1317,6 +1351,35 @@ struct InvalidateAnalysisPass
13171351
auto PassName = MapClassName2PassName(ClassName);
13181352
OS << "invalidate<" << PassName << '>';
13191353
}
1354+
1355+
// MachineFunctionPass interface, define Define these separately to prevent
1356+
// dependency on CodeGen
1357+
template <typename MachineFunctionPropertiesT = MachineFunctionProperties,
1358+
typename MachineFunctionAnalysisT = AnalysisT,
1359+
typename = std::enable_if_t<std::is_base_of_v<
1360+
MachineFunctionAnalysisInfoMixin<MachineFunctionAnalysisT>,
1361+
MachineFunctionAnalysisT>>>
1362+
static MachineFunctionPropertiesT getRequiredProperties() {
1363+
return MachineFunctionPropertiesT();
1364+
}
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 getSetProperties() {
1372+
return MachineFunctionPropertiesT();
1373+
}
1374+
1375+
template <typename MachineFunctionPropertiesT = MachineFunctionProperties,
1376+
typename MachineFunctionAnalysisT = AnalysisT,
1377+
typename = std::enable_if_t<std::is_base_of_v<
1378+
MachineFunctionAnalysisInfoMixin<MachineFunctionAnalysisT>,
1379+
MachineFunctionAnalysisT>>>
1380+
static MachineFunctionPropertiesT getClearedProperties() {
1381+
return MachineFunctionPropertiesT();
1382+
}
13201383
};
13211384

13221385
/// 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)