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" 19fe6060f1SDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 20*0b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 21fe6060f1SDimitry Andric #include "llvm/IR/LLVMContext.h" 22*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 23*0b57cec5SDimitry Andric #include "llvm/IR/Value.h" 24*0b57cec5SDimitry Andric #include "llvm/IR/ValueHandle.h" 25480093f4SDimitry Andric #include "llvm/InitializePasses.h" 26*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 27*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 28480093f4SDimitry Andric #include "llvm/MC/MCSymbolXCOFF.h" 29*0b57cec5SDimitry Andric #include "llvm/Pass.h" 30*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 31*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 32*0b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 33*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 34*0b57cec5SDimitry Andric #include <algorithm> 35*0b57cec5SDimitry Andric #include <cassert> 36*0b57cec5SDimitry Andric #include <memory> 37*0b57cec5SDimitry Andric #include <utility> 38*0b57cec5SDimitry Andric #include <vector> 39*0b57cec5SDimitry Andric 40*0b57cec5SDimitry Andric using namespace llvm; 41*0b57cec5SDimitry Andric using namespace llvm::dwarf; 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric // Out of line virtual method. 44*0b57cec5SDimitry Andric MachineModuleInfoImpl::~MachineModuleInfoImpl() = default; 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric namespace llvm { 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric class MMIAddrLabelMapCallbackPtr final : CallbackVH { 49*0b57cec5SDimitry Andric MMIAddrLabelMap *Map = nullptr; 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric public: 52*0b57cec5SDimitry Andric MMIAddrLabelMapCallbackPtr() = default; 53*0b57cec5SDimitry Andric MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric void setPtr(BasicBlock *BB) { 56*0b57cec5SDimitry Andric ValueHandleBase::operator=(BB); 57*0b57cec5SDimitry Andric } 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric void setMap(MMIAddrLabelMap *map) { Map = map; } 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric void deleted() override; 62*0b57cec5SDimitry Andric void allUsesReplacedWith(Value *V2) override; 63*0b57cec5SDimitry Andric }; 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric class MMIAddrLabelMap { 66*0b57cec5SDimitry Andric MCContext &Context; 67*0b57cec5SDimitry Andric struct AddrLabelSymEntry { 68*0b57cec5SDimitry Andric /// The symbols for the label. 69*0b57cec5SDimitry Andric TinyPtrVector<MCSymbol *> Symbols; 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric Function *Fn; // The containing function of the BasicBlock. 72*0b57cec5SDimitry Andric unsigned Index; // The index in BBCallbacks for the BasicBlock. 73*0b57cec5SDimitry Andric }; 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric /// Callbacks for the BasicBlock's that we have entries for. We use this so 78*0b57cec5SDimitry Andric /// we get notified if a block is deleted or RAUWd. 79*0b57cec5SDimitry Andric std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks; 80*0b57cec5SDimitry Andric 81fe6060f1SDimitry Andric /// This is a per-function list of symbols whose corresponding BasicBlock got 82fe6060f1SDimitry Andric /// deleted. These symbols need to be emitted at some point in the file, so 83fe6060f1SDimitry Andric /// AsmPrinter emits them after the function body. 84fe6060f1SDimitry Andric DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>> 85fe6060f1SDimitry Andric DeletedAddrLabelsNeedingEmission; 86fe6060f1SDimitry Andric 87*0b57cec5SDimitry Andric public: 88*0b57cec5SDimitry Andric MMIAddrLabelMap(MCContext &context) : Context(context) {} 89*0b57cec5SDimitry Andric 90fe6060f1SDimitry Andric ~MMIAddrLabelMap() { 91fe6060f1SDimitry Andric assert(DeletedAddrLabelsNeedingEmission.empty() && 92fe6060f1SDimitry Andric "Some labels for deleted blocks never got emitted"); 93fe6060f1SDimitry Andric } 94fe6060f1SDimitry Andric 95*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); 96*0b57cec5SDimitry Andric 97fe6060f1SDimitry Andric void takeDeletedSymbolsForFunction(Function *F, 98fe6060f1SDimitry Andric std::vector<MCSymbol*> &Result); 99fe6060f1SDimitry Andric 100*0b57cec5SDimitry Andric void UpdateForDeletedBlock(BasicBlock *BB); 101*0b57cec5SDimitry Andric void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); 102*0b57cec5SDimitry Andric }; 103*0b57cec5SDimitry Andric 104*0b57cec5SDimitry Andric } // end namespace llvm 105*0b57cec5SDimitry Andric 106*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { 107*0b57cec5SDimitry Andric assert(BB->hasAddressTaken() && 108*0b57cec5SDimitry Andric "Shouldn't get label for block without address taken"); 109*0b57cec5SDimitry Andric AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric // If we already had an entry for this block, just return it. 112*0b57cec5SDimitry Andric if (!Entry.Symbols.empty()) { 113*0b57cec5SDimitry Andric assert(BB->getParent() == Entry.Fn && "Parent changed"); 114*0b57cec5SDimitry Andric return Entry.Symbols; 115*0b57cec5SDimitry Andric } 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric // Otherwise, this is a new entry, create a new symbol for it and add an 118*0b57cec5SDimitry Andric // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. 119*0b57cec5SDimitry Andric BBCallbacks.emplace_back(BB); 120*0b57cec5SDimitry Andric BBCallbacks.back().setMap(this); 121*0b57cec5SDimitry Andric Entry.Index = BBCallbacks.size() - 1; 122*0b57cec5SDimitry Andric Entry.Fn = BB->getParent(); 123e8d8bef9SDimitry Andric MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol() 124e8d8bef9SDimitry Andric : Context.createTempSymbol(); 125480093f4SDimitry Andric Entry.Symbols.push_back(Sym); 126*0b57cec5SDimitry Andric return Entry.Symbols; 127*0b57cec5SDimitry Andric } 128*0b57cec5SDimitry Andric 129fe6060f1SDimitry Andric /// If we have any deleted symbols for F, return them. 130fe6060f1SDimitry Andric void MMIAddrLabelMap:: 131fe6060f1SDimitry Andric takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) { 132fe6060f1SDimitry Andric DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>::iterator I = 133fe6060f1SDimitry Andric DeletedAddrLabelsNeedingEmission.find(F); 134fe6060f1SDimitry Andric 135fe6060f1SDimitry Andric // If there are no entries for the function, just return. 136fe6060f1SDimitry Andric if (I == DeletedAddrLabelsNeedingEmission.end()) return; 137fe6060f1SDimitry Andric 138fe6060f1SDimitry Andric // Otherwise, take the list. 139fe6060f1SDimitry Andric std::swap(Result, I->second); 140fe6060f1SDimitry Andric DeletedAddrLabelsNeedingEmission.erase(I); 141fe6060f1SDimitry Andric } 142fe6060f1SDimitry Andric 143*0b57cec5SDimitry Andric void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 144*0b57cec5SDimitry Andric // If the block got deleted, there is no need for the symbol. If the symbol 145*0b57cec5SDimitry Andric // was already emitted, we can just forget about it, otherwise we need to 146*0b57cec5SDimitry Andric // queue it up for later emission when the function is output. 147*0b57cec5SDimitry Andric AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 148*0b57cec5SDimitry Andric AddrLabelSymbols.erase(BB); 149*0b57cec5SDimitry Andric assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 150*0b57cec5SDimitry Andric BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 151*0b57cec5SDimitry Andric 152*0b57cec5SDimitry Andric assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 153*0b57cec5SDimitry Andric "Block/parent mismatch"); 154*0b57cec5SDimitry Andric 155fe6060f1SDimitry Andric for (MCSymbol *Sym : Entry.Symbols) { 156fe6060f1SDimitry Andric if (Sym->isDefined()) 157fe6060f1SDimitry Andric return; 158fe6060f1SDimitry Andric 159fe6060f1SDimitry Andric // If the block is not yet defined, we need to emit it at the end of the 160fe6060f1SDimitry Andric // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list 161fe6060f1SDimitry Andric // for the containing Function. Since the block is being deleted, its 162fe6060f1SDimitry Andric // parent may already be removed, we have to get the function from 'Entry'. 163fe6060f1SDimitry Andric DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); 164fe6060f1SDimitry Andric } 165*0b57cec5SDimitry Andric } 166*0b57cec5SDimitry Andric 167*0b57cec5SDimitry Andric void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 168*0b57cec5SDimitry Andric // Get the entry for the RAUW'd block and remove it from our map. 169*0b57cec5SDimitry Andric AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 170*0b57cec5SDimitry Andric AddrLabelSymbols.erase(Old); 171*0b57cec5SDimitry Andric assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andric AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric // If New is not address taken, just move our symbol over to it. 176*0b57cec5SDimitry Andric if (NewEntry.Symbols.empty()) { 177*0b57cec5SDimitry Andric BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 178*0b57cec5SDimitry Andric NewEntry = std::move(OldEntry); // Set New's entry. 179*0b57cec5SDimitry Andric return; 180*0b57cec5SDimitry Andric } 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andric BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 183*0b57cec5SDimitry Andric 184*0b57cec5SDimitry Andric // Otherwise, we need to add the old symbols to the new block's set. 185e8d8bef9SDimitry Andric llvm::append_range(NewEntry.Symbols, OldEntry.Symbols); 186*0b57cec5SDimitry Andric } 187*0b57cec5SDimitry Andric 188*0b57cec5SDimitry Andric void MMIAddrLabelMapCallbackPtr::deleted() { 189*0b57cec5SDimitry Andric Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); 190*0b57cec5SDimitry Andric } 191*0b57cec5SDimitry Andric 192*0b57cec5SDimitry Andric void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { 193*0b57cec5SDimitry Andric Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); 194*0b57cec5SDimitry Andric } 195*0b57cec5SDimitry Andric 1968bcb0991SDimitry Andric void MachineModuleInfo::initialize() { 197*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 198*0b57cec5SDimitry Andric CurCallSite = 0; 199fe6060f1SDimitry Andric NextFnNum = 0; 200*0b57cec5SDimitry Andric UsesMSVCFloatingPoint = UsesMorestackAddr = false; 201*0b57cec5SDimitry Andric HasSplitStack = HasNosplitStack = false; 202*0b57cec5SDimitry Andric AddrLabelSymbols = nullptr; 203*0b57cec5SDimitry Andric } 204*0b57cec5SDimitry Andric 2058bcb0991SDimitry Andric void MachineModuleInfo::finalize() { 206*0b57cec5SDimitry Andric Personalities.clear(); 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andric delete AddrLabelSymbols; 209*0b57cec5SDimitry Andric AddrLabelSymbols = nullptr; 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric Context.reset(); 212e8d8bef9SDimitry Andric // We don't clear the ExternalContext. 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andric delete ObjFileMMI; 215*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 216*0b57cec5SDimitry Andric } 217*0b57cec5SDimitry Andric 2188bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) 2198bcb0991SDimitry Andric : TM(std::move(MMI.TM)), 220fe6060f1SDimitry Andric Context(MMI.TM.getTargetTriple(), MMI.TM.getMCAsmInfo(), 221fe6060f1SDimitry Andric MMI.TM.getMCRegisterInfo(), MMI.TM.getMCSubtargetInfo(), nullptr, 222fe6060f1SDimitry Andric nullptr, false), 223e8d8bef9SDimitry Andric MachineFunctions(std::move(MMI.MachineFunctions)) { 224fe6060f1SDimitry Andric Context.setObjectFileInfo(MMI.TM.getObjFileLowering()); 2258bcb0991SDimitry Andric ObjFileMMI = MMI.ObjFileMMI; 2268bcb0991SDimitry Andric CurCallSite = MMI.CurCallSite; 2278bcb0991SDimitry Andric UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint; 2288bcb0991SDimitry Andric UsesMorestackAddr = MMI.UsesMorestackAddr; 2298bcb0991SDimitry Andric HasSplitStack = MMI.HasSplitStack; 2308bcb0991SDimitry Andric HasNosplitStack = MMI.HasNosplitStack; 2318bcb0991SDimitry Andric AddrLabelSymbols = MMI.AddrLabelSymbols; 232e8d8bef9SDimitry Andric ExternalContext = MMI.ExternalContext; 2338bcb0991SDimitry Andric TheModule = MMI.TheModule; 2348bcb0991SDimitry Andric } 2358bcb0991SDimitry Andric 2368bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 237fe6060f1SDimitry Andric : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), 238fe6060f1SDimitry Andric TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), 239fe6060f1SDimitry Andric nullptr, nullptr, false) { 240fe6060f1SDimitry Andric Context.setObjectFileInfo(TM->getObjFileLowering()); 2418bcb0991SDimitry Andric initialize(); 2428bcb0991SDimitry Andric } 2438bcb0991SDimitry Andric 244e8d8bef9SDimitry Andric MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM, 245e8d8bef9SDimitry Andric MCContext *ExtContext) 246fe6060f1SDimitry Andric : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), 247fe6060f1SDimitry Andric TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), 248fe6060f1SDimitry Andric nullptr, nullptr, false), 249e8d8bef9SDimitry Andric ExternalContext(ExtContext) { 250fe6060f1SDimitry Andric Context.setObjectFileInfo(TM->getObjFileLowering()); 251e8d8bef9SDimitry Andric initialize(); 252e8d8bef9SDimitry Andric } 253e8d8bef9SDimitry Andric 2548bcb0991SDimitry Andric MachineModuleInfo::~MachineModuleInfo() { finalize(); } 2558bcb0991SDimitry Andric 256*0b57cec5SDimitry Andric //===- Address of Block Management ----------------------------------------===// 257*0b57cec5SDimitry Andric 258*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> 259*0b57cec5SDimitry Andric MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 260*0b57cec5SDimitry Andric // Lazily create AddrLabelSymbols. 261*0b57cec5SDimitry Andric if (!AddrLabelSymbols) 262e8d8bef9SDimitry Andric AddrLabelSymbols = new MMIAddrLabelMap(getContext()); 263*0b57cec5SDimitry Andric return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); 264*0b57cec5SDimitry Andric } 265*0b57cec5SDimitry Andric 266fe6060f1SDimitry Andric void MachineModuleInfo:: 267fe6060f1SDimitry Andric takeDeletedSymbolsForFunction(const Function *F, 268fe6060f1SDimitry Andric std::vector<MCSymbol*> &Result) { 269fe6060f1SDimitry Andric // If no blocks have had their addresses taken, we're done. 270fe6060f1SDimitry Andric if (!AddrLabelSymbols) return; 271fe6060f1SDimitry Andric return AddrLabelSymbols-> 272fe6060f1SDimitry Andric takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result); 273fe6060f1SDimitry Andric } 274fe6060f1SDimitry Andric 275*0b57cec5SDimitry Andric /// \name Exception Handling 276*0b57cec5SDimitry Andric /// \{ 277*0b57cec5SDimitry Andric 278*0b57cec5SDimitry Andric void MachineModuleInfo::addPersonality(const Function *Personality) { 279fe6060f1SDimitry Andric if (!llvm::is_contained(Personalities, Personality)) 280*0b57cec5SDimitry Andric Personalities.push_back(Personality); 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric /// \} 284*0b57cec5SDimitry Andric 285*0b57cec5SDimitry Andric MachineFunction * 286*0b57cec5SDimitry Andric MachineModuleInfo::getMachineFunction(const Function &F) const { 287*0b57cec5SDimitry Andric auto I = MachineFunctions.find(&F); 288*0b57cec5SDimitry Andric return I != MachineFunctions.end() ? I->second.get() : nullptr; 289*0b57cec5SDimitry Andric } 290*0b57cec5SDimitry Andric 2915ffd83dbSDimitry Andric MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) { 292*0b57cec5SDimitry Andric // Shortcut for the common case where a sequence of MachineFunctionPasses 293*0b57cec5SDimitry Andric // all query for the same Function. 294*0b57cec5SDimitry Andric if (LastRequest == &F) 295*0b57cec5SDimitry Andric return *LastResult; 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric auto I = MachineFunctions.insert( 298*0b57cec5SDimitry Andric std::make_pair(&F, std::unique_ptr<MachineFunction>())); 299*0b57cec5SDimitry Andric MachineFunction *MF; 300*0b57cec5SDimitry Andric if (I.second) { 301*0b57cec5SDimitry Andric // No pre-existing machine function, create a new one. 302*0b57cec5SDimitry Andric const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 303*0b57cec5SDimitry Andric MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 304*0b57cec5SDimitry Andric // Update the set entry. 305*0b57cec5SDimitry Andric I.first->second.reset(MF); 306*0b57cec5SDimitry Andric } else { 307*0b57cec5SDimitry Andric MF = I.first->second.get(); 308*0b57cec5SDimitry Andric } 309*0b57cec5SDimitry Andric 310*0b57cec5SDimitry Andric LastRequest = &F; 311*0b57cec5SDimitry Andric LastResult = MF; 312*0b57cec5SDimitry Andric return *MF; 313*0b57cec5SDimitry Andric } 314*0b57cec5SDimitry Andric 315*0b57cec5SDimitry Andric void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 316*0b57cec5SDimitry Andric MachineFunctions.erase(&F); 317*0b57cec5SDimitry Andric LastRequest = nullptr; 318*0b57cec5SDimitry Andric LastResult = nullptr; 319*0b57cec5SDimitry Andric } 320*0b57cec5SDimitry Andric 321*0b57cec5SDimitry Andric namespace { 322*0b57cec5SDimitry Andric 323*0b57cec5SDimitry Andric /// This pass frees the MachineFunction object associated with a Function. 324*0b57cec5SDimitry Andric class FreeMachineFunction : public FunctionPass { 325*0b57cec5SDimitry Andric public: 326*0b57cec5SDimitry Andric static char ID; 327*0b57cec5SDimitry Andric 328*0b57cec5SDimitry Andric FreeMachineFunction() : FunctionPass(ID) {} 329*0b57cec5SDimitry Andric 330*0b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 3318bcb0991SDimitry Andric AU.addRequired<MachineModuleInfoWrapperPass>(); 3328bcb0991SDimitry Andric AU.addPreserved<MachineModuleInfoWrapperPass>(); 333*0b57cec5SDimitry Andric } 334*0b57cec5SDimitry Andric 335*0b57cec5SDimitry Andric bool runOnFunction(Function &F) override { 3368bcb0991SDimitry Andric MachineModuleInfo &MMI = 3378bcb0991SDimitry Andric getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 338*0b57cec5SDimitry Andric MMI.deleteMachineFunctionFor(F); 339*0b57cec5SDimitry Andric return true; 340*0b57cec5SDimitry Andric } 341*0b57cec5SDimitry Andric 342*0b57cec5SDimitry Andric StringRef getPassName() const override { 343*0b57cec5SDimitry Andric return "Free MachineFunction"; 344*0b57cec5SDimitry Andric } 345*0b57cec5SDimitry Andric }; 346*0b57cec5SDimitry Andric 347*0b57cec5SDimitry Andric } // end anonymous namespace 348*0b57cec5SDimitry Andric 349*0b57cec5SDimitry Andric char FreeMachineFunction::ID; 350*0b57cec5SDimitry Andric 351*0b57cec5SDimitry Andric FunctionPass *llvm::createFreeMachineFunctionPass() { 352*0b57cec5SDimitry Andric return new FreeMachineFunction(); 353*0b57cec5SDimitry Andric } 3548bcb0991SDimitry Andric 3558bcb0991SDimitry Andric MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 3568bcb0991SDimitry Andric const LLVMTargetMachine *TM) 3578bcb0991SDimitry Andric : ImmutablePass(ID), MMI(TM) { 3588bcb0991SDimitry Andric initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 3598bcb0991SDimitry Andric } 3608bcb0991SDimitry Andric 361e8d8bef9SDimitry Andric MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 362e8d8bef9SDimitry Andric const LLVMTargetMachine *TM, MCContext *ExtContext) 363e8d8bef9SDimitry Andric : ImmutablePass(ID), MMI(TM, ExtContext) { 364e8d8bef9SDimitry Andric initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 365e8d8bef9SDimitry Andric } 366e8d8bef9SDimitry Andric 3678bcb0991SDimitry Andric // Handle the Pass registration stuff necessary to use DataLayout's. 3688bcb0991SDimitry Andric INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 3698bcb0991SDimitry Andric "Machine Module Information", false, false) 3708bcb0991SDimitry Andric char MachineModuleInfoWrapperPass::ID = 0; 3718bcb0991SDimitry Andric 372fe6060f1SDimitry Andric static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr, 373fe6060f1SDimitry Andric std::vector<const MDNode *> &LocInfos) { 374fe6060f1SDimitry Andric // Look up a LocInfo for the buffer this diagnostic is coming from. 375fe6060f1SDimitry Andric unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc()); 376fe6060f1SDimitry Andric const MDNode *LocInfo = nullptr; 377fe6060f1SDimitry Andric if (BufNum > 0 && BufNum <= LocInfos.size()) 378fe6060f1SDimitry Andric LocInfo = LocInfos[BufNum - 1]; 379fe6060f1SDimitry Andric 380fe6060f1SDimitry Andric // If the inline asm had metadata associated with it, pull out a location 381fe6060f1SDimitry Andric // cookie corresponding to which line the error occurred on. 382fe6060f1SDimitry Andric unsigned LocCookie = 0; 383fe6060f1SDimitry Andric if (LocInfo) { 384fe6060f1SDimitry Andric unsigned ErrorLine = SMD.getLineNo() - 1; 385fe6060f1SDimitry Andric if (ErrorLine >= LocInfo->getNumOperands()) 386fe6060f1SDimitry Andric ErrorLine = 0; 387fe6060f1SDimitry Andric 388fe6060f1SDimitry Andric if (LocInfo->getNumOperands() != 0) 389fe6060f1SDimitry Andric if (const ConstantInt *CI = 390fe6060f1SDimitry Andric mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine))) 391fe6060f1SDimitry Andric LocCookie = CI->getZExtValue(); 392fe6060f1SDimitry Andric } 393fe6060f1SDimitry Andric 394fe6060f1SDimitry Andric return LocCookie; 395fe6060f1SDimitry Andric } 396fe6060f1SDimitry Andric 3978bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 3988bcb0991SDimitry Andric MMI.initialize(); 3998bcb0991SDimitry Andric MMI.TheModule = &M; 400fe6060f1SDimitry Andric // FIXME: Do this for new pass manager. 401fe6060f1SDimitry Andric LLVMContext &Ctx = M.getContext(); 402fe6060f1SDimitry Andric MMI.getContext().setDiagnosticHandler( 403fe6060f1SDimitry Andric [&Ctx](const SMDiagnostic &SMD, bool IsInlineAsm, const SourceMgr &SrcMgr, 404fe6060f1SDimitry Andric std::vector<const MDNode *> &LocInfos) { 405fe6060f1SDimitry Andric unsigned LocCookie = 0; 406fe6060f1SDimitry Andric if (IsInlineAsm) 407fe6060f1SDimitry Andric LocCookie = getLocCookie(SMD, SrcMgr, LocInfos); 408fe6060f1SDimitry Andric Ctx.diagnose(DiagnosticInfoSrcMgr(SMD, IsInlineAsm, LocCookie)); 409fe6060f1SDimitry Andric }); 4108bcb0991SDimitry Andric MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 4118bcb0991SDimitry Andric return false; 4128bcb0991SDimitry Andric } 4138bcb0991SDimitry Andric 4148bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 4158bcb0991SDimitry Andric MMI.finalize(); 4168bcb0991SDimitry Andric return false; 4178bcb0991SDimitry Andric } 4188bcb0991SDimitry Andric 4198bcb0991SDimitry Andric AnalysisKey MachineModuleAnalysis::Key; 4208bcb0991SDimitry Andric 4218bcb0991SDimitry Andric MachineModuleInfo MachineModuleAnalysis::run(Module &M, 4228bcb0991SDimitry Andric ModuleAnalysisManager &) { 4238bcb0991SDimitry Andric MachineModuleInfo MMI(TM); 4248bcb0991SDimitry Andric MMI.TheModule = &M; 4258bcb0991SDimitry Andric MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 4268bcb0991SDimitry Andric return MMI; 4278bcb0991SDimitry Andric } 428