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