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/ArrayRef.h" 11*0b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 12*0b57cec5SDimitry Andric #include "llvm/ADT/PostOrderIterator.h" 13*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 14*0b57cec5SDimitry Andric #include "llvm/ADT/TinyPtrVector.h" 15*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 16*0b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h" 17*0b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 18*0b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 19*0b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 20*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 21*0b57cec5SDimitry Andric #include "llvm/IR/Value.h" 22*0b57cec5SDimitry Andric #include "llvm/IR/ValueHandle.h" 23480093f4SDimitry Andric #include "llvm/InitializePasses.h" 24*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 25*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 26480093f4SDimitry Andric #include "llvm/MC/MCSymbolXCOFF.h" 27*0b57cec5SDimitry Andric #include "llvm/Pass.h" 28*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 29*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 30*0b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 31*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 32*0b57cec5SDimitry Andric #include <algorithm> 33*0b57cec5SDimitry Andric #include <cassert> 34*0b57cec5SDimitry Andric #include <memory> 35*0b57cec5SDimitry Andric #include <utility> 36*0b57cec5SDimitry Andric #include <vector> 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric using namespace llvm; 39*0b57cec5SDimitry Andric using namespace llvm::dwarf; 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric // Out of line virtual method. 42*0b57cec5SDimitry Andric MachineModuleInfoImpl::~MachineModuleInfoImpl() = default; 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric namespace llvm { 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric class MMIAddrLabelMapCallbackPtr final : CallbackVH { 47*0b57cec5SDimitry Andric MMIAddrLabelMap *Map = nullptr; 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric public: 50*0b57cec5SDimitry Andric MMIAddrLabelMapCallbackPtr() = default; 51*0b57cec5SDimitry Andric MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric void setPtr(BasicBlock *BB) { 54*0b57cec5SDimitry Andric ValueHandleBase::operator=(BB); 55*0b57cec5SDimitry Andric } 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric void setMap(MMIAddrLabelMap *map) { Map = map; } 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric void deleted() override; 60*0b57cec5SDimitry Andric void allUsesReplacedWith(Value *V2) override; 61*0b57cec5SDimitry Andric }; 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric class MMIAddrLabelMap { 64*0b57cec5SDimitry Andric MCContext &Context; 65*0b57cec5SDimitry Andric struct AddrLabelSymEntry { 66*0b57cec5SDimitry Andric /// The symbols for the label. 67*0b57cec5SDimitry Andric TinyPtrVector<MCSymbol *> Symbols; 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric Function *Fn; // The containing function of the BasicBlock. 70*0b57cec5SDimitry Andric unsigned Index; // The index in BBCallbacks for the BasicBlock. 71*0b57cec5SDimitry Andric }; 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric /// Callbacks for the BasicBlock's that we have entries for. We use this so 76*0b57cec5SDimitry Andric /// we get notified if a block is deleted or RAUWd. 77*0b57cec5SDimitry Andric std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks; 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric public: 80*0b57cec5SDimitry Andric MMIAddrLabelMap(MCContext &context) : Context(context) {} 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric void UpdateForDeletedBlock(BasicBlock *BB); 85*0b57cec5SDimitry Andric void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); 86*0b57cec5SDimitry Andric }; 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric } // end namespace llvm 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { 91*0b57cec5SDimitry Andric assert(BB->hasAddressTaken() && 92*0b57cec5SDimitry Andric "Shouldn't get label for block without address taken"); 93*0b57cec5SDimitry Andric AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric // If we already had an entry for this block, just return it. 96*0b57cec5SDimitry Andric if (!Entry.Symbols.empty()) { 97*0b57cec5SDimitry Andric assert(BB->getParent() == Entry.Fn && "Parent changed"); 98*0b57cec5SDimitry Andric return Entry.Symbols; 99*0b57cec5SDimitry Andric } 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric // Otherwise, this is a new entry, create a new symbol for it and add an 102*0b57cec5SDimitry Andric // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. 103*0b57cec5SDimitry Andric BBCallbacks.emplace_back(BB); 104*0b57cec5SDimitry Andric BBCallbacks.back().setMap(this); 105*0b57cec5SDimitry Andric Entry.Index = BBCallbacks.size() - 1; 106*0b57cec5SDimitry Andric Entry.Fn = BB->getParent(); 107e8d8bef9SDimitry Andric MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol() 108e8d8bef9SDimitry Andric : Context.createTempSymbol(); 109480093f4SDimitry Andric Entry.Symbols.push_back(Sym); 110*0b57cec5SDimitry Andric return Entry.Symbols; 111*0b57cec5SDimitry Andric } 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 114*0b57cec5SDimitry Andric // If the block got deleted, there is no need for the symbol. If the symbol 115*0b57cec5SDimitry Andric // was already emitted, we can just forget about it, otherwise we need to 116*0b57cec5SDimitry Andric // queue it up for later emission when the function is output. 117*0b57cec5SDimitry Andric AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 118*0b57cec5SDimitry Andric AddrLabelSymbols.erase(BB); 119*0b57cec5SDimitry Andric assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 120*0b57cec5SDimitry Andric BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 121*0b57cec5SDimitry Andric 122*0b57cec5SDimitry Andric assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 123*0b57cec5SDimitry Andric "Block/parent mismatch"); 124*0b57cec5SDimitry Andric 1255ffd83dbSDimitry Andric assert(llvm::all_of(Entry.Symbols, [](MCSymbol *Sym) { 1265ffd83dbSDimitry Andric return Sym->isDefined(); })); 127*0b57cec5SDimitry Andric } 128*0b57cec5SDimitry Andric 129*0b57cec5SDimitry Andric void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 130*0b57cec5SDimitry Andric // Get the entry for the RAUW'd block and remove it from our map. 131*0b57cec5SDimitry Andric AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 132*0b57cec5SDimitry Andric AddrLabelSymbols.erase(Old); 133*0b57cec5SDimitry Andric assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 136*0b57cec5SDimitry Andric 137*0b57cec5SDimitry Andric // If New is not address taken, just move our symbol over to it. 138*0b57cec5SDimitry Andric if (NewEntry.Symbols.empty()) { 139*0b57cec5SDimitry Andric BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 140*0b57cec5SDimitry Andric NewEntry = std::move(OldEntry); // Set New's entry. 141*0b57cec5SDimitry Andric return; 142*0b57cec5SDimitry Andric } 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric // Otherwise, we need to add the old symbols to the new block's set. 147e8d8bef9SDimitry Andric llvm::append_range(NewEntry.Symbols, OldEntry.Symbols); 148*0b57cec5SDimitry Andric } 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric void MMIAddrLabelMapCallbackPtr::deleted() { 151*0b57cec5SDimitry Andric Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); 152*0b57cec5SDimitry Andric } 153*0b57cec5SDimitry Andric 154*0b57cec5SDimitry Andric void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { 155*0b57cec5SDimitry Andric Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); 156*0b57cec5SDimitry Andric } 157*0b57cec5SDimitry Andric 1588bcb0991SDimitry Andric void MachineModuleInfo::initialize() { 159*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 160*0b57cec5SDimitry Andric CurCallSite = 0; 161*0b57cec5SDimitry Andric UsesMSVCFloatingPoint = UsesMorestackAddr = false; 162*0b57cec5SDimitry Andric HasSplitStack = HasNosplitStack = false; 163*0b57cec5SDimitry Andric AddrLabelSymbols = nullptr; 164*0b57cec5SDimitry Andric } 165*0b57cec5SDimitry Andric 1668bcb0991SDimitry Andric void MachineModuleInfo::finalize() { 167*0b57cec5SDimitry Andric Personalities.clear(); 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric delete AddrLabelSymbols; 170*0b57cec5SDimitry Andric AddrLabelSymbols = nullptr; 171*0b57cec5SDimitry Andric 172*0b57cec5SDimitry Andric Context.reset(); 173e8d8bef9SDimitry Andric // We don't clear the ExternalContext. 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric delete ObjFileMMI; 176*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 177*0b57cec5SDimitry Andric } 178*0b57cec5SDimitry Andric 1798bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) 1808bcb0991SDimitry Andric : TM(std::move(MMI.TM)), 1818bcb0991SDimitry Andric Context(MMI.TM.getMCAsmInfo(), MMI.TM.getMCRegisterInfo(), 182e8d8bef9SDimitry Andric MMI.TM.getObjFileLowering(), nullptr, nullptr, false), 183e8d8bef9SDimitry Andric MachineFunctions(std::move(MMI.MachineFunctions)) { 1848bcb0991SDimitry Andric ObjFileMMI = MMI.ObjFileMMI; 1858bcb0991SDimitry Andric CurCallSite = MMI.CurCallSite; 1868bcb0991SDimitry Andric UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint; 1878bcb0991SDimitry Andric UsesMorestackAddr = MMI.UsesMorestackAddr; 1888bcb0991SDimitry Andric HasSplitStack = MMI.HasSplitStack; 1898bcb0991SDimitry Andric HasNosplitStack = MMI.HasNosplitStack; 1908bcb0991SDimitry Andric AddrLabelSymbols = MMI.AddrLabelSymbols; 191e8d8bef9SDimitry Andric ExternalContext = MMI.ExternalContext; 1928bcb0991SDimitry Andric TheModule = MMI.TheModule; 1938bcb0991SDimitry Andric } 1948bcb0991SDimitry Andric 1958bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 1968bcb0991SDimitry Andric : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 1978bcb0991SDimitry Andric TM->getObjFileLowering(), nullptr, nullptr, false) { 1988bcb0991SDimitry Andric initialize(); 1998bcb0991SDimitry Andric } 2008bcb0991SDimitry Andric 201e8d8bef9SDimitry Andric MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM, 202e8d8bef9SDimitry Andric MCContext *ExtContext) 203e8d8bef9SDimitry Andric : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 204e8d8bef9SDimitry Andric TM->getObjFileLowering(), nullptr, nullptr, false), 205e8d8bef9SDimitry Andric ExternalContext(ExtContext) { 206e8d8bef9SDimitry Andric initialize(); 207e8d8bef9SDimitry Andric } 208e8d8bef9SDimitry Andric 2098bcb0991SDimitry Andric MachineModuleInfo::~MachineModuleInfo() { finalize(); } 2108bcb0991SDimitry Andric 211*0b57cec5SDimitry Andric //===- Address of Block Management ----------------------------------------===// 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> 214*0b57cec5SDimitry Andric MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 215*0b57cec5SDimitry Andric // Lazily create AddrLabelSymbols. 216*0b57cec5SDimitry Andric if (!AddrLabelSymbols) 217e8d8bef9SDimitry Andric AddrLabelSymbols = new MMIAddrLabelMap(getContext()); 218*0b57cec5SDimitry Andric return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); 219*0b57cec5SDimitry Andric } 220*0b57cec5SDimitry Andric 221*0b57cec5SDimitry Andric /// \name Exception Handling 222*0b57cec5SDimitry Andric /// \{ 223*0b57cec5SDimitry Andric 224*0b57cec5SDimitry Andric void MachineModuleInfo::addPersonality(const Function *Personality) { 225*0b57cec5SDimitry Andric for (unsigned i = 0; i < Personalities.size(); ++i) 226*0b57cec5SDimitry Andric if (Personalities[i] == Personality) 227*0b57cec5SDimitry Andric return; 228*0b57cec5SDimitry Andric Personalities.push_back(Personality); 229*0b57cec5SDimitry Andric } 230*0b57cec5SDimitry Andric 231*0b57cec5SDimitry Andric /// \} 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andric MachineFunction * 234*0b57cec5SDimitry Andric MachineModuleInfo::getMachineFunction(const Function &F) const { 235*0b57cec5SDimitry Andric auto I = MachineFunctions.find(&F); 236*0b57cec5SDimitry Andric return I != MachineFunctions.end() ? I->second.get() : nullptr; 237*0b57cec5SDimitry Andric } 238*0b57cec5SDimitry Andric 2395ffd83dbSDimitry Andric MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) { 240*0b57cec5SDimitry Andric // Shortcut for the common case where a sequence of MachineFunctionPasses 241*0b57cec5SDimitry Andric // all query for the same Function. 242*0b57cec5SDimitry Andric if (LastRequest == &F) 243*0b57cec5SDimitry Andric return *LastResult; 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andric auto I = MachineFunctions.insert( 246*0b57cec5SDimitry Andric std::make_pair(&F, std::unique_ptr<MachineFunction>())); 247*0b57cec5SDimitry Andric MachineFunction *MF; 248*0b57cec5SDimitry Andric if (I.second) { 249*0b57cec5SDimitry Andric // No pre-existing machine function, create a new one. 250*0b57cec5SDimitry Andric const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 251*0b57cec5SDimitry Andric MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 252*0b57cec5SDimitry Andric // Update the set entry. 253*0b57cec5SDimitry Andric I.first->second.reset(MF); 254*0b57cec5SDimitry Andric } else { 255*0b57cec5SDimitry Andric MF = I.first->second.get(); 256*0b57cec5SDimitry Andric } 257*0b57cec5SDimitry Andric 258*0b57cec5SDimitry Andric LastRequest = &F; 259*0b57cec5SDimitry Andric LastResult = MF; 260*0b57cec5SDimitry Andric return *MF; 261*0b57cec5SDimitry Andric } 262*0b57cec5SDimitry Andric 263*0b57cec5SDimitry Andric void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 264*0b57cec5SDimitry Andric MachineFunctions.erase(&F); 265*0b57cec5SDimitry Andric LastRequest = nullptr; 266*0b57cec5SDimitry Andric LastResult = nullptr; 267*0b57cec5SDimitry Andric } 268*0b57cec5SDimitry Andric 269*0b57cec5SDimitry Andric namespace { 270*0b57cec5SDimitry Andric 271*0b57cec5SDimitry Andric /// This pass frees the MachineFunction object associated with a Function. 272*0b57cec5SDimitry Andric class FreeMachineFunction : public FunctionPass { 273*0b57cec5SDimitry Andric public: 274*0b57cec5SDimitry Andric static char ID; 275*0b57cec5SDimitry Andric 276*0b57cec5SDimitry Andric FreeMachineFunction() : FunctionPass(ID) {} 277*0b57cec5SDimitry Andric 278*0b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 2798bcb0991SDimitry Andric AU.addRequired<MachineModuleInfoWrapperPass>(); 2808bcb0991SDimitry Andric AU.addPreserved<MachineModuleInfoWrapperPass>(); 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric bool runOnFunction(Function &F) override { 2848bcb0991SDimitry Andric MachineModuleInfo &MMI = 2858bcb0991SDimitry Andric getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 286*0b57cec5SDimitry Andric MMI.deleteMachineFunctionFor(F); 287*0b57cec5SDimitry Andric return true; 288*0b57cec5SDimitry Andric } 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric StringRef getPassName() const override { 291*0b57cec5SDimitry Andric return "Free MachineFunction"; 292*0b57cec5SDimitry Andric } 293*0b57cec5SDimitry Andric }; 294*0b57cec5SDimitry Andric 295*0b57cec5SDimitry Andric } // end anonymous namespace 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric char FreeMachineFunction::ID; 298*0b57cec5SDimitry Andric 299*0b57cec5SDimitry Andric FunctionPass *llvm::createFreeMachineFunctionPass() { 300*0b57cec5SDimitry Andric return new FreeMachineFunction(); 301*0b57cec5SDimitry Andric } 3028bcb0991SDimitry Andric 3038bcb0991SDimitry Andric MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 3048bcb0991SDimitry Andric const LLVMTargetMachine *TM) 3058bcb0991SDimitry Andric : ImmutablePass(ID), MMI(TM) { 3068bcb0991SDimitry Andric initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 3078bcb0991SDimitry Andric } 3088bcb0991SDimitry Andric 309e8d8bef9SDimitry Andric MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 310e8d8bef9SDimitry Andric const LLVMTargetMachine *TM, MCContext *ExtContext) 311e8d8bef9SDimitry Andric : ImmutablePass(ID), MMI(TM, ExtContext) { 312e8d8bef9SDimitry Andric initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 313e8d8bef9SDimitry Andric } 314e8d8bef9SDimitry Andric 3158bcb0991SDimitry Andric // Handle the Pass registration stuff necessary to use DataLayout's. 3168bcb0991SDimitry Andric INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 3178bcb0991SDimitry Andric "Machine Module Information", false, false) 3188bcb0991SDimitry Andric char MachineModuleInfoWrapperPass::ID = 0; 3198bcb0991SDimitry Andric 3208bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 3218bcb0991SDimitry Andric MMI.initialize(); 3228bcb0991SDimitry Andric MMI.TheModule = &M; 3238bcb0991SDimitry Andric MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 3248bcb0991SDimitry Andric return false; 3258bcb0991SDimitry Andric } 3268bcb0991SDimitry Andric 3278bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 3288bcb0991SDimitry Andric MMI.finalize(); 3298bcb0991SDimitry Andric return false; 3308bcb0991SDimitry Andric } 3318bcb0991SDimitry Andric 3328bcb0991SDimitry Andric AnalysisKey MachineModuleAnalysis::Key; 3338bcb0991SDimitry Andric 3348bcb0991SDimitry Andric MachineModuleInfo MachineModuleAnalysis::run(Module &M, 3358bcb0991SDimitry Andric ModuleAnalysisManager &) { 3368bcb0991SDimitry Andric MachineModuleInfo MMI(TM); 3378bcb0991SDimitry Andric MMI.TheModule = &M; 3388bcb0991SDimitry Andric MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 3398bcb0991SDimitry Andric return MMI; 3408bcb0991SDimitry Andric } 341