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(MMI.TM.getTargetTriple(), MMI.TM.getMCAsmInfo(), 60 MMI.TM.getMCRegisterInfo(), MMI.TM.getMCSubtargetInfo(), nullptr, 61 &MMI.TM.Options.MCOptions, false), 62 MachineFunctions(std::move(MMI.MachineFunctions)) { 63 Context.setObjectFileInfo(MMI.TM.getObjFileLowering()); 64 ObjFileMMI = MMI.ObjFileMMI; 65 CurCallSite = MMI.CurCallSite; 66 ExternalContext = MMI.ExternalContext; 67 TheModule = MMI.TheModule; 68 } 69 70 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 71 : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), 72 TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), 73 nullptr, &TM->Options.MCOptions, false) { 74 Context.setObjectFileInfo(TM->getObjFileLowering()); 75 initialize(); 76 } 77 78 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM, 79 MCContext *ExtContext) 80 : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), 81 TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), 82 nullptr, &TM->Options.MCOptions, false), 83 ExternalContext(ExtContext) { 84 Context.setObjectFileInfo(TM->getObjFileLowering()); 85 initialize(); 86 } 87 88 MachineModuleInfo::~MachineModuleInfo() { finalize(); } 89 90 MachineFunction * 91 MachineModuleInfo::getMachineFunction(const Function &F) const { 92 auto I = MachineFunctions.find(&F); 93 return I != MachineFunctions.end() ? I->second.get() : nullptr; 94 } 95 96 MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) { 97 // Shortcut for the common case where a sequence of MachineFunctionPasses 98 // all query for the same Function. 99 if (LastRequest == &F) 100 return *LastResult; 101 102 auto I = MachineFunctions.insert( 103 std::make_pair(&F, std::unique_ptr<MachineFunction>())); 104 MachineFunction *MF; 105 if (I.second) { 106 // No pre-existing machine function, create a new one. 107 const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 108 MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 109 MF->initTargetMachineFunctionInfo(STI); 110 // Update the set entry. 111 I.first->second.reset(MF); 112 } else { 113 MF = I.first->second.get(); 114 } 115 116 LastRequest = &F; 117 LastResult = MF; 118 return *MF; 119 } 120 121 void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 122 MachineFunctions.erase(&F); 123 LastRequest = nullptr; 124 LastResult = nullptr; 125 } 126 127 void MachineModuleInfo::insertFunction(const Function &F, 128 std::unique_ptr<MachineFunction> &&MF) { 129 auto I = MachineFunctions.insert(std::make_pair(&F, std::move(MF))); 130 assert(I.second && "machine function already mapped"); 131 (void)I; 132 } 133 134 namespace { 135 136 /// This pass frees the MachineFunction object associated with a Function. 137 class FreeMachineFunction : public FunctionPass { 138 public: 139 static char ID; 140 141 FreeMachineFunction() : FunctionPass(ID) {} 142 143 void getAnalysisUsage(AnalysisUsage &AU) const override { 144 AU.addRequired<MachineModuleInfoWrapperPass>(); 145 AU.addPreserved<MachineModuleInfoWrapperPass>(); 146 } 147 148 bool runOnFunction(Function &F) override { 149 MachineModuleInfo &MMI = 150 getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 151 MMI.deleteMachineFunctionFor(F); 152 return true; 153 } 154 155 StringRef getPassName() const override { 156 return "Free MachineFunction"; 157 } 158 }; 159 160 } // end anonymous namespace 161 162 char FreeMachineFunction::ID; 163 164 FunctionPass *llvm::createFreeMachineFunctionPass() { 165 return new FreeMachineFunction(); 166 } 167 168 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 169 const LLVMTargetMachine *TM) 170 : ImmutablePass(ID), MMI(TM) { 171 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 172 } 173 174 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 175 const LLVMTargetMachine *TM, MCContext *ExtContext) 176 : ImmutablePass(ID), MMI(TM, ExtContext) { 177 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 178 } 179 180 // Handle the Pass registration stuff necessary to use DataLayout's. 181 INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 182 "Machine Module Information", false, false) 183 char MachineModuleInfoWrapperPass::ID = 0; 184 185 static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr, 186 std::vector<const MDNode *> &LocInfos) { 187 // Look up a LocInfo for the buffer this diagnostic is coming from. 188 unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc()); 189 const MDNode *LocInfo = nullptr; 190 if (BufNum > 0 && BufNum <= LocInfos.size()) 191 LocInfo = LocInfos[BufNum - 1]; 192 193 // If the inline asm had metadata associated with it, pull out a location 194 // cookie corresponding to which line the error occurred on. 195 unsigned LocCookie = 0; 196 if (LocInfo) { 197 unsigned ErrorLine = SMD.getLineNo() - 1; 198 if (ErrorLine >= LocInfo->getNumOperands()) 199 ErrorLine = 0; 200 201 if (LocInfo->getNumOperands() != 0) 202 if (const ConstantInt *CI = 203 mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine))) 204 LocCookie = CI->getZExtValue(); 205 } 206 207 return LocCookie; 208 } 209 210 bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 211 MMI.initialize(); 212 MMI.TheModule = &M; 213 // FIXME: Do this for new pass manager. 214 LLVMContext &Ctx = M.getContext(); 215 MMI.getContext().setDiagnosticHandler( 216 [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm, 217 const SourceMgr &SrcMgr, 218 std::vector<const MDNode *> &LocInfos) { 219 unsigned LocCookie = 0; 220 if (IsInlineAsm) 221 LocCookie = getLocCookie(SMD, SrcMgr, LocInfos); 222 Ctx.diagnose( 223 DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie)); 224 }); 225 MMI.DbgInfoAvailable = !DisableDebugInfoPrinting && 226 !M.debug_compile_units().empty(); 227 return false; 228 } 229 230 bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 231 MMI.finalize(); 232 return false; 233 } 234 235 AnalysisKey MachineModuleAnalysis::Key; 236 237 MachineModuleInfo MachineModuleAnalysis::run(Module &M, 238 ModuleAnalysisManager &) { 239 MachineModuleInfo MMI(TM); 240 MMI.TheModule = &M; 241 MMI.DbgInfoAvailable = !DisableDebugInfoPrinting && 242 !M.debug_compile_units().empty(); 243 return MMI; 244 } 245