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" 23*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 24*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 25*0b57cec5SDimitry Andric #include "llvm/Pass.h" 26*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 27*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 28*0b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 29*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 30*0b57cec5SDimitry Andric #include <algorithm> 31*0b57cec5SDimitry Andric #include <cassert> 32*0b57cec5SDimitry Andric #include <memory> 33*0b57cec5SDimitry Andric #include <utility> 34*0b57cec5SDimitry Andric #include <vector> 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric using namespace llvm; 37*0b57cec5SDimitry Andric using namespace llvm::dwarf; 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric // Out of line virtual method. 40*0b57cec5SDimitry Andric MachineModuleInfoImpl::~MachineModuleInfoImpl() = default; 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric namespace llvm { 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric class MMIAddrLabelMapCallbackPtr final : CallbackVH { 45*0b57cec5SDimitry Andric MMIAddrLabelMap *Map = nullptr; 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric public: 48*0b57cec5SDimitry Andric MMIAddrLabelMapCallbackPtr() = default; 49*0b57cec5SDimitry Andric MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric void setPtr(BasicBlock *BB) { 52*0b57cec5SDimitry Andric ValueHandleBase::operator=(BB); 53*0b57cec5SDimitry Andric } 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric void setMap(MMIAddrLabelMap *map) { Map = map; } 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric void deleted() override; 58*0b57cec5SDimitry Andric void allUsesReplacedWith(Value *V2) override; 59*0b57cec5SDimitry Andric }; 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric class MMIAddrLabelMap { 62*0b57cec5SDimitry Andric MCContext &Context; 63*0b57cec5SDimitry Andric struct AddrLabelSymEntry { 64*0b57cec5SDimitry Andric /// The symbols for the label. 65*0b57cec5SDimitry Andric TinyPtrVector<MCSymbol *> Symbols; 66*0b57cec5SDimitry Andric 67*0b57cec5SDimitry Andric Function *Fn; // The containing function of the BasicBlock. 68*0b57cec5SDimitry Andric unsigned Index; // The index in BBCallbacks for the BasicBlock. 69*0b57cec5SDimitry Andric }; 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric /// Callbacks for the BasicBlock's that we have entries for. We use this so 74*0b57cec5SDimitry Andric /// we get notified if a block is deleted or RAUWd. 75*0b57cec5SDimitry Andric std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks; 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric /// This is a per-function list of symbols whose corresponding BasicBlock got 78*0b57cec5SDimitry Andric /// deleted. These symbols need to be emitted at some point in the file, so 79*0b57cec5SDimitry Andric /// AsmPrinter emits them after the function body. 80*0b57cec5SDimitry Andric DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>> 81*0b57cec5SDimitry Andric DeletedAddrLabelsNeedingEmission; 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric public: 84*0b57cec5SDimitry Andric MMIAddrLabelMap(MCContext &context) : Context(context) {} 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric ~MMIAddrLabelMap() { 87*0b57cec5SDimitry Andric assert(DeletedAddrLabelsNeedingEmission.empty() && 88*0b57cec5SDimitry Andric "Some labels for deleted blocks never got emitted"); 89*0b57cec5SDimitry Andric } 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andric void takeDeletedSymbolsForFunction(Function *F, 94*0b57cec5SDimitry Andric std::vector<MCSymbol*> &Result); 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric void UpdateForDeletedBlock(BasicBlock *BB); 97*0b57cec5SDimitry Andric void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); 98*0b57cec5SDimitry Andric }; 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric } // end namespace llvm 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { 103*0b57cec5SDimitry Andric assert(BB->hasAddressTaken() && 104*0b57cec5SDimitry Andric "Shouldn't get label for block without address taken"); 105*0b57cec5SDimitry Andric AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric // If we already had an entry for this block, just return it. 108*0b57cec5SDimitry Andric if (!Entry.Symbols.empty()) { 109*0b57cec5SDimitry Andric assert(BB->getParent() == Entry.Fn && "Parent changed"); 110*0b57cec5SDimitry Andric return Entry.Symbols; 111*0b57cec5SDimitry Andric } 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric // Otherwise, this is a new entry, create a new symbol for it and add an 114*0b57cec5SDimitry Andric // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. 115*0b57cec5SDimitry Andric BBCallbacks.emplace_back(BB); 116*0b57cec5SDimitry Andric BBCallbacks.back().setMap(this); 117*0b57cec5SDimitry Andric Entry.Index = BBCallbacks.size() - 1; 118*0b57cec5SDimitry Andric Entry.Fn = BB->getParent(); 119*0b57cec5SDimitry Andric Entry.Symbols.push_back(Context.createTempSymbol(!BB->hasAddressTaken())); 120*0b57cec5SDimitry Andric return Entry.Symbols; 121*0b57cec5SDimitry Andric } 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric /// If we have any deleted symbols for F, return them. 124*0b57cec5SDimitry Andric void MMIAddrLabelMap:: 125*0b57cec5SDimitry Andric takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) { 126*0b57cec5SDimitry Andric DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>::iterator I = 127*0b57cec5SDimitry Andric DeletedAddrLabelsNeedingEmission.find(F); 128*0b57cec5SDimitry Andric 129*0b57cec5SDimitry Andric // If there are no entries for the function, just return. 130*0b57cec5SDimitry Andric if (I == DeletedAddrLabelsNeedingEmission.end()) return; 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric // Otherwise, take the list. 133*0b57cec5SDimitry Andric std::swap(Result, I->second); 134*0b57cec5SDimitry Andric DeletedAddrLabelsNeedingEmission.erase(I); 135*0b57cec5SDimitry Andric } 136*0b57cec5SDimitry Andric 137*0b57cec5SDimitry Andric void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 138*0b57cec5SDimitry Andric // If the block got deleted, there is no need for the symbol. If the symbol 139*0b57cec5SDimitry Andric // was already emitted, we can just forget about it, otherwise we need to 140*0b57cec5SDimitry Andric // queue it up for later emission when the function is output. 141*0b57cec5SDimitry Andric AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 142*0b57cec5SDimitry Andric AddrLabelSymbols.erase(BB); 143*0b57cec5SDimitry Andric assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 144*0b57cec5SDimitry Andric BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 147*0b57cec5SDimitry Andric "Block/parent mismatch"); 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andric for (MCSymbol *Sym : Entry.Symbols) { 150*0b57cec5SDimitry Andric if (Sym->isDefined()) 151*0b57cec5SDimitry Andric return; 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric // If the block is not yet defined, we need to emit it at the end of the 154*0b57cec5SDimitry Andric // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list 155*0b57cec5SDimitry Andric // for the containing Function. Since the block is being deleted, its 156*0b57cec5SDimitry Andric // parent may already be removed, we have to get the function from 'Entry'. 157*0b57cec5SDimitry Andric DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); 158*0b57cec5SDimitry Andric } 159*0b57cec5SDimitry Andric } 160*0b57cec5SDimitry Andric 161*0b57cec5SDimitry Andric void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 162*0b57cec5SDimitry Andric // Get the entry for the RAUW'd block and remove it from our map. 163*0b57cec5SDimitry Andric AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 164*0b57cec5SDimitry Andric AddrLabelSymbols.erase(Old); 165*0b57cec5SDimitry Andric assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 166*0b57cec5SDimitry Andric 167*0b57cec5SDimitry Andric AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric // If New is not address taken, just move our symbol over to it. 170*0b57cec5SDimitry Andric if (NewEntry.Symbols.empty()) { 171*0b57cec5SDimitry Andric BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 172*0b57cec5SDimitry Andric NewEntry = std::move(OldEntry); // Set New's entry. 173*0b57cec5SDimitry Andric return; 174*0b57cec5SDimitry Andric } 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric // Otherwise, we need to add the old symbols to the new block's set. 179*0b57cec5SDimitry Andric NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(), 180*0b57cec5SDimitry Andric OldEntry.Symbols.end()); 181*0b57cec5SDimitry Andric } 182*0b57cec5SDimitry Andric 183*0b57cec5SDimitry Andric void MMIAddrLabelMapCallbackPtr::deleted() { 184*0b57cec5SDimitry Andric Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); 185*0b57cec5SDimitry Andric } 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { 188*0b57cec5SDimitry Andric Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); 189*0b57cec5SDimitry Andric } 190*0b57cec5SDimitry Andric 1918bcb0991SDimitry Andric void MachineModuleInfo::initialize() { 192*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 193*0b57cec5SDimitry Andric CurCallSite = 0; 194*0b57cec5SDimitry Andric UsesMSVCFloatingPoint = UsesMorestackAddr = false; 195*0b57cec5SDimitry Andric HasSplitStack = HasNosplitStack = false; 196*0b57cec5SDimitry Andric AddrLabelSymbols = nullptr; 197*0b57cec5SDimitry Andric } 198*0b57cec5SDimitry Andric 1998bcb0991SDimitry Andric void MachineModuleInfo::finalize() { 200*0b57cec5SDimitry Andric Personalities.clear(); 201*0b57cec5SDimitry Andric 202*0b57cec5SDimitry Andric delete AddrLabelSymbols; 203*0b57cec5SDimitry Andric AddrLabelSymbols = nullptr; 204*0b57cec5SDimitry Andric 205*0b57cec5SDimitry Andric Context.reset(); 206*0b57cec5SDimitry Andric 207*0b57cec5SDimitry Andric delete ObjFileMMI; 208*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 209*0b57cec5SDimitry Andric } 210*0b57cec5SDimitry Andric 2118bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) 2128bcb0991SDimitry Andric : TM(std::move(MMI.TM)), 2138bcb0991SDimitry Andric Context(MMI.TM.getMCAsmInfo(), MMI.TM.getMCRegisterInfo(), 2148bcb0991SDimitry Andric MMI.TM.getObjFileLowering(), nullptr, nullptr, false) { 2158bcb0991SDimitry Andric ObjFileMMI = MMI.ObjFileMMI; 2168bcb0991SDimitry Andric CurCallSite = MMI.CurCallSite; 2178bcb0991SDimitry Andric UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint; 2188bcb0991SDimitry Andric UsesMorestackAddr = MMI.UsesMorestackAddr; 2198bcb0991SDimitry Andric HasSplitStack = MMI.HasSplitStack; 2208bcb0991SDimitry Andric HasNosplitStack = MMI.HasNosplitStack; 2218bcb0991SDimitry Andric AddrLabelSymbols = MMI.AddrLabelSymbols; 2228bcb0991SDimitry Andric TheModule = MMI.TheModule; 2238bcb0991SDimitry Andric } 2248bcb0991SDimitry Andric 2258bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 2268bcb0991SDimitry Andric : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 2278bcb0991SDimitry Andric TM->getObjFileLowering(), nullptr, nullptr, false) { 2288bcb0991SDimitry Andric initialize(); 2298bcb0991SDimitry Andric } 2308bcb0991SDimitry Andric 2318bcb0991SDimitry Andric MachineModuleInfo::~MachineModuleInfo() { finalize(); } 2328bcb0991SDimitry Andric 233*0b57cec5SDimitry Andric //===- Address of Block Management ----------------------------------------===// 234*0b57cec5SDimitry Andric 235*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> 236*0b57cec5SDimitry Andric MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 237*0b57cec5SDimitry Andric // Lazily create AddrLabelSymbols. 238*0b57cec5SDimitry Andric if (!AddrLabelSymbols) 239*0b57cec5SDimitry Andric AddrLabelSymbols = new MMIAddrLabelMap(Context); 240*0b57cec5SDimitry Andric return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); 241*0b57cec5SDimitry Andric } 242*0b57cec5SDimitry Andric 243*0b57cec5SDimitry Andric void MachineModuleInfo:: 244*0b57cec5SDimitry Andric takeDeletedSymbolsForFunction(const Function *F, 245*0b57cec5SDimitry Andric std::vector<MCSymbol*> &Result) { 246*0b57cec5SDimitry Andric // If no blocks have had their addresses taken, we're done. 247*0b57cec5SDimitry Andric if (!AddrLabelSymbols) return; 248*0b57cec5SDimitry Andric return AddrLabelSymbols-> 249*0b57cec5SDimitry Andric takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result); 250*0b57cec5SDimitry Andric } 251*0b57cec5SDimitry Andric 252*0b57cec5SDimitry Andric /// \name Exception Handling 253*0b57cec5SDimitry Andric /// \{ 254*0b57cec5SDimitry Andric 255*0b57cec5SDimitry Andric void MachineModuleInfo::addPersonality(const Function *Personality) { 256*0b57cec5SDimitry Andric for (unsigned i = 0; i < Personalities.size(); ++i) 257*0b57cec5SDimitry Andric if (Personalities[i] == Personality) 258*0b57cec5SDimitry Andric return; 259*0b57cec5SDimitry Andric Personalities.push_back(Personality); 260*0b57cec5SDimitry Andric } 261*0b57cec5SDimitry Andric 262*0b57cec5SDimitry Andric /// \} 263*0b57cec5SDimitry Andric 264*0b57cec5SDimitry Andric MachineFunction * 265*0b57cec5SDimitry Andric MachineModuleInfo::getMachineFunction(const Function &F) const { 266*0b57cec5SDimitry Andric auto I = MachineFunctions.find(&F); 267*0b57cec5SDimitry Andric return I != MachineFunctions.end() ? I->second.get() : nullptr; 268*0b57cec5SDimitry Andric } 269*0b57cec5SDimitry Andric 270*0b57cec5SDimitry Andric MachineFunction & 271*0b57cec5SDimitry Andric MachineModuleInfo::getOrCreateMachineFunction(const Function &F) { 272*0b57cec5SDimitry Andric // Shortcut for the common case where a sequence of MachineFunctionPasses 273*0b57cec5SDimitry Andric // all query for the same Function. 274*0b57cec5SDimitry Andric if (LastRequest == &F) 275*0b57cec5SDimitry Andric return *LastResult; 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric auto I = MachineFunctions.insert( 278*0b57cec5SDimitry Andric std::make_pair(&F, std::unique_ptr<MachineFunction>())); 279*0b57cec5SDimitry Andric MachineFunction *MF; 280*0b57cec5SDimitry Andric if (I.second) { 281*0b57cec5SDimitry Andric // No pre-existing machine function, create a new one. 282*0b57cec5SDimitry Andric const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 283*0b57cec5SDimitry Andric MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 284*0b57cec5SDimitry Andric // Update the set entry. 285*0b57cec5SDimitry Andric I.first->second.reset(MF); 286*0b57cec5SDimitry Andric } else { 287*0b57cec5SDimitry Andric MF = I.first->second.get(); 288*0b57cec5SDimitry Andric } 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric LastRequest = &F; 291*0b57cec5SDimitry Andric LastResult = MF; 292*0b57cec5SDimitry Andric return *MF; 293*0b57cec5SDimitry Andric } 294*0b57cec5SDimitry Andric 295*0b57cec5SDimitry Andric void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 296*0b57cec5SDimitry Andric MachineFunctions.erase(&F); 297*0b57cec5SDimitry Andric LastRequest = nullptr; 298*0b57cec5SDimitry Andric LastResult = nullptr; 299*0b57cec5SDimitry Andric } 300*0b57cec5SDimitry Andric 301*0b57cec5SDimitry Andric namespace { 302*0b57cec5SDimitry Andric 303*0b57cec5SDimitry Andric /// This pass frees the MachineFunction object associated with a Function. 304*0b57cec5SDimitry Andric class FreeMachineFunction : public FunctionPass { 305*0b57cec5SDimitry Andric public: 306*0b57cec5SDimitry Andric static char ID; 307*0b57cec5SDimitry Andric 308*0b57cec5SDimitry Andric FreeMachineFunction() : FunctionPass(ID) {} 309*0b57cec5SDimitry Andric 310*0b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 3118bcb0991SDimitry Andric AU.addRequired<MachineModuleInfoWrapperPass>(); 3128bcb0991SDimitry Andric AU.addPreserved<MachineModuleInfoWrapperPass>(); 313*0b57cec5SDimitry Andric } 314*0b57cec5SDimitry Andric 315*0b57cec5SDimitry Andric bool runOnFunction(Function &F) override { 3168bcb0991SDimitry Andric MachineModuleInfo &MMI = 3178bcb0991SDimitry Andric getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 318*0b57cec5SDimitry Andric MMI.deleteMachineFunctionFor(F); 319*0b57cec5SDimitry Andric return true; 320*0b57cec5SDimitry Andric } 321*0b57cec5SDimitry Andric 322*0b57cec5SDimitry Andric StringRef getPassName() const override { 323*0b57cec5SDimitry Andric return "Free MachineFunction"; 324*0b57cec5SDimitry Andric } 325*0b57cec5SDimitry Andric }; 326*0b57cec5SDimitry Andric 327*0b57cec5SDimitry Andric } // end anonymous namespace 328*0b57cec5SDimitry Andric 329*0b57cec5SDimitry Andric char FreeMachineFunction::ID; 330*0b57cec5SDimitry Andric 331*0b57cec5SDimitry Andric FunctionPass *llvm::createFreeMachineFunctionPass() { 332*0b57cec5SDimitry Andric return new FreeMachineFunction(); 333*0b57cec5SDimitry Andric } 3348bcb0991SDimitry Andric 3358bcb0991SDimitry Andric MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 3368bcb0991SDimitry Andric const LLVMTargetMachine *TM) 3378bcb0991SDimitry Andric : ImmutablePass(ID), MMI(TM) { 3388bcb0991SDimitry Andric initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 3398bcb0991SDimitry Andric } 3408bcb0991SDimitry Andric 3418bcb0991SDimitry Andric // Handle the Pass registration stuff necessary to use DataLayout's. 3428bcb0991SDimitry Andric INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 3438bcb0991SDimitry Andric "Machine Module Information", false, false) 3448bcb0991SDimitry Andric char MachineModuleInfoWrapperPass::ID = 0; 3458bcb0991SDimitry Andric 3468bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 3478bcb0991SDimitry Andric MMI.initialize(); 3488bcb0991SDimitry Andric MMI.TheModule = &M; 3498bcb0991SDimitry Andric MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 3508bcb0991SDimitry Andric return false; 3518bcb0991SDimitry Andric } 3528bcb0991SDimitry Andric 3538bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 3548bcb0991SDimitry Andric MMI.finalize(); 3558bcb0991SDimitry Andric return false; 3568bcb0991SDimitry Andric } 3578bcb0991SDimitry Andric 3588bcb0991SDimitry Andric AnalysisKey MachineModuleAnalysis::Key; 3598bcb0991SDimitry Andric 3608bcb0991SDimitry Andric MachineModuleInfo MachineModuleAnalysis::run(Module &M, 3618bcb0991SDimitry Andric ModuleAnalysisManager &) { 3628bcb0991SDimitry Andric MachineModuleInfo MMI(TM); 3638bcb0991SDimitry Andric MMI.TheModule = &M; 3648bcb0991SDimitry Andric MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 3658bcb0991SDimitry Andric return MMI; 3668bcb0991SDimitry Andric } 367