diff --git a/include/llvm/MC/MCFragment.h b/include/llvm/MC/MCFragment.h index ed237eb1e88..e052098611a 100644 --- a/include/llvm/MC/MCFragment.h +++ b/include/llvm/MC/MCFragment.h @@ -533,7 +533,7 @@ class MCBoundaryAlignFragment : public MCFragment { uint64_t Size = 0; public: - MCBoundaryAlignFragment(Align AlignBoundary, bool Fused = false, + MCBoundaryAlignFragment(Align AlignBoundary = Align(1), bool Fused = false, bool EmitNops = false, MCSection *Sec = nullptr) : MCFragment(FT_BoundaryAlign, false, Sec), AlignBoundary(AlignBoundary), Fused(Fused), EmitNops(EmitNops) {} @@ -542,6 +542,7 @@ public: void setSize(uint64_t Value) { Size = Value; } Align getAlignment() const { return AlignBoundary; } + void setAlignment(Align Value) { AlignBoundary = Value; } bool isFused() const { return Fused; } void setFused(bool Value) { Fused = Value; } diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 362b6e923e5..b0a3bd31a3c 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -87,6 +87,11 @@ public: /// if the Subtarget differs from the current fragment. MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr); + /// Get a boundary-align fragment to write into, creating a new one if the + /// current fragment is not a boundary-align fragment or has been used to emit + /// something. + MCBoundaryAlignFragment *getOrCreateBoundaryAlignFragment(); + protected: bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection); diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index a36cdc4c1ab..33fcc20cb7b 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -215,6 +215,15 @@ MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) { return F; } +MCBoundaryAlignFragment *MCObjectStreamer::getOrCreateBoundaryAlignFragment() { + auto *F = dyn_cast_or_null(getCurrentFragment()); + if (!F || F->canEmitNops()) { + F = new MCBoundaryAlignFragment(); + insert(F); + } + return F; +} + void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) { Assembler->registerSymbol(Sym); } diff --git a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 0e1d8b89a15..8ec3f4241c3 100644 --- a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -120,8 +120,6 @@ class X86AsmBackend : public MCAsmBackend { bool needAlign(MCObjectStreamer &OS) const; bool needAlignInst(const MCInst &Inst) const; - MCBoundaryAlignFragment * - getOrCreateBoundaryAlignFragment(MCObjectStreamer &OS) const; MCInst PrevInst; public: @@ -395,21 +393,6 @@ bool X86AsmBackend::needAlignInst(const MCInst &Inst) const { (AlignBranchType & X86::AlignBranchIndirect)); } -static bool canReuseBoundaryAlignFragment(const MCBoundaryAlignFragment &F) { - // If a MCBoundaryAlignFragment has not been used to emit NOP,we can reuse it. - return !F.canEmitNops(); -} - -MCBoundaryAlignFragment * -X86AsmBackend::getOrCreateBoundaryAlignFragment(MCObjectStreamer &OS) const { - auto *F = dyn_cast_or_null(OS.getCurrentFragment()); - if (!F || !canReuseBoundaryAlignFragment(*F)) { - F = new MCBoundaryAlignFragment(AlignBoundary); - OS.insert(F); - } - return F; -} - /// Insert MCBoundaryAlignFragment before instructions to align branches. void X86AsmBackend::alignBranchesBegin(MCObjectStreamer &OS, const MCInst &Inst) { @@ -439,13 +422,15 @@ void X86AsmBackend::alignBranchesBegin(MCObjectStreamer &OS, // // We will treat the JCC as a unfused branch although it may be fused // with the CMP. - auto *F = getOrCreateBoundaryAlignFragment(OS); + auto *F = OS.getOrCreateBoundaryAlignFragment(); + F->setAlignment(AlignBoundary); F->setEmitNops(true); F->setFused(false); } else if (NeedAlignFused && isFirstMacroFusibleInst(Inst, *MCII)) { // We don't know if macro fusion happens until the reaching the next // instruction, so a place holder is put here if necessary. - getOrCreateBoundaryAlignFragment(OS); + auto *F = OS.getOrCreateBoundaryAlignFragment(); + F->setAlignment(AlignBoundary); } PrevInst = Inst;