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