LLVM API Documentation

MachineModuleInfo.cpp
Go to the documentation of this file.
00001 //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "llvm/CodeGen/MachineModuleInfo.h"
00011 #include "llvm/ADT/PointerUnion.h"
00012 #include "llvm/Analysis/ValueTracking.h"
00013 #include "llvm/CodeGen/MachineFunction.h"
00014 #include "llvm/CodeGen/MachineFunctionPass.h"
00015 #include "llvm/CodeGen/Passes.h"
00016 #include "llvm/IR/Constants.h"
00017 #include "llvm/IR/DerivedTypes.h"
00018 #include "llvm/IR/GlobalVariable.h"
00019 #include "llvm/IR/Module.h"
00020 #include "llvm/MC/MCObjectFileInfo.h"
00021 #include "llvm/MC/MCSymbol.h"
00022 #include "llvm/Support/Dwarf.h"
00023 #include "llvm/Support/ErrorHandling.h"
00024 using namespace llvm;
00025 using namespace llvm::dwarf;
00026 
00027 // Handle the Pass registration stuff necessary to use DataLayout's.
00028 INITIALIZE_PASS(MachineModuleInfo, "machinemoduleinfo",
00029                 "Machine Module Information", false, false)
00030 char MachineModuleInfo::ID = 0;
00031 
00032 // Out of line virtual method.
00033 MachineModuleInfoImpl::~MachineModuleInfoImpl() {}
00034 
00035 namespace llvm {
00036 class MMIAddrLabelMapCallbackPtr : CallbackVH {
00037   MMIAddrLabelMap *Map;
00038 public:
00039   MMIAddrLabelMapCallbackPtr() : Map(nullptr) {}
00040   MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V), Map(nullptr) {}
00041 
00042   void setPtr(BasicBlock *BB) {
00043     ValueHandleBase::operator=(BB);
00044   }
00045 
00046   void setMap(MMIAddrLabelMap *map) { Map = map; }
00047 
00048   void deleted() override;
00049   void allUsesReplacedWith(Value *V2) override;
00050 };
00051 
00052 class MMIAddrLabelMap {
00053   MCContext &Context;
00054   struct AddrLabelSymEntry {
00055     /// Symbols - The symbols for the label.  This is a pointer union that is
00056     /// either one symbol (the common case) or a list of symbols.
00057     PointerUnion<MCSymbol *, std::vector<MCSymbol*>*> Symbols;
00058 
00059     Function *Fn;   // The containing function of the BasicBlock.
00060     unsigned Index; // The index in BBCallbacks for the BasicBlock.
00061   };
00062 
00063   DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;
00064 
00065   /// BBCallbacks - Callbacks for the BasicBlock's that we have entries for.  We
00066   /// use this so we get notified if a block is deleted or RAUWd.
00067   std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks;
00068 
00069   /// DeletedAddrLabelsNeedingEmission - This is a per-function list of symbols
00070   /// whose corresponding BasicBlock got deleted.  These symbols need to be
00071   /// emitted at some point in the file, so AsmPrinter emits them after the
00072   /// function body.
00073   DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >
00074     DeletedAddrLabelsNeedingEmission;
00075 public:
00076 
00077   MMIAddrLabelMap(MCContext &context) : Context(context) {}
00078   ~MMIAddrLabelMap() {
00079     assert(DeletedAddrLabelsNeedingEmission.empty() &&
00080            "Some labels for deleted blocks never got emitted");
00081 
00082     // Deallocate any of the 'list of symbols' case.
00083     for (DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry>::iterator
00084          I = AddrLabelSymbols.begin(), E = AddrLabelSymbols.end(); I != E; ++I)
00085       if (I->second.Symbols.is<std::vector<MCSymbol*>*>())
00086         delete I->second.Symbols.get<std::vector<MCSymbol*>*>();
00087   }
00088 
00089   MCSymbol *getAddrLabelSymbol(BasicBlock *BB);
00090   std::vector<MCSymbol*> getAddrLabelSymbolToEmit(BasicBlock *BB);
00091 
00092   void takeDeletedSymbolsForFunction(Function *F,
00093                                      std::vector<MCSymbol*> &Result);
00094 
00095   void UpdateForDeletedBlock(BasicBlock *BB);
00096   void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);
00097 };
00098 }
00099 
00100 MCSymbol *MMIAddrLabelMap::getAddrLabelSymbol(BasicBlock *BB) {
00101   assert(BB->hasAddressTaken() &&
00102          "Shouldn't get label for block without address taken");
00103   AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
00104 
00105   // If we already had an entry for this block, just return it.
00106   if (!Entry.Symbols.isNull()) {
00107     assert(BB->getParent() == Entry.Fn && "Parent changed");
00108     if (Entry.Symbols.is<MCSymbol*>())
00109       return Entry.Symbols.get<MCSymbol*>();
00110     return (*Entry.Symbols.get<std::vector<MCSymbol*>*>())[0];
00111   }
00112 
00113   // Otherwise, this is a new entry, create a new symbol for it and add an
00114   // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
00115   BBCallbacks.push_back(BB);
00116   BBCallbacks.back().setMap(this);
00117   Entry.Index = BBCallbacks.size()-1;
00118   Entry.Fn = BB->getParent();
00119   MCSymbol *Result = Context.CreateTempSymbol();
00120   Entry.Symbols = Result;
00121   return Result;
00122 }
00123 
00124 std::vector<MCSymbol*>
00125 MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
00126   assert(BB->hasAddressTaken() &&
00127          "Shouldn't get label for block without address taken");
00128   AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
00129 
00130   std::vector<MCSymbol*> Result;
00131 
00132   // If we already had an entry for this block, just return it.
00133   if (Entry.Symbols.isNull())
00134     Result.push_back(getAddrLabelSymbol(BB));
00135   else if (MCSymbol *Sym = Entry.Symbols.dyn_cast<MCSymbol*>())
00136     Result.push_back(Sym);
00137   else
00138     Result = *Entry.Symbols.get<std::vector<MCSymbol*>*>();
00139   return Result;
00140 }
00141 
00142 
00143 /// takeDeletedSymbolsForFunction - If we have any deleted symbols for F, return
00144 /// them.
00145 void MMIAddrLabelMap::
00146 takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) {
00147   DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >::iterator I =
00148     DeletedAddrLabelsNeedingEmission.find(F);
00149 
00150   // If there are no entries for the function, just return.
00151   if (I == DeletedAddrLabelsNeedingEmission.end()) return;
00152 
00153   // Otherwise, take the list.
00154   std::swap(Result, I->second);
00155   DeletedAddrLabelsNeedingEmission.erase(I);
00156 }
00157 
00158 
00159 void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
00160   // If the block got deleted, there is no need for the symbol.  If the symbol
00161   // was already emitted, we can just forget about it, otherwise we need to
00162   // queue it up for later emission when the function is output.
00163   AddrLabelSymEntry Entry = AddrLabelSymbols[BB];
00164   AddrLabelSymbols.erase(BB);
00165   assert(!Entry.Symbols.isNull() && "Didn't have a symbol, why a callback?");
00166   BBCallbacks[Entry.Index] = nullptr;  // Clear the callback.
00167 
00168   assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&
00169          "Block/parent mismatch");
00170 
00171   // Handle both the single and the multiple symbols cases.
00172   if (MCSymbol *Sym = Entry.Symbols.dyn_cast<MCSymbol*>()) {
00173     if (Sym->isDefined())
00174       return;
00175 
00176     // If the block is not yet defined, we need to emit it at the end of the
00177     // function.  Add the symbol to the DeletedAddrLabelsNeedingEmission list
00178     // for the containing Function.  Since the block is being deleted, its
00179     // parent may already be removed, we have to get the function from 'Entry'.
00180     DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
00181   } else {
00182     std::vector<MCSymbol*> *Syms = Entry.Symbols.get<std::vector<MCSymbol*>*>();
00183 
00184     for (unsigned i = 0, e = Syms->size(); i != e; ++i) {
00185       MCSymbol *Sym = (*Syms)[i];
00186       if (Sym->isDefined()) continue;  // Ignore already emitted labels.
00187 
00188       // If the block is not yet defined, we need to emit it at the end of the
00189       // function.  Add the symbol to the DeletedAddrLabelsNeedingEmission list
00190       // for the containing Function.  Since the block is being deleted, its
00191       // parent may already be removed, we have to get the function from
00192       // 'Entry'.
00193       DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
00194     }
00195 
00196     // The entry is deleted, free the memory associated with the symbol list.
00197     delete Syms;
00198   }
00199 }
00200 
00201 void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
00202   // Get the entry for the RAUW'd block and remove it from our map.
00203   AddrLabelSymEntry OldEntry = AddrLabelSymbols[Old];
00204   AddrLabelSymbols.erase(Old);
00205   assert(!OldEntry.Symbols.isNull() && "Didn't have a symbol, why a callback?");
00206 
00207   AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
00208 
00209   // If New is not address taken, just move our symbol over to it.
00210   if (NewEntry.Symbols.isNull()) {
00211     BBCallbacks[OldEntry.Index].setPtr(New);    // Update the callback.
00212     NewEntry = OldEntry;     // Set New's entry.
00213     return;
00214   }
00215 
00216   BBCallbacks[OldEntry.Index] = nullptr;    // Update the callback.
00217 
00218   // Otherwise, we need to add the old symbol to the new block's set.  If it is
00219   // just a single entry, upgrade it to a symbol list.
00220   if (MCSymbol *PrevSym = NewEntry.Symbols.dyn_cast<MCSymbol*>()) {
00221     std::vector<MCSymbol*> *SymList = new std::vector<MCSymbol*>();
00222     SymList->push_back(PrevSym);
00223     NewEntry.Symbols = SymList;
00224   }
00225 
00226   std::vector<MCSymbol*> *SymList =
00227     NewEntry.Symbols.get<std::vector<MCSymbol*>*>();
00228 
00229   // If the old entry was a single symbol, add it.
00230   if (MCSymbol *Sym = OldEntry.Symbols.dyn_cast<MCSymbol*>()) {
00231     SymList->push_back(Sym);
00232     return;
00233   }
00234 
00235   // Otherwise, concatenate the list.
00236   std::vector<MCSymbol*> *Syms =OldEntry.Symbols.get<std::vector<MCSymbol*>*>();
00237   SymList->insert(SymList->end(), Syms->begin(), Syms->end());
00238   delete Syms;
00239 }
00240 
00241 
00242 void MMIAddrLabelMapCallbackPtr::deleted() {
00243   Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));
00244 }
00245 
00246 void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {
00247   Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
00248 }
00249 
00250 
00251 //===----------------------------------------------------------------------===//
00252 
00253 MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI,
00254                                      const MCRegisterInfo &MRI,
00255                                      const MCObjectFileInfo *MOFI)
00256   : ImmutablePass(ID), Context(&MAI, &MRI, MOFI, nullptr, false) {
00257   initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry());
00258 }
00259 
00260 MachineModuleInfo::MachineModuleInfo()
00261   : ImmutablePass(ID), Context(nullptr, nullptr, nullptr) {
00262   llvm_unreachable("This MachineModuleInfo constructor should never be called, "
00263                    "MMI should always be explicitly constructed by "
00264                    "LLVMTargetMachine");
00265 }
00266 
00267 MachineModuleInfo::~MachineModuleInfo() {
00268 }
00269 
00270 bool MachineModuleInfo::doInitialization(Module &M) {
00271 
00272   ObjFileMMI = nullptr;
00273   CurCallSite = 0;
00274   CallsEHReturn = 0;
00275   CallsUnwindInit = 0;
00276   DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
00277   // Always emit some info, by default "no personality" info.
00278   Personalities.push_back(nullptr);
00279   PersonalityTypeCache = EHPersonality::None;
00280   AddrLabelSymbols = nullptr;
00281   TheModule = nullptr;
00282 
00283   return false;
00284 }
00285 
00286 bool MachineModuleInfo::doFinalization(Module &M) {
00287 
00288   Personalities.clear();
00289 
00290   delete AddrLabelSymbols;
00291   AddrLabelSymbols = nullptr;
00292 
00293   Context.reset();
00294 
00295   delete ObjFileMMI;
00296   ObjFileMMI = nullptr;
00297 
00298   return false;
00299 }
00300 
00301 /// EndFunction - Discard function meta information.
00302 ///
00303 void MachineModuleInfo::EndFunction() {
00304   // Clean up frame info.
00305   FrameInstructions.clear();
00306 
00307   // Clean up exception info.
00308   LandingPads.clear();
00309   CallSiteMap.clear();
00310   TypeInfos.clear();
00311   FilterIds.clear();
00312   FilterEnds.clear();
00313   CallsEHReturn = 0;
00314   CallsUnwindInit = 0;
00315   VariableDbgInfos.clear();
00316 }
00317 
00318 /// AnalyzeModule - Scan the module for global debug information.
00319 ///
00320 void MachineModuleInfo::AnalyzeModule(const Module &M) {
00321   // Insert functions in the llvm.used array (but not llvm.compiler.used) into
00322   // UsedFunctions.
00323   const GlobalVariable *GV = M.getGlobalVariable("llvm.used");
00324   if (!GV || !GV->hasInitializer()) return;
00325 
00326   // Should be an array of 'i8*'.
00327   const ConstantArray *InitList = cast<ConstantArray>(GV->getInitializer());
00328 
00329   for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
00330     if (const Function *F =
00331           dyn_cast<Function>(InitList->getOperand(i)->stripPointerCasts()))
00332       UsedFunctions.insert(F);
00333 }
00334 
00335 //===- Address of Block Management ----------------------------------------===//
00336 
00337 
00338 /// getAddrLabelSymbol - Return the symbol to be used for the specified basic
00339 /// block when its address is taken.  This cannot be its normal LBB label
00340 /// because the block may be accessed outside its containing function.
00341 MCSymbol *MachineModuleInfo::getAddrLabelSymbol(const BasicBlock *BB) {
00342   // Lazily create AddrLabelSymbols.
00343   if (!AddrLabelSymbols)
00344     AddrLabelSymbols = new MMIAddrLabelMap(Context);
00345   return AddrLabelSymbols->getAddrLabelSymbol(const_cast<BasicBlock*>(BB));
00346 }
00347 
00348 /// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
00349 /// basic block when its address is taken.  If other blocks were RAUW'd to
00350 /// this one, we may have to emit them as well, return the whole set.
00351 std::vector<MCSymbol*> MachineModuleInfo::
00352 getAddrLabelSymbolToEmit(const BasicBlock *BB) {
00353   // Lazily create AddrLabelSymbols.
00354   if (!AddrLabelSymbols)
00355     AddrLabelSymbols = new MMIAddrLabelMap(Context);
00356  return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB));
00357 }
00358 
00359 
00360 /// takeDeletedSymbolsForFunction - If the specified function has had any
00361 /// references to address-taken blocks generated, but the block got deleted,
00362 /// return the symbol now so we can emit it.  This prevents emitting a
00363 /// reference to a symbol that has no definition.
00364 void MachineModuleInfo::
00365 takeDeletedSymbolsForFunction(const Function *F,
00366                               std::vector<MCSymbol*> &Result) {
00367   // If no blocks have had their addresses taken, we're done.
00368   if (!AddrLabelSymbols) return;
00369   return AddrLabelSymbols->
00370      takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result);
00371 }
00372 
00373 //===- EH -----------------------------------------------------------------===//
00374 
00375 /// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
00376 /// specified MachineBasicBlock.
00377 LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
00378     (MachineBasicBlock *LandingPad) {
00379   unsigned N = LandingPads.size();
00380   for (unsigned i = 0; i < N; ++i) {
00381     LandingPadInfo &LP = LandingPads[i];
00382     if (LP.LandingPadBlock == LandingPad)
00383       return LP;
00384   }
00385 
00386   LandingPads.push_back(LandingPadInfo(LandingPad));
00387   return LandingPads[N];
00388 }
00389 
00390 /// addInvoke - Provide the begin and end labels of an invoke style call and
00391 /// associate it with a try landing pad block.
00392 void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad,
00393                                   MCSymbol *BeginLabel, MCSymbol *EndLabel) {
00394   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00395   LP.BeginLabels.push_back(BeginLabel);
00396   LP.EndLabels.push_back(EndLabel);
00397 }
00398 
00399 /// addLandingPad - Provide the label of a try LandingPad block.
00400 ///
00401 MCSymbol *MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
00402   MCSymbol *LandingPadLabel = Context.CreateTempSymbol();
00403   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00404   LP.LandingPadLabel = LandingPadLabel;
00405   return LandingPadLabel;
00406 }
00407 
00408 /// addPersonality - Provide the personality function for the exception
00409 /// information.
00410 void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
00411                                        const Function *Personality) {
00412   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00413   LP.Personality = Personality;
00414 
00415   for (unsigned i = 0; i < Personalities.size(); ++i)
00416     if (Personalities[i] == Personality)
00417       return;
00418 
00419   // If this is the first personality we're adding go
00420   // ahead and add it at the beginning.
00421   if (!Personalities[0])
00422     Personalities[0] = Personality;
00423   else
00424     Personalities.push_back(Personality);
00425 }
00426 
00427 /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
00428 ///
00429 void MachineModuleInfo::
00430 addCatchTypeInfo(MachineBasicBlock *LandingPad,
00431                  ArrayRef<const GlobalValue *> TyInfo) {
00432   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00433   for (unsigned N = TyInfo.size(); N; --N)
00434     LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
00435 }
00436 
00437 /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
00438 ///
00439 void MachineModuleInfo::
00440 addFilterTypeInfo(MachineBasicBlock *LandingPad,
00441                   ArrayRef<const GlobalValue *> TyInfo) {
00442   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00443   std::vector<unsigned> IdsInFilter(TyInfo.size());
00444   for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
00445     IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
00446   LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
00447 }
00448 
00449 /// addCleanup - Add a cleanup action for a landing pad.
00450 ///
00451 void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
00452   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00453   LP.TypeIds.push_back(0);
00454 }
00455 
00456 MCSymbol *
00457 MachineModuleInfo::addClauseForLandingPad(MachineBasicBlock *LandingPad) {
00458   MCSymbol *ClauseLabel = Context.CreateTempSymbol();
00459   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00460   LP.ClauseLabels.push_back(ClauseLabel);
00461   return ClauseLabel;
00462 }
00463 
00464 /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
00465 /// pads.
00466 void MachineModuleInfo::TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap) {
00467   for (unsigned i = 0; i != LandingPads.size(); ) {
00468     LandingPadInfo &LandingPad = LandingPads[i];
00469     if (LandingPad.LandingPadLabel &&
00470         !LandingPad.LandingPadLabel->isDefined() &&
00471         (!LPMap || (*LPMap)[LandingPad.LandingPadLabel] == 0))
00472       LandingPad.LandingPadLabel = nullptr;
00473 
00474     // Special case: we *should* emit LPs with null LP MBB. This indicates
00475     // "nounwind" case.
00476     if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
00477       LandingPads.erase(LandingPads.begin() + i);
00478       continue;
00479     }
00480 
00481     for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) {
00482       MCSymbol *BeginLabel = LandingPad.BeginLabels[j];
00483       MCSymbol *EndLabel = LandingPad.EndLabels[j];
00484       if ((BeginLabel->isDefined() ||
00485            (LPMap && (*LPMap)[BeginLabel] != 0)) &&
00486           (EndLabel->isDefined() ||
00487            (LPMap && (*LPMap)[EndLabel] != 0))) continue;
00488 
00489       LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
00490       LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
00491       --j, --e;
00492     }
00493 
00494     // Remove landing pads with no try-ranges.
00495     if (LandingPads[i].BeginLabels.empty()) {
00496       LandingPads.erase(LandingPads.begin() + i);
00497       continue;
00498     }
00499 
00500     // If there is no landing pad, ensure that the list of typeids is empty.
00501     // If the only typeid is a cleanup, this is the same as having no typeids.
00502     if (!LandingPad.LandingPadBlock ||
00503         (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
00504       LandingPad.TypeIds.clear();
00505     ++i;
00506   }
00507 }
00508 
00509 /// setCallSiteLandingPad - Map the landing pad's EH symbol to the call site
00510 /// indexes.
00511 void MachineModuleInfo::setCallSiteLandingPad(MCSymbol *Sym,
00512                                               ArrayRef<unsigned> Sites) {
00513   LPadToCallSiteMap[Sym].append(Sites.begin(), Sites.end());
00514 }
00515 
00516 /// getTypeIDFor - Return the type id for the specified typeinfo.  This is
00517 /// function wide.
00518 unsigned MachineModuleInfo::getTypeIDFor(const GlobalValue *TI) {
00519   for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
00520     if (TypeInfos[i] == TI) return i + 1;
00521 
00522   TypeInfos.push_back(TI);
00523   return TypeInfos.size();
00524 }
00525 
00526 /// getFilterIDFor - Return the filter id for the specified typeinfos.  This is
00527 /// function wide.
00528 int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
00529   // If the new filter coincides with the tail of an existing filter, then
00530   // re-use the existing filter.  Folding filters more than this requires
00531   // re-ordering filters and/or their elements - probably not worth it.
00532   for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
00533        E = FilterEnds.end(); I != E; ++I) {
00534     unsigned i = *I, j = TyIds.size();
00535 
00536     while (i && j)
00537       if (FilterIds[--i] != TyIds[--j])
00538         goto try_next;
00539 
00540     if (!j)
00541       // The new filter coincides with range [i, end) of the existing filter.
00542       return -(1 + i);
00543 
00544 try_next:;
00545   }
00546 
00547   // Add the new filter.
00548   int FilterID = -(1 + FilterIds.size());
00549   FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
00550   FilterIds.insert(FilterIds.end(), TyIds.begin(), TyIds.end());
00551   FilterEnds.push_back(FilterIds.size());
00552   FilterIds.push_back(0); // terminator
00553   return FilterID;
00554 }
00555 
00556 /// getPersonality - Return the personality function for the current function.
00557 const Function *MachineModuleInfo::getPersonality() const {
00558   for (const LandingPadInfo &LPI : LandingPads)
00559     if (LPI.Personality)
00560       return LPI.Personality;
00561   return nullptr;
00562 }
00563 
00564 EHPersonality MachineModuleInfo::getPersonalityTypeSlow() {
00565   const Function *Per = getPersonality();
00566   if (!Per)
00567     PersonalityTypeCache = EHPersonality::None;
00568   else if (Per->getName() == "__C_specific_handler")
00569     PersonalityTypeCache = EHPersonality::Win64SEH;
00570   else // Assume everything else is Itanium.
00571     PersonalityTypeCache = EHPersonality::Itanium;
00572   return PersonalityTypeCache;
00573 }
00574 
00575 /// getPersonalityIndex - Return unique index for current personality
00576 /// function. NULL/first personality function should always get zero index.
00577 unsigned MachineModuleInfo::getPersonalityIndex() const {
00578   const Function* Personality = nullptr;
00579 
00580   // Scan landing pads. If there is at least one non-NULL personality - use it.
00581   for (unsigned i = 0, e = LandingPads.size(); i != e; ++i)
00582     if (LandingPads[i].Personality) {
00583       Personality = LandingPads[i].Personality;
00584       break;
00585     }
00586 
00587   for (unsigned i = 0, e = Personalities.size(); i < e; ++i) {
00588     if (Personalities[i] == Personality)
00589       return i;
00590   }
00591 
00592   // This will happen if the current personality function is
00593   // in the zero index.
00594   return 0;
00595 }