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