1219820Sjeff//===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//
2219820Sjeff//
3219820Sjeff//                     The LLVM Compiler Infrastructure
4219820Sjeff//
5219820Sjeff// This file is distributed under the University of Illinois Open Source
6219820Sjeff// License. See LICENSE.TXT for details.
7219820Sjeff//
8219820Sjeff//===----------------------------------------------------------------------===//
9219820Sjeff
10219820Sjeff#include "llvm/Support/DebugLoc.h"
11219820Sjeff#include "LLVMContextImpl.h"
12219820Sjeff#include "llvm/ADT/DenseMapInfo.h"
13219820Sjeff#include "llvm/DebugInfo.h"
14219820Sjeffusing namespace llvm;
15219820Sjeff
16219820Sjeff//===----------------------------------------------------------------------===//
17219820Sjeff// DebugLoc Implementation
18219820Sjeff//===----------------------------------------------------------------------===//
19219820Sjeff
20219820SjeffMDNode *DebugLoc::getScope(const LLVMContext &Ctx) const {
21219820Sjeff  if (ScopeIdx == 0) return 0;
22219820Sjeff
23219820Sjeff  if (ScopeIdx > 0) {
24219820Sjeff    // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
25219820Sjeff    // position specified.
26219820Sjeff    assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() &&
27219820Sjeff           "Invalid ScopeIdx!");
28219820Sjeff    return Ctx.pImpl->ScopeRecords[ScopeIdx-1].get();
29219820Sjeff  }
30219820Sjeff
31219820Sjeff  // Otherwise, the index is in the ScopeInlinedAtRecords array.
32219820Sjeff  assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
33219820Sjeff         "Invalid ScopeIdx");
34219820Sjeff  return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get();
35219820Sjeff}
36219820Sjeff
37219820SjeffMDNode *DebugLoc::getInlinedAt(const LLVMContext &Ctx) const {
38219820Sjeff  // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
39219820Sjeff  // position specified.  Zero is invalid.
40219820Sjeff  if (ScopeIdx >= 0) return 0;
41219820Sjeff
42219820Sjeff  // Otherwise, the index is in the ScopeInlinedAtRecords array.
43219820Sjeff  assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
44219820Sjeff         "Invalid ScopeIdx");
45219820Sjeff  return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get();
46219820Sjeff}
47219820Sjeff
48219820Sjeff/// Return both the Scope and the InlinedAt values.
49219820Sjeffvoid DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
50219820Sjeff                                    const LLVMContext &Ctx) const {
51219820Sjeff  if (ScopeIdx == 0) {
52219820Sjeff    Scope = IA = 0;
53219820Sjeff    return;
54219820Sjeff  }
55219820Sjeff
56219820Sjeff  if (ScopeIdx > 0) {
57219820Sjeff    // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
58219820Sjeff    // position specified.
59219820Sjeff    assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() &&
60219820Sjeff           "Invalid ScopeIdx!");
61219820Sjeff    Scope = Ctx.pImpl->ScopeRecords[ScopeIdx-1].get();
62219820Sjeff    IA = 0;
63219820Sjeff    return;
64219820Sjeff  }
65219820Sjeff
66219820Sjeff  // Otherwise, the index is in the ScopeInlinedAtRecords array.
67219820Sjeff  assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
68219820Sjeff         "Invalid ScopeIdx");
69219820Sjeff  Scope = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get();
70219820Sjeff  IA    = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get();
71219820Sjeff}
72219820Sjeff
73219820Sjeff
74219820SjeffDebugLoc DebugLoc::get(unsigned Line, unsigned Col,
75219820Sjeff                       MDNode *Scope, MDNode *InlinedAt) {
76219820Sjeff  DebugLoc Result;
77219820Sjeff
78219820Sjeff  // If no scope is available, this is an unknown location.
79219820Sjeff  if (Scope == 0) return Result;
80219820Sjeff
81219820Sjeff  // Saturate line and col to "unknown".
82219820Sjeff  if (Col > 255) Col = 0;
83219820Sjeff  if (Line >= (1 << 24)) Line = 0;
84219820Sjeff  Result.LineCol = Line | (Col << 24);
85219820Sjeff
86219820Sjeff  LLVMContext &Ctx = Scope->getContext();
87219820Sjeff
88219820Sjeff  // If there is no inlined-at location, use the ScopeRecords array.
89219820Sjeff  if (InlinedAt == 0)
90219820Sjeff    Result.ScopeIdx = Ctx.pImpl->getOrAddScopeRecordIdxEntry(Scope, 0);
91219820Sjeff  else
92219820Sjeff    Result.ScopeIdx = Ctx.pImpl->getOrAddScopeInlinedAtIdxEntry(Scope,
93219820Sjeff                                                                InlinedAt, 0);
94219820Sjeff
95219820Sjeff  return Result;
96219820Sjeff}
97219820Sjeff
98219820Sjeff/// getAsMDNode - This method converts the compressed DebugLoc node into a
99219820Sjeff/// DILocation compatible MDNode.
100219820SjeffMDNode *DebugLoc::getAsMDNode(const LLVMContext &Ctx) const {
101219820Sjeff  if (isUnknown()) return 0;
102219820Sjeff
103219820Sjeff  MDNode *Scope, *IA;
104219820Sjeff  getScopeAndInlinedAt(Scope, IA, Ctx);
105219820Sjeff  assert(Scope && "If scope is null, this should be isUnknown()");
106219820Sjeff
107219820Sjeff  LLVMContext &Ctx2 = Scope->getContext();
108219820Sjeff  Type *Int32 = Type::getInt32Ty(Ctx2);
109219820Sjeff  Value *Elts[] = {
110219820Sjeff    ConstantInt::get(Int32, getLine()), ConstantInt::get(Int32, getCol()),
111219820Sjeff    Scope, IA
112219820Sjeff  };
113219820Sjeff  return MDNode::get(Ctx2, Elts);
114219820Sjeff}
115219820Sjeff
116219820Sjeff/// getFromDILocation - Translate the DILocation quad into a DebugLoc.
117219820SjeffDebugLoc DebugLoc::getFromDILocation(MDNode *N) {
118219820Sjeff  DILocation Loc(N);
119219820Sjeff  MDNode *Scope = Loc.getScope();
120219820Sjeff  if (Scope == 0) return DebugLoc();
121219820Sjeff  return get(Loc.getLineNumber(), Loc.getColumnNumber(), Scope,
122219820Sjeff             Loc.getOrigLocation());
123219820Sjeff}
124219820Sjeff
125219820Sjeff/// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
126219820SjeffDebugLoc DebugLoc::getFromDILexicalBlock(MDNode *N) {
127219820Sjeff  DILexicalBlock LexBlock(N);
128219820Sjeff  MDNode *Scope = LexBlock.getContext();
129219820Sjeff  if (Scope == 0) return DebugLoc();
130219820Sjeff  return get(LexBlock.getLineNumber(), LexBlock.getColumnNumber(), Scope, NULL);
131219820Sjeff}
132219820Sjeff
133219820Sjeffvoid DebugLoc::dump(const LLVMContext &Ctx) const {
134219820Sjeff#ifndef NDEBUG
135219820Sjeff  if (!isUnknown()) {
136219820Sjeff    dbgs() << getLine();
137219820Sjeff    if (getCol() != 0)
138219820Sjeff      dbgs() << ',' << getCol();
139219820Sjeff    DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx));
140219820Sjeff    if (!InlinedAtDL.isUnknown()) {
141219820Sjeff      dbgs() << " @ ";
142219820Sjeff      InlinedAtDL.dump(Ctx);
143219820Sjeff    } else
144219820Sjeff      dbgs() << "\n";
145219820Sjeff  }
146219820Sjeff#endif
147219820Sjeff}
148219820Sjeff
149219820Sjeff//===----------------------------------------------------------------------===//
150219820Sjeff// DenseMap specialization
151219820Sjeff//===----------------------------------------------------------------------===//
152219820Sjeff
153219820Sjeffunsigned DenseMapInfo<DebugLoc>::getHashValue(const DebugLoc &Key) {
154219820Sjeff  return static_cast<unsigned>(hash_combine(Key.LineCol, Key.ScopeIdx));
155219820Sjeff}
156219820Sjeff
157219820Sjeff//===----------------------------------------------------------------------===//
158219820Sjeff// LLVMContextImpl Implementation
159219820Sjeff//===----------------------------------------------------------------------===//
160219820Sjeff
161219820Sjeffint LLVMContextImpl::getOrAddScopeRecordIdxEntry(MDNode *Scope,
162219820Sjeff                                                 int ExistingIdx) {
163219820Sjeff  // If we already have an entry for this scope, return it.
164219820Sjeff  int &Idx = ScopeRecordIdx[Scope];
165219820Sjeff  if (Idx) return Idx;
166219820Sjeff
167219820Sjeff  // If we don't have an entry, but ExistingIdx is specified, use it.
168219820Sjeff  if (ExistingIdx)
169219820Sjeff    return Idx = ExistingIdx;
170219820Sjeff
171219820Sjeff  // Otherwise add a new entry.
172219820Sjeff
173219820Sjeff  // Start out ScopeRecords with a minimal reasonable size to avoid
174219820Sjeff  // excessive reallocation starting out.
175219820Sjeff  if (ScopeRecords.empty())
176219820Sjeff    ScopeRecords.reserve(128);
177219820Sjeff
178219820Sjeff  // Index is biased by 1 for index.
179219820Sjeff  Idx = ScopeRecords.size()+1;
180219820Sjeff  ScopeRecords.push_back(DebugRecVH(Scope, this, Idx));
181219820Sjeff  return Idx;
182219820Sjeff}
183219820Sjeff
184219820Sjeffint LLVMContextImpl::getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,
185219820Sjeff                                                    int ExistingIdx) {
186219820Sjeff  // If we already have an entry, return it.
187219820Sjeff  int &Idx = ScopeInlinedAtIdx[std::make_pair(Scope, IA)];
188219820Sjeff  if (Idx) return Idx;
189219820Sjeff
190219820Sjeff  // If we don't have an entry, but ExistingIdx is specified, use it.
191219820Sjeff  if (ExistingIdx)
192219820Sjeff    return Idx = ExistingIdx;
193219820Sjeff
194219820Sjeff  // Start out ScopeInlinedAtRecords with a minimal reasonable size to avoid
195219820Sjeff  // excessive reallocation starting out.
196219820Sjeff  if (ScopeInlinedAtRecords.empty())
197219820Sjeff    ScopeInlinedAtRecords.reserve(128);
198219820Sjeff
199219820Sjeff  // Index is biased by 1 and negated.
200219820Sjeff  Idx = -ScopeInlinedAtRecords.size()-1;
201219820Sjeff  ScopeInlinedAtRecords.push_back(std::make_pair(DebugRecVH(Scope, this, Idx),
202219820Sjeff                                                 DebugRecVH(IA, this, Idx)));
203219820Sjeff  return Idx;
204219820Sjeff}
205219820Sjeff
206219820Sjeff
207219820Sjeff//===----------------------------------------------------------------------===//
208219820Sjeff// DebugRecVH Implementation
209219820Sjeff//===----------------------------------------------------------------------===//
210219820Sjeff
211219820Sjeff/// deleted - The MDNode this is pointing to got deleted, so this pointer needs
212219820Sjeff/// to drop to null and we need remove our entry from the DenseMap.
213219820Sjeffvoid DebugRecVH::deleted() {
214219820Sjeff  // If this is a non-canonical reference, just drop the value to null, we know
215219820Sjeff  // it doesn't have a map entry.
216219820Sjeff  if (Idx == 0) {
217219820Sjeff    setValPtr(0);
218219820Sjeff    return;
219219820Sjeff  }
220219820Sjeff
221219820Sjeff  MDNode *Cur = get();
222219820Sjeff
223219820Sjeff  // If the index is positive, it is an entry in ScopeRecords.
224219820Sjeff  if (Idx > 0) {
225219820Sjeff    assert(Ctx->ScopeRecordIdx[Cur] == Idx && "Mapping out of date!");
226219820Sjeff    Ctx->ScopeRecordIdx.erase(Cur);
227219820Sjeff    // Reset this VH to null and we're done.
228219820Sjeff    setValPtr(0);
229219820Sjeff    Idx = 0;
230219820Sjeff    return;
231219820Sjeff  }
232219820Sjeff
233219820Sjeff  // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it
234219820Sjeff  // is the scope or the inlined-at record entry.
235219820Sjeff  assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size());
236219820Sjeff  std::pair<DebugRecVH, DebugRecVH> &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1];
237219820Sjeff  assert((this == &Entry.first || this == &Entry.second) &&
238219820Sjeff         "Mapping out of date!");
239219820Sjeff
240219820Sjeff  MDNode *OldScope = Entry.first.get();
241219820Sjeff  MDNode *OldInlinedAt = Entry.second.get();
242219820Sjeff  assert(OldScope != 0 && OldInlinedAt != 0 &&
243219820Sjeff         "Entry should be non-canonical if either val dropped to null");
244219820Sjeff
245219820Sjeff  // Otherwise, we do have an entry in it, nuke it and we're done.
246219820Sjeff  assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&&
247219820Sjeff         "Mapping out of date");
248219820Sjeff  Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt));
249219820Sjeff
250219820Sjeff  // Reset this VH to null.  Drop both 'Idx' values to null to indicate that
251219820Sjeff  // we're in non-canonical form now.
252219820Sjeff  setValPtr(0);
253219820Sjeff  Entry.first.Idx = Entry.second.Idx = 0;
254219820Sjeff}
255219820Sjeff
256219820Sjeffvoid DebugRecVH::allUsesReplacedWith(Value *NewVa) {
257219820Sjeff  // If being replaced with a non-mdnode value (e.g. undef) handle this as if
258219820Sjeff  // the mdnode got deleted.
259219820Sjeff  MDNode *NewVal = dyn_cast<MDNode>(NewVa);
260219820Sjeff  if (NewVal == 0) return deleted();
261219820Sjeff
262219820Sjeff  // If this is a non-canonical reference, just change it, we know it already
263219820Sjeff  // doesn't have a map entry.
264219820Sjeff  if (Idx == 0) {
265219820Sjeff    setValPtr(NewVa);
266219820Sjeff    return;
267219820Sjeff  }
268219820Sjeff
269219820Sjeff  MDNode *OldVal = get();
270219820Sjeff  assert(OldVal != NewVa && "Node replaced with self?");
271219820Sjeff
272219820Sjeff  // If the index is positive, it is an entry in ScopeRecords.
273219820Sjeff  if (Idx > 0) {
274219820Sjeff    assert(Ctx->ScopeRecordIdx[OldVal] == Idx && "Mapping out of date!");
275219820Sjeff    Ctx->ScopeRecordIdx.erase(OldVal);
276219820Sjeff    setValPtr(NewVal);
277219820Sjeff
278219820Sjeff    int NewEntry = Ctx->getOrAddScopeRecordIdxEntry(NewVal, Idx);
279219820Sjeff
280219820Sjeff    // If NewVal already has an entry, this becomes a non-canonical reference,
281219820Sjeff    // just drop Idx to 0 to signify this.
282219820Sjeff    if (NewEntry != Idx)
283219820Sjeff      Idx = 0;
284219820Sjeff    return;
285219820Sjeff  }
286219820Sjeff
287219820Sjeff  // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it
288219820Sjeff  // is the scope or the inlined-at record entry.
289219820Sjeff  assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size());
290219820Sjeff  std::pair<DebugRecVH, DebugRecVH> &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1];
291219820Sjeff  assert((this == &Entry.first || this == &Entry.second) &&
292219820Sjeff         "Mapping out of date!");
293219820Sjeff
294219820Sjeff  MDNode *OldScope = Entry.first.get();
295219820Sjeff  MDNode *OldInlinedAt = Entry.second.get();
296219820Sjeff  assert(OldScope != 0 && OldInlinedAt != 0 &&
297219820Sjeff         "Entry should be non-canonical if either val dropped to null");
298219820Sjeff
299219820Sjeff  // Otherwise, we do have an entry in it, nuke it and we're done.
300219820Sjeff  assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&&
301219820Sjeff         "Mapping out of date");
302219820Sjeff  Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt));
303219820Sjeff
304219820Sjeff  // Reset this VH to the new value.
305219820Sjeff  setValPtr(NewVal);
306219820Sjeff
307219820Sjeff  int NewIdx = Ctx->getOrAddScopeInlinedAtIdxEntry(Entry.first.get(),
308219820Sjeff                                                   Entry.second.get(), Idx);
309219820Sjeff  // If NewVal already has an entry, this becomes a non-canonical reference,
310219820Sjeff  // just drop Idx to 0 to signify this.
311219820Sjeff  if (NewIdx != Idx) {
312219820Sjeff    std::pair<DebugRecVH, DebugRecVH> &Entry=Ctx->ScopeInlinedAtRecords[-Idx-1];
313219820Sjeff    Entry.first.Idx = Entry.second.Idx = 0;
314219820Sjeff  }
315219820Sjeff}
316219820Sjeff