diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ObjCARCInstKind.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 28 | ||||
-rw-r--r-- | llvm/lib/CodeGen/IntrinsicLowering.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 67 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfo.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfoMetadata.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 33 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 61 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 1 |
15 files changed, 250 insertions, 40 deletions
diff --git a/llvm/lib/Analysis/ObjCARCInstKind.cpp b/llvm/lib/Analysis/ObjCARCInstKind.cpp index 332c9e894de..f268e2a9abd 100644 --- a/llvm/lib/Analysis/ObjCARCInstKind.cpp +++ b/llvm/lib/Analysis/ObjCARCInstKind.cpp @@ -209,6 +209,7 @@ static bool isInertIntrinsic(unsigned ID) { // Don't let dbg info affect our results. case Intrinsic::dbg_declare: case Intrinsic::dbg_value: + case Intrinsic::dbg_label: // Short cut: Some intrinsics obviously don't use ObjC pointers. return true; default: diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index f757acfade0..60981a1a720 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -501,6 +501,7 @@ bool llvm::isAssumeLikeIntrinsic(const Instruction *I) { case Intrinsic::sideeffect: case Intrinsic::dbg_declare: case Intrinsic::dbg_value: + case Intrinsic::dbg_label: case Intrinsic::invariant_start: case Intrinsic::invariant_end: case Intrinsic::lifetime_start: diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 0f28864534e..a8f634bddce 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4347,7 +4347,7 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { /// virtuality: DW_VIRTUALTIY_pure_virtual, /// virtualIndex: 10, thisAdjustment: 4, flags: 11, /// isOptimized: false, templateParams: !4, declaration: !5, -/// variables: !6, thrownTypes: !7) +/// retainedNodes: !6, thrownTypes: !7) bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { auto Loc = Lex.getLoc(); #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ @@ -4369,7 +4369,7 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { OPTIONAL(unit, MDField, ); \ OPTIONAL(templateParams, MDField, ); \ OPTIONAL(declaration, MDField, ); \ - OPTIONAL(variables, MDField, ); \ + OPTIONAL(retainedNodes, MDField, ); \ OPTIONAL(thrownTypes, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4385,7 +4385,7 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { type.Val, isLocal.Val, isDefinition.Val, scopeLine.Val, containingType.Val, virtuality.Val, virtualIndex.Val, thisAdjustment.Val, flags.Val, isOptimized.Val, unit.Val, templateParams.Val, - declaration.Val, variables.Val, thrownTypes.Val)); + declaration.Val, retainedNodes.Val, thrownTypes.Val)); return false; } @@ -4568,6 +4568,22 @@ bool LLParser::ParseDILocalVariable(MDNode *&Result, bool IsDistinct) { return false; } +/// ParseDILabel: +/// ::= !DILabel(scope: !0, name: "foo", file: !1, line: 7) +bool LLParser::ParseDILabel(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(scope, MDField, (/* AllowNull */ false)); \ + REQUIRED(name, MDStringField, ); \ + REQUIRED(file, MDField, ); \ + REQUIRED(line, LineField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(DILabel, + (Context, scope.Val, name.Val, file.Val, line.Val)); + return false; +} + /// ParseDIExpression: /// ::= !DIExpression(0, 7, -1) bool LLParser::ParseDIExpression(MDNode *&Result, bool IsDistinct) { diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index efaee21a8d8..011c41e2cec 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -822,6 +822,7 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() { case bitc::METADATA_TEMPLATE_VALUE: case bitc::METADATA_GLOBAL_VAR: case bitc::METADATA_LOCAL_VAR: + case bitc::METADATA_LABEL: case bitc::METADATA_EXPRESSION: case bitc::METADATA_OBJC_PROPERTY: case bitc::METADATA_IMPORTED_ENTITY: @@ -1438,7 +1439,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( HasUnit ? CUorFn : nullptr, // unit getMDOrNull(Record[15 + Offset]), // templateParams getMDOrNull(Record[16 + Offset]), // declaration - getMDOrNull(Record[17 + Offset]), // variables + getMDOrNull(Record[17 + Offset]), // retainedNodes HasThrownTypes ? getMDOrNull(Record[20]) : nullptr // thrownTypes )); MetadataList.assignValue(SP, NextMetadataNo); @@ -1647,6 +1648,20 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( NextMetadataNo++; break; } + case bitc::METADATA_LABEL: { + if (Record.size() != 5) + return error("Invalid record"); + + IsDistinct = Record[0] & 1; + MetadataList.assignValue( + GET_OR_DISTINCT(DILabel, + (Context, getMDOrNull(Record[1]), + getMDString(Record[2]), + getMDOrNull(Record[3]), Record[4])), + NextMetadataNo); + NextMetadataNo++; + break; + } case bitc::METADATA_EXPRESSION: { if (Record.size() < 1) return error("Invalid record"); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 90c9392b802..a3bcf6378cb 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -335,6 +335,8 @@ private: unsigned Abbrev); void writeDILocalVariable(const DILocalVariable *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); + void writeDILabel(const DILabel *N, + SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); void writeDIExpression(const DIExpression *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); void writeDIGlobalVariableExpression(const DIGlobalVariableExpression *N, @@ -1628,7 +1630,7 @@ void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N, Record.push_back(VE.getMetadataOrNullID(N->getRawUnit())); Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get())); Record.push_back(VE.getMetadataOrNullID(N->getDeclaration())); - Record.push_back(VE.getMetadataOrNullID(N->getVariables().get())); + Record.push_back(VE.getMetadataOrNullID(N->getRetainedNodes().get())); Record.push_back(N->getThisAdjustment()); Record.push_back(VE.getMetadataOrNullID(N->getThrownTypes().get())); @@ -1785,6 +1787,19 @@ void ModuleBitcodeWriter::writeDILocalVariable( Record.clear(); } +void ModuleBitcodeWriter::writeDILabel( + const DILabel *N, SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back((uint64_t)N->isDistinct()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(N->getLine()); + + Stream.EmitRecord(bitc::METADATA_LABEL, Record, Abbrev); + Record.clear(); +} + void ModuleBitcodeWriter::writeDIExpression(const DIExpression *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 182fbd6a6ce..b16dc3c1759 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1202,10 +1202,12 @@ void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, } // Collect info for variables that were optimized out. - for (const DILocalVariable *DV : SP->getVariables()) { - if (Processed.insert(InlinedVariable(DV, nullptr)).second) - if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope())) - createConcreteVariable(TheCU, *Scope, InlinedVariable(DV, nullptr)); + for (const DINode *DN : SP->getRetainedNodes()) { + if (auto *DV = dyn_cast<DILocalVariable>(DN)) { + if (Processed.insert(InlinedVariable(DV, nullptr)).second) + if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope())) + createConcreteVariable(TheCU, *Scope, InlinedVariable(DV, nullptr)); + } } } @@ -1386,14 +1388,16 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) { // Construct abstract scopes. for (LexicalScope *AScope : LScopes.getAbstractScopesList()) { auto *SP = cast<DISubprogram>(AScope->getScopeNode()); - // Collect info for variables that were optimized out. - for (const DILocalVariable *DV : SP->getVariables()) { - if (!ProcessedVars.insert(InlinedVariable(DV, nullptr)).second) - continue; - ensureAbstractVariableIsCreated(TheCU, InlinedVariable(DV, nullptr), - DV->getScope()); - assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes - && "ensureAbstractVariableIsCreated inserted abstract scopes"); + for (const DINode *DN : SP->getRetainedNodes()) { + if (auto *DV = dyn_cast<DILocalVariable>(DN)) { + // Collect info for variables that were optimized out. + if (!ProcessedVars.insert(InlinedVariable(DV, nullptr)).second) + continue; + ensureAbstractVariableIsCreated(TheCU, InlinedVariable(DV, nullptr), + DV->getScope()); + assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes + && "ensureAbstractVariableIsCreated inserted abstract scopes"); + } } constructAbstractSubprogramScopeDIE(TheCU, AScope); } diff --git a/llvm/lib/CodeGen/IntrinsicLowering.cpp b/llvm/lib/CodeGen/IntrinsicLowering.cpp index 12777d5ed11..eb409996424 100644 --- a/llvm/lib/CodeGen/IntrinsicLowering.cpp +++ b/llvm/lib/CodeGen/IntrinsicLowering.cpp @@ -456,6 +456,7 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { } case Intrinsic::dbg_declare: + case Intrinsic::dbg_label: break; // Simply strip out debugging intrinsics case Intrinsic::eh_typeid_for: 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()); diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index d9601556595..0a8375d1d27 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -372,6 +372,11 @@ bool llvm::wouldInstructionBeTriviallyDead(Instruction *I, return false; return true; } + if (DbgLabelInst *DLI = dyn_cast<DbgLabelInst>(I)) { + if (DLI->getLabel()) + return false; + return true; + } if (!I->mayHaveSideEffects()) return true; diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 424a8815954..d900b03ec24 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3896,6 +3896,7 @@ static bool removeEmptyCleanup(CleanupReturnInst *RI) { switch (IntrinsicID) { case Intrinsic::dbg_declare: case Intrinsic::dbg_value: + case Intrinsic::dbg_label: case Intrinsic::lifetime_end: break; default: |