Commit 95fa5c4f authored by Shengchen Kan's avatar Shengchen Kan
Browse files

[X86] Move the function getOrCreateBoundaryAlignFragment

MCObjectStreamer is more suitable to create fragments than
X86AsmBackend, for example, the function getOrCreateDataFragment is
defined in MCObjectStreamer.

Differential Revision: https://reviews.llvm.org/D75351
parent 129a7625
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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; }
+5 −0
Original line number Diff line number Diff line
@@ -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);

+9 −0
Original line number Diff line number Diff line
@@ -215,6 +215,15 @@ MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
  return F;
}

MCBoundaryAlignFragment *MCObjectStreamer::getOrCreateBoundaryAlignFragment() {
  auto *F = dyn_cast_or_null<MCBoundaryAlignFragment>(getCurrentFragment());
  if (!F || F->canEmitNops()) {
    F = new MCBoundaryAlignFragment();
    insert(F);
  }
  return F;
}

void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
  Assembler->registerSymbol(Sym);
}
+4 −19
Original line number Diff line number Diff line
@@ -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<MCBoundaryAlignFragment>(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;