mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-16 00:17:32 +00:00
[codeview] Correctly handle inlining functions post-dominated by unreachable
CodeView requires us to accurately describe the extent of the inlined code. We did this by grabbing the next debug location in source order and using *that* to denote where we stopped inlining. However, this is not sufficient or correct in instances where there is no next debug location or the next debug location belongs to the start of another function. To get this correct, use the end symbol of the function to denote the last possible place the inlining could have stopped at. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@259548 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d01172110e
commit
b20745dd5e
@ -145,8 +145,11 @@ public:
|
||||
}
|
||||
|
||||
ArrayRef<MCCVLineEntry> getLinesForExtent(size_t L, size_t R) {
|
||||
size_t S = std::min(R, MCCVLines.size()) - L;
|
||||
return makeArrayRef(&MCCVLines[L], S);
|
||||
if (R <= L)
|
||||
return None;
|
||||
if (L >= MCCVLines.size())
|
||||
return None;
|
||||
return makeArrayRef(&MCCVLines[L], R - L);
|
||||
}
|
||||
|
||||
/// Emits a line table substream.
|
||||
@ -154,12 +157,10 @@ public:
|
||||
const MCSymbol *FuncBegin,
|
||||
const MCSymbol *FuncEnd);
|
||||
|
||||
void emitInlineLineTableForFunction(MCObjectStreamer &OS,
|
||||
unsigned PrimaryFunctionId,
|
||||
unsigned SourceFileId,
|
||||
unsigned SourceLineNum,
|
||||
const MCSymbol *FnStartSym,
|
||||
ArrayRef<unsigned> SecondaryFunctionIds);
|
||||
void emitInlineLineTableForFunction(
|
||||
MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId,
|
||||
unsigned SourceLineNum, const MCSymbol *FnStartSym,
|
||||
const MCSymbol *FnEndSym, ArrayRef<unsigned> SecondaryFunctionIds);
|
||||
|
||||
/// Encodes the binary annotations once we have a layout.
|
||||
void encodeInlineLineTable(MCAsmLayout &Layout,
|
||||
|
@ -492,6 +492,7 @@ class MCCVInlineLineTableFragment : public MCFragment {
|
||||
unsigned StartFileId;
|
||||
unsigned StartLineNum;
|
||||
const MCSymbol *FnStartSym;
|
||||
const MCSymbol *FnEndSym;
|
||||
SmallVector<unsigned, 3> SecondaryFuncs;
|
||||
SmallString<8> Contents;
|
||||
|
||||
@ -502,11 +503,12 @@ class MCCVInlineLineTableFragment : public MCFragment {
|
||||
public:
|
||||
MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
|
||||
unsigned StartLineNum, const MCSymbol *FnStartSym,
|
||||
const MCSymbol *FnEndSym,
|
||||
ArrayRef<unsigned> SecondaryFuncs,
|
||||
MCSection *Sec = nullptr)
|
||||
: MCFragment(FT_CVInlineLines, false, 0, Sec), SiteFuncId(SiteFuncId),
|
||||
StartFileId(StartFileId), StartLineNum(StartLineNum),
|
||||
FnStartSym(FnStartSym),
|
||||
FnStartSym(FnStartSym), FnEndSym(FnEndSym),
|
||||
SecondaryFuncs(SecondaryFuncs.begin(), SecondaryFuncs.end()) {
|
||||
Contents.push_back(0);
|
||||
}
|
||||
@ -515,6 +517,7 @@ public:
|
||||
/// @{
|
||||
|
||||
const MCSymbol *getFnStartSym() const { return FnStartSym; }
|
||||
const MCSymbol *getFnEndSym() const { return FnEndSym; }
|
||||
|
||||
SmallString<8> &getContents() { return Contents; }
|
||||
const SmallString<8> &getContents() const { return Contents; }
|
||||
|
@ -129,7 +129,7 @@ public:
|
||||
const MCSymbol *End) override;
|
||||
void EmitCVInlineLinetableDirective(
|
||||
unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
|
||||
const MCSymbol *FnStartSym,
|
||||
const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
|
||||
ArrayRef<unsigned> SecondaryFunctionIds) override;
|
||||
void EmitCVStringTableDirective() override;
|
||||
void EmitCVFileChecksumsDirective() override;
|
||||
|
@ -659,7 +659,8 @@ public:
|
||||
/// directive.
|
||||
virtual void EmitCVInlineLinetableDirective(
|
||||
unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
|
||||
const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds);
|
||||
const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
|
||||
ArrayRef<unsigned> SecondaryFunctionIds);
|
||||
|
||||
/// \brief This implements the CodeView '.cv_stringtable' assembler directive.
|
||||
virtual void EmitCVStringTableDirective() {}
|
||||
|
@ -345,7 +345,7 @@ void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI,
|
||||
collectInlineSiteChildren(SecondaryFuncIds, FI, Site);
|
||||
|
||||
OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum,
|
||||
FI.Begin, SecondaryFuncIds);
|
||||
FI.Begin, FI.End, SecondaryFuncIds);
|
||||
|
||||
OS.EmitLabel(InlineEnd);
|
||||
|
||||
|
@ -207,7 +207,7 @@ public:
|
||||
const MCSymbol *FnEnd) override;
|
||||
void EmitCVInlineLinetableDirective(
|
||||
unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
|
||||
const MCSymbol *FnStartSym,
|
||||
const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
|
||||
ArrayRef<unsigned> SecondaryFunctionIds) override;
|
||||
void EmitCVStringTableDirective() override;
|
||||
void EmitCVFileChecksumsDirective() override;
|
||||
@ -1020,10 +1020,13 @@ void MCAsmStreamer::EmitCVLinetableDirective(unsigned FunctionId,
|
||||
|
||||
void MCAsmStreamer::EmitCVInlineLinetableDirective(
|
||||
unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
|
||||
const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds) {
|
||||
const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
|
||||
ArrayRef<unsigned> SecondaryFunctionIds) {
|
||||
OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId
|
||||
<< ' ' << SourceLineNum << ' ';
|
||||
FnStartSym->print(OS, MAI);
|
||||
OS << ' ';
|
||||
FnEndSym->print(OS, MAI);
|
||||
if (!SecondaryFunctionIds.empty()) {
|
||||
OS << " contains";
|
||||
for (unsigned SecondaryFunctionId : SecondaryFunctionIds)
|
||||
@ -1031,7 +1034,7 @@ void MCAsmStreamer::EmitCVInlineLinetableDirective(
|
||||
}
|
||||
EmitEOL();
|
||||
this->MCStreamer::EmitCVInlineLinetableDirective(
|
||||
PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
|
||||
PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym,
|
||||
SecondaryFunctionIds);
|
||||
}
|
||||
|
||||
|
@ -228,11 +228,11 @@ static uint32_t encodeSignedNumber(uint32_t Data) {
|
||||
void CodeViewContext::emitInlineLineTableForFunction(
|
||||
MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId,
|
||||
unsigned SourceLineNum, const MCSymbol *FnStartSym,
|
||||
ArrayRef<unsigned> SecondaryFunctionIds) {
|
||||
const MCSymbol *FnEndSym, ArrayRef<unsigned> SecondaryFunctionIds) {
|
||||
// Create and insert a fragment into the current section that will be encoded
|
||||
// later.
|
||||
new MCCVInlineLineTableFragment(
|
||||
PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
|
||||
PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym,
|
||||
SecondaryFunctionIds, OS.getCurrentSectionOnly());
|
||||
}
|
||||
|
||||
@ -265,7 +265,7 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout,
|
||||
}
|
||||
if (LocBegin >= LocEnd)
|
||||
return;
|
||||
ArrayRef<MCCVLineEntry> Locs = getLinesForExtent(LocBegin, LocEnd + 1);
|
||||
ArrayRef<MCCVLineEntry> Locs = getLinesForExtent(LocBegin, LocEnd);
|
||||
if (Locs.empty())
|
||||
return;
|
||||
|
||||
@ -331,6 +331,19 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout,
|
||||
|
||||
LastLoc = &Loc;
|
||||
}
|
||||
|
||||
assert(WithinFunction);
|
||||
|
||||
unsigned EndSymLength =
|
||||
computeLabelDiff(Layout, LastLoc->getLabel(), Frag.getFnEndSym());
|
||||
unsigned LocAfterLength = ~0U;
|
||||
ArrayRef<MCCVLineEntry> LocAfter = getLinesForExtent(LocEnd, LocEnd + 1);
|
||||
if (!LocAfter.empty())
|
||||
LocAfterLength =
|
||||
computeLabelDiff(Layout, LastLoc->getLabel(), LocAfter[0].getLabel());
|
||||
|
||||
compressAnnotation(ChangeCodeLength, Buffer);
|
||||
compressAnnotation(std::min(EndSymLength, LocAfterLength), Buffer);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -386,12 +386,13 @@ void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
|
||||
|
||||
void MCObjectStreamer::EmitCVInlineLinetableDirective(
|
||||
unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
|
||||
const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds) {
|
||||
const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
|
||||
ArrayRef<unsigned> SecondaryFunctionIds) {
|
||||
getContext().getCVContext().emitInlineLineTableForFunction(
|
||||
*this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
|
||||
SecondaryFunctionIds);
|
||||
FnEndSym, SecondaryFunctionIds);
|
||||
this->MCStreamer::EmitCVInlineLinetableDirective(
|
||||
PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
|
||||
PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym,
|
||||
SecondaryFunctionIds);
|
||||
}
|
||||
|
||||
|
@ -3229,7 +3229,7 @@ bool AsmParser::parseDirectiveCVLinetable() {
|
||||
}
|
||||
|
||||
/// parseDirectiveCVInlineLinetable
|
||||
/// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart
|
||||
/// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
|
||||
/// ("contains" SecondaryFunctionId+)?
|
||||
bool AsmParser::parseDirectiveCVInlineLinetable() {
|
||||
int64_t PrimaryFunctionId = getTok().getIntVal();
|
||||
@ -3256,6 +3256,12 @@ bool AsmParser::parseDirectiveCVInlineLinetable() {
|
||||
return Error(Loc, "expected identifier in directive");
|
||||
MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
|
||||
|
||||
Loc = getLexer().getLoc();
|
||||
StringRef FnEndName;
|
||||
if (parseIdentifier(FnEndName))
|
||||
return Error(Loc, "expected identifier in directive");
|
||||
MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
|
||||
|
||||
SmallVector<unsigned, 8> SecondaryFunctionIds;
|
||||
if (getLexer().is(AsmToken::Identifier)) {
|
||||
if (getTok().getIdentifier() != "contains")
|
||||
@ -3276,7 +3282,7 @@ bool AsmParser::parseDirectiveCVInlineLinetable() {
|
||||
|
||||
getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
|
||||
SourceLineNum, FnStartSym,
|
||||
SecondaryFunctionIds);
|
||||
FnEndSym, SecondaryFunctionIds);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -198,7 +198,8 @@ void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId,
|
||||
|
||||
void MCStreamer::EmitCVInlineLinetableDirective(
|
||||
unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
|
||||
const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds) {}
|
||||
const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
|
||||
ArrayRef<unsigned> SecondaryFunctionIds) {}
|
||||
|
||||
void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
|
||||
MCSymbol *EHSymbol) {
|
||||
|
@ -56,10 +56,10 @@
|
||||
; ASM: .long Ltmp3-Ltmp2
|
||||
; ASM: .short 4429
|
||||
; ASM: .asciz
|
||||
; ASM: .cv_inline_linetable 1 1 8 Lfunc_begin0 contains 2
|
||||
; ASM: .cv_inline_linetable 1 1 8 Lfunc_begin0 Lfunc_end0 contains 2
|
||||
; ASM: .short 4429
|
||||
; ASM: .asciz
|
||||
; ASM: .cv_inline_linetable 2 1 2 Lfunc_begin0
|
||||
; ASM: .cv_inline_linetable 2 1 2 Lfunc_begin0 Lfunc_end0
|
||||
; ASM: .short 4430
|
||||
; ASM: .short 4430
|
||||
|
||||
|
97
test/MC/COFF/cv-inline-linetable-unreachable.s
Normal file
97
test/MC/COFF/cv-inline-linetable-unreachable.s
Normal file
@ -0,0 +1,97 @@
|
||||
# RUN: llvm-mc -triple=i686-pc-win32 -filetype=obj < %s | llvm-readobj -codeview | FileCheck %s
|
||||
.text
|
||||
.def @feat.00;
|
||||
.scl 3;
|
||||
.type 0;
|
||||
.endef
|
||||
.globl @feat.00
|
||||
@feat.00 = 1
|
||||
.def _g;
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.globl _g
|
||||
.p2align 4, 0x90
|
||||
_g: # @g
|
||||
Lfunc_begin0:
|
||||
.cv_file 1 "\\usr\\local\\google\\home\\majnemer\\llvm\\src\\<stdin>"
|
||||
.cv_loc 0 1 7 0 is_stmt 0 # <stdin>:7:0
|
||||
# BB#0: # %entry
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
.cv_loc 1 1 4 3 # <stdin>:4:3
|
||||
movl _x, %eax
|
||||
addl $1, %eax
|
||||
movl %eax, _x
|
||||
Lfunc_end0:
|
||||
|
||||
.comm _x,4,2 # @x
|
||||
.section .debug$T,"dr"
|
||||
.long 4
|
||||
.short 6
|
||||
.short 4609
|
||||
.long 0
|
||||
.short 14
|
||||
.short 4104
|
||||
.asciz "\003\000\000\000\000\000\000\000\000\020\000"
|
||||
.short 12
|
||||
.short 5633
|
||||
.asciz "\000\000\000\000\001\020\000"
|
||||
.byte 103
|
||||
.byte 0
|
||||
.short 12
|
||||
.short 5633
|
||||
.asciz "\000\000\000\000\001\020\000"
|
||||
.byte 102
|
||||
.byte 0
|
||||
.section .debug$S,"dr"
|
||||
.long 4
|
||||
.long 246 # Inlinee lines subsection
|
||||
.long Ltmp1-Ltmp0
|
||||
Ltmp0:
|
||||
.long 0
|
||||
.long 4099 # Inlined function f starts at <stdin>:3
|
||||
.long 0
|
||||
.long 3
|
||||
Ltmp1:
|
||||
.long 241 # Symbol subsection for g
|
||||
.long Ltmp3-Ltmp2
|
||||
Ltmp2:
|
||||
.short Ltmp5-Ltmp4
|
||||
Ltmp4:
|
||||
.short 4423
|
||||
.zero 12
|
||||
.long Lfunc_end0-_g
|
||||
.zero 12
|
||||
.secrel32 _g
|
||||
.secidx _g
|
||||
.byte 0
|
||||
.byte 103
|
||||
.byte 0
|
||||
Ltmp5:
|
||||
.short Ltmp7-Ltmp6
|
||||
Ltmp6:
|
||||
.short 4429
|
||||
.asciz "\000\000\000\000\000\000\000\000\003\020\000"
|
||||
.cv_inline_linetable 1 1 3 Lfunc_begin0 Lfunc_end0
|
||||
# CHECK: InlineSite {
|
||||
# CHECK: PtrParent: 0x0
|
||||
# CHECK: PtrEnd: 0x0
|
||||
# CHECK: Inlinee: f (0x1003)
|
||||
# CHECK: BinaryAnnotations [
|
||||
# CHECK: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x3, LineOffset: 1}
|
||||
# CHECK: ChangeCodeLength: 0xD
|
||||
# CHECK: ]
|
||||
# CHECK: }
|
||||
Ltmp7:
|
||||
.short 2
|
||||
.short 4430
|
||||
# CHECK: InlineSiteEnd {
|
||||
# CHECK: }
|
||||
.short 2
|
||||
.short 4431
|
||||
Ltmp3:
|
||||
.p2align 2
|
||||
.cv_linetable 0, _g, Lfunc_end0
|
||||
.cv_filechecksums # File index to string table offset subsection
|
||||
.cv_stringtable # String table
|
@ -84,7 +84,7 @@ Ltmp3:
|
||||
Ltmp4:
|
||||
.short 4429
|
||||
.asciz "\000\000\000\000\000\000\000\000\003\020\000"
|
||||
.cv_inline_linetable 1 1 9 Lfunc_begin0 contains 2
|
||||
.cv_inline_linetable 1 1 9 Lfunc_begin0 Lfunc_end0 contains 2
|
||||
# CHECK: InlineSite {
|
||||
# CHECK: PtrParent: 0x0
|
||||
# CHECK: PtrEnd: 0x0
|
||||
@ -105,7 +105,7 @@ Ltmp5:
|
||||
Ltmp6:
|
||||
.short 4429
|
||||
.asciz "\000\000\000\000\000\000\000\000\004\020\000"
|
||||
.cv_inline_linetable 2 1 3 Lfunc_begin0
|
||||
.cv_inline_linetable 2 1 3 Lfunc_begin0 Lfunc_end0
|
||||
# CHECK: InlineSite {
|
||||
# CHECK: PtrParent: 0x0
|
||||
# CHECK: PtrEnd: 0x0
|
||||
|
Loading…
Reference in New Issue
Block a user