// Emit BB Information for each basic block in the funciton.
for (const MachineBasicBlock &MBB : MF) {
const MCSymbol *MBBSymbol =
- MBB.pred_empty() ? FunctionSymbol : MBB.getSymbol();
+ MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol();
// Emit the basic block offset.
emitLabelDifferenceAsULEB128(MBBSymbol, FunctionSymbol);
// Emit the basic block size. When BBs have alignments, their size cannot
// Switch to a new section if this basic block must begin a section. The
// entry block is always placed in the function section and is handled
// separately.
- if (MBB.isBeginSection() && !MBB.pred_empty()) {
+ if (MBB.isBeginSection() && !MBB.isEntryBlock()) {
OutStreamer->SwitchSection(
getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(),
MBB, TM));
}
// Print the main label for the block.
- if (MBB.pred_empty() ||
- (!MF->hasBBLabels() && isBlockOnlyReachableByFallthrough(&MBB) &&
- !MBB.isEHFuncletEntry() && !MBB.hasLabelMustBeEmitted())) {
+ if (shouldEmitLabelForBasicBlock(MBB)) {
+ if (isVerbose() && MBB.hasLabelMustBeEmitted())
+ OutStreamer->AddComment("Label of block must be emitted");
+ OutStreamer->emitLabel(MBB.getSymbol());
+ } else {
if (isVerbose()) {
// NOTE: Want this comment at start of line, don't emit with AddComment.
OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":",
false);
}
- } else {
- if (isVerbose() && MBB.hasLabelMustBeEmitted())
- OutStreamer->AddComment("Label of block must be emitted");
- OutStreamer->emitLabel(MBB.getSymbol());
}
// With BB sections, each basic block must handle CFI information on its own
// if it begins a section (Entry block is handled separately by
// AsmPrinterHandler::beginFunction).
- if (MBB.isBeginSection() && !MBB.pred_empty())
+ if (MBB.isBeginSection() && !MBB.isEntryBlock())
for (const HandlerInfo &HI : Handlers)
HI.Handler->beginBasicBlock(MBB);
}
OutStreamer->emitSymbolAttribute(Sym, Attr);
}
+bool AsmPrinter::shouldEmitLabelForBasicBlock(
+ const MachineBasicBlock &MBB) const {
+ // With `-fbasic-block-sections=`, a label is needed for every non-entry block
+ // in the labels mode (option `=labels`) and every section beginning in the
+ // sections mode (`=all` and `=list=`).
+ if ((MF->hasBBLabels() || MBB.isBeginSection()) && !MBB.isEntryBlock())
+ return true;
+ // A label is needed for any block with at least one predecessor (when that
+ // predecessor is not the fallthrough predecessor, or if it is an EH funclet
+ // entry, or if a label is forced).
+ return !MBB.pred_empty() &&
+ (!isBlockOnlyReachableByFallthrough(&MBB) || MBB.isEHFuncletEntry() ||
+ MBB.hasLabelMustBeEmitted());
+}
+
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
/// exactly one predecessor and the control transfer mechanism between
/// the predecessor and this block is a fall-through.
bool AsmPrinter::
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
- // With BasicBlock Sections, beginning of the section is not a fallthrough.
- if (MBB->isBeginSection())
- return false;
-
// If this is a landing pad, it isn't a fall through. If it has no preds,
// then nothing falls through to it.
if (MBB->isEHPad() || MBB->pred_empty())
--- /dev/null
+; Check that basic block section is emitted when a non-entry block has no predecessors.
+; RUN: llc < %s -mtriple=x86_64 -O0 -basic-block-sections=all | FileCheck %s --check-prefix=CHECK-SECTIONS
+; RUN: llc < %s -mtriple=x86_64 -O0 | FileCheck %s --check-prefix=CHECK-NOSECTIONS
+define void @foo(i32* %bar) {
+ %v = load i32, i32* %bar
+ switch i32 %v, label %default [
+ i32 0, label %target
+ ]
+target:
+ ret void
+;; This is the block which will not have any predecessors. If the block is not garbage collected, it must
+;; be placed in a basic block section with a corresponding symbol.
+default:
+ unreachable
+; CHECK-NOSECTIONS: # %bb.2: # %default
+; CHECK-SECTIONS: .section .text,"ax",@progbits,unique,2
+; CHECK-SECTIONS-NEXT: foo.2: # %default
+}