Skip to content

Commit b6058e0

Browse files
committed
[NewPM][CodeGen] Add MachineFunctionAnalysis
1 parent b45c9c3 commit b6058e0

16 files changed

+287
-64
lines changed

llvm/include/llvm/CodeGen/FreeMachineFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace llvm {
1515

16+
// TODO: Convert it to function pass.
1617
class FreeMachineFunctionPass : public PassInfoMixin<FreeMachineFunctionPass> {
1718
public:
1819
PreservedAnalyses run(MachineFunction &MF,
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===- llvm/CodeGen/FunctionToMachineFunctionAnalysis.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+
//
9+
// This file declares the FunctionToMachineFunctionAnalysis class.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CODEGEN_FUNCTIONTOMACHINEFUNCTIONANALYSIS
14+
#define LLVM_CODEGEN_FUNCTIONTOMACHINEFUNCTIONANALYSIS
15+
16+
#include "llvm/IR/PassManager.h"
17+
18+
namespace llvm {
19+
20+
class MachineFunction;
21+
class LLVMTargetMachine;
22+
23+
/// This analysis create MachineFunction for given Function.
24+
/// To release the MachineFunction, users should invalidate it explicitly.
25+
class FunctionToMachineFunctionAnalysis
26+
: public AnalysisInfoMixin<FunctionToMachineFunctionAnalysis> {
27+
friend AnalysisInfoMixin<FunctionToMachineFunctionAnalysis>;
28+
29+
static AnalysisKey Key;
30+
31+
const LLVMTargetMachine *TM;
32+
33+
public:
34+
class Result {
35+
std::unique_ptr<MachineFunction> MF;
36+
37+
public:
38+
Result(std::unique_ptr<MachineFunction> MF) : MF(std::move(MF)) {}
39+
MachineFunction &getMF() { return *MF; };
40+
bool invalidate(Function &, const PreservedAnalyses &PA,
41+
FunctionAnalysisManager::Invalidator &);
42+
};
43+
44+
FunctionToMachineFunctionAnalysis(const LLVMTargetMachine *TM) : TM(TM){};
45+
Result run(Function &F, FunctionAnalysisManager &FAM);
46+
};
47+
48+
} // namespace llvm
49+
50+
#endif // LLVM_CODEGEN_FUNCTIONTOMACHINEFUNCTIONANALYSIS

llvm/include/llvm/CodeGen/MIRParser/MIRParser.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ class MachineModuleInfo;
3434
class SMDiagnostic;
3535
class StringRef;
3636

37+
template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
38+
using ModuleAnalysisManager = AnalysisManager<Module>;
39+
3740
typedef llvm::function_ref<std::optional<std::string>(StringRef, StringRef)>
3841
DataLayoutCallbackTy;
3942

@@ -60,6 +63,15 @@ class MIRParser {
6063
///
6164
/// \returns true if an error occurred.
6265
bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI);
66+
67+
/// Parses MachineFunctions in the MIR file and add them as the result
68+
/// of MachineFunctionAnalysis in ModulePassManager \p MAM.
69+
/// User should register at least MachineFunctionAnalysis,
70+
/// MachineModuleAnalysis, FunctionAnalysisManagerModuleProxy and
71+
/// PassInstrumentationAnalysis in \p MAM before parsing MIR.
72+
///
73+
/// \returns true if an error occurred.
74+
bool parseMachineFunctions(Module &M, ModuleAnalysisManager &MAM);
6375
};
6476

6577
/// This function is the main interface to the MIR serialization format parser.

llvm/include/llvm/CodeGen/MachineModuleInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,14 @@ class MachineModuleInfo {
147147

148148
/// Returns the MachineFunction constructed for the IR function \p F.
149149
/// Creates a new MachineFunction if none exists yet.
150+
/// NOTE: New pass manager clients shall not use this method to get
151+
/// the `MachineFunction`, use `MachineFunctionAnalysis` instead.
150152
MachineFunction &getOrCreateMachineFunction(Function &F);
151153

152154
/// \brief Returns the MachineFunction associated to IR function \p F if there
153155
/// is one, otherwise nullptr.
156+
/// NOTE: New pass manager clients shall not use this method to get
157+
/// the `MachineFunction`, use `MachineFunctionAnalysis` instead.
154158
MachineFunction *getMachineFunction(const Function &F) const;
155159

156160
/// Delete the MachineFunction \p MF and reset the link in the IR Function to

llvm/include/llvm/CodeGen/MachinePassManager.h

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ struct MachinePassModel
7676
#endif
7777

7878
auto PA = this->Pass.run(IR, AM);
79+
// Machine function passes are not allowed to modify the LLVM
80+
// representation, therefore we should preserve all IR analyses.
81+
PA.template preserveSet<AllAnalysesOn<Module>>();
82+
PA.template preserveSet<AllAnalysesOn<Function>>();
7983

8084
if constexpr (is_detected<has_get_set_properties_t, PassT>::value)
8185
IR.getProperties().set(PassT::getSetProperties());
@@ -129,16 +133,6 @@ class FunctionAnalysisManagerMachineFunctionProxy
129133
Arg.FAM = nullptr;
130134
}
131135

132-
~Result() {
133-
// FAM is cleared in a moved from state where there is nothing to do.
134-
if (!FAM)
135-
return;
136-
137-
// Clear out the analysis manager if we're being destroyed -- it means we
138-
// didn't even see an invalidate call when we got invalidated.
139-
FAM->clear();
140-
}
141-
142136
Result &operator=(Result &&RHS) {
143137
FAM = RHS.FAM;
144138
// We have to null out the analysis manager in the moved-from state
@@ -211,15 +205,46 @@ class ModuleToMachineFunctionPassAdaptor
211205
template <typename MachineFunctionPassT>
212206
ModuleToMachineFunctionPassAdaptor
213207
createModuleToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
214-
using PassModelT = detail::PassModel<MachineFunction, MachineFunctionPassT,
215-
MachineFunctionAnalysisManager>;
208+
using PassModelT = detail::MachinePassModel<MachineFunctionPassT>;
216209
// Do not use make_unique, it causes too many template instantiations,
217210
// causing terrible compile times.
218211
return ModuleToMachineFunctionPassAdaptor(
219212
std::unique_ptr<ModuleToMachineFunctionPassAdaptor::PassConceptT>(
220213
new PassModelT(std::forward<MachineFunctionPassT>(Pass))));
221214
}
222215

216+
class FunctionToMachineFunctionPassAdaptor
217+
: public PassInfoMixin<FunctionToMachineFunctionPassAdaptor> {
218+
public:
219+
using PassConceptT =
220+
detail::PassConcept<MachineFunction, MachineFunctionAnalysisManager>;
221+
222+
explicit FunctionToMachineFunctionPassAdaptor(
223+
std::unique_ptr<PassConceptT> Pass)
224+
: Pass(std::move(Pass)) {}
225+
226+
/// Runs the machine function pass across every function.
227+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
228+
void printPipeline(raw_ostream &OS,
229+
function_ref<StringRef(StringRef)> MapClassName2PassName);
230+
231+
static bool isRequired() { return true; }
232+
233+
private:
234+
std::unique_ptr<PassConceptT> Pass;
235+
};
236+
237+
template <typename MachineFunctionPassT>
238+
FunctionToMachineFunctionPassAdaptor
239+
createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
240+
using PassModelT = detail::MachinePassModel<MachineFunctionPassT>;
241+
// Do not use make_unique, it causes too many template instantiations,
242+
// causing terrible compile times.
243+
return FunctionToMachineFunctionPassAdaptor(
244+
std::unique_ptr<FunctionToMachineFunctionPassAdaptor::PassConceptT>(
245+
new PassModelT(std::forward<MachineFunctionPassT>(Pass))));
246+
}
247+
223248
template <>
224249
template <typename PassT>
225250
void PassManager<MachineFunction>::addPass(PassT &&Pass) {

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ add_llvm_component_library(LLVMCodeGen
6767
FixupStatepointCallerSaved.cpp
6868
FreeMachineFunction.cpp
6969
FuncletLayout.cpp
70+
FunctionToMachineFunctionAnalysis.cpp
7071
GCMetadata.cpp
7172
GCMetadataPrinter.cpp
7273
GCRootLowering.cpp

llvm/lib/CodeGen/FreeMachineFunction.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/CodeGen/FreeMachineFunction.h"
10+
#include "llvm/CodeGen/FunctionToMachineFunctionAnalysis.h"
1011
#include "llvm/CodeGen/MachineFunction.h"
1112
#include "llvm/CodeGen/MachineModuleInfo.h"
1213

@@ -15,8 +16,7 @@ using namespace llvm;
1516
PreservedAnalyses
1617
FreeMachineFunctionPass::run(MachineFunction &MF,
1718
MachineFunctionAnalysisManager &MFAM) {
18-
auto &MMI = MF.getMMI();
19-
MFAM.invalidate(MF, PreservedAnalyses::none());
20-
MMI.deleteMachineFunctionFor(MF.getFunction()); // MF is dangling now.
21-
return PreservedAnalyses::none();
19+
PreservedAnalyses PA = PreservedAnalyses::none();
20+
PA.abandon<FunctionToMachineFunctionAnalysis>();
21+
return PA;
2222
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===- FunctionToMachineFunctionAnalysis.cpp ------------------------------===//
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+
//
9+
// This file contains the definitions of the FunctionToMachineFunctionAnalysis
10+
// members.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "llvm/CodeGen/FunctionToMachineFunctionAnalysis.h"
15+
#include "llvm/CodeGen/MachineFunction.h"
16+
#include "llvm/CodeGen/MachineModuleInfo.h"
17+
#include "llvm/Target/TargetMachine.h"
18+
#include <atomic>
19+
20+
using namespace llvm;
21+
22+
AnalysisKey FunctionToMachineFunctionAnalysis::Key;
23+
24+
bool FunctionToMachineFunctionAnalysis::Result::invalidate(
25+
Function &, const PreservedAnalyses &PA,
26+
FunctionAnalysisManager::Invalidator &) {
27+
// Unless it is invalidated explicitly, it should remain preserved.
28+
auto PAC = PA.getChecker<FunctionToMachineFunctionAnalysis>();
29+
return !PAC.preservedWhenStateless();
30+
}
31+
32+
FunctionToMachineFunctionAnalysis::Result
33+
FunctionToMachineFunctionAnalysis::run(Function &F,
34+
FunctionAnalysisManager &FAM) {
35+
// Next unique number available for a MachineFunction in current module.
36+
static std::atomic_uint NextFnNum = 0;
37+
38+
const TargetSubtargetInfo &STI = *TM->getSubtargetImpl(F);
39+
auto &MMI = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F)
40+
.getCachedResult<MachineModuleAnalysis>(*F.getParent())
41+
->getMMI();
42+
auto MF = std::make_unique<MachineFunction>(F, *TM, STI, NextFnNum++, MMI);
43+
MF->initTargetMachineFunctionInfo(STI);
44+
45+
// MRI callback for target specific initializations.
46+
TM->registerMachineRegisterInfoCallback(*MF);
47+
48+
return Result(std::move(MF));
49+
}

llvm/lib/CodeGen/MIRParser/MIRParser.cpp

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/ADT/StringRef.h"
1717
#include "llvm/AsmParser/Parser.h"
1818
#include "llvm/AsmParser/SlotMapping.h"
19+
#include "llvm/CodeGen/FunctionToMachineFunctionAnalysis.h"
1920
#include "llvm/CodeGen/MIRParser/MIParser.h"
2021
#include "llvm/CodeGen/MIRYamlMapping.h"
2122
#include "llvm/CodeGen/MachineConstantPool.h"
@@ -97,13 +98,15 @@ class MIRParserImpl {
9798
/// Create an empty function with the given name.
9899
Function *createDummyFunction(StringRef Name, Module &M);
99100

100-
bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI);
101+
bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI,
102+
ModuleAnalysisManager *FAM = nullptr);
101103

102104
/// Parse the machine function in the current YAML document.
103105
///
104106
///
105107
/// Return true if an error occurred.
106-
bool parseMachineFunction(Module &M, MachineModuleInfo &MMI);
108+
bool parseMachineFunction(Module &M, MachineModuleInfo &MMI,
109+
ModuleAnalysisManager *FAM);
107110

108111
/// Initialize the machine function to the state that's described in the MIR
109112
/// file.
@@ -275,13 +278,14 @@ MIRParserImpl::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {
275278
return M;
276279
}
277280

278-
bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
281+
bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI,
282+
ModuleAnalysisManager *MAM) {
279283
if (NoMIRDocuments)
280284
return false;
281285

282286
// Parse the machine functions.
283287
do {
284-
if (parseMachineFunction(M, MMI))
288+
if (parseMachineFunction(M, MMI, MAM))
285289
return true;
286290
In.nextDocument();
287291
} while (In.setCurrentDocument());
@@ -303,7 +307,8 @@ Function *MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
303307
return F;
304308
}
305309

306-
bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI) {
310+
bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI,
311+
ModuleAnalysisManager *MAM) {
307312
// Parse the yaml.
308313
yaml::MachineFunction YamlMF;
309314
yaml::EmptyContext Ctx;
@@ -327,14 +332,29 @@ bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI) {
327332
"' isn't defined in the provided LLVM IR");
328333
}
329334
}
330-
if (MMI.getMachineFunction(*F) != nullptr)
331-
return error(Twine("redefinition of machine function '") + FunctionName +
332-
"'");
333335

334-
// Create the MachineFunction.
335-
MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
336-
if (initializeMachineFunction(YamlMF, MF))
337-
return true;
336+
if (!MAM) {
337+
if (MMI.getMachineFunction(*F) != nullptr)
338+
return error(Twine("redefinition of machine function '") + FunctionName +
339+
"'");
340+
341+
// Create the MachineFunction.
342+
MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
343+
if (initializeMachineFunction(YamlMF, MF))
344+
return true;
345+
} else {
346+
auto &FAM =
347+
MAM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
348+
if (FAM.getCachedResult<FunctionToMachineFunctionAnalysis>(*F))
349+
return error(Twine("redefinition of machine function '") + FunctionName +
350+
"'");
351+
352+
// Create the MachineFunction.
353+
MachineFunction &MF =
354+
FAM.getResult<FunctionToMachineFunctionAnalysis>(*F).getMF();
355+
if (initializeMachineFunction(YamlMF, MF))
356+
return true;
357+
}
338358

339359
return false;
340360
}
@@ -1101,6 +1121,11 @@ bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
11011121
return Impl->parseMachineFunctions(M, MMI);
11021122
}
11031123

1124+
bool MIRParser::parseMachineFunctions(Module &M, ModuleAnalysisManager &MAM) {
1125+
auto &MMI = MAM.getResult<MachineModuleAnalysis>(M).getMMI();
1126+
return Impl->parseMachineFunctions(M, MMI, &MAM);
1127+
}
1128+
11041129
std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(
11051130
StringRef Filename, SMDiagnostic &Error, LLVMContext &Context,
11061131
std::function<void(Function &)> ProcessIRFunction) {

0 commit comments

Comments
 (0)