[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-02-01 Thread Aiden Grossman via cfe-commits


@@ -73,68 +83,89 @@ FileHeader:
 Sections:
   - Name:.text.foo
 Type:SHT_PROGBITS
-Address: [[FOO_ADDR]]
+Address: 0x4000
 Flags:   [SHF_ALLOC, SHF_EXECINSTR]
-Content: '503b050520907d02ebf5c3'
+Content: '503b050530907d08ebf50f8dee1fc3'
   - Name:.text.bar
 Type:SHT_PROGBITS
-Address: [[BAR_ADDR]]
+Address: 0x5000
 Flags:   [SHF_ALLOC, SHF_EXECINSTR]
 Content: '5089d0740231f6e8f4ffc3'
+  - Name:.text.split
+Type:SHT_PROGBITS
+Address: 0x6000
+Flags:   [SHF_ALLOC, SHF_EXECINSTR]
+Content: 'c3'
   - Name:.data
 Type:SHT_PROGBITS
 Flags:   [SHF_ALLOC, SHF_WRITE]
-Address: 0x6000
+Address: 0x7000
   - Name:   .llvm_bb_addr_map.foo
 Type:   SHT_LLVM_BB_ADDR_MAP
 Link:   .text.foo
 Entries:
   - Version: 2
-Address: [[FOO_ADDR]]
-BBEntries:
-  - ID:3
-AddressOffset: 0x0
-Size:  0x1
-Metadata:  0x1
-  - ID:1
-AddressOffset: 0x0
-Size:  0x6
-Metadata:  0x0
-  - ID:2
-AddressOffset: 0x1
-Size:  0x4
-Metadata:  0x0
-  - ID:5
-AddressOffset: 0x0
-Size:  0x1
-Metadata:  0x2
+Feature: 0x8
+BBRanges:
+  - BaseAddress: 0x4000
+BBEntries:
+ - ID:3
+   AddressOffset: 0x0

boomanaiden154 wrote:

Makes sense. The test case was passing, so everything was getting decoded 
correctly.  For some reason never made the connection that the address offset 
was relative.

https://github.com/llvm/llvm-project/pull/74128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-02-01 Thread Rahman Lavaee via cfe-commits


@@ -858,62 +899,64 @@ struct BBAddrMap {
 bool hasIndirectBranch() const { return MD.HasIndirectBranch; }
   };
 
-  BBAddrMap(uint64_t Addr, std::vector BBEntries)
-  : Addr(Addr), BBEntries(std::move(BBEntries)) {}
+  // Struct representing the BBAddrMap information for a contiguous range of
+  // basic blocks (a function or a basic block section).
+  struct BBRangeEntry {
+uint64_t BaseAddress;   // Base address of the range.

rlavaee wrote:

Done.

https://github.com/llvm/llvm-project/pull/74128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-02-01 Thread Rahman Lavaee via cfe-commits


@@ -858,62 +899,64 @@ struct BBAddrMap {
 bool hasIndirectBranch() const { return MD.HasIndirectBranch; }
   };
 
-  BBAddrMap(uint64_t Addr, std::vector BBEntries)
-  : Addr(Addr), BBEntries(std::move(BBEntries)) {}
+  // Struct representing the BBAddrMap information for a contiguous range of
+  // basic blocks (a function or a basic block section).
+  struct BBRangeEntry {
+uint64_t BaseAddress;   // Base address of the range.
+std::vector BBEntries; // Basic block entries for this range.
+
+// Equality operator for unit testing.
+bool operator==(const BBRangeEntry ) const {
+  return BaseAddress == Other.BaseAddress &&
+ std::equal(BBEntries.begin(), BBEntries.end(),
+Other.BBEntries.begin());
+}
+  };
 
-  // Returns the address of the corresponding function.
-  uint64_t getFunctionAddress() const { return Addr; }
+  // All ranges for this function. The first range always corresponds to the
+  // function entry.
+  std::vector BBRanges;
 
-  // Returns the basic block entries for this function.
-  const std::vector () const { return BBEntries; }
+  // Returns the function address associated with this BBAddrMap, which is
+  // stored as the `BaseAddress` of its first BBRangeEntry. Returns 0 if
+  // BBRanges is empty.
+  uint64_t getFunctionAddress() const {

rlavaee wrote:

I now enforce (when decoding) that BB ranges must be non-empty. Thanks for the 
suggestion.

https://github.com/llvm/llvm-project/pull/74128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-01-26 Thread Aiden Grossman via cfe-commits


@@ -172,6 +172,105 @@ class OtoolOptTable : public CommonOptTable {
"Mach-O object file displaying tool") {}
 };
 
+struct BBAddrMapLabel {
+  std::string BlockLabel;
+  std::string PGOAnalysis;
+};
+
+// This class represents the BBAddrMap and PGOMap associated with a single
+// function.
+class BBAddrMapFunctionEntry {
+public:
+  BBAddrMapFunctionEntry(BBAddrMap AddrMap, PGOAnalysisMap PGOMap)
+  : AddrMap(std::move(AddrMap)), PGOMap(std::move(PGOMap)) {}
+
+  const BBAddrMap () const { return AddrMap; }
+
+  // Returns the PGO string associated with the entry of index 
`PGOBBEntryIndex`
+  // in `PGOMap`.
+  std::string constructPGOLabelString(size_t PGOBBEntryIndex) const {
+if (!PGOMap.FeatEnable.hasPGOAnalysis())
+  return "";
+std::string PGOString;
+raw_string_ostream PGOSS(PGOString);
+
+PGOSS << " (";
+if (PGOMap.FeatEnable.FuncEntryCount && PGOBBEntryIndex == 0) {
+  PGOSS << "Entry count: " << Twine(PGOMap.FuncEntryCount);
+  if (PGOMap.FeatEnable.hasPGOAnalysisBBData()) {
+PGOSS << ", ";
+  }
+}
+
+if (PGOMap.FeatEnable.hasPGOAnalysisBBData()) {
+
+  assert(PGOBBEntryIndex < PGOMap.BBEntries.size() &&
+ "Expected PGOAnalysisMap and BBAddrMap to have the same entires");
+  const PGOAnalysisMap::PGOBBEntry  =
+  PGOMap.BBEntries[PGOBBEntryIndex];
+
+  if (PGOMap.FeatEnable.BBFreq) {
+PGOSS << "Frequency: " << Twine(PGOBBEntry.BlockFreq.getFrequency());
+if (PGOMap.FeatEnable.BrProb && PGOBBEntry.Successors.size() > 0) {
+  PGOSS << ", ";
+}
+  }
+  if (PGOMap.FeatEnable.BrProb && PGOBBEntry.Successors.size() > 0) {
+PGOSS << "Successors: ";
+interleaveComma(
+PGOBBEntry.Successors, PGOSS,
+[](const PGOAnalysisMap::PGOBBEntry::SuccessorEntry ) {
+  PGOSS << "BB" << SE.ID << ":";
+  PGOSS.write_hex(SE.Prob.getNumerator());
+});
+  }
+}
+PGOSS << ")";
+
+return PGOString;
+  }
+
+private:
+  const BBAddrMap AddrMap;
+  const PGOAnalysisMap PGOMap;
+};
+
+// This class represents the BBAddrMap and PGOMap of potentially multiple
+// functions in a section.
+class BBAddrMapInfo {
+public:
+  void clear() {
+FunctionAddrToMap.clear();
+RangeBaseAddrToFunctionAddr.clear();
+  }
+  bool empty() const { return FunctionAddrToMap.empty(); }
+
+  void AddFunctionEntry(BBAddrMap AddrMap, PGOAnalysisMap PGOMap) {
+uint64_t FunctionAddr = AddrMap.getFunctionAddress();
+for (size_t I = 1; I < AddrMap.BBRanges.size(); ++I)
+  RangeBaseAddrToFunctionAddr.emplace(AddrMap.BBRanges[I].BaseAddress,
+  FunctionAddr);
+[[maybe_unused]] auto R = FunctionAddrToMap.try_emplace(
+FunctionAddr, std::move(AddrMap), std::move(PGOMap));
+assert(R.second && "duplicate function address");
+  }
+
+  const BBAddrMapFunctionEntry *getEntryForAddress(uint64_t BaseAddress) const 
{

boomanaiden154 wrote:

I'm assuming this is returning a pointer rather than a `std::optional` due to 
the inability to return an optional reference without something like a 
`std::reference_wrapper`?

https://github.com/llvm/llvm-project/pull/74128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-01-26 Thread Aiden Grossman via cfe-commits


@@ -1693,24 +1750,21 @@ disassembleObject(ObjectFile , const ObjectFile 
,
 
   LLVM_DEBUG(LVP.dump());
 
-  std::unordered_map AddrToBBAddrMap;
-  std::unordered_map AddrToPGOAnalysisMap;
+  BBAddrMapInfo FullAddrMap;
   auto ReadBBAddrMap = [&](std::optional SectionIndex =
std::nullopt) {
-AddrToBBAddrMap.clear();
+FullAddrMap.clear();
 if (const auto *Elf = dyn_cast()) {
   std::vector PGOAnalyses;
   auto BBAddrMapsOrErr = Elf->readBBAddrMap(SectionIndex, );
   if (!BBAddrMapsOrErr) {
 reportWarning(toString(BBAddrMapsOrErr.takeError()), 
Obj.getFileName());
 return;
   }
-  for (const auto &[FunctionBBAddrMap, FunctionPGOAnalysis] :
+  for (auto &&[FunctionBBAddrMap, FunctionPGOAnalysis] :

boomanaiden154 wrote:

Looks like this is still here since this hasn't been rebased/main hasn't been 
merged in recently?

https://github.com/llvm/llvm-project/pull/74128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-01-25 Thread Mircea Trofin via cfe-commits


@@ -858,62 +899,64 @@ struct BBAddrMap {
 bool hasIndirectBranch() const { return MD.HasIndirectBranch; }
   };
 
-  BBAddrMap(uint64_t Addr, std::vector BBEntries)
-  : Addr(Addr), BBEntries(std::move(BBEntries)) {}
+  // Struct representing the BBAddrMap information for a contiguous range of
+  // basic blocks (a function or a basic block section).
+  struct BBRangeEntry {
+uint64_t BaseAddress;   // Base address of the range.
+std::vector BBEntries; // Basic block entries for this range.
+
+// Equality operator for unit testing.
+bool operator==(const BBRangeEntry ) const {
+  return BaseAddress == Other.BaseAddress &&
+ std::equal(BBEntries.begin(), BBEntries.end(),
+Other.BBEntries.begin());
+}
+  };
 
-  // Returns the address of the corresponding function.
-  uint64_t getFunctionAddress() const { return Addr; }
+  // All ranges for this function. The first range always corresponds to the
+  // function entry.
+  std::vector BBRanges;
 
-  // Returns the basic block entries for this function.
-  const std::vector () const { return BBEntries; }
+  // Returns the function address associated with this BBAddrMap, which is
+  // stored as the `BaseAddress` of its first BBRangeEntry. Returns 0 if
+  // BBRanges is empty.
+  uint64_t getFunctionAddress() const {

mtrofin wrote:

nit: how about return `std::optional`? makes the user check that the 
result is actually a value ("0" can be used in subsequent numerical operations, 
`std::nullopt` can't)

https://github.com/llvm/llvm-project/pull/74128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-01-19 Thread via cfe-commits


@@ -1401,17 +1406,48 @@ void AsmPrinter::emitBBAddrMapSection(const 
MachineFunction ) {
   uint8_t BBAddrMapVersion = OutStreamer->getContext().getBBAddrMapVersion();
   OutStreamer->emitInt8(BBAddrMapVersion);
   OutStreamer->AddComment("feature");
-  auto FeaturesBits = static_cast(PgoAnalysisMapFeatures.getBits());
-  OutStreamer->emitInt8(FeaturesBits);
-  OutStreamer->AddComment("function address");
-  OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize());
-  OutStreamer->AddComment("number of basic blocks");
-  OutStreamer->emitULEB128IntValue(MF.size());
-  const MCSymbol *PrevMBBEndSymbol = FunctionSymbol;
+  auto Features = getBBAddrMapFeature(MF, MBBSectionRanges.size());
+  OutStreamer->emitInt8(Features.encode());
   // Emit BB Information for each basic block in the function.
+  if (Features.MultiBBRange) {
+OutStreamer->AddComment("number of basic block ranges");
+OutStreamer->emitULEB128IntValue(MBBSectionRanges.size());
+  }
+  // Number of blocks in each MBB section.
+  MapVector MBBSectionNumBlocks;
+  const MCSymbol *PrevMBBEndSymbol = nullptr;
+  if (!Features.MultiBBRange) {
+OutStreamer->AddComment("function address");

lifengxiang1025 wrote:

Thanks. I understand your point now.

https://github.com/llvm/llvm-project/pull/74128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-01-11 Thread James Henderson via cfe-commits


@@ -1419,32 +1419,50 @@ void ELFState::writeSectionContent(
   CBA.write(E.Feature);
   SHeader.sh_size += 2;
 }
-
-if (Section.PGOAnalyses) {
-  if (E.Version < 2)
-WithColor::warning()
-<< "unsupported SHT_LLVM_BB_ADDR_MAP version when using PGO: "
-<< static_cast(E.Version) << "; must use version >= 2";
+auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(E.Feature);
+bool MultiBBRangeFeatureEnabled = false;
+if (!FeatureOrErr)
+  WithColor::warning() << toString(FeatureOrErr.takeError());
+else
+  MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;
+bool MultiBBRange =
+MultiBBRangeFeatureEnabled ||
+(E.NumBBRanges.has_value() && E.NumBBRanges.value() > 1) ||
+(E.BBRanges && E.BBRanges->size() > 1);
+if (MultiBBRange && !MultiBBRangeFeatureEnabled)
+  WithColor::warning() << "Feature value(" << E.Feature

jh7370 wrote:

```suggestion
  WithColor::warning() << "feature value(" << E.Feature
```
Nit, per coding standards.

https://github.com/llvm/llvm-project/pull/74128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-01-08 Thread Micah Weston via cfe-commits


@@ -7574,30 +7573,38 @@ template  void 
LLVMELFDumper::printBBAddrMaps() {
   continue;
 }
 for (const BBAddrMap  : *BBAddrMapOrErr) {
-  DictScope D(W, "Function");
-  W.printHex("At", AM.Addr);
+  DictScope FD(W, "Function");
+  if (AM.BBRanges.empty())

red1bluelost wrote:

Are there scenarios where BBRanges would be completely empty? If so, what are 
those scenarios?

https://github.com/llvm/llvm-project/pull/74128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-01-07 Thread Micah Weston via cfe-commits


@@ -719,60 +730,83 @@ decodeBBAddrMapImpl(const ELFFile ,
   Feature = Data.getU8(Cur); // Feature byte
   if (!Cur)
 break;
-  auto FeatEnableOrErr = PGOAnalysisMap::Features::decode(Feature);
+  auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature);
   if (!FeatEnableOrErr)
 return FeatEnableOrErr.takeError();
-  FeatEnable =
-  FeatEnableOrErr ? *FeatEnableOrErr : PGOAnalysisMap::Features{};
+  FeatEnable = FeatEnableOrErr ? *FeatEnableOrErr : BBAddrMap::Features{};

red1bluelost wrote:

(Nit) I think this can just always assume true given that we return on error in 
the line before. (woops, I think I wrote this wrong)

```suggestion
  FeatEnable = *FeatEnableOrErr;
```

https://github.com/llvm/llvm-project/pull/74128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-01-04 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-lld-elf
@llvm/pr-subscribers-backend-x86

@llvm/pr-subscribers-clang

Author: Rahman Lavaee (rlavaee)


Changes


Today `-split-machine-functions` and `-fbasic-block-sections={all,list}` cannot 
be combined with `-basic-block-sections=labels` (the labels option will be 
ignored).
The inconsistency comes from the way basic block address map -- the underlying 
mechanism for basic block labels -- encodes basic block addresses 
(https://lists.llvm.org/pipermail/llvm-dev/2020-July/143512.html).  
Specifically, basic block offsets are computed relative to the function begin 
symbol. This relies on functions being contiguous which is not the case for MFS 
and basic block section binaries. This means Propeller cannot use binary 
profiles collected from these binaries, which limits the applicability of 
Propeller for iterative optimization.

To make the `SHT_LLVM_BB_ADDR_MAP` feature work with basic block section 
binaries, we propose modifying the encoding of this section as follows.

First let us review the current encoding which emits the address of each 
function and its number of basic blocks, followed by basic block entries for 
each basic block.

| | |
|--|--|
|  Address of the function   | Function Address  |
|  Number of basic blocks in this function | NumBlocks |
|  BB entry 1
|  BB entry 2
|   ...
|  BB entry #NumBlocks

To make this work for basic block sections, we treat each basic block section 
similar to a function, except that basic block sections of the same function 
must be encapsulated in the same structure so we can map all of them to their 
single function.

We modify the encoding to first emit the number of basic block sections (BB 
ranges) in the function. Then we emit the address map of each basic block 
section section as before: the base address of the section, its number of 
blocks, and BB entries for its basic block. The first section in the BB address 
map is always the function entry section.
| | |
|--|--|
|  Number of sections for this function   | NumBBRanges |
| Section 1 begin address | BaseAddress[1]  |
| Number of basic blocks in section 1 | NumBlocks[1]|
| BB entries for Section 1
|..|
| Section #NumBBRanges begin address  | 
BaseAddress[NumBBRanges] |
| Number of basic blocks in section #NumBBRanges  | NumBlocks[NumBBRanges]  |
| BB entries for Section #NumBBRanges

The encoding of basic block entries remains as before with the minor change 
that each basic block offset is now computed relative to the begin symbol of 
its containing BB section.

This patch adds a new boolean codegen option `-basic-block-address-map`. 
Correspondingly, the front-end flag `-fbasic-block-address-map` and LLD flag 
`--lto-basic-block-address-map` are introduced.
Analogously, we add a new TargetOption field `BBAddrMap`. This means BB 
address maps are either generated for all functions in the compiling unit, or 
for none (depending on `TargetOptions::BBAddrMap`).

This patch keeps the functionality of the old `-fbasic-block-sections=labels` 
option but does not remove it. A subsequent patch will remove the obsolete 
option.

We refactor the `BasicBlockSections` pass by separating the BB address map and 
BB sections handing to their own functions (named `handleBBAddrMap` and 
`handleBBSections`).  `handleBBSections` renumbers basic blocks and places them 
in their assigned sections. `handleBBAddrMap` is invoked after 
`handleBBSections` (if requested) and only renumbers the blocks.
  - New tests added:
   - Two tests basic-block-address-map-with-basic-block-sections.ll and  
basic-block-address-map-with-mfs.ll to exercise the combination of 
`-basic-block-address-map` with `-basic-block-sections=list` and 
'-split-machine-functions`.
   - A driver sanity test for the `-fbasic-block-address-map` option 
(basic-block-address-map.c).
   - An LLD test for testing the `--lto-basic-block-address-map` option. 
This reuses the LLVM IR from `lld/test/ELF/lto/basic-block-sections.ll`.
  - Renamed and modified the two existing codegen tests for basic block address 
map (`basic-block-sections-labels-functions-sections.ll` and 
`basic-block-sections-labels.ll`)


---

Patch is 125.95 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/74128.diff


38 Files Affected:

- (modified) clang/include/clang/Basic/CodeGenOptions.def (+1) 
- (modified) clang/include/clang/Driver/Options.td (+4) 
- (modified) clang/lib/CodeGen/BackendUtil.cpp (+1) 
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+11) 
- (added) clang/test/Driver/basic-block-address-map.c (+8) 
- (modified) lld/ELF/Config.h (+3) 
- (modified) lld/ELF/Driver.cpp (+3) 
- (modified) lld/ELF/LTO.cpp (+2) 
- (modified) lld/ELF/Options.td (+3) 
- (added) lld/test/ELF/lto/basic-block-address-map.ll (+28) 
- (modified) 

[llvm] [lld] [clang] [SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (PR #74128)

2024-01-04 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-binary-utilities

Author: Rahman Lavaee (rlavaee)


Changes


Today `-split-machine-functions` and `-fbasic-block-sections={all,list}` cannot 
be combined with `-basic-block-sections=labels` (the labels option will be 
ignored).
The inconsistency comes from the way basic block address map -- the underlying 
mechanism for basic block labels -- encodes basic block addresses 
(https://lists.llvm.org/pipermail/llvm-dev/2020-July/143512.html).  
Specifically, basic block offsets are computed relative to the function begin 
symbol. This relies on functions being contiguous which is not the case for MFS 
and basic block section binaries. This means Propeller cannot use binary 
profiles collected from these binaries, which limits the applicability of 
Propeller for iterative optimization.

To make the `SHT_LLVM_BB_ADDR_MAP` feature work with basic block section 
binaries, we propose modifying the encoding of this section as follows.

First let us review the current encoding which emits the address of each 
function and its number of basic blocks, followed by basic block entries for 
each basic block.

| | |
|--|--|
|  Address of the function   | Function Address  |
|  Number of basic blocks in this function | NumBlocks |
|  BB entry 1
|  BB entry 2
|   ...
|  BB entry #NumBlocks

To make this work for basic block sections, we treat each basic block section 
similar to a function, except that basic block sections of the same function 
must be encapsulated in the same structure so we can map all of them to their 
single function.

We modify the encoding to first emit the number of basic block sections (BB 
ranges) in the function. Then we emit the address map of each basic block 
section section as before: the base address of the section, its number of 
blocks, and BB entries for its basic block. The first section in the BB address 
map is always the function entry section.
| | |
|--|--|
|  Number of sections for this function   | NumBBRanges |
| Section 1 begin address | BaseAddress[1]  |
| Number of basic blocks in section 1 | NumBlocks[1]|
| BB entries for Section 1
|..|
| Section #NumBBRanges begin address  | 
BaseAddress[NumBBRanges] |
| Number of basic blocks in section #NumBBRanges  | NumBlocks[NumBBRanges]  |
| BB entries for Section #NumBBRanges

The encoding of basic block entries remains as before with the minor change 
that each basic block offset is now computed relative to the begin symbol of 
its containing BB section.

This patch adds a new boolean codegen option `-basic-block-address-map`. 
Correspondingly, the front-end flag `-fbasic-block-address-map` and LLD flag 
`--lto-basic-block-address-map` are introduced.
Analogously, we add a new TargetOption field `BBAddrMap`. This means BB 
address maps are either generated for all functions in the compiling unit, or 
for none (depending on `TargetOptions::BBAddrMap`).

This patch keeps the functionality of the old `-fbasic-block-sections=labels` 
option but does not remove it. A subsequent patch will remove the obsolete 
option.

We refactor the `BasicBlockSections` pass by separating the BB address map and 
BB sections handing to their own functions (named `handleBBAddrMap` and 
`handleBBSections`).  `handleBBSections` renumbers basic blocks and places them 
in their assigned sections. `handleBBAddrMap` is invoked after 
`handleBBSections` (if requested) and only renumbers the blocks.
  - New tests added:
   - Two tests basic-block-address-map-with-basic-block-sections.ll and  
basic-block-address-map-with-mfs.ll to exercise the combination of 
`-basic-block-address-map` with `-basic-block-sections=list` and 
'-split-machine-functions`.
   - A driver sanity test for the `-fbasic-block-address-map` option 
(basic-block-address-map.c).
   - An LLD test for testing the `--lto-basic-block-address-map` option. 
This reuses the LLVM IR from `lld/test/ELF/lto/basic-block-sections.ll`.
  - Renamed and modified the two existing codegen tests for basic block address 
map (`basic-block-sections-labels-functions-sections.ll` and 
`basic-block-sections-labels.ll`)


---

Patch is 125.95 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/74128.diff


38 Files Affected:

- (modified) clang/include/clang/Basic/CodeGenOptions.def (+1) 
- (modified) clang/include/clang/Driver/Options.td (+4) 
- (modified) clang/lib/CodeGen/BackendUtil.cpp (+1) 
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+11) 
- (added) clang/test/Driver/basic-block-address-map.c (+8) 
- (modified) lld/ELF/Config.h (+3) 
- (modified) lld/ELF/Driver.cpp (+3) 
- (modified) lld/ELF/LTO.cpp (+2) 
- (modified) lld/ELF/Options.td (+3) 
- (added) lld/test/ELF/lto/basic-block-address-map.ll (+28) 
- (modified) llvm/include/llvm/CodeGen/CommandFlags.h (+2) 
- (modified)