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 /// This is a per-function list of symbols whose corresponding BasicBlock got 80*0b57cec5SDimitry Andric /// deleted. These symbols need to be emitted at some point in the file, so 81*0b57cec5SDimitry Andric /// AsmPrinter emits them after the function body. 82*0b57cec5SDimitry Andric DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>> 83*0b57cec5SDimitry Andric DeletedAddrLabelsNeedingEmission; 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric public: 86*0b57cec5SDimitry Andric MMIAddrLabelMap(MCContext &context) : Context(context) {} 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric ~MMIAddrLabelMap() { 89*0b57cec5SDimitry Andric assert(DeletedAddrLabelsNeedingEmission.empty() && 90*0b57cec5SDimitry Andric "Some labels for deleted blocks never got emitted"); 91*0b57cec5SDimitry Andric } 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric void takeDeletedSymbolsForFunction(Function *F, 96*0b57cec5SDimitry Andric std::vector<MCSymbol*> &Result); 97*0b57cec5SDimitry Andric 98*0b57cec5SDimitry Andric void UpdateForDeletedBlock(BasicBlock *BB); 99*0b57cec5SDimitry Andric void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); 100*0b57cec5SDimitry Andric }; 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric } // end namespace llvm 103*0b57cec5SDimitry Andric 104*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { 105*0b57cec5SDimitry Andric assert(BB->hasAddressTaken() && 106*0b57cec5SDimitry Andric "Shouldn't get label for block without address taken"); 107*0b57cec5SDimitry Andric AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andric // If we already had an entry for this block, just return it. 110*0b57cec5SDimitry Andric if (!Entry.Symbols.empty()) { 111*0b57cec5SDimitry Andric assert(BB->getParent() == Entry.Fn && "Parent changed"); 112*0b57cec5SDimitry Andric return Entry.Symbols; 113*0b57cec5SDimitry Andric } 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andric // Otherwise, this is a new entry, create a new symbol for it and add an 116*0b57cec5SDimitry Andric // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. 117*0b57cec5SDimitry Andric BBCallbacks.emplace_back(BB); 118*0b57cec5SDimitry Andric BBCallbacks.back().setMap(this); 119*0b57cec5SDimitry Andric Entry.Index = BBCallbacks.size() - 1; 120*0b57cec5SDimitry Andric Entry.Fn = BB->getParent(); 121480093f4SDimitry Andric MCSymbol *Sym = Context.createTempSymbol(!BB->hasAddressTaken()); 122480093f4SDimitry Andric if (Context.getObjectFileInfo()->getTargetTriple().isOSBinFormatXCOFF()) { 123480093f4SDimitry Andric MCSymbol *FnEntryPointSym = 124480093f4SDimitry Andric Context.lookupSymbol("." + Entry.Fn->getName()); 125480093f4SDimitry Andric assert(FnEntryPointSym && "The function entry pointer symbol should have" 126480093f4SDimitry Andric " already been initialized."); 127480093f4SDimitry Andric MCSectionXCOFF *Csect = 128480093f4SDimitry Andric cast<MCSymbolXCOFF>(FnEntryPointSym)->getContainingCsect(); 129480093f4SDimitry Andric cast<MCSymbolXCOFF>(Sym)->setContainingCsect(Csect); 130480093f4SDimitry Andric } 131480093f4SDimitry Andric Entry.Symbols.push_back(Sym); 132*0b57cec5SDimitry Andric return Entry.Symbols; 133*0b57cec5SDimitry Andric } 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric /// If we have any deleted symbols for F, return them. 136*0b57cec5SDimitry Andric void MMIAddrLabelMap:: 137*0b57cec5SDimitry Andric takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) { 138*0b57cec5SDimitry Andric DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>::iterator I = 139*0b57cec5SDimitry Andric DeletedAddrLabelsNeedingEmission.find(F); 140*0b57cec5SDimitry Andric 141*0b57cec5SDimitry Andric // If there are no entries for the function, just return. 142*0b57cec5SDimitry Andric if (I == DeletedAddrLabelsNeedingEmission.end()) return; 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric // Otherwise, take the list. 145*0b57cec5SDimitry Andric std::swap(Result, I->second); 146*0b57cec5SDimitry Andric DeletedAddrLabelsNeedingEmission.erase(I); 147*0b57cec5SDimitry Andric } 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andric void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 150*0b57cec5SDimitry Andric // If the block got deleted, there is no need for the symbol. If the symbol 151*0b57cec5SDimitry Andric // was already emitted, we can just forget about it, otherwise we need to 152*0b57cec5SDimitry Andric // queue it up for later emission when the function is output. 153*0b57cec5SDimitry Andric AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 154*0b57cec5SDimitry Andric AddrLabelSymbols.erase(BB); 155*0b57cec5SDimitry Andric assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 156*0b57cec5SDimitry Andric BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 159*0b57cec5SDimitry Andric "Block/parent mismatch"); 160*0b57cec5SDimitry Andric 161*0b57cec5SDimitry Andric for (MCSymbol *Sym : Entry.Symbols) { 162*0b57cec5SDimitry Andric if (Sym->isDefined()) 163*0b57cec5SDimitry Andric return; 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric // If the block is not yet defined, we need to emit it at the end of the 166*0b57cec5SDimitry Andric // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list 167*0b57cec5SDimitry Andric // for the containing Function. Since the block is being deleted, its 168*0b57cec5SDimitry Andric // parent may already be removed, we have to get the function from 'Entry'. 169*0b57cec5SDimitry Andric DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); 170*0b57cec5SDimitry Andric } 171*0b57cec5SDimitry Andric } 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andric void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 174*0b57cec5SDimitry Andric // Get the entry for the RAUW'd block and remove it from our map. 175*0b57cec5SDimitry Andric AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 176*0b57cec5SDimitry Andric AddrLabelSymbols.erase(Old); 177*0b57cec5SDimitry Andric assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 178*0b57cec5SDimitry Andric 179*0b57cec5SDimitry Andric AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric // If New is not address taken, just move our symbol over to it. 182*0b57cec5SDimitry Andric if (NewEntry.Symbols.empty()) { 183*0b57cec5SDimitry Andric BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 184*0b57cec5SDimitry Andric NewEntry = std::move(OldEntry); // Set New's entry. 185*0b57cec5SDimitry Andric return; 186*0b57cec5SDimitry Andric } 187*0b57cec5SDimitry Andric 188*0b57cec5SDimitry Andric BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric // Otherwise, we need to add the old symbols to the new block's set. 191*0b57cec5SDimitry Andric NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(), 192*0b57cec5SDimitry Andric OldEntry.Symbols.end()); 193*0b57cec5SDimitry Andric } 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric void MMIAddrLabelMapCallbackPtr::deleted() { 196*0b57cec5SDimitry Andric Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); 197*0b57cec5SDimitry Andric } 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { 200*0b57cec5SDimitry Andric Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); 201*0b57cec5SDimitry Andric } 202*0b57cec5SDimitry Andric 2038bcb0991SDimitry Andric void MachineModuleInfo::initialize() { 204*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 205*0b57cec5SDimitry Andric CurCallSite = 0; 206*0b57cec5SDimitry Andric UsesMSVCFloatingPoint = UsesMorestackAddr = false; 207*0b57cec5SDimitry Andric HasSplitStack = HasNosplitStack = false; 208*0b57cec5SDimitry Andric AddrLabelSymbols = nullptr; 209*0b57cec5SDimitry Andric } 210*0b57cec5SDimitry Andric 2118bcb0991SDimitry Andric void MachineModuleInfo::finalize() { 212*0b57cec5SDimitry Andric Personalities.clear(); 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andric delete AddrLabelSymbols; 215*0b57cec5SDimitry Andric AddrLabelSymbols = nullptr; 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric Context.reset(); 218*0b57cec5SDimitry Andric 219*0b57cec5SDimitry Andric delete ObjFileMMI; 220*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 221*0b57cec5SDimitry Andric } 222*0b57cec5SDimitry Andric 2238bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) 2248bcb0991SDimitry Andric : TM(std::move(MMI.TM)), 2258bcb0991SDimitry Andric Context(MMI.TM.getMCAsmInfo(), MMI.TM.getMCRegisterInfo(), 2268bcb0991SDimitry Andric MMI.TM.getObjFileLowering(), nullptr, nullptr, false) { 2278bcb0991SDimitry Andric ObjFileMMI = MMI.ObjFileMMI; 2288bcb0991SDimitry Andric CurCallSite = MMI.CurCallSite; 2298bcb0991SDimitry Andric UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint; 2308bcb0991SDimitry Andric UsesMorestackAddr = MMI.UsesMorestackAddr; 2318bcb0991SDimitry Andric HasSplitStack = MMI.HasSplitStack; 2328bcb0991SDimitry Andric HasNosplitStack = MMI.HasNosplitStack; 2338bcb0991SDimitry Andric AddrLabelSymbols = MMI.AddrLabelSymbols; 2348bcb0991SDimitry Andric TheModule = MMI.TheModule; 2358bcb0991SDimitry Andric } 2368bcb0991SDimitry Andric 2378bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 2388bcb0991SDimitry Andric : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 2398bcb0991SDimitry Andric TM->getObjFileLowering(), nullptr, nullptr, false) { 2408bcb0991SDimitry Andric initialize(); 2418bcb0991SDimitry Andric } 2428bcb0991SDimitry Andric 2438bcb0991SDimitry Andric MachineModuleInfo::~MachineModuleInfo() { finalize(); } 2448bcb0991SDimitry Andric 245*0b57cec5SDimitry Andric //===- Address of Block Management ----------------------------------------===// 246*0b57cec5SDimitry Andric 247*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> 248*0b57cec5SDimitry Andric MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 249*0b57cec5SDimitry Andric // Lazily create AddrLabelSymbols. 250*0b57cec5SDimitry Andric if (!AddrLabelSymbols) 251*0b57cec5SDimitry Andric AddrLabelSymbols = new MMIAddrLabelMap(Context); 252*0b57cec5SDimitry Andric return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); 253*0b57cec5SDimitry Andric } 254*0b57cec5SDimitry Andric 255*0b57cec5SDimitry Andric void MachineModuleInfo:: 256*0b57cec5SDimitry Andric takeDeletedSymbolsForFunction(const Function *F, 257*0b57cec5SDimitry Andric std::vector<MCSymbol*> &Result) { 258*0b57cec5SDimitry Andric // If no blocks have had their addresses taken, we're done. 259*0b57cec5SDimitry Andric if (!AddrLabelSymbols) return; 260*0b57cec5SDimitry Andric return AddrLabelSymbols-> 261*0b57cec5SDimitry Andric takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result); 262*0b57cec5SDimitry Andric } 263*0b57cec5SDimitry Andric 264*0b57cec5SDimitry Andric /// \name Exception Handling 265*0b57cec5SDimitry Andric /// \{ 266*0b57cec5SDimitry Andric 267*0b57cec5SDimitry Andric void MachineModuleInfo::addPersonality(const Function *Personality) { 268*0b57cec5SDimitry Andric for (unsigned i = 0; i < Personalities.size(); ++i) 269*0b57cec5SDimitry Andric if (Personalities[i] == Personality) 270*0b57cec5SDimitry Andric return; 271*0b57cec5SDimitry Andric Personalities.push_back(Personality); 272*0b57cec5SDimitry Andric } 273*0b57cec5SDimitry Andric 274*0b57cec5SDimitry Andric /// \} 275*0b57cec5SDimitry Andric 276*0b57cec5SDimitry Andric MachineFunction * 277*0b57cec5SDimitry Andric MachineModuleInfo::getMachineFunction(const Function &F) const { 278*0b57cec5SDimitry Andric auto I = MachineFunctions.find(&F); 279*0b57cec5SDimitry Andric return I != MachineFunctions.end() ? I->second.get() : nullptr; 280*0b57cec5SDimitry Andric } 281*0b57cec5SDimitry Andric 282*0b57cec5SDimitry Andric MachineFunction & 283*0b57cec5SDimitry Andric MachineModuleInfo::getOrCreateMachineFunction(const Function &F) { 284*0b57cec5SDimitry Andric // Shortcut for the common case where a sequence of MachineFunctionPasses 285*0b57cec5SDimitry Andric // all query for the same Function. 286*0b57cec5SDimitry Andric if (LastRequest == &F) 287*0b57cec5SDimitry Andric return *LastResult; 288*0b57cec5SDimitry Andric 289*0b57cec5SDimitry Andric auto I = MachineFunctions.insert( 290*0b57cec5SDimitry Andric std::make_pair(&F, std::unique_ptr<MachineFunction>())); 291*0b57cec5SDimitry Andric MachineFunction *MF; 292*0b57cec5SDimitry Andric if (I.second) { 293*0b57cec5SDimitry Andric // No pre-existing machine function, create a new one. 294*0b57cec5SDimitry Andric const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 295*0b57cec5SDimitry Andric MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 296*0b57cec5SDimitry Andric // Update the set entry. 297*0b57cec5SDimitry Andric I.first->second.reset(MF); 298*0b57cec5SDimitry Andric } else { 299*0b57cec5SDimitry Andric MF = I.first->second.get(); 300*0b57cec5SDimitry Andric } 301*0b57cec5SDimitry Andric 302*0b57cec5SDimitry Andric LastRequest = &F; 303*0b57cec5SDimitry Andric LastResult = MF; 304*0b57cec5SDimitry Andric return *MF; 305*0b57cec5SDimitry Andric } 306*0b57cec5SDimitry Andric 307*0b57cec5SDimitry Andric void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 308*0b57cec5SDimitry Andric MachineFunctions.erase(&F); 309*0b57cec5SDimitry Andric LastRequest = nullptr; 310*0b57cec5SDimitry Andric LastResult = nullptr; 311*0b57cec5SDimitry Andric } 312*0b57cec5SDimitry Andric 313*0b57cec5SDimitry Andric namespace { 314*0b57cec5SDimitry Andric 315*0b57cec5SDimitry Andric /// This pass frees the MachineFunction object associated with a Function. 316*0b57cec5SDimitry Andric class FreeMachineFunction : public FunctionPass { 317*0b57cec5SDimitry Andric public: 318*0b57cec5SDimitry Andric static char ID; 319*0b57cec5SDimitry Andric 320*0b57cec5SDimitry Andric FreeMachineFunction() : FunctionPass(ID) {} 321*0b57cec5SDimitry Andric 322*0b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 3238bcb0991SDimitry Andric AU.addRequired<MachineModuleInfoWrapperPass>(); 3248bcb0991SDimitry Andric AU.addPreserved<MachineModuleInfoWrapperPass>(); 325*0b57cec5SDimitry Andric } 326*0b57cec5SDimitry Andric 327*0b57cec5SDimitry Andric bool runOnFunction(Function &F) override { 3288bcb0991SDimitry Andric MachineModuleInfo &MMI = 3298bcb0991SDimitry Andric getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 330*0b57cec5SDimitry Andric MMI.deleteMachineFunctionFor(F); 331*0b57cec5SDimitry Andric return true; 332*0b57cec5SDimitry Andric } 333*0b57cec5SDimitry Andric 334*0b57cec5SDimitry Andric StringRef getPassName() const override { 335*0b57cec5SDimitry Andric return "Free MachineFunction"; 336*0b57cec5SDimitry Andric } 337*0b57cec5SDimitry Andric }; 338*0b57cec5SDimitry Andric 339*0b57cec5SDimitry Andric } // end anonymous namespace 340*0b57cec5SDimitry Andric 341*0b57cec5SDimitry Andric char FreeMachineFunction::ID; 342*0b57cec5SDimitry Andric 343*0b57cec5SDimitry Andric FunctionPass *llvm::createFreeMachineFunctionPass() { 344*0b57cec5SDimitry Andric return new FreeMachineFunction(); 345*0b57cec5SDimitry Andric } 3468bcb0991SDimitry Andric 3478bcb0991SDimitry Andric MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 3488bcb0991SDimitry Andric const LLVMTargetMachine *TM) 3498bcb0991SDimitry Andric : ImmutablePass(ID), MMI(TM) { 3508bcb0991SDimitry Andric initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 3518bcb0991SDimitry Andric } 3528bcb0991SDimitry Andric 3538bcb0991SDimitry Andric // Handle the Pass registration stuff necessary to use DataLayout's. 3548bcb0991SDimitry Andric INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 3558bcb0991SDimitry Andric "Machine Module Information", false, false) 3568bcb0991SDimitry Andric char MachineModuleInfoWrapperPass::ID = 0; 3578bcb0991SDimitry Andric 3588bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 3598bcb0991SDimitry Andric MMI.initialize(); 3608bcb0991SDimitry Andric MMI.TheModule = &M; 3618bcb0991SDimitry Andric MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 3628bcb0991SDimitry Andric return false; 3638bcb0991SDimitry Andric } 3648bcb0991SDimitry Andric 3658bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 3668bcb0991SDimitry Andric MMI.finalize(); 3678bcb0991SDimitry Andric return false; 3688bcb0991SDimitry Andric } 3698bcb0991SDimitry Andric 3708bcb0991SDimitry Andric AnalysisKey MachineModuleAnalysis::Key; 3718bcb0991SDimitry Andric 3728bcb0991SDimitry Andric MachineModuleInfo MachineModuleAnalysis::run(Module &M, 3738bcb0991SDimitry Andric ModuleAnalysisManager &) { 3748bcb0991SDimitry Andric MachineModuleInfo MMI(TM); 3758bcb0991SDimitry Andric MMI.TheModule = &M; 3768bcb0991SDimitry Andric MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 3778bcb0991SDimitry Andric return MMI; 3788bcb0991SDimitry Andric } 379