xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/MachineModuleInfo.cpp (revision d14c38ceb8aa10bd94913d0456ec0f726693379b)
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  
31  using namespace llvm;
32  using namespace llvm::dwarf;
33  
34  static 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.
39  MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;
40  
41  void MachineModuleInfo::initialize() {
42    ObjFileMMI = nullptr;
43    CurCallSite = 0;
44    NextFnNum = 0;
45    UsesMSVCFloatingPoint = false;
46    DbgInfoAvailable = false;
47  }
48  
49  void MachineModuleInfo::finalize() {
50    Context.reset();
51    // We don't clear the ExternalContext.
52  
53    delete ObjFileMMI;
54    ObjFileMMI = nullptr;
55  }
56  
57  MachineModuleInfo::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  
69  MachineModuleInfo::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  
77  MachineModuleInfo::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  
87  MachineModuleInfo::~MachineModuleInfo() { finalize(); }
88  
89  MachineFunction *
90  MachineModuleInfo::getMachineFunction(const Function &F) const {
91    auto I = MachineFunctions.find(&F);
92    return I != MachineFunctions.end() ? I->second.get() : nullptr;
93  }
94  
95  MachineFunction &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  
124  void MachineModuleInfo::deleteMachineFunctionFor(Function &F) {
125    MachineFunctions.erase(&F);
126    LastRequest = nullptr;
127    LastResult = nullptr;
128  }
129  
130  void 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  
137  namespace {
138  
139  /// This pass frees the MachineFunction object associated with a Function.
140  class FreeMachineFunction : public FunctionPass {
141  public:
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  
165  char FreeMachineFunction::ID;
166  
167  FunctionPass *llvm::createFreeMachineFunctionPass() {
168    return new FreeMachineFunction();
169  }
170  
171  MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
172      const LLVMTargetMachine *TM)
173      : ImmutablePass(ID), MMI(TM) {
174    initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
175  }
176  
177  MachineModuleInfoWrapperPass::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.
184  INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo",
185                  "Machine Module Information", false, false)
186  char MachineModuleInfoWrapperPass::ID = 0;
187  
188  static uint64_t 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    uint64_t 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  
213  bool MachineModuleInfoWrapperPass::doInitialization(Module &M) {
214    MMI.initialize();
215    MMI.TheModule = &M;
216    LLVMContext &Ctx = M.getContext();
217    MMI.getContext().setDiagnosticHandler(
218        [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm,
219                   const SourceMgr &SrcMgr,
220                   std::vector<const MDNode *> &LocInfos) {
221          uint64_t LocCookie = 0;
222          if (IsInlineAsm)
223            LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
224          Ctx.diagnose(
225              DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
226        });
227    MMI.DbgInfoAvailable = !DisableDebugInfoPrinting &&
228                           !M.debug_compile_units().empty();
229    return false;
230  }
231  
232  bool MachineModuleInfoWrapperPass::doFinalization(Module &M) {
233    MMI.finalize();
234    return false;
235  }
236  
237  AnalysisKey MachineModuleAnalysis::Key;
238  
239  MachineModuleAnalysis::Result
240  MachineModuleAnalysis::run(Module &M, ModuleAnalysisManager &) {
241    MMI.TheModule = &M;
242    LLVMContext &Ctx = M.getContext();
243    MMI.getContext().setDiagnosticHandler(
244        [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm,
245                   const SourceMgr &SrcMgr,
246                   std::vector<const MDNode *> &LocInfos) {
247          unsigned LocCookie = 0;
248          if (IsInlineAsm)
249            LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
250          Ctx.diagnose(
251              DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
252        });
253    MMI.DbgInfoAvailable =
254        !DisableDebugInfoPrinting && !M.debug_compile_units().empty();
255    return Result(MMI);
256  }
257