Home | History | Annotate | Download | only in IR
      1 //===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//
      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/IR/DebugLoc.h"
     11 #include "LLVMContextImpl.h"
     12 #include "llvm/ADT/DenseMapInfo.h"
     13 #include "llvm/IR/DebugInfo.h"
     14 using namespace llvm;
     15 
     16 //===----------------------------------------------------------------------===//
     17 // DebugLoc Implementation
     18 //===----------------------------------------------------------------------===//
     19 
     20 MDNode *DebugLoc::getScope(const LLVMContext &Ctx) const {
     21   if (ScopeIdx == 0) return nullptr;
     22 
     23   if (ScopeIdx > 0) {
     24     // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
     25     // position specified.
     26     assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() &&
     27            "Invalid ScopeIdx!");
     28     return Ctx.pImpl->ScopeRecords[ScopeIdx-1].get();
     29   }
     30 
     31   // Otherwise, the index is in the ScopeInlinedAtRecords array.
     32   assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
     33          "Invalid ScopeIdx");
     34   return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get();
     35 }
     36 
     37 MDNode *DebugLoc::getInlinedAt(const LLVMContext &Ctx) const {
     38   // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
     39   // position specified.  Zero is invalid.
     40   if (ScopeIdx >= 0) return nullptr;
     41 
     42   // Otherwise, the index is in the ScopeInlinedAtRecords array.
     43   assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
     44          "Invalid ScopeIdx");
     45   return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get();
     46 }
     47 
     48 /// Return both the Scope and the InlinedAt values.
     49 void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
     50                                     const LLVMContext &Ctx) const {
     51   if (ScopeIdx == 0) {
     52     Scope = IA = nullptr;
     53     return;
     54   }
     55 
     56   if (ScopeIdx > 0) {
     57     // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
     58     // position specified.
     59     assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() &&
     60            "Invalid ScopeIdx!");
     61     Scope = Ctx.pImpl->ScopeRecords[ScopeIdx-1].get();
     62     IA = nullptr;
     63     return;
     64   }
     65 
     66   // Otherwise, the index is in the ScopeInlinedAtRecords array.
     67   assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
     68          "Invalid ScopeIdx");
     69   Scope = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get();
     70   IA    = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get();
     71 }
     72 
     73 MDNode *DebugLoc::getScopeNode(const LLVMContext &Ctx) const {
     74   if (MDNode *InlinedAt = getInlinedAt(Ctx))
     75     return DebugLoc::getFromDILocation(InlinedAt).getScopeNode(Ctx);
     76   return getScope(Ctx);
     77 }
     78 
     79 DebugLoc DebugLoc::getFnDebugLoc(const LLVMContext &Ctx) const {
     80   const MDNode *Scope = getScopeNode(Ctx);
     81   DISubprogram SP = getDISubprogram(Scope);
     82   if (SP.isSubprogram()) {
     83     // Check for number of operands since the compatibility is
     84     // cheap here.  FIXME: Name the magic constant.
     85     if (SP->getNumOperands() > 19)
     86       return DebugLoc::get(SP.getScopeLineNumber(), 0, SP);
     87     else
     88       return DebugLoc::get(SP.getLineNumber(), 0, SP);
     89   }
     90 
     91   return DebugLoc();
     92 }
     93 
     94 DebugLoc DebugLoc::get(unsigned Line, unsigned Col,
     95                        MDNode *Scope, MDNode *InlinedAt) {
     96   DebugLoc Result;
     97 
     98   // If no scope is available, this is an unknown location.
     99   if (!Scope) return Result;
    100 
    101   // Saturate line and col to "unknown".
    102   if (Col > 255) Col = 0;
    103   if (Line >= (1 << 24)) Line = 0;
    104   Result.LineCol = Line | (Col << 24);
    105 
    106   LLVMContext &Ctx = Scope->getContext();
    107 
    108   // If there is no inlined-at location, use the ScopeRecords array.
    109   if (!InlinedAt)
    110     Result.ScopeIdx = Ctx.pImpl->getOrAddScopeRecordIdxEntry(Scope, 0);
    111   else
    112     Result.ScopeIdx = Ctx.pImpl->getOrAddScopeInlinedAtIdxEntry(Scope,
    113                                                                 InlinedAt, 0);
    114 
    115   return Result;
    116 }
    117 
    118 /// getAsMDNode - This method converts the compressed DebugLoc node into a
    119 /// DILocation-compatible MDNode.
    120 MDNode *DebugLoc::getAsMDNode(const LLVMContext &Ctx) const {
    121   if (isUnknown()) return nullptr;
    122 
    123   MDNode *Scope, *IA;
    124   getScopeAndInlinedAt(Scope, IA, Ctx);
    125   assert(Scope && "If scope is null, this should be isUnknown()");
    126 
    127   LLVMContext &Ctx2 = Scope->getContext();
    128   Type *Int32 = Type::getInt32Ty(Ctx2);
    129   Value *Elts[] = {
    130     ConstantInt::get(Int32, getLine()), ConstantInt::get(Int32, getCol()),
    131     Scope, IA
    132   };
    133   return MDNode::get(Ctx2, Elts);
    134 }
    135 
    136 /// getFromDILocation - Translate the DILocation quad into a DebugLoc.
    137 DebugLoc DebugLoc::getFromDILocation(MDNode *N) {
    138   DILocation Loc(N);
    139   MDNode *Scope = Loc.getScope();
    140   if (!Scope) return DebugLoc();
    141   return get(Loc.getLineNumber(), Loc.getColumnNumber(), Scope,
    142              Loc.getOrigLocation());
    143 }
    144 
    145 /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
    146 DebugLoc DebugLoc::getFromDILexicalBlock(MDNode *N) {
    147   DILexicalBlock LexBlock(N);
    148   MDNode *Scope = LexBlock.getContext();
    149   if (!Scope) return DebugLoc();
    150   return get(LexBlock.getLineNumber(), LexBlock.getColumnNumber(), Scope,
    151              nullptr);
    152 }
    153 
    154 void DebugLoc::dump(const LLVMContext &Ctx) const {
    155 #ifndef NDEBUG
    156   if (!isUnknown()) {
    157     dbgs() << getLine();
    158     if (getCol() != 0)
    159       dbgs() << ',' << getCol();
    160     DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx));
    161     if (!InlinedAtDL.isUnknown()) {
    162       dbgs() << " @ ";
    163       InlinedAtDL.dump(Ctx);
    164     } else
    165       dbgs() << "\n";
    166   }
    167 #endif
    168 }
    169 
    170 void DebugLoc::print(const LLVMContext &Ctx, raw_ostream &OS) const {
    171   if (!isUnknown()) {
    172     // Print source line info.
    173     DIScope Scope(getScope(Ctx));
    174     assert((!Scope || Scope.isScope()) &&
    175            "Scope of a DebugLoc should be null or a DIScope.");
    176     if (Scope)
    177       OS << Scope.getFilename();
    178     else
    179       OS << "<unknown>";
    180     OS << ':' << getLine();
    181     if (getCol() != 0)
    182       OS << ':' << getCol();
    183     DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx));
    184     if (!InlinedAtDL.isUnknown()) {
    185       OS << " @[ ";
    186       InlinedAtDL.print(Ctx, OS);
    187       OS << " ]";
    188     }
    189   }
    190 }
    191 
    192 //===----------------------------------------------------------------------===//
    193 // DenseMap specialization
    194 //===----------------------------------------------------------------------===//
    195 
    196 unsigned DenseMapInfo<DebugLoc>::getHashValue(const DebugLoc &Key) {
    197   return static_cast<unsigned>(hash_combine(Key.LineCol, Key.ScopeIdx));
    198 }
    199 
    200 //===----------------------------------------------------------------------===//
    201 // LLVMContextImpl Implementation
    202 //===----------------------------------------------------------------------===//
    203 
    204 int LLVMContextImpl::getOrAddScopeRecordIdxEntry(MDNode *Scope,
    205                                                  int ExistingIdx) {
    206   // If we already have an entry for this scope, return it.
    207   int &Idx = ScopeRecordIdx[Scope];
    208   if (Idx) return Idx;
    209 
    210   // If we don't have an entry, but ExistingIdx is specified, use it.
    211   if (ExistingIdx)
    212     return Idx = ExistingIdx;
    213 
    214   // Otherwise add a new entry.
    215 
    216   // Start out ScopeRecords with a minimal reasonable size to avoid
    217   // excessive reallocation starting out.
    218   if (ScopeRecords.empty())
    219     ScopeRecords.reserve(128);
    220 
    221   // Index is biased by 1 for index.
    222   Idx = ScopeRecords.size()+1;
    223   ScopeRecords.push_back(DebugRecVH(Scope, this, Idx));
    224   return Idx;
    225 }
    226 
    227 int LLVMContextImpl::getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,
    228                                                     int ExistingIdx) {
    229   // If we already have an entry, return it.
    230   int &Idx = ScopeInlinedAtIdx[std::make_pair(Scope, IA)];
    231   if (Idx) return Idx;
    232 
    233   // If we don't have an entry, but ExistingIdx is specified, use it.
    234   if (ExistingIdx)
    235     return Idx = ExistingIdx;
    236 
    237   // Start out ScopeInlinedAtRecords with a minimal reasonable size to avoid
    238   // excessive reallocation starting out.
    239   if (ScopeInlinedAtRecords.empty())
    240     ScopeInlinedAtRecords.reserve(128);
    241 
    242   // Index is biased by 1 and negated.
    243   Idx = -ScopeInlinedAtRecords.size()-1;
    244   ScopeInlinedAtRecords.push_back(std::make_pair(DebugRecVH(Scope, this, Idx),
    245                                                  DebugRecVH(IA, this, Idx)));
    246   return Idx;
    247 }
    248 
    249 
    250 //===----------------------------------------------------------------------===//
    251 // DebugRecVH Implementation
    252 //===----------------------------------------------------------------------===//
    253 
    254 /// deleted - The MDNode this is pointing to got deleted, so this pointer needs
    255 /// to drop to null and we need remove our entry from the DenseMap.
    256 void DebugRecVH::deleted() {
    257   // If this is a non-canonical reference, just drop the value to null, we know
    258   // it doesn't have a map entry.
    259   if (Idx == 0) {
    260     setValPtr(nullptr);
    261     return;
    262   }
    263 
    264   MDNode *Cur = get();
    265 
    266   // If the index is positive, it is an entry in ScopeRecords.
    267   if (Idx > 0) {
    268     assert(Ctx->ScopeRecordIdx[Cur] == Idx && "Mapping out of date!");
    269     Ctx->ScopeRecordIdx.erase(Cur);
    270     // Reset this VH to null and we're done.
    271     setValPtr(nullptr);
    272     Idx = 0;
    273     return;
    274   }
    275 
    276   // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it
    277   // is the scope or the inlined-at record entry.
    278   assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size());
    279   std::pair<DebugRecVH, DebugRecVH> &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1];
    280   assert((this == &Entry.first || this == &Entry.second) &&
    281          "Mapping out of date!");
    282 
    283   MDNode *OldScope = Entry.first.get();
    284   MDNode *OldInlinedAt = Entry.second.get();
    285   assert(OldScope && OldInlinedAt &&
    286          "Entry should be non-canonical if either val dropped to null");
    287 
    288   // Otherwise, we do have an entry in it, nuke it and we're done.
    289   assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&&
    290          "Mapping out of date");
    291   Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt));
    292 
    293   // Reset this VH to null.  Drop both 'Idx' values to null to indicate that
    294   // we're in non-canonical form now.
    295   setValPtr(nullptr);
    296   Entry.first.Idx = Entry.second.Idx = 0;
    297 }
    298 
    299 void DebugRecVH::allUsesReplacedWith(Value *NewVa) {
    300   // If being replaced with a non-mdnode value (e.g. undef) handle this as if
    301   // the mdnode got deleted.
    302   MDNode *NewVal = dyn_cast<MDNode>(NewVa);
    303   if (!NewVal) return deleted();
    304 
    305   // If this is a non-canonical reference, just change it, we know it already
    306   // doesn't have a map entry.
    307   if (Idx == 0) {
    308     setValPtr(NewVa);
    309     return;
    310   }
    311 
    312   MDNode *OldVal = get();
    313   assert(OldVal != NewVa && "Node replaced with self?");
    314 
    315   // If the index is positive, it is an entry in ScopeRecords.
    316   if (Idx > 0) {
    317     assert(Ctx->ScopeRecordIdx[OldVal] == Idx && "Mapping out of date!");
    318     Ctx->ScopeRecordIdx.erase(OldVal);
    319     setValPtr(NewVal);
    320 
    321     int NewEntry = Ctx->getOrAddScopeRecordIdxEntry(NewVal, Idx);
    322 
    323     // If NewVal already has an entry, this becomes a non-canonical reference,
    324     // just drop Idx to 0 to signify this.
    325     if (NewEntry != Idx)
    326       Idx = 0;
    327     return;
    328   }
    329 
    330   // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it
    331   // is the scope or the inlined-at record entry.
    332   assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size());
    333   std::pair<DebugRecVH, DebugRecVH> &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1];
    334   assert((this == &Entry.first || this == &Entry.second) &&
    335          "Mapping out of date!");
    336 
    337   MDNode *OldScope = Entry.first.get();
    338   MDNode *OldInlinedAt = Entry.second.get();
    339   assert(OldScope && OldInlinedAt &&
    340          "Entry should be non-canonical if either val dropped to null");
    341 
    342   // Otherwise, we do have an entry in it, nuke it and we're done.
    343   assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&&
    344          "Mapping out of date");
    345   Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt));
    346 
    347   // Reset this VH to the new value.
    348   setValPtr(NewVal);
    349 
    350   int NewIdx = Ctx->getOrAddScopeInlinedAtIdxEntry(Entry.first.get(),
    351                                                    Entry.second.get(), Idx);
    352   // If NewVal already has an entry, this becomes a non-canonical reference,
    353   // just drop Idx to 0 to signify this.
    354   if (NewIdx != Idx) {
    355     std::pair<DebugRecVH, DebugRecVH> &Entry=Ctx->ScopeInlinedAtRecords[-Idx-1];
    356     Entry.first.Idx = Entry.second.Idx = 0;
    357   }
    358 }
    359