1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
//===---------- MachinePassManager.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the pass management machinery for machine functions.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManagerImpl.h"
#include "llvm/Support/Compiler.h"
using namespace llvm;
AnalysisKey FunctionAnalysisManagerMachineFunctionProxy::Key;
namespace llvm {
template class LLVM_EXPORT_TEMPLATE AnalysisManager<MachineFunction>;
template class PassManager<MachineFunction>;
template class LLVM_EXPORT_TEMPLATE
InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Module>;
template class LLVM_EXPORT_TEMPLATE
InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Function>;
template class LLVM_EXPORT_TEMPLATE
OuterAnalysisManagerProxy<ModuleAnalysisManager, MachineFunction>;
} // namespace llvm
bool FunctionAnalysisManagerMachineFunctionProxy::Result::invalidate(
MachineFunction &IR, const PreservedAnalyses &PA,
MachineFunctionAnalysisManager::Invalidator &Inv) {
// MachineFunction passes should not invalidate Function analyses.
// TODO: verify that PA doesn't invalidate Function analyses.
return false;
}
template <>
bool MachineFunctionAnalysisManagerModuleProxy::Result::invalidate(
Module &M, const PreservedAnalyses &PA,
ModuleAnalysisManager::Invalidator &Inv) {
// If literally everything is preserved, we're done.
if (PA.areAllPreserved())
return false; // This is still a valid proxy.
// If this proxy isn't marked as preserved, then even if the result remains
// valid, the key itself may no longer be valid, so we clear everything.
//
// Note that in order to preserve this proxy, a module pass must ensure that
// the MFAM has been completely updated to handle the deletion of functions.
// Specifically, any MFAM-cached results for those functions need to have been
// forcibly cleared. When preserved, this proxy will only invalidate results
// cached on functions *still in the module* at the end of the module pass.
auto PAC = PA.getChecker<MachineFunctionAnalysisManagerModuleProxy>();
if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
InnerAM->clear();
return true;
}
// FIXME: be more precise, see
// FunctionAnalysisManagerModuleProxy::Result::invalidate.
if (!PA.allAnalysesInSetPreserved<AllAnalysesOn<MachineFunction>>()) {
InnerAM->clear();
return true;
}
// Return false to indicate that this result is still a valid proxy.
return false;
}
template <>
bool MachineFunctionAnalysisManagerFunctionProxy::Result::invalidate(
Function &F, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv) {
// If literally everything is preserved, we're done.
if (PA.areAllPreserved())
return false; // This is still a valid proxy.
// If this proxy isn't marked as preserved, then even if the result remains
// valid, the key itself may no longer be valid, so we clear everything.
//
// Note that in order to preserve this proxy, a module pass must ensure that
// the MFAM has been completely updated to handle the deletion of functions.
// Specifically, any MFAM-cached results for those functions need to have been
// forcibly cleared. When preserved, this proxy will only invalidate results
// cached on functions *still in the module* at the end of the module pass.
auto PAC = PA.getChecker<MachineFunctionAnalysisManagerFunctionProxy>();
if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>()) {
InnerAM->clear();
return true;
}
// FIXME: be more precise, see
// FunctionAnalysisManagerModuleProxy::Result::invalidate.
if (!PA.allAnalysesInSetPreserved<AllAnalysesOn<MachineFunction>>()) {
InnerAM->clear();
return true;
}
// Return false to indicate that this result is still a valid proxy.
return false;
}
PreservedAnalyses
FunctionToMachineFunctionPassAdaptor::run(Function &F,
FunctionAnalysisManager &FAM) {
MachineFunctionAnalysisManager &MFAM =
FAM.getResult<MachineFunctionAnalysisManagerFunctionProxy>(F)
.getManager();
PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(F);
PreservedAnalyses PA = PreservedAnalyses::all();
// Do not codegen any 'available_externally' functions at all, they have
// definitions outside the translation unit.
if (F.isDeclaration() || F.hasAvailableExternallyLinkage())
return PreservedAnalyses::all();
MachineFunction &MF = FAM.getResult<MachineFunctionAnalysis>(F).getMF();
if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
return PreservedAnalyses::all();
PreservedAnalyses PassPA = Pass->run(MF, MFAM);
MFAM.invalidate(MF, PassPA);
PI.runAfterPass(*Pass, MF, PassPA);
PA.intersect(std::move(PassPA));
return PA;
}
void FunctionToMachineFunctionPassAdaptor::printPipeline(
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
OS << "machine-function(";
Pass->printPipeline(OS, MapClassName2PassName);
OS << ')';
}
template <>
PreservedAnalyses
PassManager<MachineFunction>::run(MachineFunction &MF,
AnalysisManager<MachineFunction> &MFAM) {
PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(MF);
PreservedAnalyses PA = PreservedAnalyses::all();
for (auto &Pass : Passes) {
if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
continue;
PreservedAnalyses PassPA = Pass->run(MF, MFAM);
MFAM.invalidate(MF, PassPA);
PI.runAfterPass(*Pass, MF, PassPA);
PA.intersect(std::move(PassPA));
}
PA.preserveSet<AllAnalysesOn<MachineFunction>>();
return PA;
}
PreservedAnalyses llvm::getMachineFunctionPassPreservedAnalyses() {
PreservedAnalyses PA;
// Machine function passes are not allowed to modify the LLVM
// representation, therefore we should preserve all IR analyses.
PA.template preserveSet<AllAnalysesOn<Module>>();
PA.template preserveSet<AllAnalysesOn<Function>>();
return PA;
}
|