summaryrefslogtreecommitdiff
path: root/lib/IR/DebugInfoMetadata.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
commitd8e91e46262bc44006913e6796843909f1ac7bcd (patch)
tree7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/IR/DebugInfoMetadata.cpp
parentb7eb8e35e481a74962664b63dfb09483b200209a (diff)
Notes
Diffstat (limited to 'lib/IR/DebugInfoMetadata.cpp')
-rw-r--r--lib/IR/DebugInfoMetadata.cpp225
1 files changed, 176 insertions, 49 deletions
diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp
index 910e8c2fb74f..92f3f21f754c 100644
--- a/lib/IR/DebugInfoMetadata.cpp
+++ b/lib/IR/DebugInfoMetadata.cpp
@@ -14,16 +14,19 @@
#include "llvm/IR/DebugInfoMetadata.h"
#include "LLVMContextImpl.h"
#include "MetadataImpl.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
+#include <numeric>
+
using namespace llvm;
DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
- unsigned Column, ArrayRef<Metadata *> MDs)
+ unsigned Column, ArrayRef<Metadata *> MDs,
+ bool ImplicitCode)
: MDNode(C, DILocationKind, Storage, MDs) {
assert((MDs.size() == 1 || MDs.size() == 2) &&
"Expected a scope and optional inlined-at");
@@ -33,6 +36,8 @@ DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
SubclassData32 = Line;
SubclassData16 = Column;
+
+ setImplicitCode(ImplicitCode);
}
static void adjustColumn(unsigned &Column) {
@@ -43,15 +48,15 @@ static void adjustColumn(unsigned &Column) {
DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
unsigned Column, Metadata *Scope,
- Metadata *InlinedAt, StorageType Storage,
- bool ShouldCreate) {
+ Metadata *InlinedAt, bool ImplicitCode,
+ StorageType Storage, bool ShouldCreate) {
// Fixup column.
adjustColumn(Column);
if (Storage == Uniqued) {
- if (auto *N =
- getUniqued(Context.pImpl->DILocations,
- DILocationInfo::KeyTy(Line, Column, Scope, InlinedAt)))
+ if (auto *N = getUniqued(Context.pImpl->DILocations,
+ DILocationInfo::KeyTy(Line, Column, Scope,
+ InlinedAt, ImplicitCode)))
return N;
if (!ShouldCreate)
return nullptr;
@@ -63,36 +68,94 @@ DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
Ops.push_back(Scope);
if (InlinedAt)
Ops.push_back(InlinedAt);
- return storeImpl(new (Ops.size())
- DILocation(Context, Storage, Line, Column, Ops),
+ return storeImpl(new (Ops.size()) DILocation(Context, Storage, Line, Column,
+ Ops, ImplicitCode),
Storage, Context.pImpl->DILocations);
}
const DILocation *DILocation::getMergedLocation(const DILocation *LocA,
- const DILocation *LocB,
- bool GenerateLocation) {
+ const DILocation *LocB) {
if (!LocA || !LocB)
return nullptr;
- if (LocA == LocB || !LocA->canDiscriminate(*LocB))
+ if (LocA == LocB)
return LocA;
- if (!GenerateLocation)
- return nullptr;
-
SmallPtrSet<DILocation *, 5> InlinedLocationsA;
for (DILocation *L = LocA->getInlinedAt(); L; L = L->getInlinedAt())
InlinedLocationsA.insert(L);
+ SmallSet<std::pair<DIScope *, DILocation *>, 5> Locations;
+ DIScope *S = LocA->getScope();
+ DILocation *L = LocA->getInlinedAt();
+ while (S) {
+ Locations.insert(std::make_pair(S, L));
+ S = S->getScope().resolve();
+ if (!S && L) {
+ S = L->getScope();
+ L = L->getInlinedAt();
+ }
+ }
const DILocation *Result = LocB;
- for (DILocation *L = LocB->getInlinedAt(); L; L = L->getInlinedAt()) {
- Result = L;
- if (InlinedLocationsA.count(L))
+ S = LocB->getScope();
+ L = LocB->getInlinedAt();
+ while (S) {
+ if (Locations.count(std::make_pair(S, L)))
break;
+ S = S->getScope().resolve();
+ if (!S && L) {
+ S = L->getScope();
+ L = L->getInlinedAt();
+ }
}
- return DILocation::get(Result->getContext(), 0, 0, Result->getScope(),
- Result->getInlinedAt());
+
+ // If the two locations are irreconsilable, just pick one. This is misleading,
+ // but on the other hand, it's a "line 0" location.
+ if (!S || !isa<DILocalScope>(S))
+ S = LocA->getScope();
+ return DILocation::get(Result->getContext(), 0, 0, S, L);
}
+Optional<unsigned> DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) {
+ SmallVector<unsigned, 3> Components = {BD, DF, CI};
+ uint64_t RemainingWork = 0U;
+ // We use RemainingWork to figure out if we have no remaining components to
+ // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to
+ // encode anything for the latter 2.
+ // Since any of the input components is at most 32 bits, their sum will be
+ // less than 34 bits, and thus RemainingWork won't overflow.
+ RemainingWork = std::accumulate(Components.begin(), Components.end(), RemainingWork);
+
+ int I = 0;
+ unsigned Ret = 0;
+ unsigned NextBitInsertionIndex = 0;
+ while (RemainingWork > 0) {
+ unsigned C = Components[I++];
+ RemainingWork -= C;
+ unsigned EC = encodeComponent(C);
+ Ret |= (EC << NextBitInsertionIndex);
+ NextBitInsertionIndex += encodingBits(C);
+ }
+
+ // Encoding may be unsuccessful because of overflow. We determine success by
+ // checking equivalence of components before & after encoding. Alternatively,
+ // we could determine Success during encoding, but the current alternative is
+ // simpler.
+ unsigned TBD, TDF, TCI = 0;
+ decodeDiscriminator(Ret, TBD, TDF, TCI);
+ if (TBD == BD && TDF == DF && TCI == CI)
+ return Ret;
+ return None;
+}
+
+void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
+ unsigned &CI) {
+ BD = getUnsignedFromPrefixEncoding(D);
+ DF = getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(D));
+ CI = getUnsignedFromPrefixEncoding(
+ getNextComponentInDiscriminator(getNextComponentInDiscriminator(D)));
+}
+
+
DINode::DIFlags DINode::getFlag(StringRef Flag) {
return StringSwitch<DIFlags>(Flag)
#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
@@ -274,13 +337,14 @@ DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, int64_t Value,
DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
MDString *Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
- StorageType Storage, bool ShouldCreate) {
+ DIFlags Flags, StorageType Storage,
+ bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DIBasicType,
- (Tag, Name, SizeInBits, AlignInBits, Encoding));
+ (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags));
Metadata *Ops[] = {nullptr, nullptr, Name};
- DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding),
- Ops);
+ DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding,
+ Flags), Ops);
}
Optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
@@ -449,7 +513,8 @@ DICompileUnit *DICompileUnit::getImpl(
unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros,
uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
- bool GnuPubnames, StorageType Storage, bool ShouldCreate) {
+ unsigned NameTableKind, bool RangesBaseAddress, StorageType Storage,
+ bool ShouldCreate) {
assert(Storage != Uniqued && "Cannot unique DICompileUnit");
assert(isCanonical(Producer) && "Expected canonical MDString");
assert(isCanonical(Flags) && "Expected canonical MDString");
@@ -462,7 +527,8 @@ DICompileUnit *DICompileUnit::getImpl(
return storeImpl(new (array_lengthof(Ops)) DICompileUnit(
Context, Storage, SourceLanguage, IsOptimized,
RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,
- DebugInfoForProfiling, GnuPubnames, Ops),
+ DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
+ Ops),
Storage);
}
@@ -472,6 +538,16 @@ DICompileUnit::getEmissionKind(StringRef Str) {
.Case("NoDebug", NoDebug)
.Case("FullDebug", FullDebug)
.Case("LineTablesOnly", LineTablesOnly)
+ .Case("DebugDirectivesOnly", DebugDirectivesOnly)
+ .Default(None);
+}
+
+Optional<DICompileUnit::DebugNameTableKind>
+DICompileUnit::getNameTableKind(StringRef Str) {
+ return StringSwitch<Optional<DebugNameTableKind>>(Str)
+ .Case("Default", DebugNameTableKind::Default)
+ .Case("GNU", DebugNameTableKind::GNU)
+ .Case("None", DebugNameTableKind::None)
.Default(None);
}
@@ -480,6 +556,19 @@ const char *DICompileUnit::emissionKindString(DebugEmissionKind EK) {
case NoDebug: return "NoDebug";
case FullDebug: return "FullDebug";
case LineTablesOnly: return "LineTablesOnly";
+ case DebugDirectivesOnly: return "DebugDirectivesOnly";
+ }
+ return nullptr;
+}
+
+const char *DICompileUnit::nameTableKindString(DebugNameTableKind NTK) {
+ switch (NTK) {
+ case DebugNameTableKind::Default:
+ return nullptr;
+ case DebugNameTableKind::GNU:
+ return "GNU";
+ case DebugNameTableKind::None:
+ return "None";
}
return nullptr;
}
@@ -496,21 +585,55 @@ DILocalScope *DILocalScope::getNonLexicalBlockFileScope() const {
return const_cast<DILocalScope *>(this);
}
+DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) {
+ return StringSwitch<DISPFlags>(Flag)
+#define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)
+#include "llvm/IR/DebugInfoFlags.def"
+ .Default(SPFlagZero);
+}
+
+StringRef DISubprogram::getFlagString(DISPFlags Flag) {
+ switch (Flag) {
+ // Appease a warning.
+ case SPFlagVirtuality:
+ return "";
+#define HANDLE_DISP_FLAG(ID, NAME) \
+ case SPFlag##NAME: \
+ return "DISPFlag" #NAME;
+#include "llvm/IR/DebugInfoFlags.def"
+ }
+ return "";
+}
+
+DISubprogram::DISPFlags
+DISubprogram::splitFlags(DISPFlags Flags,
+ SmallVectorImpl<DISPFlags> &SplitFlags) {
+ // Multi-bit fields can require special handling. In our case, however, the
+ // only multi-bit field is virtuality, and all its values happen to be
+ // single-bit values, so the right behavior just falls out.
+#define HANDLE_DISP_FLAG(ID, NAME) \
+ if (DISPFlags Bit = Flags & SPFlag##NAME) { \
+ SplitFlags.push_back(Bit); \
+ Flags &= ~Bit; \
+ }
+#include "llvm/IR/DebugInfoFlags.def"
+ return Flags;
+}
+
DISubprogram *DISubprogram::getImpl(
LLVMContext &Context, Metadata *Scope, MDString *Name,
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
- bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
- Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
- int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit,
+ unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
+ int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
assert(isCanonical(LinkageName) && "Expected canonical MDString");
- DEFINE_GETIMPL_LOOKUP(
- DISubprogram, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
- IsDefinition, ScopeLine, ContainingType, Virtuality,
- VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit,
- TemplateParams, Declaration, RetainedNodes, ThrownTypes));
+ DEFINE_GETIMPL_LOOKUP(DISubprogram,
+ (Scope, Name, LinkageName, File, Line, Type, ScopeLine,
+ ContainingType, VirtualIndex, ThisAdjustment, Flags,
+ SPFlags, Unit, TemplateParams, Declaration,
+ RetainedNodes, ThrownTypes));
SmallVector<Metadata *, 11> Ops = {
File, Scope, Name, LinkageName, Type, Unit,
Declaration, RetainedNodes, ContainingType, TemplateParams, ThrownTypes};
@@ -522,11 +645,10 @@ DISubprogram *DISubprogram::getImpl(
Ops.pop_back();
}
}
- DEFINE_GETIMPL_STORE_N(DISubprogram,
- (Line, ScopeLine, Virtuality, VirtualIndex,
- ThisAdjustment, Flags, IsLocalToUnit, IsDefinition,
- IsOptimized),
- Ops, Ops.size());
+ DEFINE_GETIMPL_STORE_N(
+ DISubprogram,
+ (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops,
+ Ops.size());
}
bool DISubprogram::describes(const Function *F) const {
@@ -609,19 +731,24 @@ DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
MDString *LinkageName, Metadata *File, unsigned Line,
Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration,
- uint32_t AlignInBits, StorageType Storage,
- bool ShouldCreate) {
+ Metadata *TemplateParams, uint32_t AlignInBits,
+ StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
assert(isCanonical(LinkageName) && "Expected canonical MDString");
- DEFINE_GETIMPL_LOOKUP(DIGlobalVariable,
- (Scope, Name, LinkageName, File, Line, Type,
- IsLocalToUnit, IsDefinition,
- StaticDataMemberDeclaration, AlignInBits));
- Metadata *Ops[] = {
- Scope, Name, File, Type, Name, LinkageName, StaticDataMemberDeclaration};
+ DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition,
+ StaticDataMemberDeclaration,
+ TemplateParams, AlignInBits));
+ Metadata *Ops[] = {Scope,
+ Name,
+ File,
+ Type,
+ Name,
+ LinkageName,
+ StaticDataMemberDeclaration,
+ TemplateParams};
DEFINE_GETIMPL_STORE(DIGlobalVariable,
- (Line, IsLocalToUnit, IsDefinition, AlignInBits),
- Ops);
+ (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
}
DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope,