diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineModuleInfo.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineModuleInfo.cpp | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineModuleInfo.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineModuleInfo.cpp new file mode 100644 index 000000000000..a0c0166d06f0 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineModuleInfo.cpp @@ -0,0 +1,244 @@ +//===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/InitializePasses.h" +#include "llvm/MC/MCContext.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetMachine.h" +#include <algorithm> +#include <cassert> +#include <memory> +#include <utility> +#include <vector> + +using namespace llvm; +using namespace llvm::dwarf; + +static cl::opt<bool> + DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden, + cl::desc("Disable debug info printing")); + +// Out of line virtual method. +MachineModuleInfoImpl::~MachineModuleInfoImpl() = default; + +void MachineModuleInfo::initialize() { + ObjFileMMI = nullptr; + CurCallSite = 0; + NextFnNum = 0; + UsesMSVCFloatingPoint = false; + DbgInfoAvailable = false; +} + +void MachineModuleInfo::finalize() { + Context.reset(); + // We don't clear the ExternalContext. + + delete ObjFileMMI; + ObjFileMMI = nullptr; +} + +MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) + : TM(std::move(MMI.TM)), + Context(MMI.TM.getTargetTriple(), MMI.TM.getMCAsmInfo(), + MMI.TM.getMCRegisterInfo(), MMI.TM.getMCSubtargetInfo(), nullptr, + &MMI.TM.Options.MCOptions, false), + MachineFunctions(std::move(MMI.MachineFunctions)) { + Context.setObjectFileInfo(MMI.TM.getObjFileLowering()); + ObjFileMMI = MMI.ObjFileMMI; + CurCallSite = MMI.CurCallSite; + ExternalContext = MMI.ExternalContext; + TheModule = MMI.TheModule; +} + +MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) + : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), + TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), + nullptr, &TM->Options.MCOptions, false) { + Context.setObjectFileInfo(TM->getObjFileLowering()); + initialize(); +} + +MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM, + MCContext *ExtContext) + : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), + TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), + nullptr, &TM->Options.MCOptions, false), + ExternalContext(ExtContext) { + Context.setObjectFileInfo(TM->getObjFileLowering()); + initialize(); +} + +MachineModuleInfo::~MachineModuleInfo() { finalize(); } + +MachineFunction * +MachineModuleInfo::getMachineFunction(const Function &F) const { + auto I = MachineFunctions.find(&F); + return I != MachineFunctions.end() ? I->second.get() : nullptr; +} + +MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) { + // Shortcut for the common case where a sequence of MachineFunctionPasses + // all query for the same Function. + if (LastRequest == &F) + return *LastResult; + + auto I = MachineFunctions.insert( + std::make_pair(&F, std::unique_ptr<MachineFunction>())); + MachineFunction *MF; + if (I.second) { + // No pre-existing machine function, create a new one. + const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); + MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); + MF->initTargetMachineFunctionInfo(STI); + // Update the set entry. + I.first->second.reset(MF); + } else { + MF = I.first->second.get(); + } + + LastRequest = &F; + LastResult = MF; + return *MF; +} + +void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { + MachineFunctions.erase(&F); + LastRequest = nullptr; + LastResult = nullptr; +} + +void MachineModuleInfo::insertFunction(const Function &F, + std::unique_ptr<MachineFunction> &&MF) { + auto I = MachineFunctions.insert(std::make_pair(&F, std::move(MF))); + assert(I.second && "machine function already mapped"); + (void)I; +} + +namespace { + +/// This pass frees the MachineFunction object associated with a Function. +class FreeMachineFunction : public FunctionPass { +public: + static char ID; + + FreeMachineFunction() : FunctionPass(ID) {} + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<MachineModuleInfoWrapperPass>(); + AU.addPreserved<MachineModuleInfoWrapperPass>(); + } + + bool runOnFunction(Function &F) override { + MachineModuleInfo &MMI = + getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); + MMI.deleteMachineFunctionFor(F); + return true; + } + + StringRef getPassName() const override { + return "Free MachineFunction"; + } +}; + +} // end anonymous namespace + +char FreeMachineFunction::ID; + +FunctionPass *llvm::createFreeMachineFunctionPass() { + return new FreeMachineFunction(); +} + +MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( + const LLVMTargetMachine *TM) + : ImmutablePass(ID), MMI(TM) { + initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); +} + +MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( + const LLVMTargetMachine *TM, MCContext *ExtContext) + : ImmutablePass(ID), MMI(TM, ExtContext) { + initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); +} + +// Handle the Pass registration stuff necessary to use DataLayout's. +INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", + "Machine Module Information", false, false) +char MachineModuleInfoWrapperPass::ID = 0; + +static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr, + std::vector<const MDNode *> &LocInfos) { + // Look up a LocInfo for the buffer this diagnostic is coming from. + unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc()); + const MDNode *LocInfo = nullptr; + if (BufNum > 0 && BufNum <= LocInfos.size()) + LocInfo = LocInfos[BufNum - 1]; + + // If the inline asm had metadata associated with it, pull out a location + // cookie corresponding to which line the error occurred on. + unsigned LocCookie = 0; + if (LocInfo) { + unsigned ErrorLine = SMD.getLineNo() - 1; + if (ErrorLine >= LocInfo->getNumOperands()) + ErrorLine = 0; + + if (LocInfo->getNumOperands() != 0) + if (const ConstantInt *CI = + mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine))) + LocCookie = CI->getZExtValue(); + } + + return LocCookie; +} + +bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { + MMI.initialize(); + MMI.TheModule = &M; + // FIXME: Do this for new pass manager. + LLVMContext &Ctx = M.getContext(); + MMI.getContext().setDiagnosticHandler( + [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm, + const SourceMgr &SrcMgr, + std::vector<const MDNode *> &LocInfos) { + unsigned LocCookie = 0; + if (IsInlineAsm) + LocCookie = getLocCookie(SMD, SrcMgr, LocInfos); + Ctx.diagnose( + DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie)); + }); + MMI.DbgInfoAvailable = !DisableDebugInfoPrinting && + !M.debug_compile_units().empty(); + return false; +} + +bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { + MMI.finalize(); + return false; +} + +AnalysisKey MachineModuleAnalysis::Key; + +MachineModuleInfo MachineModuleAnalysis::run(Module &M, + ModuleAnalysisManager &) { + MachineModuleInfo MMI(TM); + MMI.TheModule = &M; + MMI.DbgInfoAvailable = !DisableDebugInfoPrinting && + !M.debug_compile_units().empty(); + return MMI; +} |
