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