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