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