[PATCH] D18518: Add an IR Verifier check for orphaned DICompileUnits.
Adrian Prantl via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 28 12:38:36 PDT 2016
> On Mar 28, 2016, at 11:40 AM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
>
>
>> On 2016-Mar-28, at 11:16, Adrian Prantl <aprantl at apple.com> wrote:
>>
>> aprantl created this revision.
>> aprantl added reviewers: dexonsmith, dblaikie.
>> aprantl added subscribers: llvm-commits, loladiro.
>>
>> Add an IR Verifier check for orphaned DICompileUnits. A DICompileUnit that is not listed in llvm.dbg.cu will cause assertion failures and/or crashes in the backend. The Verifier should reject this.
>>
>> http://reviews.llvm.org/D18518
>>
>> Files:
>> lib/IR/Verifier.cpp
>> test/Assembler/dicompileunit.ll
>> test/Transforms/LoopIdiom/debug-line.ll
>> test/Verifier/dbg-orphaned-compileunit.ll
>> tools/bugpoint/CrashDebugger.cpp
>>
>> <D18518.51808.patch>
>
>> Index: tools/bugpoint/CrashDebugger.cpp
>> ===================================================================
>> --- tools/bugpoint/CrashDebugger.cpp
>> +++ tools/bugpoint/CrashDebugger.cpp
>> @@ -552,7 +552,8 @@
>> std::vector<NamedMDNode *> ToDelete;
>> ToDelete.reserve(M->named_metadata_size() - Names.size());
>> for (auto &NamedMD : M->named_metadata())
>> - if (!Names.count(NamedMD.getName()))
>> + // Always keep llvm.dbg.cu because the Verifier would complain.
>> + if (!Names.count(NamedMD.getName()) && NamedMD.getName() != "llvm.dbg.cu")
>
> How does this interact with Keno's changes to make bugpoint reduce debug
> info? Will the compile units still get pruned?
Yes, there is a testcase BugPoint/named-mds.ll that verifies that DICompileUnits are still pruned. It’s just the named llvm.dbg.cu node that will no longer get removed.
I shall add a check for an empty CU list, which should be safe to remove.
>
>> ToDelete.push_back(&NamedMD);
>>
>> for (auto *NamedMD : ToDelete)
>> Index: test/Assembler/dicompileunit.ll
>> ===================================================================
>> --- test/Assembler/dicompileunit.ll
>> +++ test/Assembler/dicompileunit.ll
>> @@ -1,8 +1,10 @@
>> ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
>> ; RUN: verify-uselistorder %s
>>
>> -; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9}
>> -!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9}
>> +; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7}
>> +!named = !{!0, !1, !2, !3, !4, !5, !6, !7}
>
> ^ You could leave !8 and !9 in !named. Do you think that helps make it
> obvious that the numbering will be stable? (Up to you.)
Yes, I can leave them in and comment why they are listed.
>
>> +; CHECK: !llvm.dbg.cu = !{!8, !9}
>> +!llvm.dbg.cu = !{!8, !9}
>>
>> !0 = distinct !{}
>> !1 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
>> @@ -24,3 +26,5 @@
>> !9 = distinct !DICompileUnit(language: 12, file: !1, producer: "",
>> isOptimized: false, flags: "", runtimeVersion: 0,
>> splitDebugFilename: "", emissionKind: 0)
>> +!llvm.module.flags = !{!10}
>> +!10 = !{i32 2, !"Debug Info Version", i32 3}
>> Index: lib/IR/Verifier.cpp
>> ===================================================================
>> --- lib/IR/Verifier.cpp
>> +++ lib/IR/Verifier.cpp
>> @@ -302,7 +306,9 @@
>> visitModuleFlags(M);
>> visitModuleIdents(M);
>>
>> - // Verify type referneces last.
>
> s/referneces/references/
>
>> + verifyCompileUnits();
>> +
>> + // Verify type references last.
>> verifyTypeRefs();
>>
>> return !Broken;
>> @@ -4251,6 +4261,16 @@
>> Assert(false, "unresolved type ref", S, N);
>> }
>>
>> +void Verifier::verifyCompileUnits() {
>> + auto *CUs = M->getNamedMetadata("llvm.dbg.cu");
>> + SmallPtrSet<const Metadata *, 2> Listed;
>> + if (CUs)
>> + Listed.insert(CUs->op_begin(), CUs->op_end());
>> + Assert(set_difference(CUVisited, Listed).empty(),
>> + "All DICompileUnits must be listed in llvm.dbg.cu");
>
> It seems more efficient to do this directly, rather than creating a
> third new set and checking that it's empty:
>
> Assert(CUVisited.size() <= Listed.size());
> Assert(std::all_of(CUVisited.begin(), CUVisited.end(),
> [&Listed](const Metadata *CU) { return Listed.count(CU); });
>
Thanks!
> Maybe it's worth adding this to SetOperations.h (I'm not sure), but I
> think keeping the Verifier efficient is important.
I don’t know what a good name for such a function would be.
-- adrian
>> + CUVisited.clear();
>> +}
>> +
>> void Verifier::verifyTypeRefs() {
>> auto *CUs = M->getNamedMetadata("llvm.dbg.cu");
>> if (!CUs)
>>
>
More information about the llvm-commits
mailing list