mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[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
This commit is contained in:
parent
616dd1c201
commit
56f370d717
@ -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; }
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user