1*7330f729Sjoerg //===-- MachineFunctionPass.cpp -------------------------------------------===//
2*7330f729Sjoerg //
3*7330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*7330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
5*7330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*7330f729Sjoerg //
7*7330f729Sjoerg //===----------------------------------------------------------------------===//
8*7330f729Sjoerg //
9*7330f729Sjoerg // This file contains the definitions of the MachineFunctionPass members.
10*7330f729Sjoerg //
11*7330f729Sjoerg //===----------------------------------------------------------------------===//
12*7330f729Sjoerg
13*7330f729Sjoerg #include "llvm/CodeGen/MachineFunctionPass.h"
14*7330f729Sjoerg #include "llvm/Analysis/BasicAliasAnalysis.h"
15*7330f729Sjoerg #include "llvm/Analysis/DominanceFrontier.h"
16*7330f729Sjoerg #include "llvm/Analysis/GlobalsModRef.h"
17*7330f729Sjoerg #include "llvm/Analysis/IVUsers.h"
18*7330f729Sjoerg #include "llvm/Analysis/LoopInfo.h"
19*7330f729Sjoerg #include "llvm/Analysis/MemoryDependenceAnalysis.h"
20*7330f729Sjoerg #include "llvm/Analysis/ScalarEvolution.h"
21*7330f729Sjoerg #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
22*7330f729Sjoerg #include "llvm/CodeGen/MachineFunction.h"
23*7330f729Sjoerg #include "llvm/CodeGen/MachineModuleInfo.h"
24*7330f729Sjoerg #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
25*7330f729Sjoerg #include "llvm/CodeGen/Passes.h"
26*7330f729Sjoerg #include "llvm/IR/Dominators.h"
27*7330f729Sjoerg #include "llvm/IR/Function.h"
28*7330f729Sjoerg
29*7330f729Sjoerg using namespace llvm;
30*7330f729Sjoerg using namespace ore;
31*7330f729Sjoerg
createPrinterPass(raw_ostream & O,const std::string & Banner) const32*7330f729Sjoerg Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O,
33*7330f729Sjoerg const std::string &Banner) const {
34*7330f729Sjoerg return createMachineFunctionPrinterPass(O, Banner);
35*7330f729Sjoerg }
36*7330f729Sjoerg
runOnFunction(Function & F)37*7330f729Sjoerg bool MachineFunctionPass::runOnFunction(Function &F) {
38*7330f729Sjoerg // Do not codegen any 'available_externally' functions at all, they have
39*7330f729Sjoerg // definitions outside the translation unit.
40*7330f729Sjoerg if (F.hasAvailableExternallyLinkage())
41*7330f729Sjoerg return false;
42*7330f729Sjoerg
43*7330f729Sjoerg MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
44*7330f729Sjoerg MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
45*7330f729Sjoerg
46*7330f729Sjoerg MachineFunctionProperties &MFProps = MF.getProperties();
47*7330f729Sjoerg
48*7330f729Sjoerg #ifndef NDEBUG
49*7330f729Sjoerg if (!MFProps.verifyRequiredProperties(RequiredProperties)) {
50*7330f729Sjoerg errs() << "MachineFunctionProperties required by " << getPassName()
51*7330f729Sjoerg << " pass are not met by function " << F.getName() << ".\n"
52*7330f729Sjoerg << "Required properties: ";
53*7330f729Sjoerg RequiredProperties.print(errs());
54*7330f729Sjoerg errs() << "\nCurrent properties: ";
55*7330f729Sjoerg MFProps.print(errs());
56*7330f729Sjoerg errs() << "\n";
57*7330f729Sjoerg llvm_unreachable("MachineFunctionProperties check failed");
58*7330f729Sjoerg }
59*7330f729Sjoerg #endif
60*7330f729Sjoerg // Collect the MI count of the function before the pass.
61*7330f729Sjoerg unsigned CountBefore, CountAfter;
62*7330f729Sjoerg
63*7330f729Sjoerg // Check if the user asked for size remarks.
64*7330f729Sjoerg bool ShouldEmitSizeRemarks =
65*7330f729Sjoerg F.getParent()->shouldEmitInstrCountChangedRemark();
66*7330f729Sjoerg
67*7330f729Sjoerg // If we want size remarks, collect the number of MachineInstrs in our
68*7330f729Sjoerg // MachineFunction before the pass runs.
69*7330f729Sjoerg if (ShouldEmitSizeRemarks)
70*7330f729Sjoerg CountBefore = MF.getInstructionCount();
71*7330f729Sjoerg
72*7330f729Sjoerg bool RV = runOnMachineFunction(MF);
73*7330f729Sjoerg
74*7330f729Sjoerg if (ShouldEmitSizeRemarks) {
75*7330f729Sjoerg // We wanted size remarks. Check if there was a change to the number of
76*7330f729Sjoerg // MachineInstrs in the module. Emit a remark if there was a change.
77*7330f729Sjoerg CountAfter = MF.getInstructionCount();
78*7330f729Sjoerg if (CountBefore != CountAfter) {
79*7330f729Sjoerg MachineOptimizationRemarkEmitter MORE(MF, nullptr);
80*7330f729Sjoerg MORE.emit([&]() {
81*7330f729Sjoerg int64_t Delta = static_cast<int64_t>(CountAfter) -
82*7330f729Sjoerg static_cast<int64_t>(CountBefore);
83*7330f729Sjoerg MachineOptimizationRemarkAnalysis R("size-info", "FunctionMISizeChange",
84*7330f729Sjoerg MF.getFunction().getSubprogram(),
85*7330f729Sjoerg &MF.front());
86*7330f729Sjoerg R << NV("Pass", getPassName())
87*7330f729Sjoerg << ": Function: " << NV("Function", F.getName()) << ": "
88*7330f729Sjoerg << "MI Instruction count changed from "
89*7330f729Sjoerg << NV("MIInstrsBefore", CountBefore) << " to "
90*7330f729Sjoerg << NV("MIInstrsAfter", CountAfter)
91*7330f729Sjoerg << "; Delta: " << NV("Delta", Delta);
92*7330f729Sjoerg return R;
93*7330f729Sjoerg });
94*7330f729Sjoerg }
95*7330f729Sjoerg }
96*7330f729Sjoerg
97*7330f729Sjoerg MFProps.set(SetProperties);
98*7330f729Sjoerg MFProps.reset(ClearedProperties);
99*7330f729Sjoerg return RV;
100*7330f729Sjoerg }
101*7330f729Sjoerg
getAnalysisUsage(AnalysisUsage & AU) const102*7330f729Sjoerg void MachineFunctionPass::getAnalysisUsage(AnalysisUsage &AU) const {
103*7330f729Sjoerg AU.addRequired<MachineModuleInfoWrapperPass>();
104*7330f729Sjoerg AU.addPreserved<MachineModuleInfoWrapperPass>();
105*7330f729Sjoerg
106*7330f729Sjoerg // MachineFunctionPass preserves all LLVM IR passes, but there's no
107*7330f729Sjoerg // high-level way to express this. Instead, just list a bunch of
108*7330f729Sjoerg // passes explicitly. This does not include setPreservesCFG,
109*7330f729Sjoerg // because CodeGen overloads that to mean preserving the MachineBasicBlock
110*7330f729Sjoerg // CFG in addition to the LLVM IR CFG.
111*7330f729Sjoerg AU.addPreserved<BasicAAWrapperPass>();
112*7330f729Sjoerg AU.addPreserved<DominanceFrontierWrapperPass>();
113*7330f729Sjoerg AU.addPreserved<DominatorTreeWrapperPass>();
114*7330f729Sjoerg AU.addPreserved<AAResultsWrapperPass>();
115*7330f729Sjoerg AU.addPreserved<GlobalsAAWrapperPass>();
116*7330f729Sjoerg AU.addPreserved<IVUsersWrapperPass>();
117*7330f729Sjoerg AU.addPreserved<LoopInfoWrapperPass>();
118*7330f729Sjoerg AU.addPreserved<MemoryDependenceWrapperPass>();
119*7330f729Sjoerg AU.addPreserved<ScalarEvolutionWrapperPass>();
120*7330f729Sjoerg AU.addPreserved<SCEVAAWrapperPass>();
121*7330f729Sjoerg
122*7330f729Sjoerg FunctionPass::getAnalysisUsage(AU);
123*7330f729Sjoerg }
124