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 // Update the set entry. 110 I.first->second.reset(MF); 111 } else { 112 MF = I.first->second.get(); 113 } 114 115 LastRequest = &F; 116 LastResult = MF; 117 return *MF; 118 } 119 120 void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 121 MachineFunctions.erase(&F); 122 LastRequest = nullptr; 123 LastResult = nullptr; 124 } 125 126 void MachineModuleInfo::insertFunction(const Function &F, 127 std::unique_ptr<MachineFunction> &&MF) { 128 auto I = MachineFunctions.insert(std::make_pair(&F, std::move(MF))); 129 assert(I.second && "machine function already mapped"); 130 (void)I; 131 } 132 133 namespace { 134 135 /// This pass frees the MachineFunction object associated with a Function. 136 class FreeMachineFunction : public FunctionPass { 137 public: 138 static char ID; 139 140 FreeMachineFunction() : FunctionPass(ID) {} 141 142 void getAnalysisUsage(AnalysisUsage &AU) const override { 143 AU.addRequired<MachineModuleInfoWrapperPass>(); 144 AU.addPreserved<MachineModuleInfoWrapperPass>(); 145 } 146 147 bool runOnFunction(Function &F) override { 148 MachineModuleInfo &MMI = 149 getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 150 MMI.deleteMachineFunctionFor(F); 151 return true; 152 } 153 154 StringRef getPassName() const override { 155 return "Free MachineFunction"; 156 } 157 }; 158 159 } // end anonymous namespace 160 161 char FreeMachineFunction::ID; 162 163 FunctionPass *llvm::createFreeMachineFunctionPass() { 164 return new FreeMachineFunction(); 165 } 166 167 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 168 const LLVMTargetMachine *TM) 169 : ImmutablePass(ID), MMI(TM) { 170 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 171 } 172 173 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 174 const LLVMTargetMachine *TM, MCContext *ExtContext) 175 : ImmutablePass(ID), MMI(TM, ExtContext) { 176 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 177 } 178 179 // Handle the Pass registration stuff necessary to use DataLayout's. 180 INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 181 "Machine Module Information", false, false) 182 char MachineModuleInfoWrapperPass::ID = 0; 183 184 static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr, 185 std::vector<const MDNode *> &LocInfos) { 186 // Look up a LocInfo for the buffer this diagnostic is coming from. 187 unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc()); 188 const MDNode *LocInfo = nullptr; 189 if (BufNum > 0 && BufNum <= LocInfos.size()) 190 LocInfo = LocInfos[BufNum - 1]; 191 192 // If the inline asm had metadata associated with it, pull out a location 193 // cookie corresponding to which line the error occurred on. 194 unsigned LocCookie = 0; 195 if (LocInfo) { 196 unsigned ErrorLine = SMD.getLineNo() - 1; 197 if (ErrorLine >= LocInfo->getNumOperands()) 198 ErrorLine = 0; 199 200 if (LocInfo->getNumOperands() != 0) 201 if (const ConstantInt *CI = 202 mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine))) 203 LocCookie = CI->getZExtValue(); 204 } 205 206 return LocCookie; 207 } 208 209 bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 210 MMI.initialize(); 211 MMI.TheModule = &M; 212 // FIXME: Do this for new pass manager. 213 LLVMContext &Ctx = M.getContext(); 214 MMI.getContext().setDiagnosticHandler( 215 [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm, 216 const SourceMgr &SrcMgr, 217 std::vector<const MDNode *> &LocInfos) { 218 unsigned LocCookie = 0; 219 if (IsInlineAsm) 220 LocCookie = getLocCookie(SMD, SrcMgr, LocInfos); 221 Ctx.diagnose( 222 DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie)); 223 }); 224 MMI.DbgInfoAvailable = !DisableDebugInfoPrinting && 225 !M.debug_compile_units().empty(); 226 return false; 227 } 228 229 bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 230 MMI.finalize(); 231 return false; 232 } 233 234 AnalysisKey MachineModuleAnalysis::Key; 235 236 MachineModuleInfo MachineModuleAnalysis::run(Module &M, 237 ModuleAnalysisManager &) { 238 MachineModuleInfo MMI(TM); 239 MMI.TheModule = &M; 240 MMI.DbgInfoAvailable = !DisableDebugInfoPrinting && 241 !M.debug_compile_units().empty(); 242 return MMI; 243 } 244