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