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