Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion llvm/lib/CodeGen/BasicBlockSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,16 @@ void llvm::sortBasicBlocksAndUpdateBranches(
// zero implies "no landing pad." This function inserts a NOP just before the EH
// pad label to ensure a nonzero offset.
void llvm::avoidZeroOffsetLandingPad(MachineFunction &MF) {
std::optional<MBBSectionID> CurrentSection;
auto IsFirstNonEmptyBBInSection = [&](const MachineBasicBlock &MBB) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function may give false positives in the following situation:

bb0 (bbsections 0)
bb1 (bbsections cold)
bb2 (bbsections 0)

If false positives are fine (since we're just inserting a nop), then you can disregard this feedback. Otherwise, you may want to do something like

llvm::DenseSet<MBBSectionID> SectionsWithNonEmptyBlocks;
auto IsFirstNonEmptyBBInSection = [&](const MachineBasicBlock &MBB) {
  if (MBB.empty() || SectionsWithNonEmptyBlocks.contains(MBB.getSectionID()))
    return false;

  SectionsWithNonEmptyBlocks.insert(MBB.getSectionID());

Copy link
Member Author

@pzfl pzfl Oct 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I was under the impression that basic blocks are assumed to be sorted. Both callsites avoidZeroOffsetLandingPad are preceded by a call to sortBasicBlocksAndUpdateBranches. However, I see now that finishAdjustingBasicBlocksAndLandingPads sorts only by section type, but not by section number. I am not sure how section numbers are used.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, no you're right, sortBasicBlocksAndUpdateBranches guarantees the basic block sections will be contiguous. Looks good!

if (MBB.empty() || MBB.getSectionID() == CurrentSection)
return false;
CurrentSection = MBB.getSectionID();
return true;
};

for (auto &MBB : MF) {
if (MBB.isBeginSection() && MBB.isEHPad()) {
if (IsFirstNonEmptyBBInSection(MBB) && MBB.isEHPad()) {
MachineBasicBlock::iterator MI = MBB.begin();
while (!MI->isEHLabel())
++MI;
Expand Down
30 changes: 30 additions & 0 deletions llvm/test/CodeGen/Generic/machine-function-splitter.ll
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,36 @@ define void @foo22(i1 zeroext %0) nounwind !prof !14 !section_prefix !15 {
ret void
}

define i32 @foo23(i1 zeroext %0) personality ptr @__gxx_personality_v0 !prof !14 {
;; Check that nop is inserted just before the EH pad if it is the first
;; instruction in a section (but is preceeded by another empty block).
; MFS-DEFAULTS-LABEL: foo23
; MFS-DEFAULTS-X86-LABEL: callq baz
; MFS-DEFAULTS-X86: .section .text.split.foo23,"ax",@progbits
; MFS-DEFAULTS-X86-NEXT: foo23.cold:
; MFS-DEFAULTS-X86: nop
; MFS-DEFAULTS-X86: callq _Unwind_Resume@PLT
entry:
br i1 %0, label %try, label %unreachable, !prof !17

try:
invoke void @_Z1fv()
to label %try.cont unwind label %lpad, !prof !17

try.cont:
%1 = call i32 @baz()
ret i32 %1

unreachable:
unreachable

lpad:
%2 = landingpad { ptr, i32 }
cleanup
catch ptr @_ZTIi
resume { ptr, i32 } %2
}

declare i32 @bar()
declare i32 @baz()
declare i32 @bam()
Expand Down
Loading