xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/CodeGen/MachineFunctionPass.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
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