[llvm] af57b13 - Temporarily Revert [X86] Not track size of the boudaryalign fragment during the layout
Shengchen Kan via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 2 19:16:46 PST 2020
Author: Shengchen Kan
Date: 2020-03-03T11:15:56+08:00
New Revision: af57b139a0808be41383e8b3838bb8277423c2ab
URL: https://github.com/llvm/llvm-project/commit/af57b139a0808be41383e8b3838bb8277423c2ab
DIFF: https://github.com/llvm/llvm-project/commit/af57b139a0808be41383e8b3838bb8277423c2ab.diff
LOG: Temporarily Revert [X86] Not track size of the boudaryalign fragment during the layout
Summary: This reverts commit 2ac19feb1571960b8e1479a451b45ab56da7034e.
This commit causes some test cases to run fail when branch is aligned.
Added:
Modified:
llvm/include/llvm/MC/MCAssembler.h
llvm/include/llvm/MC/MCFragment.h
llvm/lib/MC/MCAssembler.cpp
llvm/lib/MC/MCFragment.cpp
llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index caa392a41b2b..b57439f02ca5 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -195,6 +195,7 @@ class MCAssembler {
bool relaxFragment(MCAsmLayout &Layout, MCFragment &F);
bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
+ bool relaxBoundaryAlign(MCAsmLayout &Layout, MCBoundaryAlignFragment &BF);
bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
MCDwarfCallFrameFragment &DF);
diff --git a/llvm/include/llvm/MC/MCFragment.h b/llvm/include/llvm/MC/MCFragment.h
index 610e924f7846..e052098611a9 100644
--- a/llvm/include/llvm/MC/MCFragment.h
+++ b/llvm/include/llvm/MC/MCFragment.h
@@ -528,6 +528,9 @@ class MCBoundaryAlignFragment : public MCFragment {
bool Fused : 1;
/// Flag to indicate whether NOPs should be emitted.
bool EmitNops : 1;
+ /// The size of the fragment. The size is lazily set during relaxation, and
+ /// is not meaningful before that.
+ uint64_t Size = 0;
public:
MCBoundaryAlignFragment(Align AlignBoundary = Align(1), bool Fused = false,
@@ -535,6 +538,9 @@ class MCBoundaryAlignFragment : public MCFragment {
: MCFragment(FT_BoundaryAlign, false, Sec), AlignBoundary(AlignBoundary),
Fused(Fused), EmitNops(EmitNops) {}
+ uint64_t getSize() const { return Size; }
+ void setSize(uint64_t Value) { Size = Value; }
+
Align getAlignment() const { return AlignBoundary; }
void setAlignment(Align Value) { AlignBoundary = Value; }
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index ca202ddf03d7..b32c9b5fdfac 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -285,43 +285,6 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
return IsResolved;
}
-/// Check if the branch crosses the boundary.
-///
-/// \param StartAddr start address of the fused/unfused branch.
-/// \param Size size of the fused/unfused branch.
-/// \param BoundaryAlignment alignment requirement of the branch.
-/// \returns true if the branch cross the boundary.
-static bool mayCrossBoundary(uint64_t StartAddr, uint64_t Size,
- Align BoundaryAlignment) {
- uint64_t EndAddr = StartAddr + Size;
- return (StartAddr >> Log2(BoundaryAlignment)) !=
- ((EndAddr - 1) >> Log2(BoundaryAlignment));
-}
-
-/// Check if the branch is against the boundary.
-///
-/// \param StartAddr start address of the fused/unfused branch.
-/// \param Size size of the fused/unfused branch.
-/// \param BoundaryAlignment alignment requirement of the branch.
-/// \returns true if the branch is against the boundary.
-static bool isAgainstBoundary(uint64_t StartAddr, uint64_t Size,
- Align BoundaryAlignment) {
- uint64_t EndAddr = StartAddr + Size;
- return (EndAddr & (BoundaryAlignment.value() - 1)) == 0;
-}
-
-/// Check if the branch needs padding.
-///
-/// \param StartAddr start address of the fused/unfused branch.
-/// \param Size size of the fused/unfused branch.
-/// \param BoundaryAlignment alignment requirement of the branch.
-/// \returns true if the branch needs padding.
-static bool needPadding(uint64_t StartAddr, uint64_t Size,
- Align BoundaryAlignment) {
- return mayCrossBoundary(StartAddr, Size, BoundaryAlignment) ||
- isAgainstBoundary(StartAddr, Size, BoundaryAlignment);
-}
-
uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
const MCFragment &F) const {
assert(getBackendPtr() && "Requires assembler backend");
@@ -351,26 +314,8 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
case MCFragment::FT_LEB:
return cast<MCLEBFragment>(F).getContents().size();
- case MCFragment::FT_BoundaryAlign: {
- const MCBoundaryAlignFragment &BF = cast<MCBoundaryAlignFragment>(F);
- // MCBoundaryAlignFragment that doesn't emit NOP should have 0 size.
- if (!BF.canEmitNops())
- return 0;
-
- uint64_t AlignedOffset = Layout.getFragmentOffset(&BF);
- uint64_t AlignedSize = 0;
- const MCFragment *F = BF.getNextNode();
- // If the branch is unfused, it is emitted into one fragment, otherwise it
- // is emitted into two fragments at most, the next
- // MCBoundaryAlignFragment(if exists) also marks the end of the branch.
- for (int I = 0, N = BF.isFused() ? 2 : 1;
- I != N && !isa<MCBoundaryAlignFragment>(F); ++I, F = F->getNextNode())
- AlignedSize += computeFragmentSize(Layout, *F);
- Align BoundaryAlignment = BF.getAlignment();
- return needPadding(AlignedOffset, AlignedSize, BoundaryAlignment)
- ? offsetToAlignment(AlignedOffset, BoundaryAlignment)
- : 0U;
- }
+ case MCFragment::FT_BoundaryAlign:
+ return cast<MCBoundaryAlignFragment>(F).getSize();
case MCFragment::FT_SymbolId:
return 4;
@@ -1012,6 +957,72 @@ bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) {
return OldSize != LF.getContents().size();
}
+/// Check if the branch crosses the boundary.
+///
+/// \param StartAddr start address of the fused/unfused branch.
+/// \param Size size of the fused/unfused branch.
+/// \param BoundaryAlignment alignment requirement of the branch.
+/// \returns true if the branch cross the boundary.
+static bool mayCrossBoundary(uint64_t StartAddr, uint64_t Size,
+ Align BoundaryAlignment) {
+ uint64_t EndAddr = StartAddr + Size;
+ return (StartAddr >> Log2(BoundaryAlignment)) !=
+ ((EndAddr - 1) >> Log2(BoundaryAlignment));
+}
+
+/// Check if the branch is against the boundary.
+///
+/// \param StartAddr start address of the fused/unfused branch.
+/// \param Size size of the fused/unfused branch.
+/// \param BoundaryAlignment alignment requirement of the branch.
+/// \returns true if the branch is against the boundary.
+static bool isAgainstBoundary(uint64_t StartAddr, uint64_t Size,
+ Align BoundaryAlignment) {
+ uint64_t EndAddr = StartAddr + Size;
+ return (EndAddr & (BoundaryAlignment.value() - 1)) == 0;
+}
+
+/// Check if the branch needs padding.
+///
+/// \param StartAddr start address of the fused/unfused branch.
+/// \param Size size of the fused/unfused branch.
+/// \param BoundaryAlignment alignment requirement of the branch.
+/// \returns true if the branch needs padding.
+static bool needPadding(uint64_t StartAddr, uint64_t Size,
+ Align BoundaryAlignment) {
+ return mayCrossBoundary(StartAddr, Size, BoundaryAlignment) ||
+ isAgainstBoundary(StartAddr, Size, BoundaryAlignment);
+}
+
+bool MCAssembler::relaxBoundaryAlign(MCAsmLayout &Layout,
+ MCBoundaryAlignFragment &BF) {
+ // The MCBoundaryAlignFragment that doesn't emit NOP should not be relaxed.
+ if (!BF.canEmitNops())
+ return false;
+
+ uint64_t AlignedOffset = Layout.getFragmentOffset(BF.getNextNode());
+ uint64_t AlignedSize = 0;
+ const MCFragment *F = BF.getNextNode();
+ // If the branch is unfused, it is emitted into one fragment, otherwise it is
+ // emitted into two fragments at most, the next MCBoundaryAlignFragment(if
+ // exists) also marks the end of the branch.
+ for (auto i = 0, N = BF.isFused() ? 2 : 1;
+ i != N && !isa<MCBoundaryAlignFragment>(F); ++i, F = F->getNextNode()) {
+ AlignedSize += computeFragmentSize(Layout, *F);
+ }
+ uint64_t OldSize = BF.getSize();
+ AlignedOffset -= OldSize;
+ Align BoundaryAlignment = BF.getAlignment();
+ uint64_t NewSize = needPadding(AlignedOffset, AlignedSize, BoundaryAlignment)
+ ? offsetToAlignment(AlignedOffset, BoundaryAlignment)
+ : 0U;
+ if (NewSize == OldSize)
+ return false;
+ BF.setSize(NewSize);
+ Layout.invalidateFragmentsFrom(&BF);
+ return true;
+}
+
bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout,
MCDwarfLineAddrFragment &DF) {
MCContext &Context = Layout.getAssembler().getContext();
@@ -1112,6 +1123,8 @@ bool MCAssembler::relaxFragment(MCAsmLayout &Layout, MCFragment &F) {
cast<MCDwarfCallFrameFragment>(F));
case MCFragment::FT_LEB:
return relaxLEB(Layout, cast<MCLEBFragment>(F));
+ case MCFragment::FT_BoundaryAlign:
+ return relaxBoundaryAlign(Layout, cast<MCBoundaryAlignFragment>(F));
case MCFragment::FT_CVInlineLines:
return relaxCVInlineLineTable(Layout, cast<MCCVInlineLineTableFragment>(F));
case MCFragment::FT_CVDefRange:
diff --git a/llvm/lib/MC/MCFragment.cpp b/llvm/lib/MC/MCFragment.cpp
index 42ba3b40c51f..a96b8e86aed3 100644
--- a/llvm/lib/MC/MCFragment.cpp
+++ b/llvm/lib/MC/MCFragment.cpp
@@ -431,7 +431,8 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
else
OS << " unfused branch)";
OS << "\n ";
- OS << " BoundarySize:" << BF->getAlignment().value();
+ OS << " BoundarySize:" << BF->getAlignment().value()
+ << " Size:" << BF->getSize();
break;
}
case MCFragment::FT_SymbolId: {
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index ce48ea2519f8..a97f8e95769d 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -466,7 +466,7 @@ void X86AsmBackend::alignBranchesEnd(MCObjectStreamer &OS, const MCInst &Inst) {
if (!needAlign(OS))
return;
// If the branch is emitted into a MCRelaxableFragment, we can determine the
- // size of the branch easily in during the process of layout. When the
+ // size of the branch easily in MCAssembler::relaxBoundaryAlign. When the
// branch is fused, the fused branch(macro fusion pair) must be emitted into
// two fragments. Or when the branch is unfused, the branch must be emitted
// into one fragment. The MCRelaxableFragment naturally marks the end of the
More information about the llvm-commits
mailing list