Skip to content

Commit 9f37c9e

Browse files
MaskRaycachemeifyoucan
authored andcommitted
X86AsmBackend: Remove some overhead from auto padding feature
MCObjectStreamer::emitInstructionImpl is hot. Devirtualize allowEnhancedRelaxation introduced by https://reviews.llvm.org/D76286
1 parent d02afb1 commit 9f37c9e

File tree

2 files changed

+33
-37
lines changed

2 files changed

+33
-37
lines changed

llvm/include/llvm/MC/MCAsmBackend.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class LLVM_ABI MCAsmBackend {
6363

6464
MCAssembler *Asm = nullptr;
6565

66+
bool AllowAutoPadding = false;
67+
bool AllowEnhancedRelaxation = false;
68+
6669
public:
6770
MCAsmBackend(const MCAsmBackend &) = delete;
6871
MCAsmBackend &operator=(const MCAsmBackend &) = delete;
@@ -76,11 +79,11 @@ class LLVM_ABI MCAsmBackend {
7679

7780
/// Return true if this target might automatically pad instructions and thus
7881
/// need to emit padding enable/disable directives around sensative code.
79-
virtual bool allowAutoPadding() const { return false; }
82+
bool allowAutoPadding() const { return AllowAutoPadding; }
8083
/// Return true if this target allows an unrelaxable instruction to be
8184
/// emitted into RelaxableFragment and then we can increase its size in a
8285
/// tricky way for optimization.
83-
virtual bool allowEnhancedRelaxation() const { return false; }
86+
bool allowEnhancedRelaxation() const { return AllowEnhancedRelaxation; }
8487

8588
/// lifetime management
8689
virtual void reset() {}

llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ class X86AsmBackend : public MCAsmBackend {
127127
unsigned PrevInstOpcode = 0;
128128
MCBoundaryAlignFragment *PendingBA = nullptr;
129129
std::pair<MCFragment *, size_t> PrevInstPosition;
130-
bool IsRightAfterData = false;
131130

132131
uint8_t determinePaddingPrefix(const MCInst &Inst) const;
133132
bool isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const;
@@ -156,10 +155,13 @@ class X86AsmBackend : public MCAsmBackend {
156155
AlignBranchType = X86AlignBranchKindLoc;
157156
if (X86PadMaxPrefixSize.getNumOccurrences())
158157
TargetPrefixMax = X86PadMaxPrefixSize;
158+
159+
AllowAutoPadding =
160+
AlignBoundary != Align(1) && AlignBranchType != X86::AlignBranchNone;
161+
AllowEnhancedRelaxation =
162+
AllowAutoPadding && TargetPrefixMax != 0 && X86PadForBranchAlign;
159163
}
160164

161-
bool allowAutoPadding() const override;
162-
bool allowEnhancedRelaxation() const override;
163165
void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst,
164166
const MCSubtargetInfo &STI);
165167
void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst);
@@ -365,14 +367,6 @@ static bool hasVariantSymbol(const MCInst &MI) {
365367
return false;
366368
}
367369

368-
bool X86AsmBackend::allowAutoPadding() const {
369-
return (AlignBoundary != Align(1) && AlignBranchType != X86::AlignBranchNone);
370-
}
371-
372-
bool X86AsmBackend::allowEnhancedRelaxation() const {
373-
return allowAutoPadding() && TargetPrefixMax != 0 && X86PadForBranchAlign;
374-
}
375-
376370
/// X86 has certain instructions which enable interrupts exactly one
377371
/// instruction *after* the instruction which stores to SS. Return true if the
378372
/// given instruction may have such an interrupt delay slot.
@@ -447,7 +441,7 @@ bool X86AsmBackend::canPadInst(const MCInst &Inst, MCObjectStreamer &OS) const {
447441
// semantic.
448442
return false;
449443

450-
if (IsRightAfterData)
444+
if (isRightAfterData(OS.getCurrentFragment(), PrevInstPosition))
451445
// If this instruction follows any data, there is no clear
452446
// instruction boundary, inserting a nop/prefix would change semantic.
453447
return false;
@@ -456,6 +450,8 @@ bool X86AsmBackend::canPadInst(const MCInst &Inst, MCObjectStreamer &OS) const {
456450
}
457451

458452
bool X86AsmBackend::canPadBranches(MCObjectStreamer &OS) const {
453+
if (!OS.getAllowAutoPadding())
454+
return false;
459455
assert(allowAutoPadding() && "incorrect initialization!");
460456

461457
// We only pad in text section.
@@ -482,22 +478,28 @@ bool X86AsmBackend::needAlign(const MCInst &Inst) const {
482478
(AlignBranchType & X86::AlignBranchIndirect));
483479
}
484480

481+
void X86_MC::emitInstruction(MCObjectStreamer &S, const MCInst &Inst,
482+
const MCSubtargetInfo &STI) {
483+
bool AutoPadding = S.getAllowAutoPadding();
484+
if (LLVM_LIKELY(!AutoPadding && !X86PadForAlign)) {
485+
S.MCObjectStreamer::emitInstruction(Inst, STI);
486+
return;
487+
}
488+
489+
auto &Backend = static_cast<X86AsmBackend &>(S.getAssembler().getBackend());
490+
Backend.emitInstructionBegin(S, Inst, STI);
491+
S.MCObjectStreamer::emitInstruction(Inst, STI);
492+
Backend.emitInstructionEnd(S, Inst);
493+
}
494+
485495
/// Insert BoundaryAlignFragment before instructions to align branches.
486496
void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
487497
const MCInst &Inst, const MCSubtargetInfo &STI) {
488-
// Used by canPadInst. Done here, because in emitInstructionEnd, the current
489-
// fragment will have changed.
490-
IsRightAfterData =
491-
isRightAfterData(OS.getCurrentFragment(), PrevInstPosition);
492-
bool CanPadInst = false;
493-
bool AutoPadding = OS.getAllowAutoPadding();
494-
if (LLVM_UNLIKELY(AutoPadding || X86PadForAlign)) {
495-
CanPadInst = canPadInst(Inst, OS);
496-
if (CanPadInst)
497-
OS.getCurrentFragment()->setAllowAutoPadding(true);
498-
}
498+
bool CanPadInst = canPadInst(Inst, OS);
499+
if (CanPadInst)
500+
OS.getCurrentFragment()->setAllowAutoPadding(true);
499501

500-
if (!AutoPadding || !canPadBranches(OS))
502+
if (!canPadBranches(OS))
501503
return;
502504

503505
// NB: PrevInst only valid if canPadBranches is true.
@@ -552,7 +554,7 @@ void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS,
552554
PrevInstOpcode = Inst.getOpcode();
553555
PrevInstPosition = std::make_pair(CF, getSizeForInstFragment(CF));
554556

555-
if (!OS.getAllowAutoPadding() || !canPadBranches(OS))
557+
if (!canPadBranches(OS))
556558
return;
557559

558560
// PrevInst is only needed if canPadBranches. Copying an MCInst isn't cheap.
@@ -572,8 +574,7 @@ void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS,
572574
OS.newFragment();
573575

574576
// Update the maximum alignment on the current section if necessary.
575-
MCSection *Sec = OS.getCurrentSectionOnly();
576-
Sec->ensureMinAlignment(AlignBoundary);
577+
CF->getParent()->ensureMinAlignment(AlignBoundary);
577578
}
578579

579580
std::optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name) const {
@@ -1544,14 +1545,6 @@ class X86ELFStreamer : public MCELFStreamer {
15441545
};
15451546
} // end anonymous namespace
15461547

1547-
void X86_MC::emitInstruction(MCObjectStreamer &S, const MCInst &Inst,
1548-
const MCSubtargetInfo &STI) {
1549-
auto &Backend = static_cast<X86AsmBackend &>(S.getAssembler().getBackend());
1550-
Backend.emitInstructionBegin(S, Inst, STI);
1551-
S.MCObjectStreamer::emitInstruction(Inst, STI);
1552-
Backend.emitInstructionEnd(S, Inst);
1553-
}
1554-
15551548
void X86ELFStreamer::emitInstruction(const MCInst &Inst,
15561549
const MCSubtargetInfo &STI) {
15571550
X86_MC::emitInstruction(*this, Inst, STI);

0 commit comments

Comments
 (0)