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 = false; 
00277   // Always emit some info, by default "no personality" info.
00278   Personalities.push_back(nullptr);
00279   AddrLabelSymbols = nullptr;
00280   TheModule = nullptr;
00281 
00282   return false;
00283 }
00284 
00285 bool MachineModuleInfo::doFinalization(Module &M) {
00286 
00287   Personalities.clear();
00288 
00289   delete AddrLabelSymbols;
00290   AddrLabelSymbols = nullptr;
00291 
00292   Context.reset();
00293 
00294   delete ObjFileMMI;
00295   ObjFileMMI = nullptr;
00296 
00297   return false;
00298 }
00299 
00300 /// EndFunction - Discard function meta information.
00301 ///
00302 void MachineModuleInfo::EndFunction() {
00303   // Clean up frame info.
00304   FrameInstructions.clear();
00305 
00306   // Clean up exception info.
00307   LandingPads.clear();
00308   CallSiteMap.clear();
00309   TypeInfos.clear();
00310   FilterIds.clear();
00311   FilterEnds.clear();
00312   CallsEHReturn = 0;
00313   CallsUnwindInit = 0;
00314   VariableDbgInfos.clear();
00315 }
00316 
00317 /// AnalyzeModule - Scan the module for global debug information.
00318 ///
00319 void MachineModuleInfo::AnalyzeModule(const Module &M) {
00320   // Insert functions in the llvm.used array (but not llvm.compiler.used) into
00321   // UsedFunctions.
00322   const GlobalVariable *GV = M.getGlobalVariable("llvm.used");
00323   if (!GV || !GV->hasInitializer()) return;
00324 
00325   // Should be an array of 'i8*'.
00326   const ConstantArray *InitList = cast<ConstantArray>(GV->getInitializer());
00327 
00328   for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
00329     if (const Function *F =
00330           dyn_cast<Function>(InitList->getOperand(i)->stripPointerCasts()))
00331       UsedFunctions.insert(F);
00332 }
00333 
00334 //===- Address of Block Management ----------------------------------------===//
00335 
00336 
00337 /// getAddrLabelSymbol - Return the symbol to be used for the specified basic
00338 /// block when its address is taken.  This cannot be its normal LBB label
00339 /// because the block may be accessed outside its containing function.
00340 MCSymbol *MachineModuleInfo::getAddrLabelSymbol(const BasicBlock *BB) {
00341   // Lazily create AddrLabelSymbols.
00342   if (!AddrLabelSymbols)
00343     AddrLabelSymbols = new MMIAddrLabelMap(Context);
00344   return AddrLabelSymbols->getAddrLabelSymbol(const_cast<BasicBlock*>(BB));
00345 }
00346 
00347 /// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
00348 /// basic block when its address is taken.  If other blocks were RAUW'd to
00349 /// this one, we may have to emit them as well, return the whole set.
00350 std::vector<MCSymbol*> MachineModuleInfo::
00351 getAddrLabelSymbolToEmit(const BasicBlock *BB) {
00352   // Lazily create AddrLabelSymbols.
00353   if (!AddrLabelSymbols)
00354     AddrLabelSymbols = new MMIAddrLabelMap(Context);
00355  return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB));
00356 }
00357 
00358 
00359 /// takeDeletedSymbolsForFunction - If the specified function has had any
00360 /// references to address-taken blocks generated, but the block got deleted,
00361 /// return the symbol now so we can emit it.  This prevents emitting a
00362 /// reference to a symbol that has no definition.
00363 void MachineModuleInfo::
00364 takeDeletedSymbolsForFunction(const Function *F,
00365                               std::vector<MCSymbol*> &Result) {
00366   // If no blocks have had their addresses taken, we're done.
00367   if (!AddrLabelSymbols) return;
00368   return AddrLabelSymbols->
00369      takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result);
00370 }
00371 
00372 //===- EH -----------------------------------------------------------------===//
00373 
00374 /// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
00375 /// specified MachineBasicBlock.
00376 LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
00377     (MachineBasicBlock *LandingPad) {
00378   unsigned N = LandingPads.size();
00379   for (unsigned i = 0; i < N; ++i) {
00380     LandingPadInfo &LP = LandingPads[i];
00381     if (LP.LandingPadBlock == LandingPad)
00382       return LP;
00383   }
00384 
00385   LandingPads.push_back(LandingPadInfo(LandingPad));
00386   return LandingPads[N];
00387 }
00388 
00389 /// addInvoke - Provide the begin and end labels of an invoke style call and
00390 /// associate it with a try landing pad block.
00391 void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad,
00392                                   MCSymbol *BeginLabel, MCSymbol *EndLabel) {
00393   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00394   LP.BeginLabels.push_back(BeginLabel);
00395   LP.EndLabels.push_back(EndLabel);
00396 }
00397 
00398 /// addLandingPad - Provide the label of a try LandingPad block.
00399 ///
00400 MCSymbol *MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
00401   MCSymbol *LandingPadLabel = Context.CreateTempSymbol();
00402   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00403   LP.LandingPadLabel = LandingPadLabel;
00404   return LandingPadLabel;
00405 }
00406 
00407 /// addPersonality - Provide the personality function for the exception
00408 /// information.
00409 void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
00410                                        const Function *Personality) {
00411   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00412   LP.Personality = Personality;
00413 
00414   for (unsigned i = 0; i < Personalities.size(); ++i)
00415     if (Personalities[i] == Personality)
00416       return;
00417 
00418   // If this is the first personality we're adding go
00419   // ahead and add it at the beginning.
00420   if (!Personalities[0])
00421     Personalities[0] = Personality;
00422   else
00423     Personalities.push_back(Personality);
00424 }
00425 
00426 /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
00427 ///
00428 void MachineModuleInfo::
00429 addCatchTypeInfo(MachineBasicBlock *LandingPad,
00430                  ArrayRef<const GlobalVariable *> TyInfo) {
00431   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00432   for (unsigned N = TyInfo.size(); N; --N)
00433     LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
00434 }
00435 
00436 /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
00437 ///
00438 void MachineModuleInfo::
00439 addFilterTypeInfo(MachineBasicBlock *LandingPad,
00440                   ArrayRef<const GlobalVariable *> TyInfo) {
00441   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00442   std::vector<unsigned> IdsInFilter(TyInfo.size());
00443   for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
00444     IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
00445   LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
00446 }
00447 
00448 /// addCleanup - Add a cleanup action for a landing pad.
00449 ///
00450 void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
00451   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
00452   LP.TypeIds.push_back(0);
00453 }
00454 
00455 /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
00456 /// pads.
00457 void MachineModuleInfo::TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap) {
00458   for (unsigned i = 0; i != LandingPads.size(); ) {
00459     LandingPadInfo &LandingPad = LandingPads[i];
00460     if (LandingPad.LandingPadLabel &&
00461         !LandingPad.LandingPadLabel->isDefined() &&
00462         (!LPMap || (*LPMap)[LandingPad.LandingPadLabel] == 0))
00463       LandingPad.LandingPadLabel = nullptr;
00464 
00465     // Special case: we *should* emit LPs with null LP MBB. This indicates
00466     // "nounwind" case.
00467     if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
00468       LandingPads.erase(LandingPads.begin() + i);
00469       continue;
00470     }
00471 
00472     for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) {
00473       MCSymbol *BeginLabel = LandingPad.BeginLabels[j];
00474       MCSymbol *EndLabel = LandingPad.EndLabels[j];
00475       if ((BeginLabel->isDefined() ||
00476            (LPMap && (*LPMap)[BeginLabel] != 0)) &&
00477           (EndLabel->isDefined() ||
00478            (LPMap && (*LPMap)[EndLabel] != 0))) continue;
00479 
00480       LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
00481       LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
00482       --j, --e;
00483     }
00484 
00485     // Remove landing pads with no try-ranges.
00486     if (LandingPads[i].BeginLabels.empty()) {
00487       LandingPads.erase(LandingPads.begin() + i);
00488       continue;
00489     }
00490 
00491     // If there is no landing pad, ensure that the list of typeids is empty.
00492     // If the only typeid is a cleanup, this is the same as having no typeids.
00493     if (!LandingPad.LandingPadBlock ||
00494         (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
00495       LandingPad.TypeIds.clear();
00496     ++i;
00497   }
00498 }
00499 
00500 /// setCallSiteLandingPad - Map the landing pad's EH symbol to the call site
00501 /// indexes.
00502 void MachineModuleInfo::setCallSiteLandingPad(MCSymbol *Sym,
00503                                               ArrayRef<unsigned> Sites) {
00504   LPadToCallSiteMap[Sym].append(Sites.begin(), Sites.end());
00505 }
00506 
00507 /// getTypeIDFor - Return the type id for the specified typeinfo.  This is
00508 /// function wide.
00509 unsigned MachineModuleInfo::getTypeIDFor(const GlobalVariable *TI) {
00510   for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
00511     if (TypeInfos[i] == TI) return i + 1;
00512 
00513   TypeInfos.push_back(TI);
00514   return TypeInfos.size();
00515 }
00516 
00517 /// getFilterIDFor - Return the filter id for the specified typeinfos.  This is
00518 /// function wide.
00519 int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
00520   // If the new filter coincides with the tail of an existing filter, then
00521   // re-use the existing filter.  Folding filters more than this requires
00522   // re-ordering filters and/or their elements - probably not worth it.
00523   for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
00524        E = FilterEnds.end(); I != E; ++I) {
00525     unsigned i = *I, j = TyIds.size();
00526 
00527     while (i && j)
00528       if (FilterIds[--i] != TyIds[--j])
00529         goto try_next;
00530 
00531     if (!j)
00532       // The new filter coincides with range [i, end) of the existing filter.
00533       return -(1 + i);
00534 
00535 try_next:;
00536   }
00537 
00538   // Add the new filter.
00539   int FilterID = -(1 + FilterIds.size());
00540   FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
00541   FilterIds.insert(FilterIds.end(), TyIds.begin(), TyIds.end());
00542   FilterEnds.push_back(FilterIds.size());
00543   FilterIds.push_back(0); // terminator
00544   return FilterID;
00545 }
00546 
00547 /// getPersonality - Return the personality function for the current function.
00548 const Function *MachineModuleInfo::getPersonality() const {
00549   // FIXME: Until PR1414 will be fixed, we're using 1 personality function per
00550   // function
00551   return !LandingPads.empty() ? LandingPads[0].Personality : nullptr;
00552 }
00553 
00554 /// getPersonalityIndex - Return unique index for current personality
00555 /// function. NULL/first personality function should always get zero index.
00556 unsigned MachineModuleInfo::getPersonalityIndex() const {
00557   const Function* Personality = nullptr;
00558 
00559   // Scan landing pads. If there is at least one non-NULL personality - use it.
00560   for (unsigned i = 0, e = LandingPads.size(); i != e; ++i)
00561     if (LandingPads[i].Personality) {
00562       Personality = LandingPads[i].Personality;
00563       break;
00564     }
00565 
00566   for (unsigned i = 0, e = Personalities.size(); i < e; ++i) {
00567     if (Personalities[i] == Personality)
00568       return i;
00569   }
00570 
00571   // This will happen if the current personality function is
00572   // in the zero index.
00573   return 0;
00574 }