[clang] 7841e21 - Let -basic-block-sections=labels emit basicblock metadata in a new .bb_addr_map section, instead of emitting special unary-encoded symbols.
Rahman Lavaee via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 14 10:16:59 PDT 2020
Author: Rahman Lavaee
Date: 2020-09-14T10:16:44-07:00
New Revision: 7841e21c98495ba5e33e0d2507d985bd5b938445
URL: https://github.com/llvm/llvm-project/commit/7841e21c98495ba5e33e0d2507d985bd5b938445
DIFF: https://github.com/llvm/llvm-project/commit/7841e21c98495ba5e33e0d2507d985bd5b938445.diff
LOG: Let -basic-block-sections=labels emit basicblock metadata in a new .bb_addr_map section, instead of emitting special unary-encoded symbols.
This patch introduces the new .bb_addr_map section feature which allows us to emit the bits needed for mapping binary profiles to basic blocks into a separate section.
The format of the emitted data is represented as follows. It includes a header for every function:
| Address of the function | -> 8 bytes (pointer size)
| Number of basic blocks in this function (>0) | -> ULEB128
The header is followed by a BB record for every basic block. These records are ordered in the same order as MachineBasicBlocks are placed in the function. Each BB Info is structured as follows:
| Offset of the basic block relative to function begin | -> ULEB128
| Binary size of the basic block | -> ULEB128
| BB metadata | -> ULEB128 [ MBB.isReturn() OR MBB.hasTailCall() << 1 OR MBB.isEHPad() << 2 ]
The new feature will replace the existing "BB labels" functionality with -basic-block-sections=labels.
The .bb_addr_map section scrubs the specially-encoded BB symbols from the binary and makes it friendly to profilers and debuggers.
Furthermore, the new feature reduces the binary size overhead from 70% bloat to only 12%.
For more information and results please refer to the RFC: https://lists.llvm.org/pipermail/llvm-dev/2020-July/143512.html
Reviewed By: MaskRay, snehasish
Differential Revision: https://reviews.llvm.org/D85408
Added:
llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll
Modified:
clang/docs/UsersManual.rst
clang/test/CodeGen/basic-block-sections.c
llvm/include/llvm/CodeGen/AsmPrinter.h
llvm/include/llvm/CodeGen/MachineFunction.h
llvm/include/llvm/MC/MCObjectFileInfo.h
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/CodeGen/BasicBlockSections.cpp
llvm/lib/CodeGen/MIRParser/MIRParser.cpp
llvm/lib/CodeGen/MachineBasicBlock.cpp
llvm/lib/CodeGen/MachineFunction.cpp
llvm/lib/MC/MCObjectFileInfo.cpp
llvm/test/CodeGen/X86/basic-block-sections-labels.ll
Removed:
################################################################################
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 1a1aea2ae538..2d0d71443dfd 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -1700,9 +1700,12 @@ are listed below.
**-fbasic-block-sections=[labels, all, list=<arg>, none]**
- Controls whether Clang emits a label for each basic block. Further, with
- values "all" and "list=arg", each basic block or a subset of basic blocks
- can be placed in its own unique section.
+ Controls how Clang emits text sections for basic blocks. With values ``all``
+ and ``list=<arg>``, each basic block or a subset of basic blocks can be placed
+ in its own unique section. With the "labels" value, normal text sections are
+ emitted, but a ``.bb_addr_map`` section is emitted which includes address
+ offsets for each basic block in the program, relative to the parent function
+ address.
With the ``list=<arg>`` option, a file containing the subset of basic blocks
that need to placed in unique sections can be specified. The format of the
diff --git a/clang/test/CodeGen/basic-block-sections.c b/clang/test/CodeGen/basic-block-sections.c
index 6cdea79f0fa7..dc414d70ba5f 100644
--- a/clang/test/CodeGen/basic-block-sections.c
+++ b/clang/test/CodeGen/basic-block-sections.c
@@ -1,12 +1,11 @@
// REQUIRES: x86-registered-target
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -o - < %s | FileCheck %s --check-prefix=PLAIN
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasic-block-sections=all -fbasic-block-sections=none -o - < %s | FileCheck %s --check-prefix=PLAIN
+// RUN: %clang_cc1 -triple x86_64 -S -o - < %s | FileCheck %s --check-prefix=PLAIN
+// RUN: %clang_cc1 -triple x86_64 -S -fbasic-block-sections=all -fbasic-block-sections=none -o - < %s | FileCheck %s --check-prefix=PLAIN
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasic-block-sections=labels -o - < %s | FileCheck %s --check-prefix=BB_LABELS
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasic-block-sections=all -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_ALL
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasic-block-sections=list=%S/Inputs/basic-block-sections.funcnames -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_LIST
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasic-block-sections=all -funique-basic-block-section-names -o - < %s | FileCheck %s --check-prefix=UNIQUE
+// RUN: %clang_cc1 -triple x86_64 -S -fbasic-block-sections=all -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_ALL
+// RUN: %clang_cc1 -triple x86_64 -S -fbasic-block-sections=list=%S/Inputs/basic-block-sections.funcnames -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_LIST
+// RUN: %clang_cc1 -triple x86_64 -S -fbasic-block-sections=all -funique-basic-block-section-names -o - < %s | FileCheck %s --check-prefix=UNIQUE
int world(int a) {
if (a > 10)
@@ -26,12 +25,6 @@ int another(int a) {
// PLAIN-NOT: section
// PLAIN: world:
//
-// BB_LABELS-NOT: section
-// BB_LABELS: world:
-// BB_LABELS: a.BB.world:
-// BB_LABELS: aa.BB.world:
-// BB_LABELS: a.BB.another:
-//
// BB_WORLD: .section .text.world,"ax", at progbits{{$}}
// BB_WORLD: world:
// BB_WORLD: .section .text.world,"ax", at progbits,unique
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index eab6eb52b86c..c157bb0672ba 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -342,6 +342,8 @@ class AsmPrinter : public MachineFunctionPass {
void emitStackSizeSection(const MachineFunction &MF);
+ void emitBBAddrMapSection(const MachineFunction &MF);
+
void emitRemarksSection(remarks::RemarkStreamer &RS);
enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index 247716df7882..8f80eca939fd 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -510,9 +510,6 @@ class MachineFunction {
void setBBSectionsType(BasicBlockSection V) { BBSectionsType = V; }
- /// Creates basic block Labels for this function.
- void createBBLabels();
-
/// Assign IsBeginSection IsEndSection fields for basic blocks in this
/// function.
void assignBeginEndSections();
diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index ca04d8e8d3b6..8c6bcba2332b 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -338,6 +338,8 @@ class MCObjectFileInfo {
MCSection *getStackSizesSection(const MCSection &TextSec) const;
+ MCSection *getBBAddrMapSection(const MCSection &TextSec) const;
+
// ELF specific sections.
MCSection *getDataRelROSection() const { return DataRelROSection; }
const MCSection *getMergeableConst4Section() const {
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 7a141819950a..01370baa4fd1 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1023,6 +1023,46 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {
MCConstantExpr::create(FrameOffset, OutContext));
}
+/// Returns the BB metadata to be emitted in the bb_addr_map section for a given
+/// basic block. This can be used to capture more precise profile information.
+/// We use the last 3 bits (LSBs) to ecnode the following information:
+/// * (1): set if return block (ret or tail call).
+/// * (2): set if ends with a tail call.
+/// * (3): set if exception handling (EH) landing pad.
+/// The remaining bits are zero.
+static unsigned getBBAddrMapMetadata(const MachineBasicBlock &MBB) {
+ const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo();
+ return ((unsigned)MBB.isReturnBlock()) |
+ ((!MBB.empty() && TII->isTailCall(MBB.back())) << 1) |
+ (MBB.isEHPad() << 2);
+}
+
+void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
+ MCSection *BBAddrMapSection =
+ getObjFileLowering().getBBAddrMapSection(*MF.getSection());
+ assert(BBAddrMapSection && ".bb_addr_map section is not initialized.");
+
+ const MCSymbol *FunctionSymbol = getFunctionBegin();
+
+ OutStreamer->PushSection();
+ OutStreamer->SwitchSection(BBAddrMapSection);
+ OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize());
+ // Emit the total number of basic blocks in this function.
+ OutStreamer->emitULEB128IntValue(MF.size());
+ // Emit BB Information for each basic block in the funciton.
+ for (const MachineBasicBlock &MBB : MF) {
+ const MCSymbol *MBBSymbol =
+ MBB.pred_empty() ? FunctionSymbol : MBB.getSymbol();
+ // Emit the basic block offset.
+ emitLabelDifferenceAsULEB128(MBBSymbol, FunctionSymbol);
+ // Emit the basic block size. When BBs have alignments, their size cannot
+ // always be computed from their offsets.
+ emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol);
+ OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB));
+ }
+ OutStreamer->PopSection();
+}
+
void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {
if (!MF.getTarget().Options.EmitStackSizeSection)
return;
@@ -1179,34 +1219,26 @@ void AsmPrinter::emitFunctionBody() {
}
// We must emit temporary symbol for the end of this basic block, if either
- // we have BBLabels enabled and we want to emit size directive for the BBs,
- // or if this basic blocks marks the end of a section (except the section
- // containing the entry basic block as the end symbol for that section is
- // CurrentFnEnd).
- if ((MAI->hasDotTypeDotSizeDirective() && MF->hasBBLabels()) ||
- (MBB.isEndSection() && !MBB.sameSection(&MF->front())))
+ // we have BBLabels enabled or if this basic blocks marks the end of a
+ // section (except the section containing the entry basic block as the end
+ // symbol for that section is CurrentFnEnd).
+ if (MF->hasBBLabels() ||
+ (MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection() &&
+ !MBB.sameSection(&MF->front())))
OutStreamer->emitLabel(MBB.getEndSymbol());
- // Helper for emitting the size directive associated with a basic block
- // symbol.
- auto emitELFSizeDirective = [&](MCSymbol *SymForSize) {
- const MCExpr *SizeExp = MCBinaryExpr::createSub(
- MCSymbolRefExpr::create(MBB.getEndSymbol(), OutContext),
- MCSymbolRefExpr::create(SymForSize, OutContext), OutContext);
- OutStreamer->emitELFSize(SymForSize, SizeExp);
- };
-
- // Emit size directive for the size of each basic block, if BBLabels is
- // enabled.
- if (MAI->hasDotTypeDotSizeDirective() && MF->hasBBLabels())
- emitELFSizeDirective(MBB.getSymbol());
-
- // Emit size directive for the size of each basic block section once we
- // get to the end of that section.
if (MBB.isEndSection()) {
+ // The size directive for the section containing the entry block is
+ // handled separately by the function section.
if (!MBB.sameSection(&MF->front())) {
- if (MAI->hasDotTypeDotSizeDirective())
- emitELFSizeDirective(CurrentSectionBeginSym);
+ if (MAI->hasDotTypeDotSizeDirective()) {
+ // Emit the size directive for the basic block section.
+ const MCExpr *SizeExp = MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(MBB.getEndSymbol(), OutContext),
+ MCSymbolRefExpr::create(CurrentSectionBeginSym, OutContext),
+ OutContext);
+ OutStreamer->emitELFSize(CurrentSectionBeginSym, SizeExp);
+ }
MBBSectionRanges[MBB.getSectionIDNum()] =
MBBSectionRange{CurrentSectionBeginSym, MBB.getEndSymbol()};
}
@@ -1298,6 +1330,11 @@ void AsmPrinter::emitFunctionBody() {
HI.Handler->endFunction(MF);
}
+ // Emit section containing BB address offsets and their metadata, when
+ // BB labels are requested for this function.
+ if (MF->hasBBLabels())
+ emitBBAddrMapSection(*MF);
+
// Emit section containing stack size metadata.
emitStackSizeSection(*MF);
@@ -1807,7 +1844,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
F.hasFnAttribute("function-instrument") ||
F.hasFnAttribute("xray-instruction-threshold") ||
needFuncLabelsForEHOrDebugInfo(MF) || NeedsLocalForSize ||
- MF.getTarget().Options.EmitStackSizeSection) {
+ MF.getTarget().Options.EmitStackSizeSection || MF.hasBBLabels()) {
CurrentFnBegin = createTempSymbol("func_begin");
if (NeedsLocalForSize)
CurrentFnSymForSize = CurrentFnBegin;
diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp
index a3c366004c7f..421c1d896a0f 100644
--- a/llvm/lib/CodeGen/BasicBlockSections.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSections.cpp
@@ -48,19 +48,11 @@
// Basic Block Labels
// ==================
//
-// With -fbasic-block-sections=labels, or when a basic block is placed in a
-// unique section, it is labelled with a symbol. This allows easy mapping of
-// virtual addresses from PMU profiles back to the corresponding basic blocks.
-// Since the number of basic blocks is large, the labeling bloats the symbol
-// table sizes and the string table sizes significantly. While the binary size
-// does increase, it does not affect performance as the symbol table is not
-// loaded in memory during run-time. The string table size bloat is kept very
-// minimal using a unary naming scheme that uses string suffix compression. The
-// basic blocks for function foo are named "a.BB.foo", "aa.BB.foo", ... This
-// turns out to be very good for string table sizes and the bloat in the string
-// table size for a very large binary is ~8 %. The naming also allows using
-// the --symbol-ordering-file option in LLD to arbitrarily reorder the
-// sections.
+// With -fbasic-block-sections=labels, we emit the offsets of BB addresses of
+// every function into a .bb_addr_map section. Along with the function symbols,
+// this allows for mapping of virtual addresses in PMU profiles back to the
+// corresponding basic blocks. This logic is implemented in AsmPrinter. This
+// pass only assigns the BBSectionType of every function to ``labels``.
//
//===----------------------------------------------------------------------===//
@@ -304,7 +296,6 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
if (BBSectionsType == BasicBlockSection::Labels) {
MF.setBBSectionsType(BBSectionsType);
- MF.createBBLabels();
return true;
}
@@ -314,7 +305,6 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
FuncBBClusterInfo))
return true;
MF.setBBSectionsType(BBSectionsType);
- MF.createBBLabels();
assignSections(MF, FuncBBClusterInfo);
// We make sure that the cluster including the entry basic block precedes all
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 945a560de3ca..030c3d3e23ab 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -451,10 +451,8 @@ MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
}
// Check Basic Block Section Flags.
if (MF.getTarget().getBBSectionsType() == BasicBlockSection::Labels) {
- MF.createBBLabels();
MF.setBBSectionsType(BasicBlockSection::Labels);
} else if (MF.hasBBSections()) {
- MF.createBBLabels();
MF.assignBeginEndSections();
}
PFS.SM = &SM;
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index ebdd17fc728d..b260af72043b 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -60,28 +60,11 @@ MCSymbol *MachineBasicBlock::getSymbol() const {
if (!CachedMCSymbol) {
const MachineFunction *MF = getParent();
MCContext &Ctx = MF->getContext();
- auto Prefix = Ctx.getAsmInfo()->getPrivateLabelPrefix();
- assert(getNumber() >= 0 && "cannot get label for unreachable MBB");
-
- // We emit a non-temporary symbol for every basic block if we have BBLabels
- // or -- with basic block sections -- when a basic block begins a section.
- // With basic block symbols, we use a unary encoding which can
- // compress the symbol names significantly. For basic block sections where
- // this block is the first in a cluster, we use a non-temp descriptive name.
- // Otherwise we fall back to use temp label.
- if (MF->hasBBLabels()) {
- auto Iter = MF->getBBSectionsSymbolPrefix().begin();
- if (getNumber() < 0 ||
- getNumber() >= (int)MF->getBBSectionsSymbolPrefix().size())
- report_fatal_error("Unreachable MBB: " + Twine(getNumber()));
- // The basic blocks for function foo are named a.BB.foo, aa.BB.foo, and
- // so on.
- std::string Prefix(Iter + 1, Iter + getNumber() + 1);
- std::reverse(Prefix.begin(), Prefix.end());
- CachedMCSymbol =
- Ctx.getOrCreateSymbol(Twine(Prefix) + ".BB." + Twine(MF->getName()));
- } else if (MF->hasBBSections() && isBeginSection()) {
+ // We emit a non-temporary symbol -- with a descriptive name -- if it begins
+ // a section (with basic block sections). Otherwise we fall back to use temp
+ // label.
+ if (MF->hasBBSections() && isBeginSection()) {
SmallString<5> Suffix;
if (SectionID == MBBSectionID::ColdSectionID) {
Suffix += ".cold";
@@ -92,6 +75,7 @@ MCSymbol *MachineBasicBlock::getSymbol() const {
}
CachedMCSymbol = Ctx.getOrCreateSymbol(MF->getName() + Suffix);
} else {
+ const StringRef Prefix = Ctx.getAsmInfo()->getPrivateLabelPrefix();
CachedMCSymbol = Ctx.getOrCreateSymbol(Twine(Prefix) + "BB" +
Twine(MF->getFunctionNumber()) +
"_" + Twine(getNumber()));
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index 0950d6497e43..e4473fd124df 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -341,33 +341,6 @@ void MachineFunction::RenumberBlocks(MachineBasicBlock *MBB) {
MBBNumbering.resize(BlockNo);
}
-/// This is used with -fbasic-block-sections or -fbasicblock-labels option.
-/// A unary encoding of basic block labels is done to keep ".strtab" sizes
-/// small.
-void MachineFunction::createBBLabels() {
- const TargetInstrInfo *TII = getSubtarget().getInstrInfo();
- this->BBSectionsSymbolPrefix.resize(getNumBlockIDs(), 'a');
- for (auto MBBI = begin(), E = end(); MBBI != E; ++MBBI) {
- assert(
- (MBBI->getNumber() >= 0 && MBBI->getNumber() < (int)getNumBlockIDs()) &&
- "BasicBlock number was out of range!");
- // 'a' - Normal block.
- // 'r' - Return block.
- // 'l' - Landing Pad.
- // 'L' - Return and landing pad.
- bool isEHPad = MBBI->isEHPad();
- bool isRetBlock = MBBI->isReturnBlock() && !TII->isTailCall(MBBI->back());
- char type = 'a';
- if (isEHPad && isRetBlock)
- type = 'L';
- else if (isEHPad)
- type = 'l';
- else if (isRetBlock)
- type = 'r';
- BBSectionsSymbolPrefix[MBBI->getNumber()] = type;
- }
-}
-
/// This method iterates over the basic blocks and assigns their IsBeginSection
/// and IsEndSection fields. This must be called after MBB layout is finalized
/// and the SectionID's are assigned to MBBs.
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 927294fcd7e1..0660780c15a1 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -953,3 +953,21 @@ MCObjectFileInfo::getStackSizesSection(const MCSection &TextSec) const {
GroupName, MCSection::NonUniqueID,
cast<MCSymbolELF>(TextSec.getBeginSymbol()));
}
+
+MCSection *
+MCObjectFileInfo::getBBAddrMapSection(const MCSection &TextSec) const {
+ if (Env != IsELF)
+ return nullptr;
+
+ const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
+ unsigned Flags = ELF::SHF_LINK_ORDER;
+ StringRef GroupName;
+ if (const MCSymbol *Group = ElfSec.getGroup()) {
+ GroupName = Group->getName();
+ Flags |= ELF::SHF_GROUP;
+ }
+
+ return Ctx->getELFSection(".bb_addr_map", ELF::SHT_PROGBITS, Flags, 0,
+ GroupName, MCSection::NonUniqueID,
+ cast<MCSymbolELF>(TextSec.getBeginSymbol()));
+}
diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll b/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll
new file mode 100644
index 000000000000..1142a8a1ec1b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll
@@ -0,0 +1,35 @@
+; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-sections=labels | FileCheck %s
+
+$_Z4fooTIiET_v = comdat any
+
+define dso_local i32 @_Z3barv() {
+ ret i32 0
+}
+;; Check we add SHF_LINK_ORDER for .bb_addr_map and link it with the corresponding .text sections.
+; CHECK: .section .text._Z3barv,"ax", at progbits
+; CHECK-LABEL: _Z3barv:
+; CHECK-NEXT: [[BAR_BEGIN:.Lfunc_begin[0-9]+]]:
+; CHECK: .section .bb_addr_map,"o", at progbits,.text._Z3barv{{$}}
+; CHECK-NEXT: .quad [[BAR_BEGIN]]
+
+
+define dso_local i32 @_Z3foov() {
+ %1 = call i32 @_Z4fooTIiET_v()
+ ret i32 %1
+}
+; CHECK: .section .text._Z3foov,"ax", at progbits
+; CHECK-LABEL: _Z3foov:
+; CHECK-NEXT: [[FOO_BEGIN:.Lfunc_begin[0-9]+]]:
+; CHECK: .section .bb_addr_map,"o", at progbits,.text._Z3foov{{$}}
+; CHECK-NEXT: .quad [[FOO_BEGIN]]
+
+
+define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat {
+ ret i32 0
+}
+;; Check we add .bb_addr_map section to a COMDAT group with the corresponding .text section if such a COMDAT exists.
+; CHECK: .section .text._Z4fooTIiET_v,"axG", at progbits,_Z4fooTIiET_v,comdat
+; CHECK-LABEL: _Z4fooTIiET_v:
+; CHECK-NEXT: [[FOOCOMDAT_BEGIN:.Lfunc_begin[0-9]+]]:
+; CHECK: .section .bb_addr_map,"Go", at progbits,_Z4fooTIiET_v,comdat,.text._Z4fooTIiET_v{{$}}
+; CHECK-NEXT: .quad [[FOOCOMDAT_BEGIN]]
diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll b/llvm/test/CodeGen/X86/basic-block-sections-labels.ll
index 80aaf79c115a..267132c92e98 100644
--- a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll
+++ b/llvm/test/CodeGen/X86/basic-block-sections-labels.ll
@@ -1,23 +1,24 @@
; Check the basic block sections labels option
-; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=labels | FileCheck %s -check-prefix=LINUX-LABELS
+; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-sections=labels | FileCheck %s
-define void @_Z3bazb(i1 zeroext) {
- %2 = alloca i8, align 1
- %3 = zext i1 %0 to i8
- store i8 %3, i8* %2, align 1
- %4 = load i8, i8* %2, align 1
- %5 = trunc i8 %4 to i1
- br i1 %5, label %6, label %8
+define void @_Z3bazb(i1 zeroext) personality i32 (...)* @__gxx_personality_v0 {
+ br i1 %0, label %2, label %7
-6: ; preds = %1
- %7 = call i32 @_Z3barv()
- br label %10
+2:
+ %3 = invoke i32 @_Z3barv()
+ to label %7 unwind label %5
+ br label %9
-8: ; preds = %1
- %9 = call i32 @_Z3foov()
- br label %10
+5:
+ landingpad { i8*, i32 }
+ catch i8* null
+ br label %9
-10: ; preds = %8, %6
+7:
+ %8 = call i32 @_Z3foov()
+ br label %9
+
+9:
ret void
}
@@ -25,9 +26,31 @@ declare i32 @_Z3barv() #1
declare i32 @_Z3foov() #1
-; LINUX-LABELS: .section
-; LINUX-LABELS: _Z3bazb:
-; LINUX-LABELS-NOT: .section
-; LINUX-LABELS: r.BB._Z3bazb:
-; LINUX-LABELS-NOT: .section
-; LINUX-LABELS: rr.BB._Z3bazb:
+declare i32 @__gxx_personality_v0(...)
+
+; CHECK-LABEL: _Z3bazb:
+; CHECK-LABEL: .Lfunc_begin0:
+; CHECK-LABEL: .LBB_END0_0:
+; CHECK-LABEL: .LBB0_1:
+; CHECK-LABEL: .LBB_END0_1:
+; CHECK-LABEL: .LBB0_2:
+; CHECK-LABEL: .LBB_END0_2:
+; CHECK-LABEL: .LBB0_3:
+; CHECK-LABEL: .LBB_END0_3:
+; CHECK-LABEL: .Lfunc_end0:
+
+; CHECK: .section .bb_addr_map,"o", at progbits,.text
+; CHECK-NEXT: .quad .Lfunc_begin0
+; CHECK-NEXT: .byte 4
+; CHECK-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0
+; CHECK-NEXT: .uleb128 .LBB_END0_0-.Lfunc_begin0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .uleb128 .LBB0_1-.Lfunc_begin0
+; CHECK-NEXT: .uleb128 .LBB_END0_1-.LBB0_1
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .uleb128 .LBB0_2-.Lfunc_begin0
+; CHECK-NEXT: .uleb128 .LBB_END0_2-.LBB0_2
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .uleb128 .LBB0_3-.Lfunc_begin0
+; CHECK-NEXT: .uleb128 .LBB_END0_3-.LBB0_3
+; CHECK-NEXT: .byte 5
More information about the cfe-commits
mailing list