1193323Sed//===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===// 2193323Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193323Sed// 7193323Sed//===----------------------------------------------------------------------===// 8193323Sed 9193323Sed#include "llvm/CodeGen/MachineModuleInfo.h" 10321369Sdim#include "llvm/ADT/ArrayRef.h" 11321369Sdim#include "llvm/ADT/DenseMap.h" 12314564Sdim#include "llvm/ADT/PostOrderIterator.h" 13321369Sdim#include "llvm/ADT/StringRef.h" 14296417Sdim#include "llvm/ADT/TinyPtrVector.h" 15249423Sdim#include "llvm/CodeGen/MachineFunction.h" 16193323Sed#include "llvm/CodeGen/Passes.h" 17321369Sdim#include "llvm/IR/BasicBlock.h" 18249423Sdim#include "llvm/IR/DerivedTypes.h" 19314564Sdim#include "llvm/IR/Instructions.h" 20249423Sdim#include "llvm/IR/Module.h" 21321369Sdim#include "llvm/IR/Value.h" 22321369Sdim#include "llvm/IR/ValueHandle.h" 23360784Sdim#include "llvm/InitializePasses.h" 24321369Sdim#include "llvm/MC/MCContext.h" 25205218Srdivacky#include "llvm/MC/MCSymbol.h" 26360784Sdim#include "llvm/MC/MCSymbolXCOFF.h" 27321369Sdim#include "llvm/Pass.h" 28321369Sdim#include "llvm/Support/Casting.h" 29198090Srdivacky#include "llvm/Support/ErrorHandling.h" 30341825Sdim#include "llvm/Target/TargetLoweringObjectFile.h" 31314564Sdim#include "llvm/Target/TargetMachine.h" 32321369Sdim#include <algorithm> 33321369Sdim#include <cassert> 34321369Sdim#include <memory> 35321369Sdim#include <utility> 36321369Sdim#include <vector> 37321369Sdim 38193323Sedusing namespace llvm; 39193323Sedusing namespace llvm::dwarf; 40193323Sed 41198090Srdivacky// Out of line virtual method. 42321369SdimMachineModuleInfoImpl::~MachineModuleInfoImpl() = default; 43198090Srdivacky 44205218Srdivackynamespace llvm { 45321369Sdim 46296417Sdimclass MMIAddrLabelMapCallbackPtr final : CallbackVH { 47321369Sdim MMIAddrLabelMap *Map = nullptr; 48321369Sdim 49205218Srdivackypublic: 50321369Sdim MMIAddrLabelMapCallbackPtr() = default; 51321369Sdim MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} 52218893Sdim 53206083Srdivacky void setPtr(BasicBlock *BB) { 54206083Srdivacky ValueHandleBase::operator=(BB); 55206083Srdivacky } 56218893Sdim 57205218Srdivacky void setMap(MMIAddrLabelMap *map) { Map = map; } 58218893Sdim 59276479Sdim void deleted() override; 60276479Sdim void allUsesReplacedWith(Value *V2) override; 61205218Srdivacky}; 62218893Sdim 63205218Srdivackyclass MMIAddrLabelMap { 64205218Srdivacky MCContext &Context; 65205218Srdivacky struct AddrLabelSymEntry { 66314564Sdim /// The symbols for the label. 67288943Sdim TinyPtrVector<MCSymbol *> Symbols; 68218893Sdim 69205218Srdivacky Function *Fn; // The containing function of the BasicBlock. 70205218Srdivacky unsigned Index; // The index in BBCallbacks for the BasicBlock. 71205218Srdivacky }; 72218893Sdim 73205218Srdivacky DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; 74218893Sdim 75314564Sdim /// Callbacks for the BasicBlock's that we have entries for. We use this so 76314564Sdim /// we get notified if a block is deleted or RAUWd. 77205218Srdivacky std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks; 78205218Srdivacky 79314564Sdim /// This is a per-function list of symbols whose corresponding BasicBlock got 80314564Sdim /// deleted. These symbols need to be emitted at some point in the file, so 81314564Sdim /// AsmPrinter emits them after the function body. 82321369Sdim DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>> 83205218Srdivacky DeletedAddrLabelsNeedingEmission; 84321369Sdim 85205218Srdivackypublic: 86321369Sdim MMIAddrLabelMap(MCContext &context) : Context(context) {} 87218893Sdim 88205218Srdivacky ~MMIAddrLabelMap() { 89205218Srdivacky assert(DeletedAddrLabelsNeedingEmission.empty() && 90205218Srdivacky "Some labels for deleted blocks never got emitted"); 91205218Srdivacky } 92218893Sdim 93288943Sdim ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); 94205218Srdivacky 95218893Sdim void takeDeletedSymbolsForFunction(Function *F, 96205218Srdivacky std::vector<MCSymbol*> &Result); 97205218Srdivacky 98205218Srdivacky void UpdateForDeletedBlock(BasicBlock *BB); 99205218Srdivacky void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); 100205218Srdivacky}; 101205218Srdivacky 102321369Sdim} // end namespace llvm 103321369Sdim 104288943SdimArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { 105205218Srdivacky assert(BB->hasAddressTaken() && 106205218Srdivacky "Shouldn't get label for block without address taken"); 107205218Srdivacky AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; 108218893Sdim 109205218Srdivacky // If we already had an entry for this block, just return it. 110288943Sdim if (!Entry.Symbols.empty()) { 111205218Srdivacky assert(BB->getParent() == Entry.Fn && "Parent changed"); 112288943Sdim return Entry.Symbols; 113205218Srdivacky } 114218893Sdim 115205218Srdivacky // Otherwise, this is a new entry, create a new symbol for it and add an 116205218Srdivacky // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. 117288943Sdim BBCallbacks.emplace_back(BB); 118205218Srdivacky BBCallbacks.back().setMap(this); 119288943Sdim Entry.Index = BBCallbacks.size() - 1; 120205218Srdivacky Entry.Fn = BB->getParent(); 121360784Sdim MCSymbol *Sym = Context.createTempSymbol(!BB->hasAddressTaken()); 122360784Sdim if (Context.getObjectFileInfo()->getTargetTriple().isOSBinFormatXCOFF()) { 123360784Sdim MCSymbol *FnEntryPointSym = 124360784Sdim Context.lookupSymbol("." + Entry.Fn->getName()); 125360784Sdim assert(FnEntryPointSym && "The function entry pointer symbol should have" 126360784Sdim " already been initialized."); 127360784Sdim MCSectionXCOFF *Csect = 128360784Sdim cast<MCSymbolXCOFF>(FnEntryPointSym)->getContainingCsect(); 129360784Sdim cast<MCSymbolXCOFF>(Sym)->setContainingCsect(Csect); 130360784Sdim } 131360784Sdim Entry.Symbols.push_back(Sym); 132288943Sdim return Entry.Symbols; 133205218Srdivacky} 134205218Srdivacky 135314564Sdim/// If we have any deleted symbols for F, return them. 136205218Srdivackyvoid MMIAddrLabelMap:: 137205218SrdivackytakeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) { 138321369Sdim DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>::iterator I = 139205218Srdivacky DeletedAddrLabelsNeedingEmission.find(F); 140205218Srdivacky 141205218Srdivacky // If there are no entries for the function, just return. 142205218Srdivacky if (I == DeletedAddrLabelsNeedingEmission.end()) return; 143218893Sdim 144205218Srdivacky // Otherwise, take the list. 145205218Srdivacky std::swap(Result, I->second); 146205218Srdivacky DeletedAddrLabelsNeedingEmission.erase(I); 147205218Srdivacky} 148205218Srdivacky 149205218Srdivackyvoid MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 150205218Srdivacky // If the block got deleted, there is no need for the symbol. If the symbol 151205218Srdivacky // was already emitted, we can just forget about it, otherwise we need to 152205218Srdivacky // queue it up for later emission when the function is output. 153288943Sdim AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 154205218Srdivacky AddrLabelSymbols.erase(BB); 155288943Sdim assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 156276479Sdim BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 157205218Srdivacky 158276479Sdim assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 159205218Srdivacky "Block/parent mismatch"); 160205218Srdivacky 161288943Sdim for (MCSymbol *Sym : Entry.Symbols) { 162205218Srdivacky if (Sym->isDefined()) 163205218Srdivacky return; 164218893Sdim 165205218Srdivacky // If the block is not yet defined, we need to emit it at the end of the 166205218Srdivacky // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list 167205218Srdivacky // for the containing Function. Since the block is being deleted, its 168205218Srdivacky // parent may already be removed, we have to get the function from 'Entry'. 169205218Srdivacky DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); 170205218Srdivacky } 171205218Srdivacky} 172205218Srdivacky 173205218Srdivackyvoid MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 174205218Srdivacky // Get the entry for the RAUW'd block and remove it from our map. 175288943Sdim AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 176205218Srdivacky AddrLabelSymbols.erase(Old); 177288943Sdim assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 178205218Srdivacky 179205218Srdivacky AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 180205218Srdivacky 181205218Srdivacky // If New is not address taken, just move our symbol over to it. 182288943Sdim if (NewEntry.Symbols.empty()) { 183206083Srdivacky BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 184288943Sdim NewEntry = std::move(OldEntry); // Set New's entry. 185205218Srdivacky return; 186205218Srdivacky } 187205218Srdivacky 188276479Sdim BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 189205218Srdivacky 190288943Sdim // Otherwise, we need to add the old symbols to the new block's set. 191288943Sdim NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(), 192288943Sdim OldEntry.Symbols.end()); 193205218Srdivacky} 194205218Srdivacky 195205218Srdivackyvoid MMIAddrLabelMapCallbackPtr::deleted() { 196205218Srdivacky Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); 197205218Srdivacky} 198205218Srdivacky 199205218Srdivackyvoid MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { 200205218Srdivacky Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); 201205218Srdivacky} 202205218Srdivacky 203360784Sdimvoid MachineModuleInfo::initialize() { 204276479Sdim ObjFileMMI = nullptr; 205249423Sdim CurCallSite = 0; 206353358Sdim UsesMSVCFloatingPoint = UsesMorestackAddr = false; 207327952Sdim HasSplitStack = HasNosplitStack = false; 208276479Sdim AddrLabelSymbols = nullptr; 209193323Sed} 210193323Sed 211360784Sdimvoid MachineModuleInfo::finalize() { 212249423Sdim Personalities.clear(); 213249423Sdim 214205218Srdivacky delete AddrLabelSymbols; 215276479Sdim AddrLabelSymbols = nullptr; 216249423Sdim 217249423Sdim Context.reset(); 218249423Sdim 219249423Sdim delete ObjFileMMI; 220276479Sdim ObjFileMMI = nullptr; 221360784Sdim} 222249423Sdim 223360784SdimMachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) 224360784Sdim : TM(std::move(MMI.TM)), 225360784Sdim Context(MMI.TM.getMCAsmInfo(), MMI.TM.getMCRegisterInfo(), 226360784Sdim MMI.TM.getObjFileLowering(), nullptr, nullptr, false) { 227360784Sdim ObjFileMMI = MMI.ObjFileMMI; 228360784Sdim CurCallSite = MMI.CurCallSite; 229360784Sdim UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint; 230360784Sdim UsesMorestackAddr = MMI.UsesMorestackAddr; 231360784Sdim HasSplitStack = MMI.HasSplitStack; 232360784Sdim HasNosplitStack = MMI.HasNosplitStack; 233360784Sdim AddrLabelSymbols = MMI.AddrLabelSymbols; 234360784Sdim TheModule = MMI.TheModule; 235193323Sed} 236193323Sed 237360784SdimMachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 238360784Sdim : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 239360784Sdim TM->getObjFileLowering(), nullptr, nullptr, false) { 240360784Sdim initialize(); 241360784Sdim} 242360784Sdim 243360784SdimMachineModuleInfo::~MachineModuleInfo() { finalize(); } 244360784Sdim 245205218Srdivacky//===- Address of Block Management ----------------------------------------===// 246193323Sed 247288943SdimArrayRef<MCSymbol *> 248288943SdimMachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 249205218Srdivacky // Lazily create AddrLabelSymbols. 250276479Sdim if (!AddrLabelSymbols) 251205218Srdivacky AddrLabelSymbols = new MMIAddrLabelMap(Context); 252205218Srdivacky return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); 253205218Srdivacky} 254205218Srdivacky 255205218Srdivackyvoid MachineModuleInfo:: 256205218SrdivackytakeDeletedSymbolsForFunction(const Function *F, 257205218Srdivacky std::vector<MCSymbol*> &Result) { 258205218Srdivacky // If no blocks have had their addresses taken, we're done. 259276479Sdim if (!AddrLabelSymbols) return; 260205218Srdivacky return AddrLabelSymbols-> 261205218Srdivacky takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result); 262205218Srdivacky} 263205218Srdivacky 264314564Sdim/// \name Exception Handling 265314564Sdim/// \{ 266205218Srdivacky 267288943Sdimvoid MachineModuleInfo::addPersonality(const Function *Personality) { 268193323Sed for (unsigned i = 0; i < Personalities.size(); ++i) 269193323Sed if (Personalities[i] == Personality) 270193323Sed return; 271296417Sdim Personalities.push_back(Personality); 272193323Sed} 273193323Sed 274314564Sdim/// \} 275193323Sed 276321369SdimMachineFunction * 277321369SdimMachineModuleInfo::getMachineFunction(const Function &F) const { 278321369Sdim auto I = MachineFunctions.find(&F); 279321369Sdim return I != MachineFunctions.end() ? I->second.get() : nullptr; 280321369Sdim} 281321369Sdim 282321369SdimMachineFunction & 283321369SdimMachineModuleInfo::getOrCreateMachineFunction(const Function &F) { 284314564Sdim // Shortcut for the common case where a sequence of MachineFunctionPasses 285314564Sdim // all query for the same Function. 286314564Sdim if (LastRequest == &F) 287314564Sdim return *LastResult; 288193323Sed 289314564Sdim auto I = MachineFunctions.insert( 290314564Sdim std::make_pair(&F, std::unique_ptr<MachineFunction>())); 291314564Sdim MachineFunction *MF; 292314564Sdim if (I.second) { 293314564Sdim // No pre-existing machine function, create a new one. 294327952Sdim const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 295327952Sdim MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 296314564Sdim // Update the set entry. 297314564Sdim I.first->second.reset(MF); 298314564Sdim } else { 299314564Sdim MF = I.first->second.get(); 300314564Sdim } 301314564Sdim 302314564Sdim LastRequest = &F; 303314564Sdim LastResult = MF; 304314564Sdim return *MF; 305288943Sdim} 306288943Sdim 307314564Sdimvoid MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 308314564Sdim MachineFunctions.erase(&F); 309314564Sdim LastRequest = nullptr; 310314564Sdim LastResult = nullptr; 311288943Sdim} 312288943Sdim 313314564Sdimnamespace { 314321369Sdim 315314564Sdim/// This pass frees the MachineFunction object associated with a Function. 316314564Sdimclass FreeMachineFunction : public FunctionPass { 317314564Sdimpublic: 318314564Sdim static char ID; 319321369Sdim 320314564Sdim FreeMachineFunction() : FunctionPass(ID) {} 321193323Sed 322314564Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 323360784Sdim AU.addRequired<MachineModuleInfoWrapperPass>(); 324360784Sdim AU.addPreserved<MachineModuleInfoWrapperPass>(); 325314564Sdim } 326193323Sed 327314564Sdim bool runOnFunction(Function &F) override { 328360784Sdim MachineModuleInfo &MMI = 329360784Sdim getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 330314564Sdim MMI.deleteMachineFunctionFor(F); 331314564Sdim return true; 332193323Sed } 333341825Sdim 334321369Sdim StringRef getPassName() const override { 335321369Sdim return "Free MachineFunction"; 336341825Sdim } 337314564Sdim}; 338321369Sdim 339314564Sdim} // end anonymous namespace 340193323Sed 341321369Sdimchar FreeMachineFunction::ID; 342321369Sdim 343321369SdimFunctionPass *llvm::createFreeMachineFunctionPass() { 344314564Sdim return new FreeMachineFunction(); 345226633Sdim} 346360784Sdim 347360784SdimMachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 348360784Sdim const LLVMTargetMachine *TM) 349360784Sdim : ImmutablePass(ID), MMI(TM) { 350360784Sdim initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 351360784Sdim} 352360784Sdim 353360784Sdim// Handle the Pass registration stuff necessary to use DataLayout's. 354360784SdimINITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 355360784Sdim "Machine Module Information", false, false) 356360784Sdimchar MachineModuleInfoWrapperPass::ID = 0; 357360784Sdim 358360784Sdimbool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 359360784Sdim MMI.initialize(); 360360784Sdim MMI.TheModule = &M; 361360784Sdim MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 362360784Sdim return false; 363360784Sdim} 364360784Sdim 365360784Sdimbool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 366360784Sdim MMI.finalize(); 367360784Sdim return false; 368360784Sdim} 369360784Sdim 370360784SdimAnalysisKey MachineModuleAnalysis::Key; 371360784Sdim 372360784SdimMachineModuleInfo MachineModuleAnalysis::run(Module &M, 373360784Sdim ModuleAnalysisManager &) { 374360784Sdim MachineModuleInfo MMI(TM); 375360784Sdim MMI.TheModule = &M; 376360784Sdim MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 377360784Sdim return MMI; 378360784Sdim} 379