Skip to content

Commit 2a7a8ce

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

20 files changed

+209
-52
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: 4 additions & 0 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());

llvm/include/llvm/IR/LLVMContext.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ class LLVMContext {
155155
void enableDebugTypeODRUniquing();
156156
void disableDebugTypeODRUniquing();
157157

158+
/// generateMachineFunctionNum - Get a unique number for MachineFunction
159+
/// that associated with the given Function.
160+
unsigned generateMachineFunctionNum(Function &);
161+
158162
/// Defines the type of a yield callback.
159163
/// \see LLVMContext::setYieldCallback.
160164
using YieldCallbackTy = void (*)(LLVMContext *Context, void *OpaqueHandle);
@@ -332,7 +336,7 @@ class LLVMContext {
332336
void addModule(Module*);
333337

334338
/// removeModule - Unregister a module from this context.
335-
void removeModule(Module*);
339+
void removeModule(Module *);
336340
};
337341

338342
// Create wrappers for C Binding types (see CBindingWrapping.h).

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "llvm/CodeGen/JMCInstrumenter.h"
3939
#include "llvm/CodeGen/LowerEmuTLS.h"
4040
#include "llvm/CodeGen/MIRPrinter.h"
41+
#include "llvm/CodeGen/MachineModuleInfo.h"
4142
#include "llvm/CodeGen/MachinePassManager.h"
4243
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
4344
#include "llvm/CodeGen/ReplaceWithVeclib.h"
@@ -512,6 +513,7 @@ Error CodeGenPassBuilder<Derived>::buildPipeline(
512513

513514
{
514515
AddIRPass addIRPass(MPM, derived());
516+
addIRPass(RequireAnalysisPass<MachineModuleAnalysis, Module>());
515517
addIRPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
516518
addIRPass(RequireAnalysisPass<CollectorMetadataAnalysis, Module>());
517519
addISelPasses(addIRPass);

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: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
19+
using namespace llvm;
20+
21+
AnalysisKey FunctionToMachineFunctionAnalysis::Key;
22+
23+
bool FunctionToMachineFunctionAnalysis::Result::invalidate(
24+
Function &, const PreservedAnalyses &PA,
25+
FunctionAnalysisManager::Invalidator &) {
26+
// Unless it is invalidated explicitly, it should remain preserved.
27+
auto PAC = PA.getChecker<FunctionToMachineFunctionAnalysis>();
28+
return !PAC.preservedWhenStateless();
29+
}
30+
31+
FunctionToMachineFunctionAnalysis::Result
32+
FunctionToMachineFunctionAnalysis::run(Function &F,
33+
FunctionAnalysisManager &FAM) {
34+
auto &Context = F.getContext();
35+
const TargetSubtargetInfo &STI = *TM->getSubtargetImpl(F);
36+
auto &MMI = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F)
37+
.getCachedResult<MachineModuleAnalysis>(*F.getParent())
38+
->getMMI();
39+
auto MF = std::make_unique<MachineFunction>(
40+
F, *TM, STI, Context.generateMachineFunctionNum(F), MMI);
41+
MF->initTargetMachineFunctionInfo(STI);
42+
43+
// MRI callback for target specific initializations.
44+
TM->registerMachineRegisterInfoCallback(*MF);
45+
46+
return Result(std::move(MF));
47+
}

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)