Home | History | Annotate | Download | only in CodeGen
      1 //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/CodeGen/MachineModuleInfo.h"
     11 #include "llvm/ADT/PointerUnion.h"
     12 #include "llvm/ADT/TinyPtrVector.h"
     13 #include "llvm/Analysis/EHPersonalities.h"
     14 #include "llvm/Analysis/ValueTracking.h"
     15 #include "llvm/CodeGen/MachineFunction.h"
     16 #include "llvm/CodeGen/MachineFunctionPass.h"
     17 #include "llvm/CodeGen/Passes.h"
     18 #include "llvm/IR/Constants.h"
     19 #include "llvm/IR/DerivedTypes.h"
     20 #include "llvm/IR/GlobalVariable.h"
     21 #include "llvm/IR/Module.h"
     22 #include "llvm/MC/MCObjectFileInfo.h"
     23 #include "llvm/MC/MCSymbol.h"
     24 #include "llvm/Support/Dwarf.h"
     25 #include "llvm/Support/ErrorHandling.h"
     26 using namespace llvm;
     27 using namespace llvm::dwarf;
     28 
     29 // Handle the Pass registration stuff necessary to use DataLayout's.
     30 INITIALIZE_PASS(MachineModuleInfo, "machinemoduleinfo",
     31                 "Machine Module Information", false, false)
     32 char MachineModuleInfo::ID = 0;
     33 
     34 // Out of line virtual method.
     35 MachineModuleInfoImpl::~MachineModuleInfoImpl() {}
     36 
     37 namespace llvm {
     38 class MMIAddrLabelMapCallbackPtr final : CallbackVH {
     39   MMIAddrLabelMap *Map;
     40 public:
     41   MMIAddrLabelMapCallbackPtr() : Map(nullptr) {}
     42   MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V), Map(nullptr) {}
     43 
     44   void setPtr(BasicBlock *BB) {
     45     ValueHandleBase::operator=(BB);
     46   }
     47 
     48   void setMap(MMIAddrLabelMap *map) { Map = map; }
     49 
     50   void deleted() override;
     51   void allUsesReplacedWith(Value *V2) override;
     52 };
     53 
     54 class MMIAddrLabelMap {
     55   MCContext &Context;
     56   struct AddrLabelSymEntry {
     57     /// Symbols - The symbols for the label.
     58     TinyPtrVector<MCSymbol *> Symbols;
     59 
     60     Function *Fn;   // The containing function of the BasicBlock.
     61     unsigned Index; // The index in BBCallbacks for the BasicBlock.
     62   };
     63 
     64   DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;
     65 
     66   /// BBCallbacks - Callbacks for the BasicBlock's that we have entries for.  We
     67   /// use this so we get notified if a block is deleted or RAUWd.
     68   std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks;
     69 
     70   /// DeletedAddrLabelsNeedingEmission - This is a per-function list of symbols
     71   /// whose corresponding BasicBlock got deleted.  These symbols need to be
     72   /// emitted at some point in the file, so AsmPrinter emits them after the
     73   /// function body.
     74   DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >
     75     DeletedAddrLabelsNeedingEmission;
     76 public:
     77 
     78   MMIAddrLabelMap(MCContext &context) : Context(context) {}
     79   ~MMIAddrLabelMap() {
     80     assert(DeletedAddrLabelsNeedingEmission.empty() &&
     81            "Some labels for deleted blocks never got emitted");
     82   }
     83 
     84   ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB);
     85 
     86   void takeDeletedSymbolsForFunction(Function *F,
     87                                      std::vector<MCSymbol*> &Result);
     88 
     89   void UpdateForDeletedBlock(BasicBlock *BB);
     90   void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);
     91 };
     92 }
     93 
     94 ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
     95   assert(BB->hasAddressTaken() &&
     96          "Shouldn't get label for block without address taken");
     97   AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
     98 
     99   // If we already had an entry for this block, just return it.
    100   if (!Entry.Symbols.empty()) {
    101     assert(BB->getParent() == Entry.Fn && "Parent changed");
    102     return Entry.Symbols;
    103   }
    104 
    105   // Otherwise, this is a new entry, create a new symbol for it and add an
    106   // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
    107   BBCallbacks.emplace_back(BB);
    108   BBCallbacks.back().setMap(this);
    109   Entry.Index = BBCallbacks.size() - 1;
    110   Entry.Fn = BB->getParent();
    111   Entry.Symbols.push_back(Context.createTempSymbol());
    112   return Entry.Symbols;
    113 }
    114 
    115 /// takeDeletedSymbolsForFunction - If we have any deleted symbols for F, return
    116 /// them.
    117 void MMIAddrLabelMap::
    118 takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) {
    119   DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >::iterator I =
    120     DeletedAddrLabelsNeedingEmission.find(F);
    121 
    122   // If there are no entries for the function, just return.
    123   if (I == DeletedAddrLabelsNeedingEmission.end()) return;
    124 
    125   // Otherwise, take the list.
    126   std::swap(Result, I->second);
    127   DeletedAddrLabelsNeedingEmission.erase(I);
    128 }
    129 
    130 
    131 void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
    132   // If the block got deleted, there is no need for the symbol.  If the symbol
    133   // was already emitted, we can just forget about it, otherwise we need to
    134   // queue it up for later emission when the function is output.
    135   AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);
    136   AddrLabelSymbols.erase(BB);
    137   assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?");
    138   BBCallbacks[Entry.Index] = nullptr;  // Clear the callback.
    139 
    140   assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&
    141          "Block/parent mismatch");
    142 
    143   for (MCSymbol *Sym : Entry.Symbols) {
    144     if (Sym->isDefined())
    145       return;
    146 
    147     // If the block is not yet defined, we need to emit it at the end of the
    148     // function.  Add the symbol to the DeletedAddrLabelsNeedingEmission list
    149     // for the containing Function.  Since the block is being deleted, its
    150     // parent may already be removed, we have to get the function from 'Entry'.
    151     DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
    152   }
    153 }
    154 
    155 void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
    156   // Get the entry for the RAUW'd block and remove it from our map.
    157   AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);
    158   AddrLabelSymbols.erase(Old);
    159   assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?");
    160 
    161   AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
    162 
    163   // If New is not address taken, just move our symbol over to it.
    164   if (NewEntry.Symbols.empty()) {
    165     BBCallbacks[OldEntry.Index].setPtr(New);    // Update the callback.
    166     NewEntry = std::move(OldEntry);             // Set New's entry.
    167     return;
    168   }
    169 
    170   BBCallbacks[OldEntry.Index] = nullptr;    // Update the callback.
    171 
    172   // Otherwise, we need to add the old symbols to the new block's set.
    173   NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(),
    174                           OldEntry.Symbols.end());
    175 }
    176 
    177 
    178 void MMIAddrLabelMapCallbackPtr::deleted() {
    179   Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));
    180 }
    181 
    182 void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {
    183   Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
    184 }
    185 
    186 
    187 //===----------------------------------------------------------------------===//
    188 
    189 MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI,
    190                                      const MCRegisterInfo &MRI,
    191                                      const MCObjectFileInfo *MOFI)
    192   : ImmutablePass(ID), Context(&MAI, &MRI, MOFI, nullptr, false) {
    193   initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry());
    194 }
    195 
    196 MachineModuleInfo::MachineModuleInfo()
    197   : ImmutablePass(ID), Context(nullptr, nullptr, nullptr) {
    198   llvm_unreachable("This MachineModuleInfo constructor should never be called, "
    199                    "MMI should always be explicitly constructed by "
    200                    "LLVMTargetMachine");
    201 }
    202 
    203 MachineModuleInfo::~MachineModuleInfo() {
    204 }
    205 
    206 bool MachineModuleInfo::doInitialization(Module &M) {
    207 
    208   ObjFileMMI = nullptr;
    209   CurCallSite = 0;
    210   CallsEHReturn = false;
    211   CallsUnwindInit = false;
    212   HasEHFunclets = false;
    213   DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
    214   PersonalityTypeCache = EHPersonality::Unknown;
    215   AddrLabelSymbols = nullptr;
    216   TheModule = nullptr;
    217 
    218   return false;
    219 }
    220 
    221 bool MachineModuleInfo::doFinalization(Module &M) {
    222 
    223   Personalities.clear();
    224 
    225   delete AddrLabelSymbols;
    226   AddrLabelSymbols = nullptr;
    227 
    228   Context.reset();
    229 
    230   delete ObjFileMMI;
    231   ObjFileMMI = nullptr;
    232 
    233   return false;
    234 }
    235 
    236 /// EndFunction - Discard function meta information.
    237 ///
    238 void MachineModuleInfo::EndFunction() {
    239   // Clean up frame info.
    240   FrameInstructions.clear();
    241 
    242   // Clean up exception info.
    243   LandingPads.clear();
    244   PersonalityTypeCache = EHPersonality::Unknown;
    245   CallSiteMap.clear();
    246   TypeInfos.clear();
    247   FilterIds.clear();
    248   FilterEnds.clear();
    249   CallsEHReturn = false;
    250   CallsUnwindInit = false;
    251   HasEHFunclets = false;
    252   VariableDbgInfos.clear();
    253 }
    254 
    255 //===- Address of Block Management ----------------------------------------===//
    256 
    257 /// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
    258 /// basic block when its address is taken.  If other blocks were RAUW'd to
    259 /// this one, we may have to emit them as well, return the whole set.
    260 ArrayRef<MCSymbol *>
    261 MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) {
    262   // Lazily create AddrLabelSymbols.
    263   if (!AddrLabelSymbols)
    264     AddrLabelSymbols = new MMIAddrLabelMap(Context);
    265  return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB));
    266 }
    267 
    268 
    269 /// takeDeletedSymbolsForFunction - If the specified function has had any
    270 /// references to address-taken blocks generated, but the block got deleted,
    271 /// return the symbol now so we can emit it.  This prevents emitting a
    272 /// reference to a symbol that has no definition.
    273 void MachineModuleInfo::
    274 takeDeletedSymbolsForFunction(const Function *F,
    275                               std::vector<MCSymbol*> &Result) {
    276   // If no blocks have had their addresses taken, we're done.
    277   if (!AddrLabelSymbols) return;
    278   return AddrLabelSymbols->
    279      takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result);
    280 }
    281 
    282 //===- EH -----------------------------------------------------------------===//
    283 
    284 /// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
    285 /// specified MachineBasicBlock.
    286 LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
    287     (MachineBasicBlock *LandingPad) {
    288   unsigned N = LandingPads.size();
    289   for (unsigned i = 0; i < N; ++i) {
    290     LandingPadInfo &LP = LandingPads[i];
    291     if (LP.LandingPadBlock == LandingPad)
    292       return LP;
    293   }
    294 
    295   LandingPads.push_back(LandingPadInfo(LandingPad));
    296   return LandingPads[N];
    297 }
    298 
    299 /// addInvoke - Provide the begin and end labels of an invoke style call and
    300 /// associate it with a try landing pad block.
    301 void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad,
    302                                   MCSymbol *BeginLabel, MCSymbol *EndLabel) {
    303   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
    304   LP.BeginLabels.push_back(BeginLabel);
    305   LP.EndLabels.push_back(EndLabel);
    306 }
    307 
    308 /// addLandingPad - Provide the label of a try LandingPad block.
    309 ///
    310 MCSymbol *MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
    311   MCSymbol *LandingPadLabel = Context.createTempSymbol();
    312   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
    313   LP.LandingPadLabel = LandingPadLabel;
    314   return LandingPadLabel;
    315 }
    316 
    317 void MachineModuleInfo::addPersonality(const Function *Personality) {
    318   for (unsigned i = 0; i < Personalities.size(); ++i)
    319     if (Personalities[i] == Personality)
    320       return;
    321   Personalities.push_back(Personality);
    322 }
    323 
    324 /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
    325 ///
    326 void MachineModuleInfo::
    327 addCatchTypeInfo(MachineBasicBlock *LandingPad,
    328                  ArrayRef<const GlobalValue *> TyInfo) {
    329   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
    330   for (unsigned N = TyInfo.size(); N; --N)
    331     LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
    332 }
    333 
    334 /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
    335 ///
    336 void MachineModuleInfo::
    337 addFilterTypeInfo(MachineBasicBlock *LandingPad,
    338                   ArrayRef<const GlobalValue *> TyInfo) {
    339   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
    340   std::vector<unsigned> IdsInFilter(TyInfo.size());
    341   for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
    342     IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
    343   LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
    344 }
    345 
    346 /// addCleanup - Add a cleanup action for a landing pad.
    347 ///
    348 void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
    349   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
    350   LP.TypeIds.push_back(0);
    351 }
    352 
    353 void MachineModuleInfo::addSEHCatchHandler(MachineBasicBlock *LandingPad,
    354                                            const Function *Filter,
    355                                            const BlockAddress *RecoverBA) {
    356   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
    357   SEHHandler Handler;
    358   Handler.FilterOrFinally = Filter;
    359   Handler.RecoverBA = RecoverBA;
    360   LP.SEHHandlers.push_back(Handler);
    361 }
    362 
    363 void MachineModuleInfo::addSEHCleanupHandler(MachineBasicBlock *LandingPad,
    364                                              const Function *Cleanup) {
    365   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
    366   SEHHandler Handler;
    367   Handler.FilterOrFinally = Cleanup;
    368   Handler.RecoverBA = nullptr;
    369   LP.SEHHandlers.push_back(Handler);
    370 }
    371 
    372 /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
    373 /// pads.
    374 void MachineModuleInfo::TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap) {
    375   for (unsigned i = 0; i != LandingPads.size(); ) {
    376     LandingPadInfo &LandingPad = LandingPads[i];
    377     if (LandingPad.LandingPadLabel &&
    378         !LandingPad.LandingPadLabel->isDefined() &&
    379         (!LPMap || (*LPMap)[LandingPad.LandingPadLabel] == 0))
    380       LandingPad.LandingPadLabel = nullptr;
    381 
    382     // Special case: we *should* emit LPs with null LP MBB. This indicates
    383     // "nounwind" case.
    384     if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
    385       LandingPads.erase(LandingPads.begin() + i);
    386       continue;
    387     }
    388 
    389     for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) {
    390       MCSymbol *BeginLabel = LandingPad.BeginLabels[j];
    391       MCSymbol *EndLabel = LandingPad.EndLabels[j];
    392       if ((BeginLabel->isDefined() ||
    393            (LPMap && (*LPMap)[BeginLabel] != 0)) &&
    394           (EndLabel->isDefined() ||
    395            (LPMap && (*LPMap)[EndLabel] != 0))) continue;
    396 
    397       LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
    398       LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
    399       --j, --e;
    400     }
    401 
    402     // Remove landing pads with no try-ranges.
    403     if (LandingPads[i].BeginLabels.empty()) {
    404       LandingPads.erase(LandingPads.begin() + i);
    405       continue;
    406     }
    407 
    408     // If there is no landing pad, ensure that the list of typeids is empty.
    409     // If the only typeid is a cleanup, this is the same as having no typeids.
    410     if (!LandingPad.LandingPadBlock ||
    411         (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
    412       LandingPad.TypeIds.clear();
    413     ++i;
    414   }
    415 }
    416 
    417 /// setCallSiteLandingPad - Map the landing pad's EH symbol to the call site
    418 /// indexes.
    419 void MachineModuleInfo::setCallSiteLandingPad(MCSymbol *Sym,
    420                                               ArrayRef<unsigned> Sites) {
    421   LPadToCallSiteMap[Sym].append(Sites.begin(), Sites.end());
    422 }
    423 
    424 /// getTypeIDFor - Return the type id for the specified typeinfo.  This is
    425 /// function wide.
    426 unsigned MachineModuleInfo::getTypeIDFor(const GlobalValue *TI) {
    427   for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
    428     if (TypeInfos[i] == TI) return i + 1;
    429 
    430   TypeInfos.push_back(TI);
    431   return TypeInfos.size();
    432 }
    433 
    434 /// getFilterIDFor - Return the filter id for the specified typeinfos.  This is
    435 /// function wide.
    436 int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
    437   // If the new filter coincides with the tail of an existing filter, then
    438   // re-use the existing filter.  Folding filters more than this requires
    439   // re-ordering filters and/or their elements - probably not worth it.
    440   for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
    441        E = FilterEnds.end(); I != E; ++I) {
    442     unsigned i = *I, j = TyIds.size();
    443 
    444     while (i && j)
    445       if (FilterIds[--i] != TyIds[--j])
    446         goto try_next;
    447 
    448     if (!j)
    449       // The new filter coincides with range [i, end) of the existing filter.
    450       return -(1 + i);
    451 
    452 try_next:;
    453   }
    454 
    455   // Add the new filter.
    456   int FilterID = -(1 + FilterIds.size());
    457   FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
    458   FilterIds.insert(FilterIds.end(), TyIds.begin(), TyIds.end());
    459   FilterEnds.push_back(FilterIds.size());
    460   FilterIds.push_back(0); // terminator
    461   return FilterID;
    462 }
    463