rahmanl updated this revision to Diff 479906.
rahmanl added a comment.

- Rebase.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100808/new/

https://reviews.llvm.org/D100808

Files:
  llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
  llvm/include/llvm/CodeGen/MachineBasicBlock.h
  llvm/include/llvm/CodeGen/MachineFunction.h
  llvm/include/llvm/Object/ELFTypes.h
  llvm/include/llvm/ObjectYAML/ELFYAML.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/BasicBlockSections.cpp
  llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
  llvm/lib/CodeGen/MIRParser/MILexer.cpp
  llvm/lib/CodeGen/MIRParser/MILexer.h
  llvm/lib/CodeGen/MIRParser/MIParser.cpp
  llvm/lib/CodeGen/MachineBasicBlock.cpp
  llvm/lib/CodeGen/MachineFunction.cpp
  llvm/lib/Object/ELF.cpp
  llvm/lib/ObjectYAML/ELFEmitter.cpp
  llvm/lib/ObjectYAML/ELFYAML.cpp
  llvm/test/CodeGen/X86/basic-block-labels-mir-parse.mir
  llvm/test/CodeGen/X86/basic-block-sections-mir-print.ll
  llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
  llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
  llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
  llvm/tools/llvm-readobj/ELFDumper.cpp
  llvm/tools/obj2yaml/elf2yaml.cpp
  llvm/unittests/Object/ELFObjectFileTest.cpp

Index: llvm/unittests/Object/ELFObjectFileTest.cpp
===================================================================
--- llvm/unittests/Object/ELFObjectFileTest.cpp
+++ llvm/unittests/Object/ELFObjectFileTest.cpp
@@ -528,7 +528,7 @@
   // Check that we can detect unsupported versions.
   SmallString<128> UnsupportedVersionYamlString(CommonYamlString);
   UnsupportedVersionYamlString += R"(
-        Version: 2
+        Version: 3
         BBEntries:
           - AddressOffset: 0x0
             Size:          0x1
@@ -536,13 +536,14 @@
 )";
 
   DoCheck(UnsupportedVersionYamlString,
-          "unsupported SHT_LLVM_BB_ADDR_MAP version: 2");
+          "unsupported SHT_LLVM_BB_ADDR_MAP version: 3");
 
   SmallString<128> CommonVersionedYamlString(CommonYamlString);
   CommonVersionedYamlString += R"(
-        Version: 1
+        Version: 2
         BBEntries:
-          - AddressOffset: 0x0
+          - ID:            1
+            AddressOffset: 0x0
             Size:          0x1
             Metadata:      0x2
 )";
@@ -551,9 +552,9 @@
   // truncated.
   SmallString<128> TruncatedYamlString(CommonVersionedYamlString);
   TruncatedYamlString += R"(
-    ShSize: 0xa
+    ShSize: 0xb
 )";
-  DoCheck(TruncatedYamlString, "unable to decode LEB128 at offset 0x0000000a: "
+  DoCheck(TruncatedYamlString, "unable to decode LEB128 at offset 0x0000000b: "
                                "malformed uleb128, extends past end");
 
   // Check that we can detect when the encoded BB entry fields exceed the UINT32
@@ -561,29 +562,32 @@
   SmallVector<SmallString<128>, 3> OverInt32LimitYamlStrings(
       3, CommonVersionedYamlString);
   OverInt32LimitYamlStrings[0] += R"(
-          - AddressOffset: 0x100000000
+          - ID:            1
+            AddressOffset: 0x100000000
             Size:          0xFFFFFFFF
             Metadata:      0xFFFFFFFF
 )";
 
   OverInt32LimitYamlStrings[1] += R"(
-          - AddressOffset: 0xFFFFFFFF
+          - ID:            2
+            AddressOffset: 0xFFFFFFFF
             Size:          0x100000000
             Metadata:      0xFFFFFFFF
 )";
 
   OverInt32LimitYamlStrings[2] += R"(
-          - AddressOffset: 0xFFFFFFFF
+          - ID:            3
+            AddressOffset: 0xFFFFFFFF
             Size:          0xFFFFFFFF
             Metadata:      0x100000000
 )";
 
   DoCheck(OverInt32LimitYamlStrings[0],
-          "ULEB128 value at offset 0xe exceeds UINT32_MAX (0x100000000)");
+          "ULEB128 value at offset 0x10 exceeds UINT32_MAX (0x100000000)");
   DoCheck(OverInt32LimitYamlStrings[1],
-          "ULEB128 value at offset 0x13 exceeds UINT32_MAX (0x100000000)");
+          "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");
   DoCheck(OverInt32LimitYamlStrings[2],
-          "ULEB128 value at offset 0x18 exceeds UINT32_MAX (0x100000000)");
+          "ULEB128 value at offset 0x1a exceeds UINT32_MAX (0x100000000)");
 
   // Check the proper error handling when the section has fields exceeding
   // UINT32 and is also truncated. This is for checking that we don't generate
@@ -592,24 +596,24 @@
       3, OverInt32LimitYamlStrings[1]);
   // Truncate before the end of the 5-byte field.
   OverInt32LimitAndTruncated[0] += R"(
-    ShSize: 0x17
+    ShSize: 0x19
 )";
   // Truncate at the end of the 5-byte field.
   OverInt32LimitAndTruncated[1] += R"(
-    ShSize: 0x18
+    ShSize: 0x1a
 )";
   // Truncate after the end of the 5-byte field.
   OverInt32LimitAndTruncated[2] += R"(
-    ShSize: 0x19
+    ShSize: 0x1b
 )";
 
   DoCheck(OverInt32LimitAndTruncated[0],
-          "unable to decode LEB128 at offset 0x00000013: malformed uleb128, "
+          "unable to decode LEB128 at offset 0x00000015: malformed uleb128, "
           "extends past end");
   DoCheck(OverInt32LimitAndTruncated[1],
-          "ULEB128 value at offset 0x13 exceeds UINT32_MAX (0x100000000)");
+          "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");
   DoCheck(OverInt32LimitAndTruncated[2],
-          "ULEB128 value at offset 0x13 exceeds UINT32_MAX (0x100000000)");
+          "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");
 
   // Check for proper error handling when the 'NumBlocks' field is overridden
   // with an out-of-range value.
@@ -635,41 +639,57 @@
     Type: SHT_LLVM_BB_ADDR_MAP
     Link: 1
     Entries:
-      - Version: 1
+      - Version: 2
         Address: 0x11111
         BBEntries:
-          - AddressOffset: 0x0
+          - ID:            1
+            AddressOffset: 0x0
             Size:          0x1
             Metadata:      0x2
   - Name: .llvm_bb_addr_map_2
     Type: SHT_LLVM_BB_ADDR_MAP
     Link: 1
     Entries:
-      - Version: 1
+      - Version: 2
         Address: 0x22222
         BBEntries:
-          - AddressOffset: 0x0
+          - ID:            2
+            AddressOffset: 0x0
             Size:          0x2
             Metadata:      0x4
-  - Name: .llvm_bb_addr_map
-    Type: SHT_LLVM_BB_ADDR_MAP_V0
-  # Link: 0 (by default)
+  - Name: .llvm_bb_addr_map_3
+    Type: SHT_LLVM_BB_ADDR_MAP
+    Link: 2
     Entries:
-      - Version: 0
+      - Version: 1
         Address: 0x33333
         BBEntries:
-          - AddressOffset: 0x0
+          - ID:            0
+            AddressOffset: 0x0
             Size:          0x3
             Metadata:      0x6
+  - Name: .llvm_bb_addr_map_4
+    Type: SHT_LLVM_BB_ADDR_MAP_V0
+  # Link: 0 (by default, can be overriden)
+    Entries:
+      - Version: 0
+        Address: 0x44444
+        BBEntries:
+          - ID:            0
+            AddressOffset: 0x0
+            Size:          0x4
+            Metadata:      0x8
 )");
 
-  BBAddrMap E1 = {0x11111, {{0x0, 0x1, 0x2}}};
-  BBAddrMap E2 = {0x22222, {{0x0, 0x2, 0x4}}};
-  BBAddrMap E3 = {0x33333, {{0x0, 0x3, 0x6}}};
+  BBAddrMap E1 = {0x11111, {{1, 0x0, 0x1, 0x2}}};
+  BBAddrMap E2 = {0x22222, {{2, 0x0, 0x2, 0x4}}};
+  BBAddrMap E3 = {0x33333, {{0, 0x0, 0x3, 0x6}}};
+  BBAddrMap E4 = {0x44444, {{0, 0x0, 0x4, 0x8}}};
 
-  std::vector<BBAddrMap> Section0BBAddrMaps = {E3};
-  std::vector<BBAddrMap> Section1BBAddrMaps = {E1, E2};
-  std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3};
+  std::vector<BBAddrMap> Section0BBAddrMaps = {E4};
+  std::vector<BBAddrMap> Section1BBAddrMaps = {E3};
+  std::vector<BBAddrMap> Section2BBAddrMaps = {E1, E2};
+  std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3, E4};
 
   auto DoCheckSucceeds = [&](StringRef YamlString,
                              std::optional<unsigned> TextSectionIndex,
@@ -706,10 +726,11 @@
   DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/std::nullopt,
                   AllBBAddrMaps);
   DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/0, Section0BBAddrMaps);
-  DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1, Section1BBAddrMaps);
+  DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2, Section1BBAddrMaps);
+  DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1, Section2BBAddrMaps);
   // Check that when no bb-address-map section is found for a text section,
   // we return an empty result.
-  DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2, {});
+  DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/3, {});
 
   // Check that we detect when a bb-addr-map section is linked to an invalid
   // (not present) section.
@@ -718,9 +739,9 @@
     Link: 10
 )";
 
-  DoCheckFails(InvalidLinkedYamlString, /*TextSectionIndex=*/1,
+  DoCheckFails(InvalidLinkedYamlString, /*TextSectionIndex=*/4,
                "unable to get the linked-to section for "
-               "SHT_LLVM_BB_ADDR_MAP_V0 section with index 3: invalid section "
+               "SHT_LLVM_BB_ADDR_MAP_V0 section with index 4: invalid section "
                "index: 10");
   // Linked sections are not checked when we don't target a specific text
   // section.
@@ -734,12 +755,12 @@
 )";
 
   DoCheckFails(TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,
-               "unable to read SHT_LLVM_BB_ADDR_MAP_V0 section with index 3: "
+               "unable to read SHT_LLVM_BB_ADDR_MAP_V0 section with index 4: "
                "unable to decode LEB128 at offset 0x00000008: malformed "
                "uleb128, extends past end");
   // Check that we can read the other section's bb-address-maps which are
   // valid.
-  DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/1,
+  DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/2,
                   Section1BBAddrMaps);
 }
 
Index: llvm/tools/obj2yaml/elf2yaml.cpp
===================================================================
--- llvm/tools/obj2yaml/elf2yaml.cpp
+++ llvm/tools/obj2yaml/elf2yaml.cpp
@@ -896,7 +896,7 @@
   while (Cur && Cur.tell() < Content.size()) {
     if (Shdr->sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
       Version = Data.getU8(Cur);
-      if (Cur && Version > 1)
+      if (Cur && Version > 2)
         return createStringError(
             errc::invalid_argument,
             "invalid SHT_LLVM_BB_ADDR_MAP section version: " +
@@ -907,11 +907,12 @@
     uint64_t NumBlocks = Data.getULEB128(Cur);
     std::vector<ELFYAML::BBAddrMapEntry::BBEntry> BBEntries;
     // Read the specified number of BB entries, or until decoding fails.
-    for (uint64_t BlockID = 0; Cur && BlockID < NumBlocks; ++BlockID) {
+    for (uint64_t BlockIndex = 0; Cur && BlockIndex < NumBlocks; ++BlockIndex) {
+      uint32_t ID = Version >= 2 ? Data.getULEB128(Cur) : BlockIndex;
       uint64_t Offset = Data.getULEB128(Cur);
       uint64_t Size = Data.getULEB128(Cur);
       uint64_t Metadata = Data.getULEB128(Cur);
-      BBEntries.push_back({Offset, Size, Metadata});
+      BBEntries.push_back({ID, Offset, Size, Metadata});
     }
     Entries.push_back(
         {Version, Feature, Address, /*NumBlocks=*/{}, std::move(BBEntries)});
Index: llvm/tools/llvm-readobj/ELFDumper.cpp
===================================================================
--- llvm/tools/llvm-readobj/ELFDumper.cpp
+++ llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -7135,6 +7135,7 @@
       ListScope L(W, "BB entries");
       for (const BBAddrMap::BBEntry &BBE : AM.BBEntries) {
         DictScope L(W);
+        W.printNumber("ID", BBE.ID);
         W.printHex("Offset", BBE.Offset);
         W.printHex("Size", BBE.Size);
         W.printBoolean("HasReturn", BBE.HasReturn);
Index: llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
===================================================================
--- llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
+++ llvm/test/tools/yaml2obj/ELF/bb-addr-map.yaml
@@ -12,13 +12,13 @@
 # CHECK-NEXT:   ]
 # CHECK-NEXT:   Address: 0x0
 # CHECK-NEXT:   Offset: 0x40
-# CHECK-NEXT:   Size: 12
+# CHECK-NEXT:   Size: 13
 # CHECK-NEXT:   Link: 0
 # CHECK-NEXT:   Info: 0
 # CHECK-NEXT:   AddressAlignment: 0
 # CHECK-NEXT:   EntrySize: 0
 # CHECK-NEXT:   SectionData (
-# CHECK-NEXT:     0000: 00000000 00000000 01010203
+# CHECK-NEXT:     0000: 00000000 00000000 01010203 04
 # CHECK-NEXT:   )
 # CHECK-NEXT: }
 
@@ -36,7 +36,7 @@
 # Case 4: Specify Entries.
 # CHECK:        Name: .llvm_bb_addr_map (1)
 # CHECK:        SectionData (
-# CHECK-NEXT:     0000: 01002000 00000000 00000101 0203
+# CHECK-NEXT:     0000: 02002000 00000000 0000010B 010203
 # CHECK-NEXT:   )
 
 # Case 5: Specify Entries and omit the Address field.
@@ -44,13 +44,13 @@
 # CHECK:        Address:
 # CHECK-SAME:   {{^ 0x0$}}
 # CHECK:        SectionData (
-# CHECK-NEXT:     0000: 00000000 00000000 00000101 0203
+# CHECK-NEXT:     0000: 02000000 00000000 0000010C 010203
 # CHECK-NEXT:   )
 
 # Case 6: Override the NumBlocks field.
 # CHECK:        Name: .llvm_bb_addr_map (1)
 # CHECK:        SectionData (
-# CHECK-NEXT:     0000: 01002000 00000000 00000201 0203
+# CHECK-NEXT:     0000: 02002000 00000000 0000020D 010203
 # CHECK-NEXT:   )
 
 --- !ELF
@@ -67,7 +67,7 @@
 ##  Specify Content.
   - Name:    '.llvm_bb_addr_map (1)'
     Type:    SHT_LLVM_BB_ADDR_MAP
-    Content: "000000000000000001010203"
+    Content: "00000000000000000101020304"
 
 ## 2) We can produce an empty .llvm_bb_addr_map section from a description
 ##    with empty section content.
@@ -85,10 +85,11 @@
   - Name: '.llvm_bb_addr_map (4)'
     Type: SHT_LLVM_BB_ADDR_MAP
     Entries:
-      - Version: 1
+      - Version: 2
         Address: 0x0000000000000020
         BBEntries:
-          - AddressOffset: 0x00000001
+          - ID:            11
+            AddressOffset: 0x00000001
             Size:          0x00000002
             Metadata:      0x00000003
 
@@ -97,9 +98,10 @@
   - Name: '.llvm_bb_addr_map (5)'
     Type: SHT_LLVM_BB_ADDR_MAP
     Entries:
-      - Version: 0
+      - Version: 2
         BBEntries:
-          - AddressOffset: 0x00000001
+          - ID:            12
+            AddressOffset: 0x00000001
             Size:          0x00000002
             Metadata:      0x00000003
 
@@ -108,11 +110,12 @@
   - Name: '.llvm_bb_addr_map (6)'
     Type: SHT_LLVM_BB_ADDR_MAP
     Entries:
-      - Version:   1
+      - Version:   2
         Address:   0x0000000000000020
         NumBlocks: 2
         BBEntries:
-          - AddressOffset: 0x00000001
+          - ID:            13
+            AddressOffset: 0x00000001
             Size:          0x00000002
             Metadata:      0x00000003
 
@@ -137,7 +140,7 @@
 
 ## Check that yaml2obj generates a warning when we use unsupported versions.
 # RUN: yaml2obj --docnum=3  %s 2>&1 | FileCheck %s --check-prefix=INVALID-VERSION
-# INVALID-VERSION: warning: unsupported SHT_LLVM_BB_ADDR_MAP version: 2; encoding using the most recent version
+# INVALID-VERSION: warning: unsupported SHT_LLVM_BB_ADDR_MAP version: 3; encoding using the most recent version
 
 --- !ELF
 FileHeader:
@@ -149,4 +152,4 @@
     Type: SHT_LLVM_BB_ADDR_MAP
     Entries:
 ##  Specify unsupported version
-      - Version: 2
+      - Version: 3
Index: llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
===================================================================
--- llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
+++ llvm/test/tools/obj2yaml/ELF/bb-addr-map.yaml
@@ -15,23 +15,27 @@
 # VALID-NEXT:     Type: SHT_LLVM_BB_ADDR_MAP
 # VALID-NEXT:     Entries:
 ## The 'Address' field is omitted when it's zero.
-# VALID-NEXT:       - Version: 1
+# VALID-NEXT:       - Version: 2
 # VALID-NEXT:         Feature: 0xFF
 # VALID-NEXT:         BBEntries:
-# VALID-NEXT:           - AddressOffset: 0x1
+# VALID-NEXT:           - ID:            0
+# VALID-NEXT:             AddressOffset: 0x1
 # VALID-NEXT:             Size:          0x2
 # VALID-NEXT:             Metadata:      0x3
-# VALID-NEXT:           - AddressOffset: 0x4
+# VALID-NEXT:           - ID:            2
+# VALID-NEXT:             AddressOffset: 0x4
 # VALID-NEXT:             Size:          0x5
 # VALID-NEXT:             Metadata:      0x6
-# VALID-NEXT:           - AddressOffset: 0xFFFFFFFFFFFFFFF7
+# VALID-NEXT:           - ID:            4
+# VALID-NEXT:             AddressOffset: 0xFFFFFFFFFFFFFFF7
 # VALID-NEXT:             Size:          0xFFFFFFFFFFFFFFF8
 # VALID-NEXT:             Metadata:      0xFFFFFFFFFFFFFFF9
-# VALID-NEXT:       - Version: 1
+# VALID-NEXT:       - Version: 2
 # VALID-NEXT:         Feature: 0xEE
 # VALID-NEXT:         Address: 0xFFFFFFFFFFFFFF20
 # VALID-NEXT:         BBEntries:
-# VALID-NEXT:           - AddressOffset: 0xA
+# VALID-NEXT:           - ID:            6
+# VALID-NEXT:             AddressOffset: 0xA
 # VALID-NEXT:             Size:          0xB
 # VALID-NEXT:             Metadata:      0xC
 
@@ -45,25 +49,29 @@
     Type:   SHT_LLVM_BB_ADDR_MAP
     ShSize: [[SIZE=<none>]]
     Entries:
-      - Version: 1
+      - Version: 2
         Feature: 0xFF
         Address: 0x0
         BBEntries:
-          - AddressOffset: 0x1
+          - ID:            0
+            AddressOffset: 0x1
             Size:          0x2
             Metadata:      0x3
-          - AddressOffset: 0x4
+          - ID:            2
+            AddressOffset: 0x4
             Size:          0x5
             Metadata:      0x6
-          - AddressOffset: 0xFFFFFFFFFFFFFFF7
+          - ID:            4
+            AddressOffset: 0xFFFFFFFFFFFFFFF7
             Size:          0xFFFFFFFFFFFFFFF8
             Metadata:      0xFFFFFFFFFFFFFFF9
-      - Version:   1
+      - Version:   2
         Feature:   0xEE
         Address:   0xFFFFFFFFFFFFFF20
         NumBlocks: [[NUMBLOCKS=<none>]]
         BBEntries:
-          - AddressOffset: 0xA
+          - ID:            6
+            AddressOffset: 0xA
             Size:          0xB
             Metadata:      0xC
 
@@ -109,7 +117,8 @@
 ## Fields 'Address' and 'Feature' are omitted when they are zero.
 # MULTI-NEXT:       - Version: 0
 # MULTI-NEXT:         BBEntries:
-# MULTI-NEXT:           - AddressOffset: 0x1
+# MULTI-NEXT:           - ID:            0
+# MULTI-NEXT:             AddressOffset: 0x1
 # MULTI-NEXT:             Size:          0x2
 # MULTI-NEXT:             Metadata:      0x3
 # MULTI-NEXT:   - Name: '.llvm_bb_addr_map (1)'
@@ -180,7 +189,8 @@
 # V0-NEXT:       - Version: 0
 # V0-NEXT:         Address: 0x1111
 # V0-NEXT:         BBEntries:
-# V0-NEXT:           - AddressOffset: 0x1
+# V0-NEXT:           - ID:            0
+# V0-NEXT:             AddressOffset: 0x1
 # V0-NEXT:             Size:          0x2
 # V0-NEXT:             Metadata:      0x3
 
@@ -199,3 +209,47 @@
           - AddressOffset: 0x1
             Size:          0x2
             Metadata:      0x3
+
+## Check obj2yaml for version 1.
+# RUN: yaml2obj --docnum=5 %s -o %t7
+# RUN: obj2yaml %t7 | FileCheck %s --check-prefix=V1
+
+# V1:      --- !ELF
+# V1-NEXT: FileHeader:
+# V1-NEXT:   Class: ELFCLASS64
+# V1-NEXT:   Data:  ELFDATA2LSB
+# V1-NEXT:   Type:  ET_EXEC
+# V1-NEXT: Sections:
+# V1-NEXT:   - Name: .llvm_bb_addr_map
+# V1-NEXT:     Type: SHT_LLVM_BB_ADDR_MAP
+# V1-NEXT:     Entries:
+# V1-NEXT:       - Version: 1
+# V1-NEXT:         Address: 0x1111
+# V1-NEXT:         BBEntries:
+# V1-NEXT:           - ID:            0
+# V1-NEXT:             AddressOffset: 0x1
+# V1-NEXT:             Size:          0x2
+# V1-NEXT:             Metadata:      0x3
+# V1-NEXT:           - ID:            1
+# V1-NEXT:             AddressOffset: 0x4
+# V1-NEXT:             Size:          0x5
+# V1-NEXT:             Metadata:      0x6
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data:  ELFDATA2LSB
+  Type:  ET_EXEC
+Sections:
+  - Name: .llvm_bb_addr_map
+    Type: SHT_LLVM_BB_ADDR_MAP
+    Entries:
+      - Version: 1
+        Address: 0x1111
+        BBEntries:
+          - AddressOffset: 0x1
+            Size:          0x2
+            Metadata:      0x3
+          - AddressOffset: 0x4
+            Size:          0x5
+            Metadata:      0x6
Index: llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
===================================================================
--- llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
+++ llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test
@@ -25,6 +25,7 @@
 # CHECK-NEXT:     Name: <?>
 # CHECK-NEXT:     BB entries [
 # CHECK-NEXT:       {
+# CHECK-NEXT:         ID: 0
 # CHECK-NEXT:         Offset: 0x0
 # CHECK-NEXT:         Size: 0x1
 # CHECK-NEXT:         HasReturn: No
@@ -33,6 +34,7 @@
 # CHECK-NEXT:         CanFallThrough: No
 # CHECK-NEXT:       }
 # CHECK-NEXT:       {
+# CHECK-NEXT:         ID: 2
 # CHECK-NEXT:         Offset: 0x4
 # CHECK-NEXT:         Size: 0x4
 # CHECK-NEXT:         HasReturn: Yes
@@ -47,6 +49,7 @@
 # CHECK-NEXT:     Name: foo
 # CHECK-NEXT:     BB entries [
 # CHECK-NEXT:       {
+# CHECK-NEXT:         ID: 4
 # CHECK-NEXT:         Offset: 0x6
 # CHECK-NEXT:         Size: 0x7
 # CHECK-NEXT:         HasReturn: No
@@ -70,6 +73,7 @@
 # TRUNCATED-NEXT:     Name: bar
 # TRUNCATED-NEXT:     BB entries [
 # TRUNCATED-NEXT:       {
+# TRUNCATED-NEXT:         ID: 6
 # TRUNCATED-NEXT:         Offset: 0x9
 # TRUNCATED-NEXT:         Size: 0xA
 # TRUNCATED-NEXT:         HasReturn: Yes
@@ -78,6 +82,7 @@
 # TRUNCATED-NEXT:         CanFallThrough: Yes
 # TRUNCATED-NEXT:       }
 # TRUNCATED-NEXT:       {
+# TRUNCATED-NEXT:         ID: 7
 # TRUNCATED-NEXT:         Offset: 0x1F
 # TRUNCATED-NEXT:         Size: 0xD
 # TRUNCATED-NEXT:         HasReturn: No
@@ -106,19 +111,22 @@
     ShSize: [[SIZE=<none>]]
     Link:   .text
     Entries:
-      - Version: 1
+      - Version: 2
         Address: [[ADDR=0x11111]]
         BBEntries:
-          - AddressOffset: 0x0
+          - ID:            0
+            AddressOffset: 0x0
             Size:          0x1
             Metadata:      0xF0000002
-          - AddressOffset: 0x3
+          - ID:            2
+            AddressOffset: 0x3
             Size:          0x4
             Metadata:      0x5
-      - Version: 1
+      - Version: 2
         Address: 0x22222
         BBEntries:
-          - AddressOffset: 0x6
+          - ID:            4
+            AddressOffset: 0x6
             Size:          0x7
             Metadata:      0x8
   - Name: dummy_section
@@ -128,13 +136,15 @@
     Type: SHT_LLVM_BB_ADDR_MAP
     Link: .text.bar
     Entries:
-      - Version: 1
+      - Version: 2
         Address: 0x33333
         BBEntries:
-          - AddressOffset: 0x9
+          - ID:            6
+            AddressOffset: 0x9
             Size:          0xa
             Metadata:      0xb
-          - AddressOffset: 0xc
+          - ID:            7
+            AddressOffset: 0xc
             Size:          0xd
             Metadata:      0xe
 Symbols:
@@ -165,6 +175,7 @@
 # V0-NEXT:     Name: foo
 # V0-NEXT:     BB entries [
 # V0-NEXT:       {
+# V0-NEXT:         ID: 0
 # V0-NEXT:         Offset: 0x1
 # V0-NEXT:         Size: 0x2
 # V0-NEXT:         HasReturn:
@@ -173,6 +184,7 @@
 # V0-NEXT:         CanFallThrough:
 # V0-NEXT:       }
 # V0-NEXT:       {
+# V0-NEXT:         ID: 1
 # V0-NEXT:         Offset: 0x4
 # V0-NEXT:         Size: 0x5
 # V0-NEXT:         HasReturn:
@@ -183,6 +195,36 @@
 # V0-NEXT:     ]
 # V0-NEXT:   }
 
+## Check version 1 (without BB IDs).
+# RUN: yaml2obj --docnum=2 %s -DVERSION=1 -DSECTION_TYPE=SHT_LLVM_BB_ADDR_MAP -o %t3
+# RUN: llvm-readobj %t3 --bb-addr-map 2>&1 | FileCheck %s --check-prefix=V1
+
+# V1:      BBAddrMap [
+# V1-NEXT:   Function {
+# V1-NEXT:     At:   0x11111
+# V1-NEXT:     Name: foo
+# V1-NEXT:     BB entries [
+# V1-NEXT:       {
+# V1-NEXT:         ID: 0
+# V1-NEXT:         Offset: 0x1
+# V1-NEXT:         Size: 0x2
+# V1-NEXT:         HasReturn:
+# V1-NEXT:         HasTailCall:
+# V1-NEXT:         IsEHPad:
+# V1-NEXT:         CanFallThrough:
+# V1-NEXT:       }
+# V1-NEXT:       {
+# V1-NEXT:         ID: 1
+# V1-NEXT:         Offset: 0x7
+# V1-NEXT:         Size: 0x5
+# V1-NEXT:         HasReturn:
+# V1-NEXT:         HasTailCall:
+# V1-NEXT:         IsEHPad:
+# V1-NEXT:         CanFallThrough:
+# V1-NEXT:       }
+# V1-NEXT:     ]
+# V1-NEXT:   }
+
 --- !ELF
 FileHeader:
   Class: ELFCLASS64
Index: llvm/test/CodeGen/X86/basic-block-sections-mir-print.ll
===================================================================
--- llvm/test/CodeGen/X86/basic-block-sections-mir-print.ll
+++ llvm/test/CodeGen/X86/basic-block-sections-mir-print.ll
@@ -1,8 +1,9 @@
 ; Stop after bbsections-prepare and check MIR output for section type.
+; RUN: llc < %s -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=labels -stop-after=bbsections-prepare | FileCheck %s -check-prefix=BBLABELS
 ; RUN: echo '!_Z3foob' > %t
 ; RUN: echo '!!1' >> %t
 ; RUN: echo '!!2' >> %t
-; RUN: llc < %s -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -stop-after=bbsections-prepare | FileCheck %s -check-prefix=CHECK
+; RUN: llc < %s -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -stop-after=bbsections-prepare | FileCheck %s -check-prefix=BBSECTIONS
 
 @_ZTIb = external constant ptr
 define dso_local i32 @_Z3foob(i1 zeroext %0) {
@@ -27,7 +28,12 @@
   ret i32 %10
 }
 
-; CHECK: bb.0 (%ir-block.1, bbsections Cold):
-; CHECK: bb.3 (%ir-block.9, bbsections Cold):
-; CHECK: bb.1 (%ir-block.7)
-; CHECK: bb.2 (%ir-block.8, bbsections 1):
+; BBSECTIONS: bb.0 (%ir-block.1, bbsections Cold, bb_id 0):
+; BBSECTIONS: bb.3 (%ir-block.9, bbsections Cold, bb_id 3):
+; BBSECTIONS: bb.1 (%ir-block.7, bb_id 1)
+; BBSECTIONS: bb.2 (%ir-block.8, bbsections 1, bb_id 2):
+
+; BBLABELS: bb.0 (%ir-block.1, bb_id 0):
+; BBLABELS: bb.1 (%ir-block.7, bb_id 1):
+; BBLABELS: bb.2 (%ir-block.8, bb_id 2):
+; BBLABELS: bb.3 (%ir-block.9, bb_id 3):
Index: llvm/test/CodeGen/X86/basic-block-labels-mir-parse.mir
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/X86/basic-block-labels-mir-parse.mir
@@ -0,0 +1,145 @@
+# Start after bbsections0-prepare and check that the BB address map is generated.
+# RUN: llc -mtriple x86_64-unknown-linux-gnu -start-after=bbsections-prepare  %s -o - | FileCheck %s -check-prefix=CHECK
+
+# How to generate the input:
+# foo.cc
+# int foo(bool k) {
+#  if (k) return 1;
+#  return 0;
+# }
+#
+# clang -O0 -S -emit-llvm foo.cc
+# llc < foo.ll -stop-after=bbsections-prepare -basic-block-sections=labels
+
+# CHECK: .section	.llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text
+--- |
+  ; ModuleID = '<stdin>'
+  source_filename = "/tmp/foo.cc"
+  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-pc-linux-gnu"
+  
+  ; Function Attrs: mustprogress noinline nounwind optnone uwtable
+  define dso_local noundef i32 @_Z3foob(i1 noundef zeroext %0) #0 {
+    %2 = alloca i32, align 4
+    %3 = alloca i8, align 1
+    %4 = zext i1 %0 to i8
+    store i8 %4, i8* %3, align 1
+    %5 = load i8, i8* %3, align 1
+    %6 = trunc i8 %5 to i1
+    br i1 %6, label %7, label %8
+  
+  7:                                                ; preds = %1
+    store i32 1, i32* %2, align 4
+    br label %9
+  
+  8:                                                ; preds = %1
+    store i32 0, i32* %2, align 4
+    br label %9
+  
+  9:                                                ; preds = %8, %7
+    %10 = load i32, i32* %2, align 4
+    ret i32 %10
+  }
+  
+  attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+  
+  !llvm.module.flags = !{!0, !1, !2, !3, !4}
+  !llvm.ident = !{!5}
+  
+  !0 = !{i32 1, !"wchar_size", i32 4}
+  !1 = !{i32 7, !"PIC Level", i32 2}
+  !2 = !{i32 7, !"PIE Level", i32 2}
+  !3 = !{i32 7, !"uwtable", i32 1}
+  !4 = !{i32 7, !"frame-pointer", i32 2}
+  !5 = !{!"Debian clang version 14.0.6-2"}
+
+...
+---
+name:            _Z3foob
+alignment:       16
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+failsVerification: false
+tracksDebugUserValues: true
+registers:       []
+liveins:
+  - { reg: '$edi', virtual-reg: '' }
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       8
+  offsetAdjustment: -8
+  maxAlignment:    4
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 0
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  localFrameSize:  0
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:
+  - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default, 
+      callee-saved-register: '', callee-saved-restored: true, debug-info-variable: '', 
+      debug-info-expression: '', debug-info-location: '' }
+stack:
+  - { id: 0, name: '', type: default, offset: -24, size: 4, alignment: 4, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: default, offset: -17, size: 1, alignment: 1, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo: {}
+body:             |
+  bb.0 (%ir-block.1, bb_id 0):
+    successors: %bb.2(0x40000000), %bb.1(0x40000000)
+    liveins: $edi
+  
+    frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
+    frame-setup CFI_INSTRUCTION def_cfa_offset 16
+    frame-setup CFI_INSTRUCTION offset $rbp, -16
+    $rbp = frame-setup MOV64rr $rsp
+    frame-setup CFI_INSTRUCTION def_cfa_register $rbp
+    renamable $dil = AND8ri renamable $dil, 1, implicit-def dead $eflags, implicit killed $edi, implicit-def $edi
+    MOV8mr $rbp, 1, $noreg, -1, $noreg, renamable $dil, implicit killed $edi :: (store (s8) into %ir.3)
+    TEST8mi $rbp, 1, $noreg, -1, $noreg, 1, implicit-def $eflags :: (load (s8) from %ir.3)
+    JCC_1 %bb.2, 4, implicit killed $eflags
+  
+  bb.1 (%ir-block.7, bb_id 1):
+    successors: %bb.3(0x80000000)
+  
+    MOV32mi $rbp, 1, $noreg, -8, $noreg, 1 :: (store (s32) into %ir.2)
+    JMP_1 %bb.3
+  
+  bb.2 (%ir-block.8, bb_id 2):
+    successors: %bb.3(0x80000000)
+  
+    MOV32mi $rbp, 1, $noreg, -8, $noreg, 0 :: (store (s32) into %ir.2)
+  
+  bb.3 (%ir-block.9, bb_id 3):
+    renamable $eax = MOV32rm $rbp, 1, $noreg, -8, $noreg :: (load (s32) from %ir.2)
+    $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+    frame-destroy CFI_INSTRUCTION def_cfa $rsp, 8
+    RET64 implicit $eax
+
+...
Index: llvm/lib/ObjectYAML/ELFYAML.cpp
===================================================================
--- llvm/lib/ObjectYAML/ELFYAML.cpp
+++ llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1794,6 +1794,7 @@
 void MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry>::mapping(
     IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E) {
   assert(IO.getContext() && "The IO context is not initialized");
+  IO.mapOptional("ID", E.ID);
   IO.mapRequired("AddressOffset", E.AddressOffset);
   IO.mapRequired("Size", E.Size);
   IO.mapRequired("Metadata", E.Metadata);
Index: llvm/lib/ObjectYAML/ELFEmitter.cpp
===================================================================
--- llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -1395,7 +1395,7 @@
   for (const ELFYAML::BBAddrMapEntry &E : *Section.Entries) {
     // Write version and feature values.
     if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP) {
-      if (E.Version > 1)
+      if (E.Version > 2)
         WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: "
                              << static_cast<int>(E.Version)
                              << "; encoding using the most recent version";
@@ -1413,10 +1413,13 @@
     // Write all BBEntries.
     if (!E.BBEntries)
       continue;
-    for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *E.BBEntries)
+    for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *E.BBEntries) {
+      if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP && E.Version > 1)
+        SHeader.sh_size += CBA.writeULEB128(BBE.ID);
       SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset) +
                          CBA.writeULEB128(BBE.Size) +
                          CBA.writeULEB128(BBE.Metadata);
+    }
   }
 }
 
Index: llvm/lib/Object/ELF.cpp
===================================================================
--- llvm/lib/Object/ELF.cpp
+++ llvm/lib/Object/ELF.cpp
@@ -669,7 +669,7 @@
       Version = Data.getU8(Cur);
       if (!Cur)
         break;
-      if (Version > 1)
+      if (Version > 2)
         return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +
                            Twine(static_cast<int>(Version)));
       Data.getU8(Cur); // Feature byte
@@ -678,8 +678,9 @@
     uint32_t NumBlocks = ReadULEB128AsUInt32();
     std::vector<BBAddrMap::BBEntry> BBEntries;
     uint32_t PrevBBEndOffset = 0;
-    for (uint32_t BlockID = 0; !ULEBSizeErr && Cur && (BlockID < NumBlocks);
-         ++BlockID) {
+    for (uint32_t BlockIndex = 0;
+         !ULEBSizeErr && Cur && (BlockIndex < NumBlocks); ++BlockIndex) {
+      uint32_t ID = Version >= 2 ? ReadULEB128AsUInt32() : BlockIndex;
       uint32_t Offset = ReadULEB128AsUInt32();
       uint32_t Size = ReadULEB128AsUInt32();
       uint32_t Metadata = ReadULEB128AsUInt32();
@@ -688,7 +689,7 @@
         Offset += PrevBBEndOffset;
         PrevBBEndOffset = Offset + Size;
       }
-      BBEntries.push_back({Offset, Size, Metadata});
+      BBEntries.push_back({ID, Offset, Size, Metadata});
     }
     FunctionEntries.push_back({Address, std::move(BBEntries)});
   }
Index: llvm/lib/CodeGen/MachineFunction.cpp
===================================================================
--- llvm/lib/CodeGen/MachineFunction.cpp
+++ llvm/lib/CodeGen/MachineFunction.cpp
@@ -437,8 +437,13 @@
 /// `new MachineBasicBlock'.
 MachineBasicBlock *
 MachineFunction::CreateMachineBasicBlock(const BasicBlock *bb) {
-  return new (BasicBlockRecycler.Allocate<MachineBasicBlock>(Allocator))
-             MachineBasicBlock(*this, bb);
+  MachineBasicBlock *MBB =
+      new (BasicBlockRecycler.Allocate<MachineBasicBlock>(Allocator))
+          MachineBasicBlock(*this, bb);
+  if (Target.getBBSectionsType() == BasicBlockSection::Labels ||
+      Target.getBBSectionsType() == BasicBlockSection::List)
+    MBB->setBBID(NextBBID++);
+  return MBB;
 }
 
 /// Delete the given MachineBasicBlock.
Index: llvm/lib/CodeGen/MachineBasicBlock.cpp
===================================================================
--- llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -558,6 +558,11 @@
       }
       hasAttributes = true;
     }
+    if (getBBID().has_value()) {
+      os << (hasAttributes ? ", " : " (");
+      os << "bb_id " << *getBBID();
+      hasAttributes = true;
+    }
   }
 
   if (hasAttributes)
@@ -1646,6 +1651,11 @@
   return false;
 }
 
+unsigned MachineBasicBlock::getBBIDOrNumber() const {
+  uint8_t BBAddrMapVersion = getParent()->getContext().getBBAddrMapVersion();
+  return BBAddrMapVersion < 2 ? getNumber() : *getBBID();
+}
+
 const MBBSectionID MBBSectionID::ColdSectionID(MBBSectionID::SectionType::Cold);
 const MBBSectionID
     MBBSectionID::ExceptionSectionID(MBBSectionID::SectionType::Exception);
Index: llvm/lib/CodeGen/MIRParser/MIParser.cpp
===================================================================
--- llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -499,6 +499,7 @@
   bool parseAlignment(uint64_t &Alignment);
   bool parseAddrspace(unsigned &Addrspace);
   bool parseSectionID(Optional<MBBSectionID> &SID);
+  bool parseBBID(Optional<unsigned> &PrID);
   bool parseOperandsOffset(MachineOperand &Op);
   bool parseIRValue(const Value *&V);
   bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags);
@@ -662,6 +663,18 @@
   return false;
 }
 
+// Parse Machine Basic Block ID.
+bool MIParser::parseBBID(Optional<unsigned> &BBID) {
+  assert(Token.is(MIToken::kw_bb_id));
+  lex();
+  unsigned Value = 0;
+  if (getUnsigned(Value))
+    return error("Unknown BB ID");
+  BBID = Value;
+  lex();
+  return false;
+}
+
 bool MIParser::parseBasicBlockDefinition(
     DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
   assert(Token.is(MIToken::MachineBasicBlockLabel));
@@ -678,6 +691,7 @@
   bool IsEHFuncletEntry = false;
   Optional<MBBSectionID> SectionID;
   uint64_t Alignment = 0;
+  Optional<unsigned> BBID;
   BasicBlock *BB = nullptr;
   if (consumeIfPresent(MIToken::lparen)) {
     do {
@@ -718,6 +732,10 @@
         if (parseSectionID(SectionID))
           return true;
         break;
+      case MIToken::kw_bb_id:
+        if (parseBBID(BBID))
+          return true;
+        break;
       default:
         break;
       }
@@ -755,6 +773,13 @@
     MBB->setSectionID(SectionID.value());
     MF.setBBSectionsType(BasicBlockSection::List);
   }
+  if (BBID.has_value()) {
+    // BBSectionsType is set to `List` if any basic blocks has `SectionID`.
+    // Here, we set it to `Labels` if it hasn't been set above.
+    if (!MF.hasBBSections())
+      MF.setBBSectionsType(BasicBlockSection::Labels);
+    MBB->setBBID(BBID.value());
+  }
   return false;
 }
 
Index: llvm/lib/CodeGen/MIRParser/MILexer.h
===================================================================
--- llvm/lib/CodeGen/MIRParser/MILexer.h
+++ llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -128,6 +128,7 @@
     kw_pcsections,
     kw_cfi_type,
     kw_bbsections,
+    kw_bb_id,
     kw_unknown_size,
     kw_unknown_address,
     kw_ir_block_address_taken,
Index: llvm/lib/CodeGen/MIRParser/MILexer.cpp
===================================================================
--- llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -273,11 +273,13 @@
       .Case("pcsections", MIToken::kw_pcsections)
       .Case("cfi-type", MIToken::kw_cfi_type)
       .Case("bbsections", MIToken::kw_bbsections)
+      .Case("bb_id", MIToken::kw_bb_id)
       .Case("unknown-size", MIToken::kw_unknown_size)
       .Case("unknown-address", MIToken::kw_unknown_address)
       .Case("distinct", MIToken::kw_distinct)
       .Case("ir-block-address-taken", MIToken::kw_ir_block_address_taken)
-      .Case("machine-block-address-taken", MIToken::kw_machine_block_address_taken)
+      .Case("machine-block-address-taken",
+            MIToken::kw_machine_block_address_taken)
       .Default(MIToken::Identifier);
 }
 
Index: llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
===================================================================
--- llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
+++ llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp
@@ -93,23 +93,23 @@
       if (FI == ProgramBBClusterInfo.end())
         return invalidProfileError(
             "Cluster list does not follow a function name specifier.");
-      SmallVector<StringRef, 4> BBIndexes;
-      S.split(BBIndexes, ' ');
+      SmallVector<StringRef, 4> BBIDs;
+      S.split(BBIDs, ' ');
       // Reset current cluster position.
       CurrentPosition = 0;
-      for (auto BBIndexStr : BBIndexes) {
-        unsigned long long BBIndex;
-        if (getAsUnsignedInteger(BBIndexStr, 10, BBIndex))
+      for (auto BBIDStr : BBIDs) {
+        unsigned long long BBID;
+        if (getAsUnsignedInteger(BBIDStr, 10, BBID))
           return invalidProfileError(Twine("Unsigned integer expected: '") +
-                                     BBIndexStr + "'.");
-        if (!FuncBBIDs.insert(BBIndex).second)
+                                     BBIDStr + "'.");
+        if (!FuncBBIDs.insert(BBID).second)
           return invalidProfileError(Twine("Duplicate basic block id found '") +
-                                     BBIndexStr + "'.");
-        if (!BBIndex && CurrentPosition)
+                                     BBIDStr + "'.");
+        if (BBID == 0 && CurrentPosition)
           return invalidProfileError("Entry BB (0) does not begin a cluster.");
 
-        FI->second.emplace_back(BBClusterInfo{
-            ((unsigned)BBIndex), CurrentCluster, CurrentPosition++});
+        FI->second.emplace_back(
+            BBClusterInfo{((unsigned)BBID), CurrentCluster, CurrentPosition++});
       }
       CurrentCluster++;
     } else { // This is a function name specifier.
Index: llvm/lib/CodeGen/BasicBlockSections.cpp
===================================================================
--- llvm/lib/CodeGen/BasicBlockSections.cpp
+++ llvm/lib/CodeGen/BasicBlockSections.cpp
@@ -71,13 +71,14 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
 #include "llvm/CodeGen/BasicBlockSectionUtils.h"
+#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/InitializePasses.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/Target/TargetMachine.h"
 #include <optional>
 
@@ -131,14 +132,15 @@
 
 // This function updates and optimizes the branching instructions of every basic
 // block in a given function to account for changes in the layout.
-static void updateBranches(
-    MachineFunction &MF,
-    const SmallVector<MachineBasicBlock *, 4> &PreLayoutFallThroughs) {
+static void
+updateBranches(MachineFunction &MF,
+               DenseMap<const MachineBasicBlock *, MachineBasicBlock *>
+                   &PreLayoutFallThroughs) {
   const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
   SmallVector<MachineOperand, 4> Cond;
   for (auto &MBB : MF) {
     auto NextMBBI = std::next(MBB.getIterator());
-    auto *FTMBB = PreLayoutFallThroughs[MBB.getNumber()];
+    auto *FTMBB = PreLayoutFallThroughs[&MBB];
     // If this block had a fallthrough before we need an explicit unconditional
     // branch to that block if either
     //     1- the block ends a section, which means its next block may be
@@ -183,13 +185,13 @@
     return true;
   }
 
-  V.resize(MF.getNumBlockIDs());
-  for (auto bbClusterInfo : P.second) {
-    // Bail out if the cluster information contains invalid MBB numbers.
-    if (bbClusterInfo.MBBNumber >= MF.getNumBlockIDs())
-      return false;
-    V[bbClusterInfo.MBBNumber] = bbClusterInfo;
-  }
+  unsigned MaxBBID = 0;
+  for (const BBClusterInfo &BBCI : P.second)
+    if (BBCI.BBID > MaxBBID)
+      MaxBBID = BBCI.BBID;
+  V.resize(MaxBBID + 1);
+  for (const BBClusterInfo &BBCI : P.second)
+    V[BBCI.BBID] = BBCI;
   return true;
 }
 
@@ -202,9 +204,10 @@
 // and "Cold" succeeding all other clusters.
 // FuncBBClusterInfo represent the cluster information for basic blocks. If this
 // is empty, it means unique sections for all basic blocks in the function.
-static void
-assignSections(MachineFunction &MF,
-               const std::vector<Optional<BBClusterInfo>> &FuncBBClusterInfo) {
+static void assignSections(
+    MachineFunction &MF,
+    const std::vector<Optional<BBClusterInfo>> &FuncBBClusterInfo,
+    const DenseMap<const MachineBasicBlock *, unsigned> &PreLayoutPosition) {
   assert(MF.hasBBSections() && "BB Sections is not set for function.");
   // This variable stores the section ID of the cluster containing eh_pads (if
   // all eh_pads are one cluster). If more than one cluster contain eh_pads, we
@@ -219,11 +222,12 @@
     if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All ||
         FuncBBClusterInfo.empty()) {
       // If unique sections are desired for all basic blocks of the function, we
-      // set every basic block's section ID equal to its number (basic block
-      // id). This further ensures that basic blocks are ordered canonically.
-      MBB.setSectionID({static_cast<unsigned int>(MBB.getNumber())});
-    } else if (FuncBBClusterInfo[MBB.getNumber()])
-      MBB.setSectionID(FuncBBClusterInfo[MBB.getNumber()]->ClusterID);
+      // set every basic block's section ID equal to its original position in
+      // the layout. This ensures that basic blocks are ordered canonically.
+      MBB.setSectionID(PreLayoutPosition.lookup(&MBB));
+    } else if (MBB.getBBIDOrNumber() < FuncBBClusterInfo.size() &&
+               FuncBBClusterInfo[MBB.getBBIDOrNumber()].has_value())
+      MBB.setSectionID(FuncBBClusterInfo[MBB.getBBIDOrNumber()]->ClusterID);
     else {
       // BB goes into the special cold section if it is not specified in the
       // cluster info map.
@@ -250,12 +254,15 @@
 
 void llvm::sortBasicBlocksAndUpdateBranches(
     MachineFunction &MF, MachineBasicBlockComparator MBBCmp) {
-  SmallVector<MachineBasicBlock *, 4> PreLayoutFallThroughs(
-      MF.getNumBlockIDs());
+  [[maybe_unused]] const MachineBasicBlock *EntryBlock = &MF.front();
+  DenseMap<const MachineBasicBlock *, MachineBasicBlock *>
+      PreLayoutFallThroughs;
   for (auto &MBB : MF)
-    PreLayoutFallThroughs[MBB.getNumber()] = MBB.getFallThrough();
+    PreLayoutFallThroughs[&MBB] = MBB.getFallThrough();
 
   MF.sort(MBBCmp);
+  assert(&MF.front() == EntryBlock &&
+         "Entry block should not be displaced by basic block sections");
 
   // Set IsBeginSection and IsEndSection according to the assigned section IDs.
   MF.assignBeginEndSections();
@@ -318,12 +325,14 @@
   if (BBSectionsType == BasicBlockSection::List &&
       hasInstrProfHashMismatch(MF))
     return true;
-
-  // Renumber blocks before sorting them for basic block sections.  This is
-  // useful during sorting, basic blocks in the same section will retain the
-  // default order.  This renumbering should also be done for basic block
-  // labels to match the profiles with the correct blocks.
-  MF.RenumberBlocks();
+  // With LLVM_BB_ADDR_MAP versions less than 2, renumber blocks before sorting
+  // them. This is useful during sorting, basic blocks in the same section will
+  // retain the default order.  This renumbering should also be done for basic
+  // block labels to match the profiles with the correct blocks. Note: This is
+  // only needed for BB address map versions lower than 2.
+  uint8_t BBAddrMapVersion = MF.getContext().getBBAddrMapVersion();
+  if (BBAddrMapVersion < 2)
+    MF.RenumberBlocks();
 
   if (BBSectionsType == BasicBlockSection::Labels) {
     MF.setBBSectionsType(BBSectionsType);
@@ -338,7 +347,14 @@
                                    FuncBBClusterInfo))
     return true;
   MF.setBBSectionsType(BBSectionsType);
-  assignSections(MF, FuncBBClusterInfo);
+
+  // Compute the original positions to use for internal ordering of the blocks
+  // in the cold section.
+  DenseMap<const MachineBasicBlock *, unsigned> PreLayoutPosition;
+  unsigned Position = 0;
+  for (const auto &MBB : MF)
+    PreLayoutPosition[&MBB] = Position++;
+  assignSections(MF, FuncBBClusterInfo, PreLayoutPosition);
 
   // We make sure that the cluster including the entry basic block precedes all
   // other clusters.
@@ -372,9 +388,9 @@
     // If the two basic block are in the same section, the order is decided by
     // their position within the section.
     if (XSectionID.Type == MBBSectionID::SectionType::Default)
-      return FuncBBClusterInfo[X.getNumber()]->PositionInCluster <
-             FuncBBClusterInfo[Y.getNumber()]->PositionInCluster;
-    return X.getNumber() < Y.getNumber();
+      return FuncBBClusterInfo[X.getBBIDOrNumber()]->PositionInCluster <
+             FuncBBClusterInfo[Y.getBBIDOrNumber()]->PositionInCluster;
+    return PreLayoutPosition[&X] < PreLayoutPosition[&Y];
   };
 
   sortBasicBlocksAndUpdateBranches(MF, Comparator);
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1347,7 +1347,8 @@
   OutStreamer->pushSection();
   OutStreamer->switchSection(BBAddrMapSection);
   OutStreamer->AddComment("version");
-  OutStreamer->emitInt8(OutStreamer->getContext().getBBAddrMapVersion());
+  uint8_t BBAddrMapVersion = OutStreamer->getContext().getBBAddrMapVersion();
+  OutStreamer->emitInt8(BBAddrMapVersion);
   OutStreamer->AddComment("feature");
   OutStreamer->emitInt8(0);
   OutStreamer->AddComment("function address");
@@ -1359,12 +1360,18 @@
   for (const MachineBasicBlock &MBB : MF) {
     const MCSymbol *MBBSymbol =
         MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol();
+    if (BBAddrMapVersion > 1) {
+      OutStreamer->AddComment("BB id");
+      // Emit the BB ID for this basic block.
+      OutStreamer->emitULEB128IntValue(*MBB.getBBID());
+    }
     // Emit the basic block offset relative to the end of the previous block.
     // This is zero unless the block is padded due to alignment.
     emitLabelDifferenceAsULEB128(MBBSymbol, PrevMBBEndSymbol);
     // Emit the basic block size. When BBs have alignments, their size cannot
     // always be computed from their offsets.
     emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol);
+    // Emit the Metadata.
     OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB));
     PrevMBBEndSymbol = MBB.getEndSymbol();
   }
Index: llvm/include/llvm/ObjectYAML/ELFYAML.h
===================================================================
--- llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -157,6 +157,7 @@
 
 struct BBAddrMapEntry {
   struct BBEntry {
+    uint32_t ID;
     llvm::yaml::Hex64 AddressOffset;
     llvm::yaml::Hex64 Size;
     llvm::yaml::Hex64 Metadata;
Index: llvm/include/llvm/Object/ELFTypes.h
===================================================================
--- llvm/include/llvm/Object/ELFTypes.h
+++ llvm/include/llvm/Object/ELFTypes.h
@@ -799,6 +799,7 @@
   uint64_t Addr; // Function address
   // Struct representing the BBAddrMap information for one basic block.
   struct BBEntry {
+    uint32_t ID;     // Unique ID of this basic block.
     uint32_t Offset; // Offset of basic block relative to function start.
     uint32_t Size;   // Size of the basic block.
 
@@ -809,13 +810,13 @@
     bool IsEHPad;        // If this is an exception handling block.
     bool CanFallThrough; // If this block can fall through to its next.
 
-    BBEntry(uint32_t Offset, uint32_t Size, uint32_t Metadata)
-        : Offset(Offset), Size(Size), HasReturn(Metadata & 1),
+    BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, uint32_t Metadata)
+        : ID(ID), Offset(Offset), Size(Size), HasReturn(Metadata & 1),
           HasTailCall(Metadata & (1 << 1)), IsEHPad(Metadata & (1 << 2)),
           CanFallThrough(Metadata & (1 << 3)){};
 
     bool operator==(const BBEntry &Other) const {
-      return Offset == Other.Offset && Size == Other.Size &&
+      return ID == Other.ID && Offset == Other.Offset && Size == Other.Size &&
              HasReturn == Other.HasReturn && HasTailCall == Other.HasTailCall &&
              IsEHPad == Other.IsEHPad && CanFallThrough == Other.CanFallThrough;
     }
Index: llvm/include/llvm/CodeGen/MachineFunction.h
===================================================================
--- llvm/include/llvm/CodeGen/MachineFunction.h
+++ llvm/include/llvm/CodeGen/MachineFunction.h
@@ -374,6 +374,9 @@
   bool HasEHScopes = false;
   bool HasEHFunclets = false;
 
+  /// BBID to assign to the next basic block of this function.
+  unsigned NextBBID = 0;
+
   /// Section Type for basic blocks, only relevant with basic block sections.
   BasicBlockSection BBSectionsType = BasicBlockSection::None;
 
Index: llvm/include/llvm/CodeGen/MachineBasicBlock.h
===================================================================
--- llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -169,6 +169,10 @@
   /// Indicate that this basic block is the entry block of a cleanup funclet.
   bool IsCleanupFuncletEntry = false;
 
+  /// Fixed unique ID assigned to this basic block upon creation. Used with
+  /// basic block sections and basic block labels.
+  Optional<unsigned> BBID;
+
   /// With basic block sections, this stores the Section ID of the basic block.
   MBBSectionID SectionID{0};
 
@@ -620,6 +624,12 @@
 
   void setIsEndSection(bool V = true) { IsEndSection = V; }
 
+  Optional<unsigned> getBBID() const { return BBID; }
+
+  /// Returns the BBID of the block when BBAddrMapVersion >= 2, otherwise
+  /// returns Number.
+  unsigned getBBIDOrNumber() const;
+
   /// Returns the section ID of this basic block.
   MBBSectionID getSectionID() const { return SectionID; }
 
@@ -629,6 +639,12 @@
            ((unsigned)SectionID.Type) + SectionID.Number;
   }
 
+  /// Sets the fixed BBID of this basic block.
+  void setBBID(unsigned V) {
+    assert(!BBID.has_value() && "Cannot change BBID.");
+    BBID = V;
+  }
+
   /// Sets the section ID for this basic block.
   void setSectionID(MBBSectionID V) { SectionID = V; }
 
Index: llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
===================================================================
--- llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
+++ llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h
@@ -32,8 +32,8 @@
 
 // The cluster information for a machine basic block.
 struct BBClusterInfo {
-  // MachineBasicBlock ID.
-  unsigned MBBNumber;
+  // Unique ID for this basic block.
+  unsigned BBID;
   // Cluster ID this basic block belongs to.
   unsigned ClusterID;
   // Position of basic block within the cluster.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to