diff options
author | Dehao Chen <dehao@google.com> | 2016-04-28 22:09:37 +0000 |
---|---|---|
committer | Dehao Chen <dehao@google.com> | 2016-04-28 22:09:37 +0000 |
commit | 1b54fce31927b508cc03c43511192da626e80d2d (patch) | |
tree | 7cf6c702920293f36f7c119e48b904ce8660234e | |
parent | 3a592df3e48f28ef9076c9a95906f9db7f907606 (diff) | |
download | bcm5719-llvm-1b54fce31927b508cc03c43511192da626e80d2d.tar.gz bcm5719-llvm-1b54fce31927b508cc03c43511192da626e80d2d.zip |
Read discriminators correctly from object file.
Summary:
This is the follow-up patch for http://reviews.llvm.org/D19436
* Update the discriminator reading algorithm to match the assignment algorithm.
* Add test to cover the new algorithm.
Reviewers: dnovillo, echristo, dblaikie
Subscribers: danielcdh, dblaikie, echristo, llvm-commits, joker.eph
Differential Revision: http://reviews.llvm.org/D19522
llvm-svn: 267945
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 77 | ||||
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 5 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/discriminator2.ll | 61 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/discriminator3.ll | 74 |
4 files changed, 169 insertions, 48 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index a0bee0da176..30cb83398dd 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -17,9 +17,7 @@ using namespace llvm; using namespace dwarf; typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; -DWARFDebugLine::Prologue::Prologue() { - clear(); -} +DWARFDebugLine::Prologue::Prologue() { clear(); } void DWARFDebugLine::Prologue::clear() { TotalLength = Version = PrologueLength = 0; @@ -44,12 +42,12 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { << format(" opcode_base: %u\n", OpcodeBase); for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i) - OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i+1), + OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i + 1), StandardOpcodeLengths[i]); if (!IncludeDirectories.empty()) for (uint32_t i = 0; i < IncludeDirectories.size(); ++i) - OS << format("include_directories[%3u] = '", i+1) + OS << format("include_directories[%3u] = '", i + 1) << IncludeDirectories[i] << "'\n"; if (!FileNames.empty()) { @@ -57,10 +55,10 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { << " ---- ---------- ---------- -----------" "----------------\n"; for (uint32_t i = 0; i < FileNames.size(); ++i) { - const FileNameEntry& fileEntry = FileNames[i]; - OS << format("file_names[%3u] %4" PRIu64 " ", i+1, fileEntry.DirIdx) - << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", - fileEntry.ModTime, fileEntry.Length) + const FileNameEntry &fileEntry = FileNames[i]; + OS << format("file_names[%3u] %4" PRIu64 " ", i + 1, fileEntry.DirIdx) + << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", fileEntry.ModTime, + fileEntry.Length) << fileEntry.Name << '\n'; } } @@ -82,8 +80,8 @@ bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data, if (Version < 2) return false; - PrologueLength = debug_line_data.getUnsigned(offset_ptr, - sizeofPrologueLength()); + PrologueLength = + debug_line_data.getUnsigned(offset_ptr, sizeofPrologueLength()); const uint64_t end_prologue_offset = PrologueLength + *offset_ptr; MinInstLength = debug_line_data.getU8(offset_ptr); if (Version >= 4) @@ -131,9 +129,7 @@ bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data, return true; } -DWARFDebugLine::Row::Row(bool default_is_stmt) { - reset(default_is_stmt); -} +DWARFDebugLine::Row::Row(bool default_is_stmt) { reset(default_is_stmt); } void DWARFDebugLine::Row::postAppend() { BasicBlock = false; @@ -158,17 +154,13 @@ void DWARFDebugLine::Row::reset(bool default_is_stmt) { void DWARFDebugLine::Row::dump(raw_ostream &OS) const { OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column) << format(" %6u %3u %13u ", File, Isa, Discriminator) - << (IsStmt ? " is_stmt" : "") - << (BasicBlock ? " basic_block" : "") + << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "") << (PrologueEnd ? " prologue_end" : "") << (EpilogueBegin ? " epilogue_begin" : "") - << (EndSequence ? " end_sequence" : "") - << '\n'; + << (EndSequence ? " end_sequence" : "") << '\n'; } -DWARFDebugLine::Sequence::Sequence() { - reset(); -} +DWARFDebugLine::Sequence::Sequence() { reset(); } void DWARFDebugLine::Sequence::reset() { LowPC = 0; @@ -178,9 +170,7 @@ void DWARFDebugLine::Sequence::reset() { Empty = true; } -DWARFDebugLine::LineTable::LineTable() { - clear(); -} +DWARFDebugLine::LineTable::LineTable() { clear(); } void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const { Prologue.dump(OS); @@ -244,7 +234,7 @@ const DWARFDebugLine::LineTable * DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data, uint32_t offset) { std::pair<LineTableIter, bool> pos = - LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable())); + LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable())); LineTable *LT = &pos.first->second; if (pos.second) { if (!LT->parse(debug_line_data, RelocMap, &offset)) @@ -266,8 +256,8 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data, return false; } - const uint32_t end_offset = debug_line_offset + Prologue.TotalLength + - Prologue.sizeofTotalLength(); + const uint32_t end_offset = + debug_line_offset + Prologue.TotalLength + Prologue.sizeofTotalLength(); ParsingState State(this); @@ -307,9 +297,9 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data, // If this address is in our relocation map, apply the relocation. RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr); if (AI != RMap->end()) { - const std::pair<uint8_t, int64_t> &R = AI->second; - State.Row.Address = - debug_line_data.getAddress(offset_ptr) + R.second; + const std::pair<uint8_t, int64_t> &R = AI->second; + State.Row.Address = + debug_line_data.getAddress(offset_ptr) + R.second; } else State.Row.Address = debug_line_data.getAddress(offset_ptr); } @@ -509,6 +499,8 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data, State.Row.Line += line_offset; State.Row.Address += addr_offset; State.appendRowToMatrix(*offset_ptr); + // Reset discriminator to 0. + State.Row.Discriminator = 0; } } @@ -566,8 +558,8 @@ uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { sequence.LowPC = address; SequenceIter first_seq = Sequences.begin(); SequenceIter last_seq = Sequences.end(); - SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence, - DWARFDebugLine::Sequence::orderByLowPC); + SequenceIter seq_pos = std::lower_bound( + first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC); DWARFDebugLine::Sequence found_seq; if (seq_pos == last_seq) { found_seq = Sequences.back(); @@ -591,8 +583,8 @@ bool DWARFDebugLine::LineTable::lookupAddressRange( sequence.LowPC = address; SequenceIter first_seq = Sequences.begin(); SequenceIter last_seq = Sequences.end(); - SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence, - DWARFDebugLine::Sequence::orderByLowPC); + SequenceIter seq_pos = std::lower_bound( + first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC); if (seq_pos == last_seq || seq_pos->LowPC != address) { if (seq_pos == first_seq) return false; @@ -632,11 +624,10 @@ bool DWARFDebugLine::LineTable::lookupAddressRange( return true; } -bool -DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, - const char *CompDir, - FileLineInfoKind Kind, - std::string &Result) const { +bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, + const char *CompDir, + FileLineInfoKind Kind, + std::string &Result) const { if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() || Kind == FileLineInfoKind::None) return false; @@ -669,11 +660,9 @@ DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, return true; } -bool -DWARFDebugLine::LineTable::getFileLineInfoForAddress(uint64_t Address, - const char *CompDir, - FileLineInfoKind Kind, - DILineInfo &Result) const { +bool DWARFDebugLine::LineTable::getFileLineInfoForAddress( + uint64_t Address, const char *CompDir, FileLineInfoKind Kind, + DILineInfo &Result) const { // Get the index of row we're looking for in the line table. uint32_t RowIndex = lookupAddress(Address); if (RowIndex == -1U) diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index e3da87709de..4ab5ade8b8f 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -114,10 +114,6 @@ EmitDwarfLineTable(MCObjectStreamer *MCOS, MCSection *Section, int64_t LineDelta = static_cast<int64_t>(it->getLine()) - LastLine; - // Discriminator will be cleared if there is line change. - if (LineDelta != 0) - Discriminator = 0; - if (FileNum != it->getFileNum()) { FileNum = it->getFileNum(); MCOS->EmitIntValue(dwarf::DW_LNS_set_file, 1); @@ -161,6 +157,7 @@ EmitDwarfLineTable(MCObjectStreamer *MCOS, MCSection *Section, MCOS->EmitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, asmInfo->getPointerSize()); + Discriminator = 0; LastLine = it->getLine(); LastLabel = Label; } diff --git a/llvm/test/DebugInfo/X86/discriminator2.ll b/llvm/test/DebugInfo/X86/discriminator2.ll new file mode 100644 index 00000000000..208fa241d40 --- /dev/null +++ b/llvm/test/DebugInfo/X86/discriminator2.ll @@ -0,0 +1,61 @@ +; RUN: llc -mtriple=i386-unknown-unknown -mcpu=core2 %s -o %t -filetype=obj +; RUN: llvm-dwarfdump -debug-dump=line %t | FileCheck %s +; +; Generated from: +; +; #1 void foo(int, int); +; #2 int bar(); +; #3 void baz() { +; #4 foo/*discriminator 1*/(bar(), +; #5 bar());bar()/*discriminator 1*/; +; #6 } +; +; The intent is to test discriminator 1 generated for both line #4 and #5. +; The instruction sequence in the final binary is: +; line 4 discriminator 0 +; line 5 discriminator 0 +; line 4 discriminator 1 +; line 5 discriminator 1 +; We need to ensure that the discriminators for the last two instructions +; are both 1. + +; Function Attrs: uwtable +define void @_Z3bazv() #0 !dbg !6 { + %1 = call i32 @_Z3barv(), !dbg !9 + %2 = call i32 @_Z3barv(), !dbg !10 + call void @_Z3fooii(i32 %1, i32 %2), !dbg !11 + %3 = call i32 @_Z3barv(), !dbg !13 + ret void, !dbg !14 +} + +declare void @_Z3fooii(i32, i32) #1 + +declare i32 @_Z3barv() #1 + +attributes #0 = { uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.9.0 (trunk 267219)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.cc", directory: ".") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang version 3.9.0 (trunk 267219)"} +!6 = distinct !DISubprogram(name: "baz", linkageName: "_Z3bazv", scope: !1, file: !1, line: 3, type: !7, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!7 = !DISubroutineType(types: !8) +!8 = !{null} +!9 = !DILocation(line: 4, column: 7, scope: !6) +!10 = !DILocation(line: 5, column: 14, scope: !6) +!11 = !DILocation(line: 4, column: 3, scope: !12) +!12 = !DILexicalBlockFile(scope: !6, file: !1, discriminator: 1) +!13 = !DILocation(line: 5, column: 21, scope: !12) +!14 = !DILocation(line: 6, column: 1, scope: !6) + +; CHECK: Address Line Column File ISA Discriminator Flags +; CHECK: ------------------ ------ ------ ------ --- ------------- ------------- +; CHECK: {{.*}} 4 3 1 0 1 {{.*}} +; CHECK: {{.*}} 5 21 1 0 1 {{.*}} diff --git a/llvm/test/DebugInfo/X86/discriminator3.ll b/llvm/test/DebugInfo/X86/discriminator3.ll new file mode 100644 index 00000000000..e7dd116cb0d --- /dev/null +++ b/llvm/test/DebugInfo/X86/discriminator3.ll @@ -0,0 +1,74 @@ +; RUN: llc -mtriple=i386-unknown-unknown -mcpu=core2 %s -o %t -filetype=obj +; RUN: llvm-dwarfdump -debug-dump=line %t | FileCheck %s +; +; Generated from: +; +; #1 void foo(int); +; #2 void baz(int i) { +; #3 if (i) {foo(i+1);/*discriminator 1*/} +; #4 } +; +; The intent is to test discriminator 1 generated for all instructions in +; the taken branch. + +; Function Attrs: uwtable +define void @_Z3bazi(i32) #0 !dbg !6 { + %2 = alloca i32, align 4 + store i32 %0, i32* %2, align 4 + call void @llvm.dbg.declare(metadata i32* %2, metadata !10, metadata !11), !dbg !12 + %3 = load i32, i32* %2, align 4, !dbg !13 + %4 = icmp ne i32 %3, 0, !dbg !13 + br i1 %4, label %5, label %8, !dbg !15 + +; <label>:5: ; preds = %1 + %6 = load i32, i32* %2, align 4, !dbg !16 + %7 = add nsw i32 %6, 1, !dbg !19 + call void @_Z3fooi(i32 %7), !dbg !20 + br label %8, !dbg !21 + +; <label>:8: ; preds = %5, %1 + ret void, !dbg !22 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +declare void @_Z3fooi(i32) #2 + +attributes #0 = { uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.9.0 (trunk 267518)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.cc", directory: ".") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang version 3.9.0 (trunk 267518)"} +!6 = distinct !DISubprogram(name: "baz", linkageName: "_Z3bazi", scope: !1, file: !1, line: 2, type: !7, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!7 = !DISubroutineType(types: !8) +!8 = !{null, !9} +!9 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = !DILocalVariable(name: "i", arg: 1, scope: !6, file: !1, line: 2, type: !9) +!11 = !DIExpression() +!12 = !DILocation(line: 2, column: 14, scope: !6) +!13 = !DILocation(line: 3, column: 7, scope: !14) +!14 = distinct !DILexicalBlock(scope: !6, file: !1, line: 3, column: 7) +!15 = !DILocation(line: 3, column: 7, scope: !6) +!16 = !DILocation(line: 3, column: 15, scope: !17) +!17 = !DILexicalBlockFile(scope: !18, file: !1, discriminator: 1) +!18 = distinct !DILexicalBlock(scope: !14, file: !1, line: 3, column: 10) +!19 = !DILocation(line: 3, column: 16, scope: !17) +!20 = !DILocation(line: 3, column: 11, scope: !17) +!21 = !DILocation(line: 3, column: 21, scope: !17) +!22 = !DILocation(line: 4, column: 1, scope: !6) + +; CHECK: Address Line Column File ISA Discriminator Flags +; CHECK: ------------------ ------ ------ ------ --- ------------- ------------- +; CHECK: {{.*}} 3 15 1 0 1 +; CHECK: {{.*}} 3 16 1 0 1 +; CHECK: {{.*}} 3 11 1 0 1 |