[llvm] [BOLT] Extract call continuation traces from pre-aggregated profile (PR #109486)

Amir Ayupov via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 21 14:32:25 PDT 2024


https://github.com/aaupov updated https://github.com/llvm/llvm-project/pull/109486

>From e713939a87239ea57c15849dc0f9a1fcc49e73fb Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Fri, 20 Sep 2024 15:04:50 -0700
Subject: [PATCH 1/7] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 bolt/test/X86/Inputs/callcont-fallthru.preagg |  21 +
 bolt/test/X86/Inputs/callcont-fallthru.yaml   | 889 ++++++++++++++++++
 bolt/test/X86/callcont-fallthru.test          |   9 +
 3 files changed, 919 insertions(+)
 create mode 100644 bolt/test/X86/Inputs/callcont-fallthru.preagg
 create mode 100644 bolt/test/X86/Inputs/callcont-fallthru.yaml
 create mode 100644 bolt/test/X86/callcont-fallthru.test

diff --git a/bolt/test/X86/Inputs/callcont-fallthru.preagg b/bolt/test/X86/Inputs/callcont-fallthru.preagg
new file mode 100644
index 00000000000000..0b5f344540573a
--- /dev/null
+++ b/bolt/test/X86/Inputs/callcont-fallthru.preagg
@@ -0,0 +1,21 @@
+B ffffffff81e01006 401194 8 0
+B 401180 401199 98482 96
+B 401199 401166 99542 0
+B 401177 401130 102776 0
+B 401135 40117c 103204 0
+B 401186 40118b 1022983 0
+B 401194 40117c 1021645 1
+F 40117c 401135 1161
+F 40117c 401180 92267
+F 40118b 401194 991002
+F 40117c 401186 968072
+F 40118b 401186 11468
+F 401130 401135 100015
+F 401166 401177 96992
+F 401199 401199 96168
+F 40117c ffffffff81e01006 7
+F 401199 401180 1140
+F 401194 ffffffff81e01006 1
+F 40117c 401194 11522
+F 401166 401199 1151
+F 401130 401177 1154
diff --git a/bolt/test/X86/Inputs/callcont-fallthru.yaml b/bolt/test/X86/Inputs/callcont-fallthru.yaml
new file mode 100644
index 00000000000000..a1f8417d1e217d
--- /dev/null
+++ b/bolt/test/X86/Inputs/callcont-fallthru.yaml
@@ -0,0 +1,889 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x401040
+ProgramHeaders:
+  - Type:            PT_PHDR
+    Flags:           [ PF_R ]
+    VAddr:           0x400040
+    Align:           0x8
+  - Type:            PT_INTERP
+    Flags:           [ PF_R ]
+    FirstSec:        .interp
+    LastSec:         .interp
+    VAddr:           0x400318
+  - Type:            PT_LOAD
+    Flags:           [ PF_R ]
+    FirstSec:        .interp
+    LastSec:         .rela.plt
+    VAddr:           0x400000
+    Align:           0x1000
+  - Type:            PT_LOAD
+    Flags:           [ PF_X, PF_R ]
+    FirstSec:        .init
+    LastSec:         .fini
+    VAddr:           0x401000
+    Align:           0x1000
+  - Type:            PT_LOAD
+    Flags:           [ PF_R ]
+    FirstSec:        .rodata
+    LastSec:         .eh_frame
+    VAddr:           0x402000
+    Align:           0x1000
+  - Type:            PT_LOAD
+    Flags:           [ PF_W, PF_R ]
+    FirstSec:        .init_array
+    LastSec:         .bss
+    VAddr:           0x403DE8
+    Align:           0x1000
+  - Type:            PT_DYNAMIC
+    Flags:           [ PF_W, PF_R ]
+    FirstSec:        .dynamic
+    LastSec:         .dynamic
+    VAddr:           0x403DF8
+    Align:           0x8
+  - Type:            PT_NOTE
+    Flags:           [ PF_R ]
+    FirstSec:        .note.gnu.property
+    LastSec:         .note.gnu.property
+    VAddr:           0x400338
+    Align:           0x8
+  - Type:            PT_NOTE
+    Flags:           [ PF_R ]
+    FirstSec:        .note.gnu.build-id
+    LastSec:         .note.ABI-tag
+    VAddr:           0x400358
+    Align:           0x4
+  - Type:            PT_GNU_PROPERTY
+    Flags:           [ PF_R ]
+    FirstSec:        .note.gnu.property
+    LastSec:         .note.gnu.property
+    VAddr:           0x400338
+    Align:           0x8
+  - Type:            PT_GNU_EH_FRAME
+    Flags:           [ PF_R ]
+    FirstSec:        .eh_frame_hdr
+    LastSec:         .eh_frame_hdr
+    VAddr:           0x402010
+    Align:           0x4
+  - Type:            PT_GNU_STACK
+    Flags:           [ PF_W, PF_R ]
+    Align:           0x10
+  - Type:            PT_GNU_RELRO
+    Flags:           [ PF_R ]
+    FirstSec:        .init_array
+    LastSec:         .got
+    VAddr:           0x403DE8
+Sections:
+  - Name:            .interp
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x400318
+    AddressAlign:    0x1
+    Content:         2F6C696236342F6C642D6C696E75782D7838362D36342E736F2E3200
+  - Name:            .note.gnu.property
+    Type:            SHT_NOTE
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x400338
+    AddressAlign:    0x8
+    Notes:
+      - Name:            GNU
+        Desc:            028000C0040000000300000000000000
+        Type:            NT_GNU_PROPERTY_TYPE_0
+  - Name:            .note.gnu.build-id
+    Type:            SHT_NOTE
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x400358
+    AddressAlign:    0x4
+    Notes:
+      - Name:            GNU
+        Desc:            A77EA471B9AAA21E180E5FD02A0A0B2E4AB643E9
+        Type:            NT_PRPSINFO
+  - Name:            .note.ABI-tag
+    Type:            SHT_NOTE
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x40037C
+    AddressAlign:    0x4
+    Notes:
+      - Name:            GNU
+        Desc:            '00000000030000000200000000000000'
+        Type:            NT_VERSION
+  - Name:            .gnu.hash
+    Type:            SHT_GNU_HASH
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x4003A0
+    Link:            .dynsym
+    AddressAlign:    0x8
+    Header:
+      SymNdx:          0x1
+      Shift2:          0x0
+    BloomFilter:     [ 0x0 ]
+    HashBuckets:     [ 0x0 ]
+    HashValues:      [  ]
+  - Name:            .dynsym
+    Type:            SHT_DYNSYM
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x4003C0
+    Link:            .dynstr
+    AddressAlign:    0x8
+  - Name:            .dynstr
+    Type:            SHT_STRTAB
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x400450
+    AddressAlign:    0x1
+  - Name:            .gnu.version
+    Type:            SHT_GNU_versym
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x4004CE
+    Link:            .dynsym
+    AddressAlign:    0x2
+    Entries:         [ 0, 2, 1, 1, 3, 1 ]
+  - Name:            .gnu.version_r
+    Type:            SHT_GNU_verneed
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x4004E0
+    Link:            .dynstr
+    AddressAlign:    0x8
+    Dependencies:
+      - Version:         1
+        File:            libc.so.6
+        Entries:
+          - Name:            GLIBC_2.2.5
+            Hash:            157882997
+            Flags:           0
+            Other:           3
+          - Name:            GLIBC_2.34
+            Hash:            110530996
+            Flags:           0
+            Other:           2
+  - Name:            .rela.dyn
+    Type:            SHT_RELA
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x400510
+    Link:            .dynsym
+    AddressAlign:    0x8
+    Relocations:
+      - Offset:          0x403FC8
+        Symbol:          __libc_start_main
+        Type:            R_X86_64_GLOB_DAT
+      - Offset:          0x403FD0
+        Symbol:          _ITM_deregisterTMCloneTable
+        Type:            R_X86_64_GLOB_DAT
+      - Offset:          0x403FD8
+        Symbol:          __gmon_start__
+        Type:            R_X86_64_GLOB_DAT
+      - Offset:          0x403FE0
+        Symbol:          _ITM_registerTMCloneTable
+        Type:            R_X86_64_GLOB_DAT
+  - Name:            .rela.plt
+    Type:            SHT_RELA
+    Flags:           [ SHF_ALLOC, SHF_INFO_LINK ]
+    Address:         0x400570
+    Link:            .dynsym
+    AddressAlign:    0x8
+    Info:            .got.plt
+    Relocations:
+      - Offset:          0x404000
+        Symbol:          atoi
+        Type:            R_X86_64_JUMP_SLOT
+  - Name:            .init
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x401000
+    AddressAlign:    0x4
+    Offset:          0x1000
+    Content:         F30F1EFA4883EC08488B05C92F00004885C07402FFD04883C408C3
+  - Name:            .plt
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x401020
+    AddressAlign:    0x10
+    EntSize:         0x10
+    Content:         FF35CA2F0000FF25CC2F00000F1F4000FF25CA2F00006800000000E9E0FFFFFF
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x401040
+    AddressAlign:    0x10
+    Content:         F30F1EFA31ED4989D15E4889E24883E4F050544531C031C948C7C740114000FF15632F0000F4662E0F1F840000000000F30F1EFAC3662E0F1F84000000000090488D3D892F0000488D05822F00004839F87415488B05362F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D592F0000488D35522F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05052F00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D152F0000007513554889E5E87AFFFFFFC605032F0000015DC390C366662E0F1F8400000000000F1F4000F30F1EFAEB8A662E0F1F840000000000554889E55DC3662E0F1F840000000000554889E54883EC20C745FC00000000897DF8488975F0488B45F0488B7808E8CDFEFFFF8945EC837DEC000F842E000000C745E80A000000E8B4FFFFFF837DE8000F8413000000E9000000008B45E883C0FF8945E8E9E3FFFFFFE9C8FFFFFF31C04883C4205DC3
+  - Name:            .fini
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x4011A8
+    AddressAlign:    0x4
+    Content:         F30F1EFA4883EC084883C408C3
+  - Name:            .rodata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x402000
+    AddressAlign:    0x8
+    Offset:          0x2000
+    Content:         '01000200000000000000000000000000'
+  - Name:            .eh_frame_hdr
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x402010
+    AddressAlign:    0x4
+    Content:         011B033B340000000500000010F0FFFF7800000030F0FFFF5000000060F0FFFF6400000020F1FFFFA000000030F1FFFFC0000000
+  - Name:            .eh_frame
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x402048
+    AddressAlign:    0x8
+    Content:         1400000000000000017A5200017810011B0C070890010000100000001C000000D8EFFFFF26000000004407101000000030000000F4EFFFFF0500000000000000240000004400000090EFFFFF20000000000E10460E184A0F0B770880003F1A3B2A332422000000001C0000006C00000078F0FFFF0600000000410E108602430D06410C07080000001C0000008C00000068F0FFFF6600000000410E108602430D0602610C0708000000000000
+  - Name:            .init_array
+    Type:            SHT_INIT_ARRAY
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x403DE8
+    AddressAlign:    0x8
+    EntSize:         0x8
+    Offset:          0x2DE8
+    Content:         '2011400000000000'
+  - Name:            .fini_array
+    Type:            SHT_FINI_ARRAY
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x403DF0
+    AddressAlign:    0x8
+    EntSize:         0x8
+    Content:         F010400000000000
+  - Name:            .dynamic
+    Type:            SHT_DYNAMIC
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x403DF8
+    Link:            .dynstr
+    AddressAlign:    0x8
+    Entries:
+      - Tag:             DT_NEEDED
+        Value:           0x18
+      - Tag:             DT_INIT
+        Value:           0x401000
+      - Tag:             DT_FINI
+        Value:           0x4011A8
+      - Tag:             DT_INIT_ARRAY
+        Value:           0x403DE8
+      - Tag:             DT_INIT_ARRAYSZ
+        Value:           0x8
+      - Tag:             DT_FINI_ARRAY
+        Value:           0x403DF0
+      - Tag:             DT_FINI_ARRAYSZ
+        Value:           0x8
+      - Tag:             DT_GNU_HASH
+        Value:           0x4003A0
+      - Tag:             DT_STRTAB
+        Value:           0x400450
+      - Tag:             DT_SYMTAB
+        Value:           0x4003C0
+      - Tag:             DT_STRSZ
+        Value:           0x7E
+      - Tag:             DT_SYMENT
+        Value:           0x18
+      - Tag:             DT_DEBUG
+        Value:           0x0
+      - Tag:             DT_PLTGOT
+        Value:           0x403FE8
+      - Tag:             DT_PLTRELSZ
+        Value:           0x18
+      - Tag:             DT_PLTREL
+        Value:           0x7
+      - Tag:             DT_JMPREL
+        Value:           0x400570
+      - Tag:             DT_RELA
+        Value:           0x400510
+      - Tag:             DT_RELASZ
+        Value:           0x60
+      - Tag:             DT_RELAENT
+        Value:           0x18
+      - Tag:             DT_VERNEED
+        Value:           0x4004E0
+      - Tag:             DT_VERNEEDNUM
+        Value:           0x1
+      - Tag:             DT_VERSYM
+        Value:           0x4004CE
+      - Tag:             DT_NULL
+        Value:           0x0
+      - Tag:             DT_NULL
+        Value:           0x0
+      - Tag:             DT_NULL
+        Value:           0x0
+      - Tag:             DT_NULL
+        Value:           0x0
+      - Tag:             DT_NULL
+        Value:           0x0
+      - Tag:             DT_NULL
+        Value:           0x0
+  - Name:            .got
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x403FC8
+    AddressAlign:    0x8
+    EntSize:         0x8
+    Content:         '0000000000000000000000000000000000000000000000000000000000000000'
+  - Name:            .got.plt
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x403FE8
+    AddressAlign:    0x8
+    EntSize:         0x8
+    Content:         F83D400000000000000000000000000000000000000000003610400000000000
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x404008
+    AddressAlign:    0x1
+    Content:         '00000000'
+  - Name:            .tm_clone_table
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x404010
+    AddressAlign:    0x8
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x404010
+    AddressAlign:    0x1
+    Size:            0x8
+  - Name:            .comment
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x1
+    EntSize:         0x1
+    Content:         4743433A2028474E55292031312E352E302032303234303731392028526564204861742031312E352E302D3229004743433A2028474E55292031332E332E312032303234303631312028526564204861742031332E332E312D322900636C616E672076657273696F6E2031382E312E38202843656E744F532031382E312E382D332E656C392900
+  - Name:            .gnu.build.attributes
+    Type:            SHT_NOTE
+    Address:         0x406018
+    AddressAlign:    0x4
+    Notes:
+      - Name:            "GA$\x013a1"
+        Desc:            '40104000000000006610400000000000'
+        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
+      - Name:            "GA$\x013a1"
+        Desc:            '75104000000000007510400000000000'
+        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
+      - Name:            "GA$\x013a1"
+        Desc:            '00104000000000001610400000000000'
+        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
+      - Name:            "GA$\x013a1"
+        Desc:            A811400000000000B011400000000000
+        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
+      - Name:            "GA$\x013a1"
+        Desc:            '80104000000000002611400000000000'
+        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
+      - Name:            "GA$\x013a1"
+        Desc:            A611400000000000A611400000000000
+        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
+      - Name:            "GA$\x013a1"
+        Desc:            A611400000000000A611400000000000
+        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
+      - Name:            "GA$\x013a1"
+        Desc:            16104000000000001B10400000000000
+        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
+      - Name:            "GA$\x013a1"
+        Desc:            B011400000000000B511400000000000
+        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
+  - Name:            .rela.init
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .init
+    Relocations:
+      - Offset:          0x40100B
+        Symbol:          __gmon_start__
+        Type:            R_X86_64_REX_GOTPCRELX
+        Addend:          -4
+  - Name:            .rela.text
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .text
+    Relocations:
+      - Offset:          0x40105B
+        Symbol:          main
+        Type:            R_X86_64_32S
+      - Offset:          0x401061
+        Symbol:          '__libc_start_main at GLIBC_2.34'
+        Type:            R_X86_64_GOTPCRELX
+        Addend:          -4
+      - Offset:          0x401083
+        Symbol:          .tm_clone_table
+        Type:            R_X86_64_PC32
+        Addend:          -4
+      - Offset:          0x40108A
+        Symbol:          __TMC_END__
+        Type:            R_X86_64_PC32
+        Addend:          -4
+      - Offset:          0x401096
+        Symbol:          _ITM_deregisterTMCloneTable
+        Type:            R_X86_64_REX_GOTPCRELX
+        Addend:          -4
+      - Offset:          0x4010B3
+        Symbol:          .tm_clone_table
+        Type:            R_X86_64_PC32
+        Addend:          -4
+      - Offset:          0x4010BA
+        Symbol:          __TMC_END__
+        Type:            R_X86_64_PC32
+        Addend:          -4
+      - Offset:          0x4010D7
+        Symbol:          _ITM_registerTMCloneTable
+        Type:            R_X86_64_REX_GOTPCRELX
+        Addend:          -4
+      - Offset:          0x4010F6
+        Symbol:          .bss
+        Type:            R_X86_64_PC32
+        Addend:          -5
+      - Offset:          0x401108
+        Symbol:          .bss
+        Type:            R_X86_64_PC32
+        Addend:          -5
+      - Offset:          0x40115F
+        Symbol:          'atoi at GLIBC_2.2.5'
+        Type:            R_X86_64_PLT32
+        Addend:          -4
+      - Offset:          0x401178
+        Symbol:          foo
+        Type:            R_X86_64_PLT32
+        Addend:          -4
+  - Name:            .rela.eh_frame
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .eh_frame
+    Relocations:
+      - Offset:          0x402068
+        Symbol:          .text
+        Type:            R_X86_64_PC32
+      - Offset:          0x40207C
+        Symbol:          .text
+        Type:            R_X86_64_PC32
+        Addend:          48
+      - Offset:          0x4020B8
+        Symbol:          .text
+        Type:            R_X86_64_PC32
+        Addend:          240
+      - Offset:          0x4020D8
+        Symbol:          .text
+        Type:            R_X86_64_PC32
+        Addend:          256
+  - Name:            .rela.init_array
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .init_array
+    Relocations:
+      - Offset:          0x403DE8
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          224
+  - Name:            .rela.fini_array
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .fini_array
+    Relocations:
+      - Offset:          0x403DF0
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          176
+  - Name:            .rela.gnu.build.attributes
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .gnu.build.attributes
+    Relocations:
+      - Offset:          0x40602C
+        Symbol:          .text
+        Type:            R_X86_64_64
+      - Offset:          0x406034
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          38
+      - Offset:          0x406050
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          53
+      - Offset:          0x406058
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          53
+      - Offset:          0x406074
+        Symbol:          .init
+        Type:            R_X86_64_64
+      - Offset:          0x40607C
+        Symbol:          .init
+        Type:            R_X86_64_64
+        Addend:          22
+      - Offset:          0x406098
+        Symbol:          .fini
+        Type:            R_X86_64_64
+      - Offset:          0x4060A0
+        Symbol:          .fini
+        Type:            R_X86_64_64
+        Addend:          8
+      - Offset:          0x4060BC
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          64
+      - Offset:          0x4060C4
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          230
+      - Offset:          0x4060E0
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          358
+      - Offset:          0x4060E8
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          358
+      - Offset:          0x406104
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          358
+      - Offset:          0x40610C
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          358
+      - Offset:          0x406128
+        Symbol:          .init
+        Type:            R_X86_64_64
+        Addend:          22
+      - Offset:          0x406130
+        Symbol:          .init
+        Type:            R_X86_64_64
+        Addend:          27
+      - Offset:          0x40614C
+        Symbol:          .fini
+        Type:            R_X86_64_64
+        Addend:          8
+      - Offset:          0x406154
+        Symbol:          .fini
+        Type:            R_X86_64_64
+        Addend:          13
+  - Type:            SectionHeaderTable
+    Sections:
+      - Name:            .interp
+      - Name:            .note.gnu.property
+      - Name:            .note.gnu.build-id
+      - Name:            .note.ABI-tag
+      - Name:            .gnu.hash
+      - Name:            .dynsym
+      - Name:            .dynstr
+      - Name:            .gnu.version
+      - Name:            .gnu.version_r
+      - Name:            .rela.dyn
+      - Name:            .rela.plt
+      - Name:            .init
+      - Name:            .rela.init
+      - Name:            .plt
+      - Name:            .text
+      - Name:            .rela.text
+      - Name:            .fini
+      - Name:            .rodata
+      - Name:            .eh_frame_hdr
+      - Name:            .eh_frame
+      - Name:            .rela.eh_frame
+      - Name:            .init_array
+      - Name:            .rela.init_array
+      - Name:            .fini_array
+      - Name:            .rela.fini_array
+      - Name:            .dynamic
+      - Name:            .got
+      - Name:            .got.plt
+      - Name:            .data
+      - Name:            .tm_clone_table
+      - Name:            .bss
+      - Name:            .comment
+      - Name:            .gnu.build.attributes
+      - Name:            .rela.gnu.build.attributes
+      - Name:            .symtab
+      - Name:            .strtab
+      - Name:            .shstrtab
+Symbols:
+  - Name:            .interp
+    Type:            STT_SECTION
+    Section:         .interp
+    Value:           0x400318
+  - Name:            .note.gnu.property
+    Type:            STT_SECTION
+    Section:         .note.gnu.property
+    Value:           0x400338
+  - Name:            .note.gnu.build-id
+    Type:            STT_SECTION
+    Section:         .note.gnu.build-id
+    Value:           0x400358
+  - Name:            .note.ABI-tag
+    Type:            STT_SECTION
+    Section:         .note.ABI-tag
+    Value:           0x40037C
+  - Name:            .gnu.hash
+    Type:            STT_SECTION
+    Section:         .gnu.hash
+    Value:           0x4003A0
+  - Name:            .dynsym
+    Type:            STT_SECTION
+    Section:         .dynsym
+    Value:           0x4003C0
+  - Name:            .dynstr
+    Type:            STT_SECTION
+    Section:         .dynstr
+    Value:           0x400450
+  - Name:            .gnu.version
+    Type:            STT_SECTION
+    Section:         .gnu.version
+    Value:           0x4004CE
+  - Name:            .gnu.version_r
+    Type:            STT_SECTION
+    Section:         .gnu.version_r
+    Value:           0x4004E0
+  - Name:            .rela.dyn
+    Type:            STT_SECTION
+    Section:         .rela.dyn
+    Value:           0x400510
+  - Name:            .rela.plt
+    Type:            STT_SECTION
+    Section:         .rela.plt
+    Value:           0x400570
+  - Name:            .init
+    Type:            STT_SECTION
+    Section:         .init
+    Value:           0x401000
+  - Name:            .plt
+    Type:            STT_SECTION
+    Section:         .plt
+    Value:           0x401020
+  - Name:            .text
+    Type:            STT_SECTION
+    Section:         .text
+    Value:           0x401040
+  - Name:            .fini
+    Type:            STT_SECTION
+    Section:         .fini
+    Value:           0x4011A8
+  - Name:            .rodata
+    Type:            STT_SECTION
+    Section:         .rodata
+    Value:           0x402000
+  - Name:            .eh_frame_hdr
+    Type:            STT_SECTION
+    Section:         .eh_frame_hdr
+    Value:           0x402010
+  - Name:            .eh_frame
+    Type:            STT_SECTION
+    Section:         .eh_frame
+    Value:           0x402048
+  - Name:            .init_array
+    Type:            STT_SECTION
+    Section:         .init_array
+    Value:           0x403DE8
+  - Name:            .fini_array
+    Type:            STT_SECTION
+    Section:         .fini_array
+    Value:           0x403DF0
+  - Name:            .dynamic
+    Type:            STT_SECTION
+    Section:         .dynamic
+    Value:           0x403DF8
+  - Name:            .got
+    Type:            STT_SECTION
+    Section:         .got
+    Value:           0x403FC8
+  - Name:            .got.plt
+    Type:            STT_SECTION
+    Section:         .got.plt
+    Value:           0x403FE8
+  - Name:            .data
+    Type:            STT_SECTION
+    Section:         .data
+    Value:           0x404008
+  - Name:            .tm_clone_table
+    Type:            STT_SECTION
+    Section:         .tm_clone_table
+    Value:           0x404010
+  - Name:            .bss
+    Type:            STT_SECTION
+    Section:         .bss
+    Value:           0x404010
+  - Name:            .comment
+    Type:            STT_SECTION
+    Section:         .comment
+  - Name:            .gnu.build.attributes
+    Type:            STT_SECTION
+    Section:         .gnu.build.attributes
+    Value:           0x406018
+  - Name:            crt1.o
+    Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            __abi_tag
+    Type:            STT_OBJECT
+    Section:         .note.ABI-tag
+    Value:           0x40037C
+    Size:            0x20
+  - Name:            crtstuff.c
+    Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            __TMC_LIST__
+    Type:            STT_OBJECT
+    Section:         .tm_clone_table
+    Value:           0x404010
+  - Name:            deregister_tm_clones
+    Type:            STT_FUNC
+    Section:         .text
+    Value:           0x401080
+  - Name:            register_tm_clones
+    Type:            STT_FUNC
+    Section:         .text
+    Value:           0x4010B0
+  - Name:            __do_global_dtors_aux
+    Type:            STT_FUNC
+    Section:         .text
+    Value:           0x4010F0
+  - Name:            completed.0
+    Type:            STT_OBJECT
+    Section:         .bss
+    Value:           0x404010
+    Size:            0x1
+  - Name:            __do_global_dtors_aux_fini_array_entry
+    Type:            STT_OBJECT
+    Section:         .fini_array
+    Value:           0x403DF0
+  - Name:            frame_dummy
+    Type:            STT_FUNC
+    Section:         .text
+    Value:           0x401120
+  - Name:            __frame_dummy_init_array_entry
+    Type:            STT_OBJECT
+    Section:         .init_array
+    Value:           0x403DE8
+  - Name:            callcont-fallthru.c
+    Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            'crtstuff.c (1)'
+    Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            __FRAME_END__
+    Type:            STT_OBJECT
+    Section:         .eh_frame
+    Value:           0x4020F0
+  - Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            _DYNAMIC
+    Type:            STT_OBJECT
+    Section:         .dynamic
+    Value:           0x403DF8
+  - Name:            __GNU_EH_FRAME_HDR
+    Section:         .eh_frame_hdr
+    Value:           0x402010
+  - Name:            _GLOBAL_OFFSET_TABLE_
+    Type:            STT_OBJECT
+    Section:         .got.plt
+    Value:           0x403FE8
+  - Name:            '__libc_start_main at GLIBC_2.34'
+    Type:            STT_FUNC
+    Binding:         STB_GLOBAL
+  - Name:            _ITM_deregisterTMCloneTable
+    Binding:         STB_WEAK
+  - Name:            data_start
+    Section:         .data
+    Binding:         STB_WEAK
+    Value:           0x404008
+  - Name:            _edata
+    Section:         .tm_clone_table
+    Binding:         STB_GLOBAL
+    Value:           0x404010
+  - Name:            _fini
+    Type:            STT_FUNC
+    Section:         .fini
+    Binding:         STB_GLOBAL
+    Value:           0x4011A8
+    Other:           [ STV_HIDDEN ]
+  - Name:            __data_start
+    Section:         .data
+    Binding:         STB_GLOBAL
+    Value:           0x404008
+  - Name:            __gmon_start__
+    Binding:         STB_WEAK
+  - Name:            __dso_handle
+    Type:            STT_OBJECT
+    Section:         .rodata
+    Binding:         STB_GLOBAL
+    Value:           0x402008
+    Other:           [ STV_HIDDEN ]
+  - Name:            _IO_stdin_used
+    Type:            STT_OBJECT
+    Section:         .rodata
+    Binding:         STB_GLOBAL
+    Value:           0x402000
+    Size:            0x4
+  - Name:            foo
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x401130
+    Size:            0x6
+  - Name:            _end
+    Section:         .bss
+    Binding:         STB_GLOBAL
+    Value:           0x404018
+  - Name:            _dl_relocate_static_pie
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x401070
+    Size:            0x5
+    Other:           [ STV_HIDDEN ]
+  - Name:            _start
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x401040
+    Size:            0x26
+  - Name:            __bss_start
+    Section:         .bss
+    Binding:         STB_GLOBAL
+    Value:           0x404010
+  - Name:            main
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x401140
+    Size:            0x66
+  - Name:            'atoi at GLIBC_2.2.5'
+    Type:            STT_FUNC
+    Binding:         STB_GLOBAL
+  - Name:            __TMC_END__
+    Type:            STT_OBJECT
+    Section:         .tm_clone_table
+    Binding:         STB_GLOBAL
+    Value:           0x404010
+    Other:           [ STV_HIDDEN ]
+  - Name:            _ITM_registerTMCloneTable
+    Binding:         STB_WEAK
+  - Name:            _init
+    Type:            STT_FUNC
+    Section:         .init
+    Binding:         STB_GLOBAL
+    Value:           0x401000
+    Other:           [ STV_HIDDEN ]
+DynamicSymbols:
+  - Name:            __libc_start_main
+    Type:            STT_FUNC
+    Binding:         STB_GLOBAL
+  - Name:            _ITM_deregisterTMCloneTable
+    Binding:         STB_WEAK
+  - Name:            __gmon_start__
+    Binding:         STB_WEAK
+  - Name:            atoi
+    Type:            STT_FUNC
+    Binding:         STB_GLOBAL
+  - Name:            _ITM_registerTMCloneTable
+    Binding:         STB_WEAK
+...
diff --git a/bolt/test/X86/callcont-fallthru.test b/bolt/test/X86/callcont-fallthru.test
new file mode 100644
index 00000000000000..8e43589e8f5425
--- /dev/null
+++ b/bolt/test/X86/callcont-fallthru.test
@@ -0,0 +1,9 @@
+## Reproduces missing call continuation fallthrough count when using
+## pre-aggregated perf data
+
+# RUN: yaml2obj %p/Inputs/callcont-fallthru.yaml > %t.exe
+# RUN: llvm-bolt %t.exe --pa -p %p/Inputs/callcont-fallthru.preagg -o %t.out \
+# RUN:   --print-cfg --print-only=main | FileCheck %s
+
+# CHECK:      callq foo
+# CHECK-NEXT: count: 0

>From 5f48b9253844f970245a7e46c85bb5343b0efc4c Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Sat, 21 Sep 2024 10:04:42 -0700
Subject: [PATCH 2/7] repurpose for the fix of call cont discontinuity

Created using spr 1.3.4
---
 bolt/include/bolt/Profile/DataAggregator.h |   9 +-
 bolt/lib/Profile/DataAggregator.cpp        | 105 ++++++++-------------
 bolt/test/X86/callcont-fallthru.test       |   2 +-
 3 files changed, 46 insertions(+), 70 deletions(-)

diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index 6453b3070ceb8d..1e7695baab62cc 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -202,8 +202,8 @@ class DataAggregator : public DataReader {
   /// Return a vector of offsets corresponding to a trace in a function
   /// if the trace is valid, std::nullopt otherwise.
   std::optional<SmallVector<std::pair<uint64_t, uint64_t>, 16>>
-  getFallthroughsInTrace(BinaryFunction &BF, const LBREntry &First,
-                         const LBREntry &Second, uint64_t Count = 1) const;
+  getFallthroughsInTrace(BinaryFunction &BF, uint64_t From, uint64_t To,
+                         uint64_t Count = 1) const;
 
   /// Record external entry into the function \p BF.
   ///
@@ -268,9 +268,8 @@ class DataAggregator : public DataReader {
   /// Register a \p Branch.
   bool doBranch(uint64_t From, uint64_t To, uint64_t Count, uint64_t Mispreds);
 
-  /// Register a trace between two LBR entries supplied in execution order.
-  bool doTrace(const LBREntry &First, const LBREntry &Second,
-               uint64_t Count = 1);
+  /// Register a trace between two addresses.
+  bool doTrace(const uint64_t From, const uint64_t To, uint64_t Count = 1);
 
   /// Parser helpers
   /// Return false if we exhausted our parser buffer and finished parsing
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index fcde6f5f4642c8..f73c966ec053a4 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -804,9 +804,10 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
   };
 
   BinaryFunction *FromFunc = handleAddress(From, /*IsFrom=*/true);
-  // Ignore returns.
+  // Record returns as call->call continuation fall-through.
   if (IsReturn)
-    return true;
+    return doTrace(To - 1, To, Count);
+
   BinaryFunction *ToFunc = handleAddress(To, /*IsFrom=*/false);
   if (!FromFunc && !ToFunc)
     return false;
@@ -820,16 +821,24 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
   return doInterBranch(FromFunc, ToFunc, From, To, Count, Mispreds);
 }
 
-bool DataAggregator::doTrace(const LBREntry &First, const LBREntry &Second,
+bool DataAggregator::doTrace(const uint64_t From, const uint64_t To,
                              uint64_t Count) {
-  BinaryFunction *FromFunc = getBinaryFunctionContainingAddress(First.To);
-  BinaryFunction *ToFunc = getBinaryFunctionContainingAddress(Second.From);
+  BinaryFunction *FromFunc = getBinaryFunctionContainingAddress(From);
+  BinaryFunction *ToFunc = getBinaryFunctionContainingAddress(To);
   if (!FromFunc || !ToFunc) {
     LLVM_DEBUG({
-      dbgs() << "Out of range trace starting in " << FromFunc->getPrintName()
-             << formatv(" @ {0:x}", First.To - FromFunc->getAddress())
-             << " and ending in " << ToFunc->getPrintName()
-             << formatv(" @ {0:x}\n", Second.From - ToFunc->getAddress());
+      dbgs() << "Out of range trace starting in ";
+      if (FromFunc)
+        dbgs() << formatv("{0} @ {1:x}", *FromFunc,
+                          From - FromFunc->getAddress());
+      else
+        dbgs() << Twine::utohexstr(From);
+      dbgs() << " and ending in ";
+      if (ToFunc)
+        dbgs() << formatv("{0} @ {1:x}", *ToFunc, To - ToFunc->getAddress());
+      else
+        dbgs() << Twine::utohexstr(To);
+      dbgs() << '\n';
     });
     NumLongRangeTraces += Count;
     return false;
@@ -838,32 +847,30 @@ bool DataAggregator::doTrace(const LBREntry &First, const LBREntry &Second,
     NumInvalidTraces += Count;
     LLVM_DEBUG({
       dbgs() << "Invalid trace starting in " << FromFunc->getPrintName()
-             << formatv(" @ {0:x}", First.To - FromFunc->getAddress())
+             << formatv(" @ {0:x}", From - FromFunc->getAddress())
              << " and ending in " << ToFunc->getPrintName()
-             << formatv(" @ {0:x}\n", Second.From - ToFunc->getAddress());
+             << formatv(" @ {0:x}\n", To - ToFunc->getAddress());
     });
     return false;
   }
 
   std::optional<BoltAddressTranslation::FallthroughListTy> FTs =
-      BAT ? BAT->getFallthroughsInTrace(FromFunc->getAddress(), First.To,
-                                        Second.From)
-          : getFallthroughsInTrace(*FromFunc, First, Second, Count);
+      BAT ? BAT->getFallthroughsInTrace(FromFunc->getAddress(), From, To)
+          : getFallthroughsInTrace(*FromFunc, From, To, Count);
   if (!FTs) {
     LLVM_DEBUG(
         dbgs() << "Invalid trace starting in " << FromFunc->getPrintName()
-               << " @ " << Twine::utohexstr(First.To - FromFunc->getAddress())
+               << " @ " << Twine::utohexstr(From - FromFunc->getAddress())
                << " and ending in " << ToFunc->getPrintName() << " @ "
                << ToFunc->getPrintName() << " @ "
-               << Twine::utohexstr(Second.From - ToFunc->getAddress()) << '\n');
+               << Twine::utohexstr(To - ToFunc->getAddress()) << '\n');
     NumInvalidTraces += Count;
     return false;
   }
 
   LLVM_DEBUG(dbgs() << "Processing " << FTs->size() << " fallthroughs for "
-                    << FromFunc->getPrintName() << ":"
-                    << Twine::utohexstr(First.To) << " to "
-                    << Twine::utohexstr(Second.From) << ".\n");
+                    << FromFunc->getPrintName() << ":" << Twine::utohexstr(From)
+                    << " to " << Twine::utohexstr(To) << ".\n");
   BinaryFunction *ParentFunc = getBATParentFunction(*FromFunc);
   for (auto [From, To] : *FTs) {
     if (BAT) {
@@ -877,10 +884,8 @@ bool DataAggregator::doTrace(const LBREntry &First, const LBREntry &Second,
 }
 
 std::optional<SmallVector<std::pair<uint64_t, uint64_t>, 16>>
-DataAggregator::getFallthroughsInTrace(BinaryFunction &BF,
-                                       const LBREntry &FirstLBR,
-                                       const LBREntry &SecondLBR,
-                                       uint64_t Count) const {
+DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, uint64_t From,
+                                       uint64_t To, uint64_t Count) const {
   SmallVector<std::pair<uint64_t, uint64_t>, 16> Branches;
 
   BinaryContext &BC = BF.getBinaryContext();
@@ -891,8 +896,8 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF,
   assert(BF.hasCFG() && "can only record traces in CFG state");
 
   // Offsets of the trace within this function.
-  const uint64_t From = FirstLBR.To - BF.getAddress();
-  const uint64_t To = SecondLBR.From - BF.getAddress();
+  From = From - BF.getAddress();
+  To = To - BF.getAddress();
 
   if (From > To)
     return std::nullopt;
@@ -903,24 +908,6 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF,
   if (!FromBB || !ToBB)
     return std::nullopt;
 
-  // Adjust FromBB if the first LBR is a return from the last instruction in
-  // the previous block (that instruction should be a call).
-  if (From == FromBB->getOffset() && !BF.containsAddress(FirstLBR.From) &&
-      !FromBB->isEntryPoint() && !FromBB->isLandingPad()) {
-    const BinaryBasicBlock *PrevBB =
-        BF.getLayout().getBlock(FromBB->getIndex() - 1);
-    if (PrevBB->getSuccessor(FromBB->getLabel())) {
-      const MCInst *Instr = PrevBB->getLastNonPseudoInstr();
-      if (Instr && BC.MIB->isCall(*Instr))
-        FromBB = PrevBB;
-      else
-        LLVM_DEBUG(dbgs() << "invalid incoming LBR (no call): " << FirstLBR
-                          << '\n');
-    } else {
-      LLVM_DEBUG(dbgs() << "invalid incoming LBR: " << FirstLBR << '\n');
-    }
-  }
-
   // Fill out information for fall-through edges. The From and To could be
   // within the same basic block, e.g. when two call instructions are in the
   // same block. In this case we skip the processing.
@@ -937,8 +924,8 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF,
     // Check for bad LBRs.
     if (!BB->getSuccessor(NextBB->getLabel())) {
       LLVM_DEBUG(dbgs() << "no fall-through for the trace:\n"
-                        << "  " << FirstLBR << '\n'
-                        << "  " << SecondLBR << '\n');
+                        << "  " << From << '\n'
+                        << "  " << To << '\n');
       return std::nullopt;
     }
 
@@ -1595,16 +1582,11 @@ void DataAggregator::processBranchEvents() {
   NamedRegionTimer T("processBranch", "Processing branch events",
                      TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
 
-  for (const auto &AggrLBR : FallthroughLBRs) {
-    const Trace &Loc = AggrLBR.first;
-    const FTInfo &Info = AggrLBR.second;
-    LBREntry First{Loc.From, Loc.From, false};
-    LBREntry Second{Loc.To, Loc.To, false};
+  for (const auto &[Loc, Info]: FallthroughLBRs) {
     if (Info.InternCount)
-      doTrace(First, Second, Info.InternCount);
+      doTrace(Loc.From, Loc.To, Info.InternCount);
     if (Info.ExternCount) {
-      First.From = 0;
-      doTrace(First, Second, Info.ExternCount);
+      doTrace(0, Loc.To, Info.ExternCount);
     }
   }
 
@@ -1768,21 +1750,16 @@ void DataAggregator::processPreAggregated() {
                      TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
 
   uint64_t NumTraces = 0;
-  for (const AggregatedLBREntry &AggrEntry : AggregatedLBRs) {
-    switch (AggrEntry.EntryType) {
+  for (const auto &[From, To, Count, Mispreds, Type]: AggregatedLBRs) {
+    bool IsExternalOrigin = Type == AggregatedLBREntry::FT_EXTERNAL_ORIGIN;
+    switch (Type) {
     case AggregatedLBREntry::BRANCH:
-      doBranch(AggrEntry.From.Offset, AggrEntry.To.Offset, AggrEntry.Count,
-               AggrEntry.Mispreds);
+      doBranch(From.Offset, To.Offset, Count, Mispreds);
       break;
     case AggregatedLBREntry::FT:
     case AggregatedLBREntry::FT_EXTERNAL_ORIGIN: {
-      LBREntry First{AggrEntry.EntryType == AggregatedLBREntry::FT
-                         ? AggrEntry.From.Offset
-                         : 0,
-                     AggrEntry.From.Offset, false};
-      LBREntry Second{AggrEntry.To.Offset, AggrEntry.To.Offset, false};
-      doTrace(First, Second, AggrEntry.Count);
-      NumTraces += AggrEntry.Count;
+      doTrace(IsExternalOrigin ? 0 : From.Offset, To.Offset, Count);
+      NumTraces += Count;
       break;
     }
     }
diff --git a/bolt/test/X86/callcont-fallthru.test b/bolt/test/X86/callcont-fallthru.test
index 8e43589e8f5425..e0a5c5a6852d42 100644
--- a/bolt/test/X86/callcont-fallthru.test
+++ b/bolt/test/X86/callcont-fallthru.test
@@ -6,4 +6,4 @@
 # RUN:   --print-cfg --print-only=main | FileCheck %s
 
 # CHECK:      callq foo
-# CHECK-NEXT: count: 0
+# CHECK-NEXT: count: 103204

>From 97412974e7e470c00b232aed69f139d28ce97e52 Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Sat, 21 Sep 2024 10:09:26 -0700
Subject: [PATCH 3/7] clang-format

Created using spr 1.3.4
---
 bolt/lib/Profile/DataAggregator.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index f73c966ec053a4..dbd0ed07c7c1d9 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -858,12 +858,12 @@ bool DataAggregator::doTrace(const uint64_t From, const uint64_t To,
       BAT ? BAT->getFallthroughsInTrace(FromFunc->getAddress(), From, To)
           : getFallthroughsInTrace(*FromFunc, From, To, Count);
   if (!FTs) {
-    LLVM_DEBUG(
-        dbgs() << "Invalid trace starting in " << FromFunc->getPrintName()
-               << " @ " << Twine::utohexstr(From - FromFunc->getAddress())
-               << " and ending in " << ToFunc->getPrintName() << " @ "
-               << ToFunc->getPrintName() << " @ "
-               << Twine::utohexstr(To - ToFunc->getAddress()) << '\n');
+    LLVM_DEBUG(dbgs() << "Invalid trace starting in "
+                      << FromFunc->getPrintName() << " @ "
+                      << Twine::utohexstr(From - FromFunc->getAddress())
+                      << " and ending in " << ToFunc->getPrintName() << " @ "
+                      << ToFunc->getPrintName() << " @ "
+                      << Twine::utohexstr(To - ToFunc->getAddress()) << '\n');
     NumInvalidTraces += Count;
     return false;
   }
@@ -1582,7 +1582,7 @@ void DataAggregator::processBranchEvents() {
   NamedRegionTimer T("processBranch", "Processing branch events",
                      TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
 
-  for (const auto &[Loc, Info]: FallthroughLBRs) {
+  for (const auto &[Loc, Info] : FallthroughLBRs) {
     if (Info.InternCount)
       doTrace(Loc.From, Loc.To, Info.InternCount);
     if (Info.ExternCount) {
@@ -1750,7 +1750,7 @@ void DataAggregator::processPreAggregated() {
                      TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
 
   uint64_t NumTraces = 0;
-  for (const auto &[From, To, Count, Mispreds, Type]: AggregatedLBRs) {
+  for (const auto &[From, To, Count, Mispreds, Type] : AggregatedLBRs) {
     bool IsExternalOrigin = Type == AggregatedLBREntry::FT_EXTERNAL_ORIGIN;
     switch (Type) {
     case AggregatedLBREntry::BRANCH:

>From 9c4effa15a5bfa7a8c03aad25421a462bb56ffaf Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Sat, 21 Sep 2024 19:08:41 -0700
Subject: [PATCH 4/7] Drop changes in doTrace/getFallthroughsInTrace

Created using spr 1.3.4
---
 bolt/include/bolt/Profile/DataAggregator.h |   9 +-
 bolt/lib/Profile/DataAggregator.cpp        | 108 ++++++++++++++-------
 2 files changed, 77 insertions(+), 40 deletions(-)

diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index 1e7695baab62cc..6453b3070ceb8d 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -202,8 +202,8 @@ class DataAggregator : public DataReader {
   /// Return a vector of offsets corresponding to a trace in a function
   /// if the trace is valid, std::nullopt otherwise.
   std::optional<SmallVector<std::pair<uint64_t, uint64_t>, 16>>
-  getFallthroughsInTrace(BinaryFunction &BF, uint64_t From, uint64_t To,
-                         uint64_t Count = 1) const;
+  getFallthroughsInTrace(BinaryFunction &BF, const LBREntry &First,
+                         const LBREntry &Second, uint64_t Count = 1) const;
 
   /// Record external entry into the function \p BF.
   ///
@@ -268,8 +268,9 @@ class DataAggregator : public DataReader {
   /// Register a \p Branch.
   bool doBranch(uint64_t From, uint64_t To, uint64_t Count, uint64_t Mispreds);
 
-  /// Register a trace between two addresses.
-  bool doTrace(const uint64_t From, const uint64_t To, uint64_t Count = 1);
+  /// Register a trace between two LBR entries supplied in execution order.
+  bool doTrace(const LBREntry &First, const LBREntry &Second,
+               uint64_t Count = 1);
 
   /// Parser helpers
   /// Return false if we exhausted our parser buffer and finished parsing
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index dbd0ed07c7c1d9..72905d0ecf6a05 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -805,8 +805,11 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
 
   BinaryFunction *FromFunc = handleAddress(From, /*IsFrom=*/true);
   // Record returns as call->call continuation fall-through.
-  if (IsReturn)
-    return doTrace(To - 1, To, Count);
+  if (IsReturn) {
+    LBREntry First{To - 1, To - 1, false};
+    LBREntry Second{To, To, false};
+    return doTrace(First, Second, Count);
+  }
 
   BinaryFunction *ToFunc = handleAddress(To, /*IsFrom=*/false);
   if (!FromFunc && !ToFunc)
@@ -821,23 +824,24 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
   return doInterBranch(FromFunc, ToFunc, From, To, Count, Mispreds);
 }
 
-bool DataAggregator::doTrace(const uint64_t From, const uint64_t To,
+bool DataAggregator::doTrace(const LBREntry &First, const LBREntry &Second,
                              uint64_t Count) {
-  BinaryFunction *FromFunc = getBinaryFunctionContainingAddress(From);
-  BinaryFunction *ToFunc = getBinaryFunctionContainingAddress(To);
+  BinaryFunction *FromFunc = getBinaryFunctionContainingAddress(First.To);
+  BinaryFunction *ToFunc = getBinaryFunctionContainingAddress(Second.From);
   if (!FromFunc || !ToFunc) {
     LLVM_DEBUG({
       dbgs() << "Out of range trace starting in ";
       if (FromFunc)
         dbgs() << formatv("{0} @ {1:x}", *FromFunc,
-                          From - FromFunc->getAddress());
+                          First.To - FromFunc->getAddress());
       else
-        dbgs() << Twine::utohexstr(From);
+        dbgs() << Twine::utohexstr(First.To);
       dbgs() << " and ending in ";
       if (ToFunc)
-        dbgs() << formatv("{0} @ {1:x}", *ToFunc, To - ToFunc->getAddress());
+        dbgs() << formatv("{0} @ {1:x}", *ToFunc,
+                          Second.From - ToFunc->getAddress());
       else
-        dbgs() << Twine::utohexstr(To);
+        dbgs() << Twine::utohexstr(Second.From);
       dbgs() << '\n';
     });
     NumLongRangeTraces += Count;
@@ -847,30 +851,32 @@ bool DataAggregator::doTrace(const uint64_t From, const uint64_t To,
     NumInvalidTraces += Count;
     LLVM_DEBUG({
       dbgs() << "Invalid trace starting in " << FromFunc->getPrintName()
-             << formatv(" @ {0:x}", From - FromFunc->getAddress())
+             << formatv(" @ {0:x}", First.To - FromFunc->getAddress())
              << " and ending in " << ToFunc->getPrintName()
-             << formatv(" @ {0:x}\n", To - ToFunc->getAddress());
+             << formatv(" @ {0:x}\n", Second.From - ToFunc->getAddress());
     });
     return false;
   }
 
   std::optional<BoltAddressTranslation::FallthroughListTy> FTs =
-      BAT ? BAT->getFallthroughsInTrace(FromFunc->getAddress(), From, To)
-          : getFallthroughsInTrace(*FromFunc, From, To, Count);
+      BAT ? BAT->getFallthroughsInTrace(FromFunc->getAddress(), First.To,
+                                        Second.From)
+          : getFallthroughsInTrace(*FromFunc, First, Second, Count);
   if (!FTs) {
-    LLVM_DEBUG(dbgs() << "Invalid trace starting in "
-                      << FromFunc->getPrintName() << " @ "
-                      << Twine::utohexstr(From - FromFunc->getAddress())
-                      << " and ending in " << ToFunc->getPrintName() << " @ "
-                      << ToFunc->getPrintName() << " @ "
-                      << Twine::utohexstr(To - ToFunc->getAddress()) << '\n');
+    LLVM_DEBUG(
+        dbgs() << "Invalid trace starting in " << FromFunc->getPrintName()
+               << " @ " << Twine::utohexstr(First.To - FromFunc->getAddress())
+               << " and ending in " << ToFunc->getPrintName() << " @ "
+               << ToFunc->getPrintName() << " @ "
+               << Twine::utohexstr(Second.From - ToFunc->getAddress()) << '\n');
     NumInvalidTraces += Count;
     return false;
   }
 
   LLVM_DEBUG(dbgs() << "Processing " << FTs->size() << " fallthroughs for "
-                    << FromFunc->getPrintName() << ":" << Twine::utohexstr(From)
-                    << " to " << Twine::utohexstr(To) << ".\n");
+                    << FromFunc->getPrintName() << ":"
+                    << Twine::utohexstr(First.To) << " to "
+                    << Twine::utohexstr(Second.From) << ".\n");
   BinaryFunction *ParentFunc = getBATParentFunction(*FromFunc);
   for (auto [From, To] : *FTs) {
     if (BAT) {
@@ -884,8 +890,10 @@ bool DataAggregator::doTrace(const uint64_t From, const uint64_t To,
 }
 
 std::optional<SmallVector<std::pair<uint64_t, uint64_t>, 16>>
-DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, uint64_t From,
-                                       uint64_t To, uint64_t Count) const {
+DataAggregator::getFallthroughsInTrace(BinaryFunction &BF,
+                                       const LBREntry &FirstLBR,
+                                       const LBREntry &SecondLBR,
+                                       uint64_t Count) const {
   SmallVector<std::pair<uint64_t, uint64_t>, 16> Branches;
 
   BinaryContext &BC = BF.getBinaryContext();
@@ -896,8 +904,8 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, uint64_t From,
   assert(BF.hasCFG() && "can only record traces in CFG state");
 
   // Offsets of the trace within this function.
-  From = From - BF.getAddress();
-  To = To - BF.getAddress();
+  const uint64_t From = FirstLBR.To - BF.getAddress();
+  const uint64_t To = SecondLBR.From - BF.getAddress();
 
   if (From > To)
     return std::nullopt;
@@ -908,6 +916,24 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, uint64_t From,
   if (!FromBB || !ToBB)
     return std::nullopt;
 
+  // Adjust FromBB if the first LBR is a return from the last instruction in
+  // the previous block (that instruction should be a call).
+  if (From == FromBB->getOffset() && !BF.containsAddress(FirstLBR.From) &&
+      !FromBB->isEntryPoint() && !FromBB->isLandingPad()) {
+    const BinaryBasicBlock *PrevBB =
+        BF.getLayout().getBlock(FromBB->getIndex() - 1);
+    if (PrevBB->getSuccessor(FromBB->getLabel())) {
+      const MCInst *Instr = PrevBB->getLastNonPseudoInstr();
+      if (Instr && BC.MIB->isCall(*Instr))
+        FromBB = PrevBB;
+      else
+        LLVM_DEBUG(dbgs() << "invalid incoming LBR (no call): " << FirstLBR
+                          << '\n');
+    } else {
+      LLVM_DEBUG(dbgs() << "invalid incoming LBR: " << FirstLBR << '\n');
+    }
+  }
+
   // Fill out information for fall-through edges. The From and To could be
   // within the same basic block, e.g. when two call instructions are in the
   // same block. In this case we skip the processing.
@@ -924,8 +950,8 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, uint64_t From,
     // Check for bad LBRs.
     if (!BB->getSuccessor(NextBB->getLabel())) {
       LLVM_DEBUG(dbgs() << "no fall-through for the trace:\n"
-                        << "  " << From << '\n'
-                        << "  " << To << '\n');
+                        << "  " << FirstLBR << '\n'
+                        << "  " << SecondLBR << '\n');
       return std::nullopt;
     }
 
@@ -1582,11 +1608,16 @@ void DataAggregator::processBranchEvents() {
   NamedRegionTimer T("processBranch", "Processing branch events",
                      TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
 
-  for (const auto &[Loc, Info] : FallthroughLBRs) {
+  for (const auto &AggrLBR : FallthroughLBRs) {
+    const Trace &Loc = AggrLBR.first;
+    const FTInfo &Info = AggrLBR.second;
+    LBREntry First{Loc.From, Loc.From, false};
+    LBREntry Second{Loc.To, Loc.To, false};
     if (Info.InternCount)
-      doTrace(Loc.From, Loc.To, Info.InternCount);
+      doTrace(First, Second, Info.InternCount);
     if (Info.ExternCount) {
-      doTrace(0, Loc.To, Info.ExternCount);
+      First.From = 0;
+      doTrace(First, Second, Info.ExternCount);
     }
   }
 
@@ -1750,16 +1781,21 @@ void DataAggregator::processPreAggregated() {
                      TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
 
   uint64_t NumTraces = 0;
-  for (const auto &[From, To, Count, Mispreds, Type] : AggregatedLBRs) {
-    bool IsExternalOrigin = Type == AggregatedLBREntry::FT_EXTERNAL_ORIGIN;
-    switch (Type) {
+  for (const AggregatedLBREntry &AggrEntry : AggregatedLBRs) {
+    switch (AggrEntry.EntryType) {
     case AggregatedLBREntry::BRANCH:
-      doBranch(From.Offset, To.Offset, Count, Mispreds);
+      doBranch(AggrEntry.From.Offset, AggrEntry.To.Offset, AggrEntry.Count,
+               AggrEntry.Mispreds);
       break;
     case AggregatedLBREntry::FT:
     case AggregatedLBREntry::FT_EXTERNAL_ORIGIN: {
-      doTrace(IsExternalOrigin ? 0 : From.Offset, To.Offset, Count);
-      NumTraces += Count;
+      LBREntry First{AggrEntry.EntryType == AggregatedLBREntry::FT
+                         ? AggrEntry.From.Offset
+                         : 0,
+                     AggrEntry.From.Offset, false};
+      LBREntry Second{AggrEntry.To.Offset, AggrEntry.To.Offset, false};
+      doTrace(First, Second, AggrEntry.Count);
+      NumTraces += AggrEntry.Count;
       break;
     }
     }

>From 9e4dd66c4669fd1a374d35b7522fde864e9b2efb Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Tue, 1 Oct 2024 17:19:07 -0700
Subject: [PATCH 5/7] Handle external origin LBR (non-BAT mode)

Created using spr 1.3.4
---
 bolt/lib/Profile/DataAggregator.cpp           | 122 ++-
 bolt/test/X86/Inputs/callcont-fallthru.preagg |  21 -
 bolt/test/X86/Inputs/callcont-fallthru.yaml   | 889 ------------------
 bolt/test/X86/callcont-fallthru.s             |  60 ++
 bolt/test/X86/callcont-fallthru.test          |   9 -
 5 files changed, 132 insertions(+), 969 deletions(-)
 delete mode 100644 bolt/test/X86/Inputs/callcont-fallthru.preagg
 delete mode 100644 bolt/test/X86/Inputs/callcont-fallthru.yaml
 create mode 100644 bolt/test/X86/callcont-fallthru.s
 delete mode 100644 bolt/test/X86/callcont-fallthru.test

diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index 72905d0ecf6a05..fe371ef3ca1050 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -775,46 +775,86 @@ bool DataAggregator::doInterBranch(BinaryFunction *FromFunc,
 
 bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
                               uint64_t Mispreds) {
-  bool IsReturn = false;
-  auto handleAddress = [&](uint64_t &Addr, bool IsFrom) -> BinaryFunction * {
-    if (BinaryFunction *Func = getBinaryFunctionContainingAddress(Addr)) {
-      Addr -= Func->getAddress();
-      if (IsFrom) {
-        auto checkReturn = [&](auto MaybeInst) {
-          IsReturn = MaybeInst && BC->MIB->isReturn(*MaybeInst);
-        };
-        if (Func->hasInstructions())
-          checkReturn(Func->getInstructionAtOffset(Addr));
-        else
-          checkReturn(Func->disassembleInstructionAtOffset(Addr));
-      }
+  // Returns whether \p Offset in \p Func contains a return instruction.
+  auto checkReturn = [&](const BinaryFunction &Func, const uint64_t Offset) {
+    auto isReturn = [&](auto MI) { return MI && BC->MIB->isReturn(*MI); };
+    return Func.hasInstructions()
+               ? isReturn(Func.getInstructionAtOffset(Offset))
+               : isReturn(Func.disassembleInstructionAtOffset(Offset));
+  };
 
-      if (BAT)
-        Addr = BAT->translate(Func->getAddress(), Addr, IsFrom);
+  // Returns whether \p Offset in \p Func corresponds to a call continuation
+  // fallthrough block.
+  auto checkCallCont = [&](BinaryFunction &Func, const uint64_t Offset) {
+    // Note the use of MCInstrAnalysis: no call continuation for a tail call.
+    auto isCall = [&](auto MI) { return MI && BC->MIA->isCall(*MI); };
+
+    // No call continuation at a function start.
+    if (!Offset)
+      return false;
+
+    // FIXME: support BAT case where the function might be in empty state
+    // (split fragments declared non-simple).
+    if (!Func.hasCFG())
+      return false;
+
+    // The offset should not be an entry point or a landing pad.
+    const BinaryBasicBlock *ContBB = Func.getBasicBlockAtOffset(Offset);
+    if (!ContBB || ContBB->isEntryPoint() || ContBB->isLandingPad())
+      return false;
+
+    // Check that preceding instruction is a call.
+    const BinaryBasicBlock *CallBB =
+        Func.getBasicBlockContainingOffset(Offset - 1);
+    if (!CallBB || CallBB == ContBB)
+      return false;
+    return isCall(CallBB->getLastNonPseudoInstr());
+  };
 
-      if (BinaryFunction *ParentFunc = getBATParentFunction(*Func)) {
-        Func = ParentFunc;
-        if (IsFrom)
-          NumColdSamples += Count;
-      }
+  // Mutates \p Addr to an offset into the containing function, performing BAT
+  // offset translation and parent lookup.
+  //
+  // Returns the containing function (or BAT parent) and whether the address
+  // corresponds to a return (if \p IsFrom) or a call continuation (otherwise).
+  auto handleAddress = [&](uint64_t &Addr, bool IsFrom) {
+    BinaryFunction *Func = getBinaryFunctionContainingAddress(Addr);
+    if (!Func)
+      return std::pair{Func, false};
 
-      return Func;
-    }
-    return nullptr;
-  };
+    Addr -= Func->getAddress();
 
-  BinaryFunction *FromFunc = handleAddress(From, /*IsFrom=*/true);
-  // Record returns as call->call continuation fall-through.
-  if (IsReturn) {
-    LBREntry First{To - 1, To - 1, false};
-    LBREntry Second{To, To, false};
-    return doTrace(First, Second, Count);
-  }
+    bool IsRetOrCallCont =
+        IsFrom ? checkReturn(*Func, Addr) : checkCallCont(*Func, Addr);
+
+    if (BAT)
+      Addr = BAT->translate(Func->getAddress(), Addr, IsFrom);
+
+    BinaryFunction *ParentFunc = getBATParentFunction(*Func);
+    if (!ParentFunc)
+      return std::pair{Func, IsRetOrCallCont};
 
-  BinaryFunction *ToFunc = handleAddress(To, /*IsFrom=*/false);
+    if (IsFrom)
+      NumColdSamples += Count;
+
+    return std::pair{ParentFunc, IsRetOrCallCont};
+  };
+
+  uint64_t ToOrig = To;
+  auto [FromFunc, IsReturn] = handleAddress(From, /*IsFrom=*/true);
+  auto [ToFunc, IsCallCont] = handleAddress(To, /*IsFrom=*/false);
   if (!FromFunc && !ToFunc)
     return false;
 
+  // Record call to continuation trace.
+  if (IsCallCont && FromFunc != ToFunc) {
+    LBREntry First{ToOrig - 1, ToOrig - 1, false};
+    LBREntry Second{ToOrig, ToOrig, false};
+    return doTrace(First, Second, Count);
+  }
+  // Ignore returns.
+  if (IsReturn)
+    return true;
+
   // Treat recursive control transfers as inter-branches.
   if (FromFunc == ToFunc && To != 0) {
     recordBranch(*FromFunc, From, To, Count, Mispreds);
@@ -916,24 +956,6 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF,
   if (!FromBB || !ToBB)
     return std::nullopt;
 
-  // Adjust FromBB if the first LBR is a return from the last instruction in
-  // the previous block (that instruction should be a call).
-  if (From == FromBB->getOffset() && !BF.containsAddress(FirstLBR.From) &&
-      !FromBB->isEntryPoint() && !FromBB->isLandingPad()) {
-    const BinaryBasicBlock *PrevBB =
-        BF.getLayout().getBlock(FromBB->getIndex() - 1);
-    if (PrevBB->getSuccessor(FromBB->getLabel())) {
-      const MCInst *Instr = PrevBB->getLastNonPseudoInstr();
-      if (Instr && BC.MIB->isCall(*Instr))
-        FromBB = PrevBB;
-      else
-        LLVM_DEBUG(dbgs() << "invalid incoming LBR (no call): " << FirstLBR
-                          << '\n');
-    } else {
-      LLVM_DEBUG(dbgs() << "invalid incoming LBR: " << FirstLBR << '\n');
-    }
-  }
-
   // Fill out information for fall-through edges. The From and To could be
   // within the same basic block, e.g. when two call instructions are in the
   // same block. In this case we skip the processing.
diff --git a/bolt/test/X86/Inputs/callcont-fallthru.preagg b/bolt/test/X86/Inputs/callcont-fallthru.preagg
deleted file mode 100644
index 0b5f344540573a..00000000000000
--- a/bolt/test/X86/Inputs/callcont-fallthru.preagg
+++ /dev/null
@@ -1,21 +0,0 @@
-B ffffffff81e01006 401194 8 0
-B 401180 401199 98482 96
-B 401199 401166 99542 0
-B 401177 401130 102776 0
-B 401135 40117c 103204 0
-B 401186 40118b 1022983 0
-B 401194 40117c 1021645 1
-F 40117c 401135 1161
-F 40117c 401180 92267
-F 40118b 401194 991002
-F 40117c 401186 968072
-F 40118b 401186 11468
-F 401130 401135 100015
-F 401166 401177 96992
-F 401199 401199 96168
-F 40117c ffffffff81e01006 7
-F 401199 401180 1140
-F 401194 ffffffff81e01006 1
-F 40117c 401194 11522
-F 401166 401199 1151
-F 401130 401177 1154
diff --git a/bolt/test/X86/Inputs/callcont-fallthru.yaml b/bolt/test/X86/Inputs/callcont-fallthru.yaml
deleted file mode 100644
index a1f8417d1e217d..00000000000000
--- a/bolt/test/X86/Inputs/callcont-fallthru.yaml
+++ /dev/null
@@ -1,889 +0,0 @@
---- !ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_EXEC
-  Machine:         EM_X86_64
-  Entry:           0x401040
-ProgramHeaders:
-  - Type:            PT_PHDR
-    Flags:           [ PF_R ]
-    VAddr:           0x400040
-    Align:           0x8
-  - Type:            PT_INTERP
-    Flags:           [ PF_R ]
-    FirstSec:        .interp
-    LastSec:         .interp
-    VAddr:           0x400318
-  - Type:            PT_LOAD
-    Flags:           [ PF_R ]
-    FirstSec:        .interp
-    LastSec:         .rela.plt
-    VAddr:           0x400000
-    Align:           0x1000
-  - Type:            PT_LOAD
-    Flags:           [ PF_X, PF_R ]
-    FirstSec:        .init
-    LastSec:         .fini
-    VAddr:           0x401000
-    Align:           0x1000
-  - Type:            PT_LOAD
-    Flags:           [ PF_R ]
-    FirstSec:        .rodata
-    LastSec:         .eh_frame
-    VAddr:           0x402000
-    Align:           0x1000
-  - Type:            PT_LOAD
-    Flags:           [ PF_W, PF_R ]
-    FirstSec:        .init_array
-    LastSec:         .bss
-    VAddr:           0x403DE8
-    Align:           0x1000
-  - Type:            PT_DYNAMIC
-    Flags:           [ PF_W, PF_R ]
-    FirstSec:        .dynamic
-    LastSec:         .dynamic
-    VAddr:           0x403DF8
-    Align:           0x8
-  - Type:            PT_NOTE
-    Flags:           [ PF_R ]
-    FirstSec:        .note.gnu.property
-    LastSec:         .note.gnu.property
-    VAddr:           0x400338
-    Align:           0x8
-  - Type:            PT_NOTE
-    Flags:           [ PF_R ]
-    FirstSec:        .note.gnu.build-id
-    LastSec:         .note.ABI-tag
-    VAddr:           0x400358
-    Align:           0x4
-  - Type:            PT_GNU_PROPERTY
-    Flags:           [ PF_R ]
-    FirstSec:        .note.gnu.property
-    LastSec:         .note.gnu.property
-    VAddr:           0x400338
-    Align:           0x8
-  - Type:            PT_GNU_EH_FRAME
-    Flags:           [ PF_R ]
-    FirstSec:        .eh_frame_hdr
-    LastSec:         .eh_frame_hdr
-    VAddr:           0x402010
-    Align:           0x4
-  - Type:            PT_GNU_STACK
-    Flags:           [ PF_W, PF_R ]
-    Align:           0x10
-  - Type:            PT_GNU_RELRO
-    Flags:           [ PF_R ]
-    FirstSec:        .init_array
-    LastSec:         .got
-    VAddr:           0x403DE8
-Sections:
-  - Name:            .interp
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x400318
-    AddressAlign:    0x1
-    Content:         2F6C696236342F6C642D6C696E75782D7838362D36342E736F2E3200
-  - Name:            .note.gnu.property
-    Type:            SHT_NOTE
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x400338
-    AddressAlign:    0x8
-    Notes:
-      - Name:            GNU
-        Desc:            028000C0040000000300000000000000
-        Type:            NT_GNU_PROPERTY_TYPE_0
-  - Name:            .note.gnu.build-id
-    Type:            SHT_NOTE
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x400358
-    AddressAlign:    0x4
-    Notes:
-      - Name:            GNU
-        Desc:            A77EA471B9AAA21E180E5FD02A0A0B2E4AB643E9
-        Type:            NT_PRPSINFO
-  - Name:            .note.ABI-tag
-    Type:            SHT_NOTE
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x40037C
-    AddressAlign:    0x4
-    Notes:
-      - Name:            GNU
-        Desc:            '00000000030000000200000000000000'
-        Type:            NT_VERSION
-  - Name:            .gnu.hash
-    Type:            SHT_GNU_HASH
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x4003A0
-    Link:            .dynsym
-    AddressAlign:    0x8
-    Header:
-      SymNdx:          0x1
-      Shift2:          0x0
-    BloomFilter:     [ 0x0 ]
-    HashBuckets:     [ 0x0 ]
-    HashValues:      [  ]
-  - Name:            .dynsym
-    Type:            SHT_DYNSYM
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x4003C0
-    Link:            .dynstr
-    AddressAlign:    0x8
-  - Name:            .dynstr
-    Type:            SHT_STRTAB
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x400450
-    AddressAlign:    0x1
-  - Name:            .gnu.version
-    Type:            SHT_GNU_versym
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x4004CE
-    Link:            .dynsym
-    AddressAlign:    0x2
-    Entries:         [ 0, 2, 1, 1, 3, 1 ]
-  - Name:            .gnu.version_r
-    Type:            SHT_GNU_verneed
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x4004E0
-    Link:            .dynstr
-    AddressAlign:    0x8
-    Dependencies:
-      - Version:         1
-        File:            libc.so.6
-        Entries:
-          - Name:            GLIBC_2.2.5
-            Hash:            157882997
-            Flags:           0
-            Other:           3
-          - Name:            GLIBC_2.34
-            Hash:            110530996
-            Flags:           0
-            Other:           2
-  - Name:            .rela.dyn
-    Type:            SHT_RELA
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x400510
-    Link:            .dynsym
-    AddressAlign:    0x8
-    Relocations:
-      - Offset:          0x403FC8
-        Symbol:          __libc_start_main
-        Type:            R_X86_64_GLOB_DAT
-      - Offset:          0x403FD0
-        Symbol:          _ITM_deregisterTMCloneTable
-        Type:            R_X86_64_GLOB_DAT
-      - Offset:          0x403FD8
-        Symbol:          __gmon_start__
-        Type:            R_X86_64_GLOB_DAT
-      - Offset:          0x403FE0
-        Symbol:          _ITM_registerTMCloneTable
-        Type:            R_X86_64_GLOB_DAT
-  - Name:            .rela.plt
-    Type:            SHT_RELA
-    Flags:           [ SHF_ALLOC, SHF_INFO_LINK ]
-    Address:         0x400570
-    Link:            .dynsym
-    AddressAlign:    0x8
-    Info:            .got.plt
-    Relocations:
-      - Offset:          0x404000
-        Symbol:          atoi
-        Type:            R_X86_64_JUMP_SLOT
-  - Name:            .init
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
-    Address:         0x401000
-    AddressAlign:    0x4
-    Offset:          0x1000
-    Content:         F30F1EFA4883EC08488B05C92F00004885C07402FFD04883C408C3
-  - Name:            .plt
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
-    Address:         0x401020
-    AddressAlign:    0x10
-    EntSize:         0x10
-    Content:         FF35CA2F0000FF25CC2F00000F1F4000FF25CA2F00006800000000E9E0FFFFFF
-  - Name:            .text
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
-    Address:         0x401040
-    AddressAlign:    0x10
-    Content:         F30F1EFA31ED4989D15E4889E24883E4F050544531C031C948C7C740114000FF15632F0000F4662E0F1F840000000000F30F1EFAC3662E0F1F84000000000090488D3D892F0000488D05822F00004839F87415488B05362F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D592F0000488D35522F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05052F00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D152F0000007513554889E5E87AFFFFFFC605032F0000015DC390C366662E0F1F8400000000000F1F4000F30F1EFAEB8A662E0F1F840000000000554889E55DC3662E0F1F840000000000554889E54883EC20C745FC00000000897DF8488975F0488B45F0488B7808E8CDFEFFFF8945EC837DEC000F842E000000C745E80A000000E8B4FFFFFF837DE8000F8413000000E9000000008B45E883C0FF8945E8E9E3FFFFFFE9C8FFFFFF31C04883C4205DC3
-  - Name:            .fini
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
-    Address:         0x4011A8
-    AddressAlign:    0x4
-    Content:         F30F1EFA4883EC084883C408C3
-  - Name:            .rodata
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x402000
-    AddressAlign:    0x8
-    Offset:          0x2000
-    Content:         '01000200000000000000000000000000'
-  - Name:            .eh_frame_hdr
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x402010
-    AddressAlign:    0x4
-    Content:         011B033B340000000500000010F0FFFF7800000030F0FFFF5000000060F0FFFF6400000020F1FFFFA000000030F1FFFFC0000000
-  - Name:            .eh_frame
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x402048
-    AddressAlign:    0x8
-    Content:         1400000000000000017A5200017810011B0C070890010000100000001C000000D8EFFFFF26000000004407101000000030000000F4EFFFFF0500000000000000240000004400000090EFFFFF20000000000E10460E184A0F0B770880003F1A3B2A332422000000001C0000006C00000078F0FFFF0600000000410E108602430D06410C07080000001C0000008C00000068F0FFFF6600000000410E108602430D0602610C0708000000000000
-  - Name:            .init_array
-    Type:            SHT_INIT_ARRAY
-    Flags:           [ SHF_WRITE, SHF_ALLOC ]
-    Address:         0x403DE8
-    AddressAlign:    0x8
-    EntSize:         0x8
-    Offset:          0x2DE8
-    Content:         '2011400000000000'
-  - Name:            .fini_array
-    Type:            SHT_FINI_ARRAY
-    Flags:           [ SHF_WRITE, SHF_ALLOC ]
-    Address:         0x403DF0
-    AddressAlign:    0x8
-    EntSize:         0x8
-    Content:         F010400000000000
-  - Name:            .dynamic
-    Type:            SHT_DYNAMIC
-    Flags:           [ SHF_WRITE, SHF_ALLOC ]
-    Address:         0x403DF8
-    Link:            .dynstr
-    AddressAlign:    0x8
-    Entries:
-      - Tag:             DT_NEEDED
-        Value:           0x18
-      - Tag:             DT_INIT
-        Value:           0x401000
-      - Tag:             DT_FINI
-        Value:           0x4011A8
-      - Tag:             DT_INIT_ARRAY
-        Value:           0x403DE8
-      - Tag:             DT_INIT_ARRAYSZ
-        Value:           0x8
-      - Tag:             DT_FINI_ARRAY
-        Value:           0x403DF0
-      - Tag:             DT_FINI_ARRAYSZ
-        Value:           0x8
-      - Tag:             DT_GNU_HASH
-        Value:           0x4003A0
-      - Tag:             DT_STRTAB
-        Value:           0x400450
-      - Tag:             DT_SYMTAB
-        Value:           0x4003C0
-      - Tag:             DT_STRSZ
-        Value:           0x7E
-      - Tag:             DT_SYMENT
-        Value:           0x18
-      - Tag:             DT_DEBUG
-        Value:           0x0
-      - Tag:             DT_PLTGOT
-        Value:           0x403FE8
-      - Tag:             DT_PLTRELSZ
-        Value:           0x18
-      - Tag:             DT_PLTREL
-        Value:           0x7
-      - Tag:             DT_JMPREL
-        Value:           0x400570
-      - Tag:             DT_RELA
-        Value:           0x400510
-      - Tag:             DT_RELASZ
-        Value:           0x60
-      - Tag:             DT_RELAENT
-        Value:           0x18
-      - Tag:             DT_VERNEED
-        Value:           0x4004E0
-      - Tag:             DT_VERNEEDNUM
-        Value:           0x1
-      - Tag:             DT_VERSYM
-        Value:           0x4004CE
-      - Tag:             DT_NULL
-        Value:           0x0
-      - Tag:             DT_NULL
-        Value:           0x0
-      - Tag:             DT_NULL
-        Value:           0x0
-      - Tag:             DT_NULL
-        Value:           0x0
-      - Tag:             DT_NULL
-        Value:           0x0
-      - Tag:             DT_NULL
-        Value:           0x0
-  - Name:            .got
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_WRITE, SHF_ALLOC ]
-    Address:         0x403FC8
-    AddressAlign:    0x8
-    EntSize:         0x8
-    Content:         '0000000000000000000000000000000000000000000000000000000000000000'
-  - Name:            .got.plt
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_WRITE, SHF_ALLOC ]
-    Address:         0x403FE8
-    AddressAlign:    0x8
-    EntSize:         0x8
-    Content:         F83D400000000000000000000000000000000000000000003610400000000000
-  - Name:            .data
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_WRITE, SHF_ALLOC ]
-    Address:         0x404008
-    AddressAlign:    0x1
-    Content:         '00000000'
-  - Name:            .tm_clone_table
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_WRITE, SHF_ALLOC ]
-    Address:         0x404010
-    AddressAlign:    0x8
-  - Name:            .bss
-    Type:            SHT_NOBITS
-    Flags:           [ SHF_WRITE, SHF_ALLOC ]
-    Address:         0x404010
-    AddressAlign:    0x1
-    Size:            0x8
-  - Name:            .comment
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_MERGE, SHF_STRINGS ]
-    AddressAlign:    0x1
-    EntSize:         0x1
-    Content:         4743433A2028474E55292031312E352E302032303234303731392028526564204861742031312E352E302D3229004743433A2028474E55292031332E332E312032303234303631312028526564204861742031332E332E312D322900636C616E672076657273696F6E2031382E312E38202843656E744F532031382E312E382D332E656C392900
-  - Name:            .gnu.build.attributes
-    Type:            SHT_NOTE
-    Address:         0x406018
-    AddressAlign:    0x4
-    Notes:
-      - Name:            "GA$\x013a1"
-        Desc:            '40104000000000006610400000000000'
-        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
-      - Name:            "GA$\x013a1"
-        Desc:            '75104000000000007510400000000000'
-        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
-      - Name:            "GA$\x013a1"
-        Desc:            '00104000000000001610400000000000'
-        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
-      - Name:            "GA$\x013a1"
-        Desc:            A811400000000000B011400000000000
-        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
-      - Name:            "GA$\x013a1"
-        Desc:            '80104000000000002611400000000000'
-        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
-      - Name:            "GA$\x013a1"
-        Desc:            A611400000000000A611400000000000
-        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
-      - Name:            "GA$\x013a1"
-        Desc:            A611400000000000A611400000000000
-        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
-      - Name:            "GA$\x013a1"
-        Desc:            16104000000000001B10400000000000
-        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
-      - Name:            "GA$\x013a1"
-        Desc:            B011400000000000B511400000000000
-        Type:            NT_GNU_BUILD_ATTRIBUTE_OPEN
-  - Name:            .rela.init
-    Type:            SHT_RELA
-    Flags:           [ SHF_INFO_LINK ]
-    Link:            .symtab
-    AddressAlign:    0x8
-    Info:            .init
-    Relocations:
-      - Offset:          0x40100B
-        Symbol:          __gmon_start__
-        Type:            R_X86_64_REX_GOTPCRELX
-        Addend:          -4
-  - Name:            .rela.text
-    Type:            SHT_RELA
-    Flags:           [ SHF_INFO_LINK ]
-    Link:            .symtab
-    AddressAlign:    0x8
-    Info:            .text
-    Relocations:
-      - Offset:          0x40105B
-        Symbol:          main
-        Type:            R_X86_64_32S
-      - Offset:          0x401061
-        Symbol:          '__libc_start_main at GLIBC_2.34'
-        Type:            R_X86_64_GOTPCRELX
-        Addend:          -4
-      - Offset:          0x401083
-        Symbol:          .tm_clone_table
-        Type:            R_X86_64_PC32
-        Addend:          -4
-      - Offset:          0x40108A
-        Symbol:          __TMC_END__
-        Type:            R_X86_64_PC32
-        Addend:          -4
-      - Offset:          0x401096
-        Symbol:          _ITM_deregisterTMCloneTable
-        Type:            R_X86_64_REX_GOTPCRELX
-        Addend:          -4
-      - Offset:          0x4010B3
-        Symbol:          .tm_clone_table
-        Type:            R_X86_64_PC32
-        Addend:          -4
-      - Offset:          0x4010BA
-        Symbol:          __TMC_END__
-        Type:            R_X86_64_PC32
-        Addend:          -4
-      - Offset:          0x4010D7
-        Symbol:          _ITM_registerTMCloneTable
-        Type:            R_X86_64_REX_GOTPCRELX
-        Addend:          -4
-      - Offset:          0x4010F6
-        Symbol:          .bss
-        Type:            R_X86_64_PC32
-        Addend:          -5
-      - Offset:          0x401108
-        Symbol:          .bss
-        Type:            R_X86_64_PC32
-        Addend:          -5
-      - Offset:          0x40115F
-        Symbol:          'atoi at GLIBC_2.2.5'
-        Type:            R_X86_64_PLT32
-        Addend:          -4
-      - Offset:          0x401178
-        Symbol:          foo
-        Type:            R_X86_64_PLT32
-        Addend:          -4
-  - Name:            .rela.eh_frame
-    Type:            SHT_RELA
-    Flags:           [ SHF_INFO_LINK ]
-    Link:            .symtab
-    AddressAlign:    0x8
-    Info:            .eh_frame
-    Relocations:
-      - Offset:          0x402068
-        Symbol:          .text
-        Type:            R_X86_64_PC32
-      - Offset:          0x40207C
-        Symbol:          .text
-        Type:            R_X86_64_PC32
-        Addend:          48
-      - Offset:          0x4020B8
-        Symbol:          .text
-        Type:            R_X86_64_PC32
-        Addend:          240
-      - Offset:          0x4020D8
-        Symbol:          .text
-        Type:            R_X86_64_PC32
-        Addend:          256
-  - Name:            .rela.init_array
-    Type:            SHT_RELA
-    Flags:           [ SHF_INFO_LINK ]
-    Link:            .symtab
-    AddressAlign:    0x8
-    Info:            .init_array
-    Relocations:
-      - Offset:          0x403DE8
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          224
-  - Name:            .rela.fini_array
-    Type:            SHT_RELA
-    Flags:           [ SHF_INFO_LINK ]
-    Link:            .symtab
-    AddressAlign:    0x8
-    Info:            .fini_array
-    Relocations:
-      - Offset:          0x403DF0
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          176
-  - Name:            .rela.gnu.build.attributes
-    Type:            SHT_RELA
-    Flags:           [ SHF_INFO_LINK ]
-    Link:            .symtab
-    AddressAlign:    0x8
-    Info:            .gnu.build.attributes
-    Relocations:
-      - Offset:          0x40602C
-        Symbol:          .text
-        Type:            R_X86_64_64
-      - Offset:          0x406034
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          38
-      - Offset:          0x406050
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          53
-      - Offset:          0x406058
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          53
-      - Offset:          0x406074
-        Symbol:          .init
-        Type:            R_X86_64_64
-      - Offset:          0x40607C
-        Symbol:          .init
-        Type:            R_X86_64_64
-        Addend:          22
-      - Offset:          0x406098
-        Symbol:          .fini
-        Type:            R_X86_64_64
-      - Offset:          0x4060A0
-        Symbol:          .fini
-        Type:            R_X86_64_64
-        Addend:          8
-      - Offset:          0x4060BC
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          64
-      - Offset:          0x4060C4
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          230
-      - Offset:          0x4060E0
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          358
-      - Offset:          0x4060E8
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          358
-      - Offset:          0x406104
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          358
-      - Offset:          0x40610C
-        Symbol:          .text
-        Type:            R_X86_64_64
-        Addend:          358
-      - Offset:          0x406128
-        Symbol:          .init
-        Type:            R_X86_64_64
-        Addend:          22
-      - Offset:          0x406130
-        Symbol:          .init
-        Type:            R_X86_64_64
-        Addend:          27
-      - Offset:          0x40614C
-        Symbol:          .fini
-        Type:            R_X86_64_64
-        Addend:          8
-      - Offset:          0x406154
-        Symbol:          .fini
-        Type:            R_X86_64_64
-        Addend:          13
-  - Type:            SectionHeaderTable
-    Sections:
-      - Name:            .interp
-      - Name:            .note.gnu.property
-      - Name:            .note.gnu.build-id
-      - Name:            .note.ABI-tag
-      - Name:            .gnu.hash
-      - Name:            .dynsym
-      - Name:            .dynstr
-      - Name:            .gnu.version
-      - Name:            .gnu.version_r
-      - Name:            .rela.dyn
-      - Name:            .rela.plt
-      - Name:            .init
-      - Name:            .rela.init
-      - Name:            .plt
-      - Name:            .text
-      - Name:            .rela.text
-      - Name:            .fini
-      - Name:            .rodata
-      - Name:            .eh_frame_hdr
-      - Name:            .eh_frame
-      - Name:            .rela.eh_frame
-      - Name:            .init_array
-      - Name:            .rela.init_array
-      - Name:            .fini_array
-      - Name:            .rela.fini_array
-      - Name:            .dynamic
-      - Name:            .got
-      - Name:            .got.plt
-      - Name:            .data
-      - Name:            .tm_clone_table
-      - Name:            .bss
-      - Name:            .comment
-      - Name:            .gnu.build.attributes
-      - Name:            .rela.gnu.build.attributes
-      - Name:            .symtab
-      - Name:            .strtab
-      - Name:            .shstrtab
-Symbols:
-  - Name:            .interp
-    Type:            STT_SECTION
-    Section:         .interp
-    Value:           0x400318
-  - Name:            .note.gnu.property
-    Type:            STT_SECTION
-    Section:         .note.gnu.property
-    Value:           0x400338
-  - Name:            .note.gnu.build-id
-    Type:            STT_SECTION
-    Section:         .note.gnu.build-id
-    Value:           0x400358
-  - Name:            .note.ABI-tag
-    Type:            STT_SECTION
-    Section:         .note.ABI-tag
-    Value:           0x40037C
-  - Name:            .gnu.hash
-    Type:            STT_SECTION
-    Section:         .gnu.hash
-    Value:           0x4003A0
-  - Name:            .dynsym
-    Type:            STT_SECTION
-    Section:         .dynsym
-    Value:           0x4003C0
-  - Name:            .dynstr
-    Type:            STT_SECTION
-    Section:         .dynstr
-    Value:           0x400450
-  - Name:            .gnu.version
-    Type:            STT_SECTION
-    Section:         .gnu.version
-    Value:           0x4004CE
-  - Name:            .gnu.version_r
-    Type:            STT_SECTION
-    Section:         .gnu.version_r
-    Value:           0x4004E0
-  - Name:            .rela.dyn
-    Type:            STT_SECTION
-    Section:         .rela.dyn
-    Value:           0x400510
-  - Name:            .rela.plt
-    Type:            STT_SECTION
-    Section:         .rela.plt
-    Value:           0x400570
-  - Name:            .init
-    Type:            STT_SECTION
-    Section:         .init
-    Value:           0x401000
-  - Name:            .plt
-    Type:            STT_SECTION
-    Section:         .plt
-    Value:           0x401020
-  - Name:            .text
-    Type:            STT_SECTION
-    Section:         .text
-    Value:           0x401040
-  - Name:            .fini
-    Type:            STT_SECTION
-    Section:         .fini
-    Value:           0x4011A8
-  - Name:            .rodata
-    Type:            STT_SECTION
-    Section:         .rodata
-    Value:           0x402000
-  - Name:            .eh_frame_hdr
-    Type:            STT_SECTION
-    Section:         .eh_frame_hdr
-    Value:           0x402010
-  - Name:            .eh_frame
-    Type:            STT_SECTION
-    Section:         .eh_frame
-    Value:           0x402048
-  - Name:            .init_array
-    Type:            STT_SECTION
-    Section:         .init_array
-    Value:           0x403DE8
-  - Name:            .fini_array
-    Type:            STT_SECTION
-    Section:         .fini_array
-    Value:           0x403DF0
-  - Name:            .dynamic
-    Type:            STT_SECTION
-    Section:         .dynamic
-    Value:           0x403DF8
-  - Name:            .got
-    Type:            STT_SECTION
-    Section:         .got
-    Value:           0x403FC8
-  - Name:            .got.plt
-    Type:            STT_SECTION
-    Section:         .got.plt
-    Value:           0x403FE8
-  - Name:            .data
-    Type:            STT_SECTION
-    Section:         .data
-    Value:           0x404008
-  - Name:            .tm_clone_table
-    Type:            STT_SECTION
-    Section:         .tm_clone_table
-    Value:           0x404010
-  - Name:            .bss
-    Type:            STT_SECTION
-    Section:         .bss
-    Value:           0x404010
-  - Name:            .comment
-    Type:            STT_SECTION
-    Section:         .comment
-  - Name:            .gnu.build.attributes
-    Type:            STT_SECTION
-    Section:         .gnu.build.attributes
-    Value:           0x406018
-  - Name:            crt1.o
-    Type:            STT_FILE
-    Index:           SHN_ABS
-  - Name:            __abi_tag
-    Type:            STT_OBJECT
-    Section:         .note.ABI-tag
-    Value:           0x40037C
-    Size:            0x20
-  - Name:            crtstuff.c
-    Type:            STT_FILE
-    Index:           SHN_ABS
-  - Name:            __TMC_LIST__
-    Type:            STT_OBJECT
-    Section:         .tm_clone_table
-    Value:           0x404010
-  - Name:            deregister_tm_clones
-    Type:            STT_FUNC
-    Section:         .text
-    Value:           0x401080
-  - Name:            register_tm_clones
-    Type:            STT_FUNC
-    Section:         .text
-    Value:           0x4010B0
-  - Name:            __do_global_dtors_aux
-    Type:            STT_FUNC
-    Section:         .text
-    Value:           0x4010F0
-  - Name:            completed.0
-    Type:            STT_OBJECT
-    Section:         .bss
-    Value:           0x404010
-    Size:            0x1
-  - Name:            __do_global_dtors_aux_fini_array_entry
-    Type:            STT_OBJECT
-    Section:         .fini_array
-    Value:           0x403DF0
-  - Name:            frame_dummy
-    Type:            STT_FUNC
-    Section:         .text
-    Value:           0x401120
-  - Name:            __frame_dummy_init_array_entry
-    Type:            STT_OBJECT
-    Section:         .init_array
-    Value:           0x403DE8
-  - Name:            callcont-fallthru.c
-    Type:            STT_FILE
-    Index:           SHN_ABS
-  - Name:            'crtstuff.c (1)'
-    Type:            STT_FILE
-    Index:           SHN_ABS
-  - Name:            __FRAME_END__
-    Type:            STT_OBJECT
-    Section:         .eh_frame
-    Value:           0x4020F0
-  - Type:            STT_FILE
-    Index:           SHN_ABS
-  - Name:            _DYNAMIC
-    Type:            STT_OBJECT
-    Section:         .dynamic
-    Value:           0x403DF8
-  - Name:            __GNU_EH_FRAME_HDR
-    Section:         .eh_frame_hdr
-    Value:           0x402010
-  - Name:            _GLOBAL_OFFSET_TABLE_
-    Type:            STT_OBJECT
-    Section:         .got.plt
-    Value:           0x403FE8
-  - Name:            '__libc_start_main at GLIBC_2.34'
-    Type:            STT_FUNC
-    Binding:         STB_GLOBAL
-  - Name:            _ITM_deregisterTMCloneTable
-    Binding:         STB_WEAK
-  - Name:            data_start
-    Section:         .data
-    Binding:         STB_WEAK
-    Value:           0x404008
-  - Name:            _edata
-    Section:         .tm_clone_table
-    Binding:         STB_GLOBAL
-    Value:           0x404010
-  - Name:            _fini
-    Type:            STT_FUNC
-    Section:         .fini
-    Binding:         STB_GLOBAL
-    Value:           0x4011A8
-    Other:           [ STV_HIDDEN ]
-  - Name:            __data_start
-    Section:         .data
-    Binding:         STB_GLOBAL
-    Value:           0x404008
-  - Name:            __gmon_start__
-    Binding:         STB_WEAK
-  - Name:            __dso_handle
-    Type:            STT_OBJECT
-    Section:         .rodata
-    Binding:         STB_GLOBAL
-    Value:           0x402008
-    Other:           [ STV_HIDDEN ]
-  - Name:            _IO_stdin_used
-    Type:            STT_OBJECT
-    Section:         .rodata
-    Binding:         STB_GLOBAL
-    Value:           0x402000
-    Size:            0x4
-  - Name:            foo
-    Type:            STT_FUNC
-    Section:         .text
-    Binding:         STB_GLOBAL
-    Value:           0x401130
-    Size:            0x6
-  - Name:            _end
-    Section:         .bss
-    Binding:         STB_GLOBAL
-    Value:           0x404018
-  - Name:            _dl_relocate_static_pie
-    Type:            STT_FUNC
-    Section:         .text
-    Binding:         STB_GLOBAL
-    Value:           0x401070
-    Size:            0x5
-    Other:           [ STV_HIDDEN ]
-  - Name:            _start
-    Type:            STT_FUNC
-    Section:         .text
-    Binding:         STB_GLOBAL
-    Value:           0x401040
-    Size:            0x26
-  - Name:            __bss_start
-    Section:         .bss
-    Binding:         STB_GLOBAL
-    Value:           0x404010
-  - Name:            main
-    Type:            STT_FUNC
-    Section:         .text
-    Binding:         STB_GLOBAL
-    Value:           0x401140
-    Size:            0x66
-  - Name:            'atoi at GLIBC_2.2.5'
-    Type:            STT_FUNC
-    Binding:         STB_GLOBAL
-  - Name:            __TMC_END__
-    Type:            STT_OBJECT
-    Section:         .tm_clone_table
-    Binding:         STB_GLOBAL
-    Value:           0x404010
-    Other:           [ STV_HIDDEN ]
-  - Name:            _ITM_registerTMCloneTable
-    Binding:         STB_WEAK
-  - Name:            _init
-    Type:            STT_FUNC
-    Section:         .init
-    Binding:         STB_GLOBAL
-    Value:           0x401000
-    Other:           [ STV_HIDDEN ]
-DynamicSymbols:
-  - Name:            __libc_start_main
-    Type:            STT_FUNC
-    Binding:         STB_GLOBAL
-  - Name:            _ITM_deregisterTMCloneTable
-    Binding:         STB_WEAK
-  - Name:            __gmon_start__
-    Binding:         STB_WEAK
-  - Name:            atoi
-    Type:            STT_FUNC
-    Binding:         STB_GLOBAL
-  - Name:            _ITM_registerTMCloneTable
-    Binding:         STB_WEAK
-...
diff --git a/bolt/test/X86/callcont-fallthru.s b/bolt/test/X86/callcont-fallthru.s
new file mode 100644
index 00000000000000..0a59d799f1ef3c
--- /dev/null
+++ b/bolt/test/X86/callcont-fallthru.s
@@ -0,0 +1,60 @@
+## Ensures that a call continuation fallthrough count is set when using
+## pre-aggregated perf data.
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
+# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib
+# RUN: link_fdata %s %t.exe %t.pa PREAGG
+# RUN: llvm-strip --strip-unneeded %t.exe
+# RUN: llvm-bolt %t.exe --pa -p %t.pa -o %t.out \
+# RUN:   --print-cfg --print-only=main | FileCheck %s
+
+  .globl foo
+  .type foo, %function
+foo:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	popq	%rbp
+Lfoo_ret:
+	retq
+.size foo, .-foo
+
+  .globl main
+  .type main, %function
+main:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	subq	$0x20, %rsp
+	movl	$0x0, -0x4(%rbp)
+	movl	%edi, -0x8(%rbp)
+	movq	%rsi, -0x10(%rbp)
+	movq	-0x10(%rbp), %rax
+	movq	0x8(%rax), %rdi
+	movl	%eax, -0x14(%rbp)
+
+Ltmp4:
+	cmpl	$0x0, -0x14(%rbp)
+	je	Ltmp0
+
+	movl	$0xa, -0x18(%rbp)
+	callq	foo
+# PREAGG: B #Lfoo_ret# #Ltmp3# 1 0
+# CHECK:      callq foo
+# CHECK-NEXT: count: 1
+
+Ltmp3:
+	cmpl	$0x0, -0x18(%rbp)
+	jmp	Ltmp2
+
+Ltmp2:
+	movl	-0x18(%rbp), %eax
+	addl	$-0x1, %eax
+	movl	%eax, -0x18(%rbp)
+	jmp	Ltmp3
+	jmp	Ltmp4
+
+Ltmp0:
+	xorl	%eax, %eax
+	addq	$0x20, %rsp
+	popq	%rbp
+	retq
+.size main, .-main
diff --git a/bolt/test/X86/callcont-fallthru.test b/bolt/test/X86/callcont-fallthru.test
deleted file mode 100644
index e0a5c5a6852d42..00000000000000
--- a/bolt/test/X86/callcont-fallthru.test
+++ /dev/null
@@ -1,9 +0,0 @@
-## Reproduces missing call continuation fallthrough count when using
-## pre-aggregated perf data
-
-# RUN: yaml2obj %p/Inputs/callcont-fallthru.yaml > %t.exe
-# RUN: llvm-bolt %t.exe --pa -p %p/Inputs/callcont-fallthru.preagg -o %t.out \
-# RUN:   --print-cfg --print-only=main | FileCheck %s
-
-# CHECK:      callq foo
-# CHECK-NEXT: count: 103204

>From 06fe34d8817695c6769f199f5ac386ac2e872af4 Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Mon, 21 Oct 2024 12:58:49 -0700
Subject: [PATCH 6/7] Added plt call (return from external location) test case

Created using spr 1.3.4
---
 bolt/test/X86/callcont-fallthru.s | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/bolt/test/X86/callcont-fallthru.s b/bolt/test/X86/callcont-fallthru.s
index 0a59d799f1ef3c..d10373720a6606 100644
--- a/bolt/test/X86/callcont-fallthru.s
+++ b/bolt/test/X86/callcont-fallthru.s
@@ -27,6 +27,12 @@ main:
 	movl	$0x0, -0x4(%rbp)
 	movl	%edi, -0x8(%rbp)
 	movq	%rsi, -0x10(%rbp)
+	callq	puts at PLT
+# PREAGG: B X:0 #Ltmp1# 2 0
+# CHECK:      callq puts at PLT
+# CHECK-NEXT: count: 2
+
+Ltmp1:
 	movq	-0x10(%rbp), %rax
 	movq	0x8(%rax), %rdi
 	movl	%eax, -0x14(%rbp)
@@ -51,6 +57,7 @@ Ltmp2:
 	movl	%eax, -0x18(%rbp)
 	jmp	Ltmp3
 	jmp	Ltmp4
+	jmp	Ltmp1
 
 Ltmp0:
 	xorl	%eax, %eax

>From e8ec9c936c31ae0ec0a56a224860045c0a2885a1 Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Mon, 21 Oct 2024 14:32:11 -0700
Subject: [PATCH 7/7] Add test for getFallthroughsInTrace

Created using spr 1.3.4
---
 bolt/test/X86/callcont-fallthru.s | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/bolt/test/X86/callcont-fallthru.s b/bolt/test/X86/callcont-fallthru.s
index d10373720a6606..1feb283edb2217 100644
--- a/bolt/test/X86/callcont-fallthru.s
+++ b/bolt/test/X86/callcont-fallthru.s
@@ -4,10 +4,16 @@
 # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
 # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib
 # RUN: link_fdata %s %t.exe %t.pa PREAGG
+# RUN: link_fdata %s %t.exe %t.pa2 PREAGG2
 # RUN: llvm-strip --strip-unneeded %t.exe
 # RUN: llvm-bolt %t.exe --pa -p %t.pa -o %t.out \
 # RUN:   --print-cfg --print-only=main | FileCheck %s
 
+## Check that getFallthroughsInTrace correctly handles a trace starting at plt
+## call continuation
+# RUN: llvm-bolt %t.exe --pa -p %t.pa2 -o %t.out2 \
+# RUN:   --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK2
+
   .globl foo
   .type foo, %function
 foo:
@@ -32,6 +38,9 @@ main:
 # CHECK:      callq puts at PLT
 # CHECK-NEXT: count: 2
 
+# CHECK2:      callq puts at PLT
+# CHECK2-NEXT: count: 0
+
 Ltmp1:
 	movq	-0x10(%rbp), %rax
 	movq	0x8(%rax), %rdi
@@ -40,6 +49,8 @@ Ltmp1:
 Ltmp4:
 	cmpl	$0x0, -0x14(%rbp)
 	je	Ltmp0
+# CHECK2:      je .Ltmp0
+# CHECK2-NEXT: count: 3
 
 	movl	$0xa, -0x18(%rbp)
 	callq	foo
@@ -47,8 +58,13 @@ Ltmp4:
 # CHECK:      callq foo
 # CHECK-NEXT: count: 1
 
+# PREAGG2: F #Ltmp1# #Ltmp3_br# 3
+# CHECK2:      callq foo
+# CHECK2-NEXT: count: 3
+
 Ltmp3:
 	cmpl	$0x0, -0x18(%rbp)
+Ltmp3_br:
 	jmp	Ltmp2
 
 Ltmp2:



More information about the llvm-commits mailing list