diff options
author | Ayke van Laethem <[email protected]> | 2022-03-03 18:20:03 +0100 |
---|---|---|
committer | Ron Evans <[email protected]> | 2022-03-12 12:55:38 +0100 |
commit | d4b1467e4c7f1c9e89a8b9efb89a25e9cd6067b2 (patch) | |
tree | 32a32cf50a432f2290090c0fadf449a455ee72c9 /stacksize | |
parent | 4cf8ad2bee058e98aaa49fbc36fb24ae220e78d0 (diff) | |
download | tinygo-d4b1467e4c7f1c9e89a8b9efb89a25e9cd6067b2.tar.gz tinygo-d4b1467e4c7f1c9e89a8b9efb89a25e9cd6067b2.zip |
build: support machine outlining pass in stacksize calculation
The machine outliner introduces a few new opcodes that weren't
previously emitted by LLVM. We need to support these.
This doesn't trigger very often, but it sometimes does. It triggers a
lot more often with ThinLTO enabled.
Diffstat (limited to 'stacksize')
-rw-r--r-- | stacksize/dwarf.go | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/stacksize/dwarf.go b/stacksize/dwarf.go index 0ba880a4c..9287b1b60 100644 --- a/stacksize/dwarf.go +++ b/stacksize/dwarf.go @@ -205,6 +205,10 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) { if err != nil { return nil, err } + case 3: // DW_CFA_restore + // Restore a register. Used after an outlined function call. + // It should be possible to ignore this. + // TODO: check that this is not the stack pointer. case 0: switch lowBits { case 0: // DW_CFA_nop @@ -218,7 +222,22 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) { } fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor entries = append(entries, fi.newLine()) - // TODO: DW_CFA_advance_loc2 etc + case 0x03: // DW_CFA_advance_loc2 + var offset uint16 + err := binary.Read(r, binary.LittleEndian, &offset) + if err != nil { + return nil, err + } + fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor + entries = append(entries, fi.newLine()) + case 0x04: // DW_CFA_advance_loc4 + var offset uint32 + err := binary.Read(r, binary.LittleEndian, &offset) + if err != nil { + return nil, err + } + fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor + entries = append(entries, fi.newLine()) case 0x05: // DW_CFA_offset_extended // Semantics are the same as DW_CFA_offset, but the encoding is // different. Ignore it just like DW_CFA_offset. @@ -239,6 +258,18 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) { if err != nil { return nil, err } + case 0x09: // DW_CFA_register + // Copies a register. Emitted by the machine outliner, for example. + // It should be possible to ignore this. + // TODO: check that the stack pointer is not affected. + _, err := readULEB128(r) + if err != nil { + return nil, err + } + _, err = readULEB128(r) + if err != nil { + return nil, err + } case 0x0c: // DW_CFA_def_cfa register, err := readULEB128(r) if err != nil { |