235 lines · cpp
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-exception6//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 21using namespace llvm;22using namespace llvm::dwarf;23 24// Out of line virtual method.25MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;26 27void MachineModuleInfo::initialize() {28 ObjFileMMI = nullptr;29 NextFnNum = 0;30}31 32void MachineModuleInfo::finalize() {33 Context.reset();34 // We don't clear the ExternalContext.35 36 delete ObjFileMMI;37 ObjFileMMI = nullptr;38}39 40MachineModuleInfo::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 51MachineModuleInfo::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 59MachineModuleInfo::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 69MachineModuleInfo::~MachineModuleInfo() { finalize(); }70 71MachineFunction *72MachineModuleInfo::getMachineFunction(const Function &F) const {73 auto I = MachineFunctions.find(&F);74 return I != MachineFunctions.end() ? I->second.get() : nullptr;75}76 77MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) {78 // Shortcut for the common case where a sequence of MachineFunctionPasses79 // 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 106void MachineModuleInfo::deleteMachineFunctionFor(Function &F) {107 MachineFunctions.erase(&F);108 LastRequest = nullptr;109 LastResult = nullptr;110}111 112void 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 119namespace {120 121/// This pass frees the MachineFunction object associated with a Function.122class FreeMachineFunction : public FunctionPass {123public: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 namespace146 147char FreeMachineFunction::ID;148 149FunctionPass *llvm::createFreeMachineFunctionPass() {150 return new FreeMachineFunction();151}152 153MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(154 const TargetMachine *TM)155 : ImmutablePass(ID), MMI(TM) {156 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());157}158 159MachineModuleInfoWrapperPass::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.166INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo",167 "Machine Module Information", false, false)168char MachineModuleInfoWrapperPass::ID = 0;169 170static 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 location179 // 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 195bool 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 212bool MachineModuleInfoWrapperPass::doFinalization(Module &M) {213 MMI.finalize();214 return false;215}216 217AnalysisKey MachineModuleAnalysis::Key;218 219MachineModuleAnalysis::Result220MachineModuleAnalysis::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