summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp14
-rw-r--r--llvm/lib/IR/DIBuilder.cpp67
-rw-r--r--llvm/lib/IR/DebugInfo.cpp2
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp20
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h33
-rw-r--r--llvm/lib/IR/Verifier.cpp61
6 files changed, 174 insertions, 23 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 08a14934b57..624350404ff 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1831,7 +1831,7 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
Printer.printMetadata("unit", N->getRawUnit());
Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printMetadata("declaration", N->getRawDeclaration());
- Printer.printMetadata("variables", N->getRawVariables());
+ Printer.printMetadata("retainedNodes", N->getRawRetainedNodes());
Printer.printMetadata("thrownTypes", N->getRawThrownTypes());
Out << ")";
}
@@ -1971,6 +1971,18 @@ static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N,
Out << ")";
}
+static void writeDILabel(raw_ostream &Out, const DILabel *N,
+ TypePrinting *TypePrinter,
+ SlotTracker *Machine, const Module *Context) {
+ Out << "!DILabel(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLine());
+ Out << ")";
+}
+
static void writeDIExpression(raw_ostream &Out, const DIExpression *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 3e5ecdc2091..8596ebd9527 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -33,7 +33,7 @@ cl::opt<bool>
DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU)
: M(m), VMContext(M.getContext()), CUNode(CU),
- DeclareFn(nullptr), ValueFn(nullptr),
+ DeclareFn(nullptr), ValueFn(nullptr), LabelFn(nullptr),
AllowUnresolvedNodes(AllowUnresolvedNodes) {}
void DIBuilder::trackIfUnresolved(MDNode *N) {
@@ -47,18 +47,23 @@ void DIBuilder::trackIfUnresolved(MDNode *N) {
}
void DIBuilder::finalizeSubprogram(DISubprogram *SP) {
- MDTuple *Temp = SP->getVariables().get();
+ MDTuple *Temp = SP->getRetainedNodes().get();
if (!Temp || !Temp->isTemporary())
return;
- SmallVector<Metadata *, 4> Variables;
+ SmallVector<Metadata *, 16> RetainedNodes;
auto PV = PreservedVariables.find(SP);
if (PV != PreservedVariables.end())
- Variables.append(PV->second.begin(), PV->second.end());
+ RetainedNodes.append(PV->second.begin(), PV->second.end());
- DINodeArray AV = getOrCreateArray(Variables);
- TempMDTuple(Temp)->replaceAllUsesWith(AV.get());
+ auto PL = PreservedLabels.find(SP);
+ if (PL != PreservedLabels.end())
+ RetainedNodes.append(PL->second.begin(), PL->second.end());
+
+ DINodeArray Node = getOrCreateArray(RetainedNodes);
+
+ TempMDTuple(Temp)->replaceAllUsesWith(Node.get());
}
void DIBuilder::finalize() {
@@ -699,6 +704,26 @@ DILocalVariable *DIBuilder::createParameterVariable(
/* AlignInBits */0);
}
+DILabel *DIBuilder::createLabel(
+ DIScope *Scope, StringRef Name, DIFile *File,
+ unsigned LineNo, bool AlwaysPreserve) {
+ DIScope *Context = getNonCompileUnitScope(Scope);
+
+ auto *Node =
+ DILabel::get(VMContext, cast_or_null<DILocalScope>(Context), Name,
+ File, LineNo);
+
+ if (AlwaysPreserve) {
+ /// The optimizer may remove labels. If there is an interest
+ /// to preserve label info in such situation then append it to
+ /// the list of retained nodes of the DISubprogram.
+ DISubprogram *Fn = getDISubprogram(Scope);
+ assert(Fn && "Missing subprogram for label");
+ PreservedLabels[Fn].emplace_back(Node);
+ }
+ return Node;
+}
+
DIExpression *DIBuilder::createExpression(ArrayRef<uint64_t> Addr) {
return DIExpression::get(VMContext, Addr);
}
@@ -821,6 +846,18 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,
return insertDeclare(Storage, VarInfo, Expr, DL, InsertAtEnd, InsertBefore);
}
+Instruction *DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL,
+ Instruction *InsertBefore) {
+ return insertLabel(
+ LabelInfo, DL, InsertBefore ? InsertBefore->getParent() : nullptr,
+ InsertBefore);
+}
+
+Instruction *DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL,
+ BasicBlock *InsertAtEnd) {
+ return insertLabel(LabelInfo, DL, InsertAtEnd, nullptr);
+}
+
Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V,
DILocalVariable *VarInfo,
DIExpression *Expr,
@@ -906,6 +943,24 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(
return B.CreateCall(ValueFn, Args);
}
+Instruction *DIBuilder::insertLabel(
+ DILabel *LabelInfo, const DILocation *DL,
+ BasicBlock *InsertBB, Instruction *InsertBefore) {
+ assert(LabelInfo && "empty or invalid DILabel* passed to dbg.label");
+ assert(DL && "Expected debug loc");
+ assert(DL->getScope()->getSubprogram() ==
+ LabelInfo->getScope()->getSubprogram() &&
+ "Expected matching subprograms");
+ if (!LabelFn)
+ LabelFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_label);
+
+ trackIfUnresolved(LabelInfo);
+ Value *Args[] = {MetadataAsValue::get(VMContext, LabelInfo)};
+
+ IRBuilder<> B = getIRBForDbgInsertion(DL, InsertBB, InsertBefore);
+ return B.CreateCall(LabelFn, Args);
+}
+
void DIBuilder::replaceVTableHolder(DICompositeType *&T,
DIType *VTableHolder) {
{
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index 1e771d03028..8cf38e74135 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -568,7 +568,7 @@ void DebugTypeInfoRemoval::traverse(MDNode *N) {
// parts of the graph.
auto prune = [](MDNode *Parent, MDNode *Child) {
if (auto *MDS = dyn_cast<DISubprogram>(Parent))
- return Child == MDS->getVariables().get();
+ return Child == MDS->getRetainedNodes().get();
return false;
};
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index bb497e458c0..a9f96e2549d 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -489,7 +489,7 @@ DISubprogram *DISubprogram::getImpl(
bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit,
- Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
+ Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
assert(isCanonical(LinkageName) && "Expected canonical MDString");
@@ -497,10 +497,10 @@ DISubprogram *DISubprogram::getImpl(
DISubprogram, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, ScopeLine, ContainingType, Virtuality,
VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit,
- TemplateParams, Declaration, Variables, ThrownTypes));
+ TemplateParams, Declaration, RetainedNodes, ThrownTypes));
SmallVector<Metadata *, 11> Ops = {
- File, Scope, Name, LinkageName, Type, Unit,
- Declaration, Variables, ContainingType, TemplateParams, ThrownTypes};
+ File, Scope, Name, LinkageName, Type, Unit,
+ Declaration, RetainedNodes, ContainingType, TemplateParams, ThrownTypes};
if (!ThrownTypes) {
Ops.pop_back();
if (!TemplateParams) {
@@ -653,6 +653,18 @@ Optional<uint64_t> DIVariable::getSizeInBits() const {
return None;
}
+DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope,
+ MDString *Name, Metadata *File, unsigned Line,
+ StorageType Storage,
+ bool ShouldCreate) {
+ assert(Scope && "Expected scope");
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(DILabel,
+ (Scope, Name, File, Line));
+ Metadata *Ops[] = {Scope, Name, File};
+ DEFINE_GETIMPL_STORE(DILabel, (Line), Ops);
+}
+
DIExpression *DIExpression::getImpl(LLVMContext &Context,
ArrayRef<uint64_t> Elements,
StorageType Storage, bool ShouldCreate) {
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 13579dcab08..7ceeca6e347 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -619,7 +619,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
Metadata *Unit;
Metadata *TemplateParams;
Metadata *Declaration;
- Metadata *Variables;
+ Metadata *RetainedNodes;
Metadata *ThrownTypes;
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
@@ -628,7 +628,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
Metadata *ContainingType, unsigned Virtuality,
unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
bool IsOptimized, Metadata *Unit, Metadata *TemplateParams,
- Metadata *Declaration, Metadata *Variables,
+ Metadata *Declaration, Metadata *RetainedNodes,
Metadata *ThrownTypes)
: Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
@@ -637,7 +637,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
VirtualIndex(VirtualIndex), ThisAdjustment(ThisAdjustment),
Flags(Flags), IsOptimized(IsOptimized), Unit(Unit),
TemplateParams(TemplateParams), Declaration(Declaration),
- Variables(Variables), ThrownTypes(ThrownTypes) {}
+ RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes) {}
MDNodeKeyImpl(const DISubprogram *N)
: Scope(N->getRawScope()), Name(N->getRawName()),
LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
@@ -648,7 +648,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
IsOptimized(N->isOptimized()), Unit(N->getRawUnit()),
TemplateParams(N->getRawTemplateParams()),
- Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()),
+ Declaration(N->getRawDeclaration()), RetainedNodes(N->getRawRetainedNodes()),
ThrownTypes(N->getRawThrownTypes()) {}
bool isKeyOf(const DISubprogram *RHS) const {
@@ -666,7 +666,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
Unit == RHS->getUnit() &&
TemplateParams == RHS->getRawTemplateParams() &&
Declaration == RHS->getRawDeclaration() &&
- Variables == RHS->getRawVariables() &&
+ RetainedNodes == RHS->getRawRetainedNodes() &&
ThrownTypes == RHS->getRawThrownTypes();
}
@@ -948,6 +948,29 @@ template <> struct MDNodeKeyImpl<DILocalVariable> {
}
};
+template <> struct MDNodeKeyImpl<DILabel> {
+ Metadata *Scope;
+ MDString *Name;
+ Metadata *File;
+ unsigned Line;
+
+ MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line)
+ : Scope(Scope), Name(Name), File(File), Line(Line) {}
+ MDNodeKeyImpl(const DILabel *N)
+ : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
+ Line(N->getLine()) {}
+
+ bool isKeyOf(const DILabel *RHS) const {
+ return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
+ File == RHS->getRawFile() && Line == RHS->getLine();
+ }
+
+ /// Using name and line to get hash value. It should already be mostly unique.
+ unsigned getHashValue() const {
+ return hash_combine(Scope, Name, Line);
+ }
+};
+
template <> struct MDNodeKeyImpl<DIExpression> {
ArrayRef<uint64_t> Elements;
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 770d21dfb7b..dca9d9b64ff 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -467,6 +467,7 @@ private:
void visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS);
void visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI);
void visitDbgIntrinsic(StringRef Kind, DbgInfoIntrinsic &DII);
+ void visitDbgLabelIntrinsic(StringRef Kind, DbgLabelInst &DLI);
void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI);
void visitAtomicRMWInst(AtomicRMWInst &RMWI);
void visitFenceInst(FenceInst &FI);
@@ -1085,12 +1086,13 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
if (auto *S = N.getRawDeclaration())
AssertDI(isa<DISubprogram>(S) && !cast<DISubprogram>(S)->isDefinition(),
"invalid subprogram declaration", &N, S);
- if (auto *RawVars = N.getRawVariables()) {
- auto *Vars = dyn_cast<MDTuple>(RawVars);
- AssertDI(Vars, "invalid variable list", &N, RawVars);
- for (Metadata *Op : Vars->operands()) {
- AssertDI(Op && isa<DILocalVariable>(Op), "invalid local variable", &N,
- Vars, Op);
+ if (auto *RawNode = N.getRawRetainedNodes()) {
+ auto *Node = dyn_cast<MDTuple>(RawNode);
+ AssertDI(Node, "invalid retained nodes list", &N, RawNode);
+ for (Metadata *Op : Node->operands()) {
+ AssertDI(Op && (isa<DILocalVariable>(Op) || isa<DILabel>(Op)),
+ "invalid retained nodes, expected DILocalVariable or DILabel",
+ &N, Node, Op);
}
}
AssertDI(!hasConflictingReferenceFlags(N.getFlags()),
@@ -1222,6 +1224,17 @@ void Verifier::visitDILocalVariable(const DILocalVariable &N) {
"local variable requires a valid scope", &N, N.getRawScope());
}
+void Verifier::visitDILabel(const DILabel &N) {
+ if (auto *S = N.getRawScope())
+ AssertDI(isa<DIScope>(S), "invalid scope", &N, S);
+ if (auto *F = N.getRawFile())
+ AssertDI(isa<DIFile>(F), "invalid file", &N, F);
+
+ AssertDI(N.getTag() == dwarf::DW_TAG_label, "invalid tag", &N);
+ AssertDI(N.getRawScope() && isa<DILocalScope>(N.getRawScope()),
+ "label requires a valid scope", &N, N.getRawScope());
+}
+
void Verifier::visitDIExpression(const DIExpression &N) {
AssertDI(N.isValid(), "invalid expression", &N);
}
@@ -4065,6 +4078,9 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
case Intrinsic::dbg_value: // llvm.dbg.value
visitDbgIntrinsic("value", cast<DbgInfoIntrinsic>(*CS.getInstruction()));
break;
+ case Intrinsic::dbg_label: // llvm.dbg.label
+ visitDbgLabelIntrinsic("label", cast<DbgLabelInst>(*CS.getInstruction()));
+ break;
case Intrinsic::memcpy:
case Intrinsic::memmove:
case Intrinsic::memset: {
@@ -4494,7 +4510,40 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgInfoIntrinsic &DII) {
verifyFnArgs(DII);
}
+void Verifier::visitDbgLabelIntrinsic(StringRef Kind, DbgLabelInst &DLI) {
+ AssertDI(isa<DILabel>(DLI.getRawVariable()),
+ "invalid llvm.dbg." + Kind + " intrinsic variable", &DLI,
+ DLI.getRawVariable());
+
+ // Ignore broken !dbg attachments; they're checked elsewhere.
+ if (MDNode *N = DLI.getDebugLoc().getAsMDNode())
+ if (!isa<DILocation>(N))
+ return;
+
+ BasicBlock *BB = DLI.getParent();
+ Function *F = BB ? BB->getParent() : nullptr;
+
+ // The scopes for variables and !dbg attachments must agree.
+ DILabel *Label = DLI.getLabel();
+ DILocation *Loc = DLI.getDebugLoc();
+ Assert(Loc, "llvm.dbg." + Kind + " intrinsic requires a !dbg attachment",
+ &DLI, BB, F);
+
+ DISubprogram *LabelSP = getSubprogram(Label->getRawScope());
+ DISubprogram *LocSP = getSubprogram(Loc->getRawScope());
+ if (!LabelSP || !LocSP)
+ return;
+
+ AssertDI(LabelSP == LocSP, "mismatched subprogram between llvm.dbg." + Kind +
+ " label and !dbg attachment",
+ &DLI, BB, F, Label, Label->getScope()->getSubprogram(), Loc,
+ Loc->getScope()->getSubprogram());
+}
+
void Verifier::verifyFragmentExpression(const DbgInfoIntrinsic &I) {
+ if (dyn_cast<DbgLabelInst>(&I))
+ return;
+
DILocalVariable *V = dyn_cast_or_null<DILocalVariable>(I.getRawVariable());
DIExpression *E = dyn_cast_or_null<DIExpression>(I.getRawExpression());
OpenPOWER on IntegriCloud