1//===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
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#include "llvm/CodeGen/MachineModuleInfo.h"
10#include "llvm/ADT/DenseMap.h"
11#include "llvm/ADT/StringRef.h"
12#include "llvm/CodeGen/MachineFunction.h"
13#include "llvm/CodeGen/Passes.h"
14#include "llvm/IR/Constants.h"
15#include "llvm/IR/DiagnosticInfo.h"
16#include "llvm/IR/LLVMContext.h"
17#include "llvm/IR/Module.h"
18#include "llvm/InitializePasses.h"
19#include "llvm/MC/MCContext.h"
20#include "llvm/Pass.h"
21#include "llvm/Support/CommandLine.h"
22#include "llvm/Support/ErrorHandling.h"
23#include "llvm/Target/TargetLoweringObjectFile.h"
24#include "llvm/Target/TargetMachine.h"
25#include <algorithm>
26#include <cassert>
27#include <memory>
28#include <utility>
29#include <vector>
30
31using namespace llvm;
32using namespace llvm::dwarf;
33
34static cl::opt<bool>
35    DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
36                             cl::desc("Disable debug info printing"));
37
38// Out of line virtual method.
39MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;
40
41void MachineModuleInfo::initialize() {
42  ObjFileMMI = nullptr;
43  CurCallSite = 0;
44  NextFnNum = 0;
45  UsesMSVCFloatingPoint = false;
46  DbgInfoAvailable = false;
47}
48
49void MachineModuleInfo::finalize() {
50  Context.reset();
51  // We don't clear the ExternalContext.
52
53  delete ObjFileMMI;
54  ObjFileMMI = nullptr;
55}
56
57MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
58    : TM(std::move(MMI.TM)),
59      Context(TM.getTargetTriple(), TM.getMCAsmInfo(), TM.getMCRegisterInfo(),
60              TM.getMCSubtargetInfo(), nullptr, &TM.Options.MCOptions, false),
61      MachineFunctions(std::move(MMI.MachineFunctions)) {
62  Context.setObjectFileInfo(TM.getObjFileLowering());
63  ObjFileMMI = MMI.ObjFileMMI;
64  CurCallSite = MMI.CurCallSite;
65  ExternalContext = MMI.ExternalContext;
66  TheModule = MMI.TheModule;
67}
68
69MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM)
70    : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
71                       TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(),
72                       nullptr, &TM->Options.MCOptions, false) {
73  Context.setObjectFileInfo(TM->getObjFileLowering());
74  initialize();
75}
76
77MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM,
78                                     MCContext *ExtContext)
79    : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
80                       TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(),
81                       nullptr, &TM->Options.MCOptions, false),
82      ExternalContext(ExtContext) {
83  Context.setObjectFileInfo(TM->getObjFileLowering());
84  initialize();
85}
86
87MachineModuleInfo::~MachineModuleInfo() { finalize(); }
88
89MachineFunction *
90MachineModuleInfo::getMachineFunction(const Function &F) const {
91  auto I = MachineFunctions.find(&F);
92  return I != MachineFunctions.end() ? I->second.get() : nullptr;
93}
94
95MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) {
96  // Shortcut for the common case where a sequence of MachineFunctionPasses
97  // all query for the same Function.
98  if (LastRequest == &F)
99    return *LastResult;
100
101  auto I = MachineFunctions.insert(
102      std::make_pair(&F, std::unique_ptr<MachineFunction>()));
103  MachineFunction *MF;
104  if (I.second) {
105    // No pre-existing machine function, create a new one.
106    const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F);
107    MF = new MachineFunction(F, TM, STI, NextFnNum++, *this);
108    MF->initTargetMachineFunctionInfo(STI);
109
110    // MRI callback for target specific initializations.
111    TM.registerMachineRegisterInfoCallback(*MF);
112
113    // Update the set entry.
114    I.first->second.reset(MF);
115  } else {
116    MF = I.first->second.get();
117  }
118
119  LastRequest = &F;
120  LastResult = MF;
121  return *MF;
122}
123
124void MachineModuleInfo::deleteMachineFunctionFor(Function &F) {
125  MachineFunctions.erase(&F);
126  LastRequest = nullptr;
127  LastResult = nullptr;
128}
129
130void MachineModuleInfo::insertFunction(const Function &F,
131                                       std::unique_ptr<MachineFunction> &&MF) {
132  auto I = MachineFunctions.insert(std::make_pair(&F, std::move(MF)));
133  assert(I.second && "machine function already mapped");
134  (void)I;
135}
136
137namespace {
138
139/// This pass frees the MachineFunction object associated with a Function.
140class FreeMachineFunction : public FunctionPass {
141public:
142  static char ID;
143
144  FreeMachineFunction() : FunctionPass(ID) {}
145
146  void getAnalysisUsage(AnalysisUsage &AU) const override {
147    AU.addRequired<MachineModuleInfoWrapperPass>();
148    AU.addPreserved<MachineModuleInfoWrapperPass>();
149  }
150
151  bool runOnFunction(Function &F) override {
152    MachineModuleInfo &MMI =
153        getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
154    MMI.deleteMachineFunctionFor(F);
155    return true;
156  }
157
158  StringRef getPassName() const override {
159    return "Free MachineFunction";
160  }
161};
162
163} // end anonymous namespace
164
165char FreeMachineFunction::ID;
166
167FunctionPass *llvm::createFreeMachineFunctionPass() {
168  return new FreeMachineFunction();
169}
170
171MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
172    const LLVMTargetMachine *TM)
173    : ImmutablePass(ID), MMI(TM) {
174  initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
175}
176
177MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
178    const LLVMTargetMachine *TM, MCContext *ExtContext)
179    : ImmutablePass(ID), MMI(TM, ExtContext) {
180  initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
181}
182
183// Handle the Pass registration stuff necessary to use DataLayout's.
184INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo",
185                "Machine Module Information", false, false)
186char MachineModuleInfoWrapperPass::ID = 0;
187
188static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr,
189                             std::vector<const MDNode *> &LocInfos) {
190  // Look up a LocInfo for the buffer this diagnostic is coming from.
191  unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc());
192  const MDNode *LocInfo = nullptr;
193  if (BufNum > 0 && BufNum <= LocInfos.size())
194    LocInfo = LocInfos[BufNum - 1];
195
196  // If the inline asm had metadata associated with it, pull out a location
197  // cookie corresponding to which line the error occurred on.
198  unsigned LocCookie = 0;
199  if (LocInfo) {
200    unsigned ErrorLine = SMD.getLineNo() - 1;
201    if (ErrorLine >= LocInfo->getNumOperands())
202      ErrorLine = 0;
203
204    if (LocInfo->getNumOperands() != 0)
205      if (const ConstantInt *CI =
206              mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine)))
207        LocCookie = CI->getZExtValue();
208  }
209
210  return LocCookie;
211}
212
213bool MachineModuleInfoWrapperPass::doInitialization(Module &M) {
214  MMI.initialize();
215  MMI.TheModule = &M;
216  // FIXME: Do this for new pass manager.
217  LLVMContext &Ctx = M.getContext();
218  MMI.getContext().setDiagnosticHandler(
219      [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm,
220                 const SourceMgr &SrcMgr,
221                 std::vector<const MDNode *> &LocInfos) {
222        unsigned LocCookie = 0;
223        if (IsInlineAsm)
224          LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
225        Ctx.diagnose(
226            DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
227      });
228  MMI.DbgInfoAvailable = !DisableDebugInfoPrinting &&
229                         !M.debug_compile_units().empty();
230  return false;
231}
232
233bool MachineModuleInfoWrapperPass::doFinalization(Module &M) {
234  MMI.finalize();
235  return false;
236}
237
238AnalysisKey MachineModuleAnalysis::Key;
239
240MachineModuleInfo MachineModuleAnalysis::run(Module &M,
241                                             ModuleAnalysisManager &) {
242  MachineModuleInfo MMI(TM);
243  MMI.TheModule = &M;
244  MMI.DbgInfoAvailable = !DisableDebugInfoPrinting &&
245                         !M.debug_compile_units().empty();
246  return MMI;
247}
248