1*0b57cec5SDimitry Andric //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 10*0b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 11*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 12*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 13*0b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h" 1481ad6265SDimitry Andric #include "llvm/IR/Constants.h" 15fe6060f1SDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 16fe6060f1SDimitry Andric #include "llvm/IR/LLVMContext.h" 17*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 18480093f4SDimitry Andric #include "llvm/InitializePasses.h" 19*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 20*0b57cec5SDimitry Andric #include "llvm/Pass.h" 2181ad6265SDimitry Andric #include "llvm/Support/CommandLine.h" 22*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 23*0b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 24*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 25*0b57cec5SDimitry Andric #include <algorithm> 26*0b57cec5SDimitry Andric #include <cassert> 27*0b57cec5SDimitry Andric #include <memory> 28*0b57cec5SDimitry Andric #include <utility> 29*0b57cec5SDimitry Andric #include <vector> 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric using namespace llvm; 32*0b57cec5SDimitry Andric using namespace llvm::dwarf; 33*0b57cec5SDimitry Andric 3481ad6265SDimitry Andric static cl::opt<bool> 3581ad6265SDimitry Andric DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden, 3681ad6265SDimitry Andric cl::desc("Disable debug info printing")); 3781ad6265SDimitry Andric 38*0b57cec5SDimitry Andric // Out of line virtual method. 39*0b57cec5SDimitry Andric MachineModuleInfoImpl::~MachineModuleInfoImpl() = default; 40*0b57cec5SDimitry Andric 418bcb0991SDimitry Andric void MachineModuleInfo::initialize() { 42*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 43*0b57cec5SDimitry Andric CurCallSite = 0; 44fe6060f1SDimitry Andric NextFnNum = 0; 4581ad6265SDimitry Andric UsesMSVCFloatingPoint = false; 4681ad6265SDimitry Andric DbgInfoAvailable = false; 47*0b57cec5SDimitry Andric } 48*0b57cec5SDimitry Andric 498bcb0991SDimitry Andric void MachineModuleInfo::finalize() { 50*0b57cec5SDimitry Andric Context.reset(); 51e8d8bef9SDimitry Andric // We don't clear the ExternalContext. 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric delete ObjFileMMI; 54*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 55*0b57cec5SDimitry Andric } 56*0b57cec5SDimitry Andric 578bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) 588bcb0991SDimitry Andric : TM(std::move(MMI.TM)), 59fe6060f1SDimitry Andric Context(MMI.TM.getTargetTriple(), MMI.TM.getMCAsmInfo(), 60fe6060f1SDimitry Andric MMI.TM.getMCRegisterInfo(), MMI.TM.getMCSubtargetInfo(), nullptr, 6181ad6265SDimitry Andric &MMI.TM.Options.MCOptions, false), 62e8d8bef9SDimitry Andric MachineFunctions(std::move(MMI.MachineFunctions)) { 63fe6060f1SDimitry Andric Context.setObjectFileInfo(MMI.TM.getObjFileLowering()); 648bcb0991SDimitry Andric ObjFileMMI = MMI.ObjFileMMI; 658bcb0991SDimitry Andric CurCallSite = MMI.CurCallSite; 66e8d8bef9SDimitry Andric ExternalContext = MMI.ExternalContext; 678bcb0991SDimitry Andric TheModule = MMI.TheModule; 688bcb0991SDimitry Andric } 698bcb0991SDimitry Andric 708bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 71fe6060f1SDimitry Andric : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), 72fe6060f1SDimitry Andric TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), 7381ad6265SDimitry Andric nullptr, &TM->Options.MCOptions, false) { 74fe6060f1SDimitry Andric Context.setObjectFileInfo(TM->getObjFileLowering()); 758bcb0991SDimitry Andric initialize(); 768bcb0991SDimitry Andric } 778bcb0991SDimitry Andric 78e8d8bef9SDimitry Andric MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM, 79e8d8bef9SDimitry Andric MCContext *ExtContext) 80fe6060f1SDimitry Andric : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), 81fe6060f1SDimitry Andric TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), 8281ad6265SDimitry Andric nullptr, &TM->Options.MCOptions, false), 83e8d8bef9SDimitry Andric ExternalContext(ExtContext) { 84fe6060f1SDimitry Andric Context.setObjectFileInfo(TM->getObjFileLowering()); 85e8d8bef9SDimitry Andric initialize(); 86e8d8bef9SDimitry Andric } 87e8d8bef9SDimitry Andric 888bcb0991SDimitry Andric MachineModuleInfo::~MachineModuleInfo() { finalize(); } 898bcb0991SDimitry Andric 90*0b57cec5SDimitry Andric MachineFunction * 91*0b57cec5SDimitry Andric MachineModuleInfo::getMachineFunction(const Function &F) const { 92*0b57cec5SDimitry Andric auto I = MachineFunctions.find(&F); 93*0b57cec5SDimitry Andric return I != MachineFunctions.end() ? I->second.get() : nullptr; 94*0b57cec5SDimitry Andric } 95*0b57cec5SDimitry Andric 965ffd83dbSDimitry Andric MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) { 97*0b57cec5SDimitry Andric // Shortcut for the common case where a sequence of MachineFunctionPasses 98*0b57cec5SDimitry Andric // all query for the same Function. 99*0b57cec5SDimitry Andric if (LastRequest == &F) 100*0b57cec5SDimitry Andric return *LastResult; 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric auto I = MachineFunctions.insert( 103*0b57cec5SDimitry Andric std::make_pair(&F, std::unique_ptr<MachineFunction>())); 104*0b57cec5SDimitry Andric MachineFunction *MF; 105*0b57cec5SDimitry Andric if (I.second) { 106*0b57cec5SDimitry Andric // No pre-existing machine function, create a new one. 107*0b57cec5SDimitry Andric const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 108*0b57cec5SDimitry Andric MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 109bdd1243dSDimitry Andric MF->initTargetMachineFunctionInfo(STI); 110*0b57cec5SDimitry Andric // Update the set entry. 111*0b57cec5SDimitry Andric I.first->second.reset(MF); 112*0b57cec5SDimitry Andric } else { 113*0b57cec5SDimitry Andric MF = I.first->second.get(); 114*0b57cec5SDimitry Andric } 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andric LastRequest = &F; 117*0b57cec5SDimitry Andric LastResult = MF; 118*0b57cec5SDimitry Andric return *MF; 119*0b57cec5SDimitry Andric } 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 122*0b57cec5SDimitry Andric MachineFunctions.erase(&F); 123*0b57cec5SDimitry Andric LastRequest = nullptr; 124*0b57cec5SDimitry Andric LastResult = nullptr; 125*0b57cec5SDimitry Andric } 126*0b57cec5SDimitry Andric 12781ad6265SDimitry Andric void MachineModuleInfo::insertFunction(const Function &F, 12881ad6265SDimitry Andric std::unique_ptr<MachineFunction> &&MF) { 12981ad6265SDimitry Andric auto I = MachineFunctions.insert(std::make_pair(&F, std::move(MF))); 13081ad6265SDimitry Andric assert(I.second && "machine function already mapped"); 13181ad6265SDimitry Andric (void)I; 13281ad6265SDimitry Andric } 13381ad6265SDimitry Andric 134*0b57cec5SDimitry Andric namespace { 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric /// This pass frees the MachineFunction object associated with a Function. 137*0b57cec5SDimitry Andric class FreeMachineFunction : public FunctionPass { 138*0b57cec5SDimitry Andric public: 139*0b57cec5SDimitry Andric static char ID; 140*0b57cec5SDimitry Andric 141*0b57cec5SDimitry Andric FreeMachineFunction() : FunctionPass(ID) {} 142*0b57cec5SDimitry Andric 143*0b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 1448bcb0991SDimitry Andric AU.addRequired<MachineModuleInfoWrapperPass>(); 1458bcb0991SDimitry Andric AU.addPreserved<MachineModuleInfoWrapperPass>(); 146*0b57cec5SDimitry Andric } 147*0b57cec5SDimitry Andric 148*0b57cec5SDimitry Andric bool runOnFunction(Function &F) override { 1498bcb0991SDimitry Andric MachineModuleInfo &MMI = 1508bcb0991SDimitry Andric getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 151*0b57cec5SDimitry Andric MMI.deleteMachineFunctionFor(F); 152*0b57cec5SDimitry Andric return true; 153*0b57cec5SDimitry Andric } 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andric StringRef getPassName() const override { 156*0b57cec5SDimitry Andric return "Free MachineFunction"; 157*0b57cec5SDimitry Andric } 158*0b57cec5SDimitry Andric }; 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric } // end anonymous namespace 161*0b57cec5SDimitry Andric 162*0b57cec5SDimitry Andric char FreeMachineFunction::ID; 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andric FunctionPass *llvm::createFreeMachineFunctionPass() { 165*0b57cec5SDimitry Andric return new FreeMachineFunction(); 166*0b57cec5SDimitry Andric } 1678bcb0991SDimitry Andric 1688bcb0991SDimitry Andric MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 1698bcb0991SDimitry Andric const LLVMTargetMachine *TM) 1708bcb0991SDimitry Andric : ImmutablePass(ID), MMI(TM) { 1718bcb0991SDimitry Andric initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 1728bcb0991SDimitry Andric } 1738bcb0991SDimitry Andric 174e8d8bef9SDimitry Andric MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 175e8d8bef9SDimitry Andric const LLVMTargetMachine *TM, MCContext *ExtContext) 176e8d8bef9SDimitry Andric : ImmutablePass(ID), MMI(TM, ExtContext) { 177e8d8bef9SDimitry Andric initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 178e8d8bef9SDimitry Andric } 179e8d8bef9SDimitry Andric 1808bcb0991SDimitry Andric // Handle the Pass registration stuff necessary to use DataLayout's. 1818bcb0991SDimitry Andric INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 1828bcb0991SDimitry Andric "Machine Module Information", false, false) 1838bcb0991SDimitry Andric char MachineModuleInfoWrapperPass::ID = 0; 1848bcb0991SDimitry Andric 185fe6060f1SDimitry Andric static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr, 186fe6060f1SDimitry Andric std::vector<const MDNode *> &LocInfos) { 187fe6060f1SDimitry Andric // Look up a LocInfo for the buffer this diagnostic is coming from. 188fe6060f1SDimitry Andric unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc()); 189fe6060f1SDimitry Andric const MDNode *LocInfo = nullptr; 190fe6060f1SDimitry Andric if (BufNum > 0 && BufNum <= LocInfos.size()) 191fe6060f1SDimitry Andric LocInfo = LocInfos[BufNum - 1]; 192fe6060f1SDimitry Andric 193fe6060f1SDimitry Andric // If the inline asm had metadata associated with it, pull out a location 194fe6060f1SDimitry Andric // cookie corresponding to which line the error occurred on. 195fe6060f1SDimitry Andric unsigned LocCookie = 0; 196fe6060f1SDimitry Andric if (LocInfo) { 197fe6060f1SDimitry Andric unsigned ErrorLine = SMD.getLineNo() - 1; 198fe6060f1SDimitry Andric if (ErrorLine >= LocInfo->getNumOperands()) 199fe6060f1SDimitry Andric ErrorLine = 0; 200fe6060f1SDimitry Andric 201fe6060f1SDimitry Andric if (LocInfo->getNumOperands() != 0) 202fe6060f1SDimitry Andric if (const ConstantInt *CI = 203fe6060f1SDimitry Andric mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine))) 204fe6060f1SDimitry Andric LocCookie = CI->getZExtValue(); 205fe6060f1SDimitry Andric } 206fe6060f1SDimitry Andric 207fe6060f1SDimitry Andric return LocCookie; 208fe6060f1SDimitry Andric } 209fe6060f1SDimitry Andric 2108bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 2118bcb0991SDimitry Andric MMI.initialize(); 2128bcb0991SDimitry Andric MMI.TheModule = &M; 213fe6060f1SDimitry Andric // FIXME: Do this for new pass manager. 214fe6060f1SDimitry Andric LLVMContext &Ctx = M.getContext(); 215fe6060f1SDimitry Andric MMI.getContext().setDiagnosticHandler( 2161fd87a68SDimitry Andric [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm, 2171fd87a68SDimitry Andric const SourceMgr &SrcMgr, 218fe6060f1SDimitry Andric std::vector<const MDNode *> &LocInfos) { 219fe6060f1SDimitry Andric unsigned LocCookie = 0; 220fe6060f1SDimitry Andric if (IsInlineAsm) 221fe6060f1SDimitry Andric LocCookie = getLocCookie(SMD, SrcMgr, LocInfos); 2221fd87a68SDimitry Andric Ctx.diagnose( 2231fd87a68SDimitry Andric DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie)); 224fe6060f1SDimitry Andric }); 22581ad6265SDimitry Andric MMI.DbgInfoAvailable = !DisableDebugInfoPrinting && 22681ad6265SDimitry Andric !M.debug_compile_units().empty(); 2278bcb0991SDimitry Andric return false; 2288bcb0991SDimitry Andric } 2298bcb0991SDimitry Andric 2308bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 2318bcb0991SDimitry Andric MMI.finalize(); 2328bcb0991SDimitry Andric return false; 2338bcb0991SDimitry Andric } 2348bcb0991SDimitry Andric 2358bcb0991SDimitry Andric AnalysisKey MachineModuleAnalysis::Key; 2368bcb0991SDimitry Andric 2378bcb0991SDimitry Andric MachineModuleInfo MachineModuleAnalysis::run(Module &M, 2388bcb0991SDimitry Andric ModuleAnalysisManager &) { 2398bcb0991SDimitry Andric MachineModuleInfo MMI(TM); 2408bcb0991SDimitry Andric MMI.TheModule = &M; 24181ad6265SDimitry Andric MMI.DbgInfoAvailable = !DisableDebugInfoPrinting && 24281ad6265SDimitry Andric !M.debug_compile_units().empty(); 2438bcb0991SDimitry Andric return MMI; 2448bcb0991SDimitry Andric } 245