Skip to content

Commit 863ee18

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

16 files changed

+195
-51
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/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) {

llvm/lib/CodeGen/MachinePassManager.cpp

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "llvm/CodeGen/MachinePassManager.h"
14+
#include "llvm/CodeGen/FreeMachineFunction.h"
15+
#include "llvm/CodeGen/FunctionToMachineFunctionAnalysis.h"
1416
#include "llvm/CodeGen/MachineFunction.h"
1517
#include "llvm/CodeGen/MachineModuleInfo.h"
1618
#include "llvm/IR/PassManagerImpl.h"
@@ -71,7 +73,9 @@ bool MachineFunctionAnalysisManagerModuleProxy::Result::invalidate(
7173

7274
PreservedAnalyses
7375
ModuleToMachineFunctionPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {
74-
auto &MMI = AM.getResult<MachineModuleAnalysis>(M).getMMI();
76+
// Ensure we have a MachineModuleInfo
77+
AM.getResult<MachineModuleAnalysis>(M).getMMI();
78+
auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
7579
MachineFunctionAnalysisManager &MFAM =
7680
AM.getResult<MachineFunctionAnalysisManagerModuleProxy>(M).getManager();
7781
PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
@@ -82,19 +86,21 @@ ModuleToMachineFunctionPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {
8286
if (F.isDeclaration() || F.hasAvailableExternallyLinkage())
8387
continue;
8488

85-
MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
89+
MachineFunction &MF =
90+
FAM.getResult<FunctionToMachineFunctionAnalysis>(F).getMF();
8691

8792
if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
8893
continue;
8994
PreservedAnalyses PassPA = Pass->run(MF, MFAM);
90-
if (MMI.getMachineFunction(F)) {
91-
MFAM.invalidate(MF, PassPA);
95+
MFAM.invalidate(MF, PassPA);
96+
if (Pass->name() != FreeMachineFunctionPass::name()) {
9297
PI.runAfterPass(*Pass, MF, PassPA);
98+
PA.intersect(std::move(PassPA));
9399
} else {
94-
MFAM.clear(MF, F.getName());
95-
PI.runAfterPassInvalidated<MachineFunction>(*Pass, PassPA);
100+
PA.intersect(std::move(PassPA));
101+
FAM.invalidate(F, PA);
102+
PI.runAfterPassInvalidated<MachineFunction>(*Pass, PA);
96103
}
97-
PA.intersect(std::move(PassPA));
98104
}
99105

100106
return PA;
@@ -112,25 +118,24 @@ PreservedAnalyses
112118
PassManager<MachineFunction>::run(MachineFunction &MF,
113119
AnalysisManager<MachineFunction> &MFAM) {
114120
PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(MF);
115-
Function &F = MF.getFunction();
116-
MachineModuleInfo &MMI =
117-
MFAM.getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF)
118-
.getCachedResult<MachineModuleAnalysis>(*F.getParent())
119-
->getMMI();
121+
FunctionAnalysisManager &FAM =
122+
MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
123+
.getManager();
120124
PreservedAnalyses PA = PreservedAnalyses::all();
121125
for (auto &Pass : Passes) {
122126
if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
123127
continue;
124128

125129
PreservedAnalyses PassPA = Pass->run(MF, MFAM);
126-
if (MMI.getMachineFunction(F)) {
127-
MFAM.invalidate(MF, PassPA);
130+
MFAM.invalidate(MF, PassPA);
131+
if (Pass->name() != FreeMachineFunctionPass::name()) {
128132
PI.runAfterPass(*Pass, MF, PassPA);
133+
PA.intersect(std::move(PassPA));
129134
} else {
130-
MFAM.clear(MF, F.getName());
131-
PI.runAfterPassInvalidated<MachineFunction>(*Pass, PassPA);
135+
PA.intersect(std::move(PassPA));
136+
FAM.invalidate(MF.getFunction(), PA);
137+
PI.runAfterPassInvalidated<MachineFunction>(*Pass, PA);
132138
}
133-
PA.intersect(std::move(PassPA));
134139
}
135140
return PA;
136141
}

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
#include "llvm/CodeGen/ExpandLargeFpConvert.h"
8484
#include "llvm/CodeGen/ExpandMemCmp.h"
8585
#include "llvm/CodeGen/FreeMachineFunction.h"
86+
#include "llvm/CodeGen/FunctionToMachineFunctionAnalysis.h"
8687
#include "llvm/CodeGen/GCMetadata.h"
8788
#include "llvm/CodeGen/GlobalMerge.h"
8889
#include "llvm/CodeGen/HardwareLoops.h"

llvm/lib/Passes/PassRegistry.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ FUNCTION_ANALYSIS("demanded-bits", DemandedBitsAnalysis())
254254
FUNCTION_ANALYSIS("domfrontier", DominanceFrontierAnalysis())
255255
FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis())
256256
FUNCTION_ANALYSIS("func-properties", FunctionPropertiesAnalysis())
257+
FUNCTION_ANALYSIS("function-to-machine-function",
258+
FunctionToMachineFunctionAnalysis(
259+
static_cast<const LLVMTargetMachine *>(TM)))
257260
FUNCTION_ANALYSIS("gc-function", GCFunctionAnalysis())
258261
FUNCTION_ANALYSIS("inliner-size-estimator", InlineSizeEstimatorAnalysis())
259262
FUNCTION_ANALYSIS("lazy-value-info", LazyValueAnalysis())

0 commit comments

Comments
 (0)