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