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(); 107480093f4SDimitry Andric MCSymbol *Sym = Context.createTempSymbol(!BB->hasAddressTaken()); 108480093f4SDimitry Andric Entry.Symbols.push_back(Sym); 109*0b57cec5SDimitry Andric return Entry.Symbols; 110*0b57cec5SDimitry Andric } 111*0b57cec5SDimitry Andric 112*0b57cec5SDimitry Andric void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 113*0b57cec5SDimitry Andric // If the block got deleted, there is no need for the symbol. If the symbol 114*0b57cec5SDimitry Andric // was already emitted, we can just forget about it, otherwise we need to 115*0b57cec5SDimitry Andric // queue it up for later emission when the function is output. 116*0b57cec5SDimitry Andric AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 117*0b57cec5SDimitry Andric AddrLabelSymbols.erase(BB); 118*0b57cec5SDimitry Andric assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 119*0b57cec5SDimitry Andric BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 122*0b57cec5SDimitry Andric "Block/parent mismatch"); 123*0b57cec5SDimitry Andric 1245ffd83dbSDimitry Andric assert(llvm::all_of(Entry.Symbols, [](MCSymbol *Sym) { 1255ffd83dbSDimitry Andric return Sym->isDefined(); })); 126*0b57cec5SDimitry Andric } 127*0b57cec5SDimitry Andric 128*0b57cec5SDimitry Andric void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 129*0b57cec5SDimitry Andric // Get the entry for the RAUW'd block and remove it from our map. 130*0b57cec5SDimitry Andric AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 131*0b57cec5SDimitry Andric AddrLabelSymbols.erase(Old); 132*0b57cec5SDimitry Andric assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric // If New is not address taken, just move our symbol over to it. 137*0b57cec5SDimitry Andric if (NewEntry.Symbols.empty()) { 138*0b57cec5SDimitry Andric BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 139*0b57cec5SDimitry Andric NewEntry = std::move(OldEntry); // Set New's entry. 140*0b57cec5SDimitry Andric return; 141*0b57cec5SDimitry Andric } 142*0b57cec5SDimitry Andric 143*0b57cec5SDimitry Andric BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 144*0b57cec5SDimitry Andric 145*0b57cec5SDimitry Andric // Otherwise, we need to add the old symbols to the new block's set. 146*0b57cec5SDimitry Andric NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(), 147*0b57cec5SDimitry Andric OldEntry.Symbols.end()); 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(); 173*0b57cec5SDimitry Andric 174*0b57cec5SDimitry Andric delete ObjFileMMI; 175*0b57cec5SDimitry Andric ObjFileMMI = nullptr; 176*0b57cec5SDimitry Andric } 177*0b57cec5SDimitry Andric 1788bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) 1798bcb0991SDimitry Andric : TM(std::move(MMI.TM)), 1808bcb0991SDimitry Andric Context(MMI.TM.getMCAsmInfo(), MMI.TM.getMCRegisterInfo(), 1818bcb0991SDimitry Andric MMI.TM.getObjFileLowering(), nullptr, nullptr, false) { 1828bcb0991SDimitry Andric ObjFileMMI = MMI.ObjFileMMI; 1838bcb0991SDimitry Andric CurCallSite = MMI.CurCallSite; 1848bcb0991SDimitry Andric UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint; 1858bcb0991SDimitry Andric UsesMorestackAddr = MMI.UsesMorestackAddr; 1868bcb0991SDimitry Andric HasSplitStack = MMI.HasSplitStack; 1878bcb0991SDimitry Andric HasNosplitStack = MMI.HasNosplitStack; 1888bcb0991SDimitry Andric AddrLabelSymbols = MMI.AddrLabelSymbols; 1898bcb0991SDimitry Andric TheModule = MMI.TheModule; 1908bcb0991SDimitry Andric } 1918bcb0991SDimitry Andric 1928bcb0991SDimitry Andric MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 1938bcb0991SDimitry Andric : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 1948bcb0991SDimitry Andric TM->getObjFileLowering(), nullptr, nullptr, false) { 1958bcb0991SDimitry Andric initialize(); 1968bcb0991SDimitry Andric } 1978bcb0991SDimitry Andric 1988bcb0991SDimitry Andric MachineModuleInfo::~MachineModuleInfo() { finalize(); } 1998bcb0991SDimitry Andric 200*0b57cec5SDimitry Andric //===- Address of Block Management ----------------------------------------===// 201*0b57cec5SDimitry Andric 202*0b57cec5SDimitry Andric ArrayRef<MCSymbol *> 203*0b57cec5SDimitry Andric MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 204*0b57cec5SDimitry Andric // Lazily create AddrLabelSymbols. 205*0b57cec5SDimitry Andric if (!AddrLabelSymbols) 206*0b57cec5SDimitry Andric AddrLabelSymbols = new MMIAddrLabelMap(Context); 207*0b57cec5SDimitry Andric return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); 208*0b57cec5SDimitry Andric } 209*0b57cec5SDimitry Andric 210*0b57cec5SDimitry Andric /// \name Exception Handling 211*0b57cec5SDimitry Andric /// \{ 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric void MachineModuleInfo::addPersonality(const Function *Personality) { 214*0b57cec5SDimitry Andric for (unsigned i = 0; i < Personalities.size(); ++i) 215*0b57cec5SDimitry Andric if (Personalities[i] == Personality) 216*0b57cec5SDimitry Andric return; 217*0b57cec5SDimitry Andric Personalities.push_back(Personality); 218*0b57cec5SDimitry Andric } 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric /// \} 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric MachineFunction * 223*0b57cec5SDimitry Andric MachineModuleInfo::getMachineFunction(const Function &F) const { 224*0b57cec5SDimitry Andric auto I = MachineFunctions.find(&F); 225*0b57cec5SDimitry Andric return I != MachineFunctions.end() ? I->second.get() : nullptr; 226*0b57cec5SDimitry Andric } 227*0b57cec5SDimitry Andric 2285ffd83dbSDimitry Andric MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) { 229*0b57cec5SDimitry Andric // Shortcut for the common case where a sequence of MachineFunctionPasses 230*0b57cec5SDimitry Andric // all query for the same Function. 231*0b57cec5SDimitry Andric if (LastRequest == &F) 232*0b57cec5SDimitry Andric return *LastResult; 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric auto I = MachineFunctions.insert( 235*0b57cec5SDimitry Andric std::make_pair(&F, std::unique_ptr<MachineFunction>())); 236*0b57cec5SDimitry Andric MachineFunction *MF; 237*0b57cec5SDimitry Andric if (I.second) { 238*0b57cec5SDimitry Andric // No pre-existing machine function, create a new one. 239*0b57cec5SDimitry Andric const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 240*0b57cec5SDimitry Andric MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 241*0b57cec5SDimitry Andric // Update the set entry. 242*0b57cec5SDimitry Andric I.first->second.reset(MF); 243*0b57cec5SDimitry Andric } else { 244*0b57cec5SDimitry Andric MF = I.first->second.get(); 245*0b57cec5SDimitry Andric } 246*0b57cec5SDimitry Andric 247*0b57cec5SDimitry Andric LastRequest = &F; 248*0b57cec5SDimitry Andric LastResult = MF; 249*0b57cec5SDimitry Andric return *MF; 250*0b57cec5SDimitry Andric } 251*0b57cec5SDimitry Andric 252*0b57cec5SDimitry Andric void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 253*0b57cec5SDimitry Andric MachineFunctions.erase(&F); 254*0b57cec5SDimitry Andric LastRequest = nullptr; 255*0b57cec5SDimitry Andric LastResult = nullptr; 256*0b57cec5SDimitry Andric } 257*0b57cec5SDimitry Andric 258*0b57cec5SDimitry Andric namespace { 259*0b57cec5SDimitry Andric 260*0b57cec5SDimitry Andric /// This pass frees the MachineFunction object associated with a Function. 261*0b57cec5SDimitry Andric class FreeMachineFunction : public FunctionPass { 262*0b57cec5SDimitry Andric public: 263*0b57cec5SDimitry Andric static char ID; 264*0b57cec5SDimitry Andric 265*0b57cec5SDimitry Andric FreeMachineFunction() : FunctionPass(ID) {} 266*0b57cec5SDimitry Andric 267*0b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 2688bcb0991SDimitry Andric AU.addRequired<MachineModuleInfoWrapperPass>(); 2698bcb0991SDimitry Andric AU.addPreserved<MachineModuleInfoWrapperPass>(); 270*0b57cec5SDimitry Andric } 271*0b57cec5SDimitry Andric 272*0b57cec5SDimitry Andric bool runOnFunction(Function &F) override { 2738bcb0991SDimitry Andric MachineModuleInfo &MMI = 2748bcb0991SDimitry Andric getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 275*0b57cec5SDimitry Andric MMI.deleteMachineFunctionFor(F); 276*0b57cec5SDimitry Andric return true; 277*0b57cec5SDimitry Andric } 278*0b57cec5SDimitry Andric 279*0b57cec5SDimitry Andric StringRef getPassName() const override { 280*0b57cec5SDimitry Andric return "Free MachineFunction"; 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric }; 283*0b57cec5SDimitry Andric 284*0b57cec5SDimitry Andric } // end anonymous namespace 285*0b57cec5SDimitry Andric 286*0b57cec5SDimitry Andric char FreeMachineFunction::ID; 287*0b57cec5SDimitry Andric 288*0b57cec5SDimitry Andric FunctionPass *llvm::createFreeMachineFunctionPass() { 289*0b57cec5SDimitry Andric return new FreeMachineFunction(); 290*0b57cec5SDimitry Andric } 2918bcb0991SDimitry Andric 2928bcb0991SDimitry Andric MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 2938bcb0991SDimitry Andric const LLVMTargetMachine *TM) 2948bcb0991SDimitry Andric : ImmutablePass(ID), MMI(TM) { 2958bcb0991SDimitry Andric initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 2968bcb0991SDimitry Andric } 2978bcb0991SDimitry Andric 2988bcb0991SDimitry Andric // Handle the Pass registration stuff necessary to use DataLayout's. 2998bcb0991SDimitry Andric INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 3008bcb0991SDimitry Andric "Machine Module Information", false, false) 3018bcb0991SDimitry Andric char MachineModuleInfoWrapperPass::ID = 0; 3028bcb0991SDimitry Andric 3038bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 3048bcb0991SDimitry Andric MMI.initialize(); 3058bcb0991SDimitry Andric MMI.TheModule = &M; 3068bcb0991SDimitry Andric MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 3078bcb0991SDimitry Andric return false; 3088bcb0991SDimitry Andric } 3098bcb0991SDimitry Andric 3108bcb0991SDimitry Andric bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 3118bcb0991SDimitry Andric MMI.finalize(); 3128bcb0991SDimitry Andric return false; 3138bcb0991SDimitry Andric } 3148bcb0991SDimitry Andric 3158bcb0991SDimitry Andric AnalysisKey MachineModuleAnalysis::Key; 3168bcb0991SDimitry Andric 3178bcb0991SDimitry Andric MachineModuleInfo MachineModuleAnalysis::run(Module &M, 3188bcb0991SDimitry Andric ModuleAnalysisManager &) { 3198bcb0991SDimitry Andric MachineModuleInfo MMI(TM); 3208bcb0991SDimitry Andric MMI.TheModule = &M; 3218bcb0991SDimitry Andric MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 3228bcb0991SDimitry Andric return MMI; 3238bcb0991SDimitry Andric } 324