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