xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp (revision aa3860851b9f6a6002d135b1cac7736e0995eedc)
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/OptimizationRemarkEmitter.h"
21  #include "llvm/Analysis/ScalarEvolution.h"
22  #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
23  #include "llvm/CodeGen/MachineFunction.h"
24  #include "llvm/CodeGen/MachineModuleInfo.h"
25  #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
26  #include "llvm/CodeGen/Passes.h"
27  #include "llvm/IR/Dominators.h"
28  #include "llvm/IR/Function.h"
29  #include "llvm/IR/PrintPasses.h"
30  
31  using namespace llvm;
32  using namespace ore;
33  
34  Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O,
35                                               const std::string &Banner) const {
36    return createMachineFunctionPrinterPass(O, Banner);
37  }
38  
39  bool MachineFunctionPass::runOnFunction(Function &F) {
40    // Do not codegen any 'available_externally' functions at all, they have
41    // definitions outside the translation unit.
42    if (F.hasAvailableExternallyLinkage())
43      return false;
44  
45    MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
46    MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
47  
48    MachineFunctionProperties &MFProps = MF.getProperties();
49  
50  #ifndef NDEBUG
51    if (!MFProps.verifyRequiredProperties(RequiredProperties)) {
52      errs() << "MachineFunctionProperties required by " << getPassName()
53             << " pass are not met by function " << F.getName() << ".\n"
54             << "Required properties: ";
55      RequiredProperties.print(errs());
56      errs() << "\nCurrent properties: ";
57      MFProps.print(errs());
58      errs() << "\n";
59      llvm_unreachable("MachineFunctionProperties check failed");
60    }
61  #endif
62    // Collect the MI count of the function before the pass.
63    unsigned CountBefore, CountAfter;
64  
65    // Check if the user asked for size remarks.
66    bool ShouldEmitSizeRemarks =
67        F.getParent()->shouldEmitInstrCountChangedRemark();
68  
69    // If we want size remarks, collect the number of MachineInstrs in our
70    // MachineFunction before the pass runs.
71    if (ShouldEmitSizeRemarks)
72      CountBefore = MF.getInstructionCount();
73  
74    // For --print-changed, if the function name is a candidate, save the
75    // serialized MF to be compared later.
76    SmallString<0> BeforeStr, AfterStr;
77    StringRef PassID;
78    if (PrintChanged != ChangePrinter::None) {
79      if (const PassInfo *PI = Pass::lookupPassInfo(getPassID()))
80        PassID = PI->getPassArgument();
81    }
82    const bool IsInterestingPass = isPassInPrintList(PassID);
83    const bool ShouldPrintChanged = PrintChanged != ChangePrinter::None &&
84                                    IsInterestingPass &&
85                                    isFunctionInPrintList(MF.getName());
86    if (ShouldPrintChanged) {
87      raw_svector_ostream OS(BeforeStr);
88      MF.print(OS);
89    }
90  
91    MFProps.reset(ClearedProperties);
92  
93    bool RV = runOnMachineFunction(MF);
94  
95    if (ShouldEmitSizeRemarks) {
96      // We wanted size remarks. Check if there was a change to the number of
97      // MachineInstrs in the module. Emit a remark if there was a change.
98      CountAfter = MF.getInstructionCount();
99      if (CountBefore != CountAfter) {
100        MachineOptimizationRemarkEmitter MORE(MF, nullptr);
101        MORE.emit([&]() {
102          int64_t Delta = static_cast<int64_t>(CountAfter) -
103                          static_cast<int64_t>(CountBefore);
104          MachineOptimizationRemarkAnalysis R("size-info", "FunctionMISizeChange",
105                                              MF.getFunction().getSubprogram(),
106                                              &MF.front());
107          R << NV("Pass", getPassName())
108            << ": Function: " << NV("Function", F.getName()) << ": "
109            << "MI Instruction count changed from "
110            << NV("MIInstrsBefore", CountBefore) << " to "
111            << NV("MIInstrsAfter", CountAfter)
112            << "; Delta: " << NV("Delta", Delta);
113          return R;
114        });
115      }
116    }
117  
118    MFProps.set(SetProperties);
119  
120    // For --print-changed, print if the serialized MF has changed. Modes other
121    // than quiet/verbose are unimplemented and treated the same as 'quiet'.
122    if (ShouldPrintChanged || !IsInterestingPass) {
123      if (ShouldPrintChanged) {
124        raw_svector_ostream OS(AfterStr);
125        MF.print(OS);
126      }
127      if (IsInterestingPass && BeforeStr != AfterStr) {
128        errs() << ("*** IR Dump After " + getPassName() + " (" + PassID +
129                   ") on " + MF.getName() + " ***\n");
130        switch (PrintChanged) {
131        case ChangePrinter::None:
132          llvm_unreachable("");
133        case ChangePrinter::Quiet:
134        case ChangePrinter::Verbose:
135        case ChangePrinter::DotCfgQuiet:   // unimplemented
136        case ChangePrinter::DotCfgVerbose: // unimplemented
137          errs() << AfterStr;
138          break;
139        case ChangePrinter::DiffQuiet:
140        case ChangePrinter::DiffVerbose:
141        case ChangePrinter::ColourDiffQuiet:
142        case ChangePrinter::ColourDiffVerbose: {
143          bool Color = llvm::is_contained(
144              {ChangePrinter::ColourDiffQuiet, ChangePrinter::ColourDiffVerbose},
145              PrintChanged.getValue());
146          StringRef Removed = Color ? "\033[31m-%l\033[0m\n" : "-%l\n";
147          StringRef Added = Color ? "\033[32m+%l\033[0m\n" : "+%l\n";
148          StringRef NoChange = " %l\n";
149          errs() << doSystemDiff(BeforeStr, AfterStr, Removed, Added, NoChange);
150          break;
151        }
152        }
153      } else if (llvm::is_contained({ChangePrinter::Verbose,
154                                     ChangePrinter::DiffVerbose,
155                                     ChangePrinter::ColourDiffVerbose},
156                                    PrintChanged.getValue())) {
157        const char *Reason =
158            IsInterestingPass ? " omitted because no change" : " filtered out";
159        errs() << "*** IR Dump After " << getPassName();
160        if (!PassID.empty())
161          errs() << " (" << PassID << ")";
162        errs() << " on " << MF.getName() + Reason + " ***\n";
163      }
164    }
165    return RV;
166  }
167  
168  void MachineFunctionPass::getAnalysisUsage(AnalysisUsage &AU) const {
169    AU.addRequired<MachineModuleInfoWrapperPass>();
170    AU.addPreserved<MachineModuleInfoWrapperPass>();
171  
172    // MachineFunctionPass preserves all LLVM IR passes, but there's no
173    // high-level way to express this. Instead, just list a bunch of
174    // passes explicitly. This does not include setPreservesCFG,
175    // because CodeGen overloads that to mean preserving the MachineBasicBlock
176    // CFG in addition to the LLVM IR CFG.
177    AU.addPreserved<BasicAAWrapperPass>();
178    AU.addPreserved<DominanceFrontierWrapperPass>();
179    AU.addPreserved<DominatorTreeWrapperPass>();
180    AU.addPreserved<AAResultsWrapperPass>();
181    AU.addPreserved<GlobalsAAWrapperPass>();
182    AU.addPreserved<IVUsersWrapperPass>();
183    AU.addPreserved<LoopInfoWrapperPass>();
184    AU.addPreserved<MemoryDependenceWrapperPass>();
185    AU.addPreserved<ScalarEvolutionWrapperPass>();
186    AU.addPreserved<SCEVAAWrapperPass>();
187  
188    FunctionPass::getAnalysisUsage(AU);
189  }
190