aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCAssembler.cpp
diff options
context:
space:
mode:
authorShengchen Kan <shengchen.kan@intel.com>2020-03-01 15:43:53 +0800
committerShengchen Kan <shengchen.kan@intel.com>2020-03-02 09:32:30 +0800
commit2ac19feb1571960b8e1479a451b45ab56da7034e (patch)
tree6d58c8295fc34cc138305fd3806e0b4b1da5714f /llvm/lib/MC/MCAssembler.cpp
parentb6e2796114d08aadfabe8c889b5d96e6bc4f5e0e (diff)
downloadllvm-2ac19feb1571960b8e1479a451b45ab56da7034e.zip
llvm-2ac19feb1571960b8e1479a451b45ab56da7034e.tar.gz
llvm-2ac19feb1571960b8e1479a451b45ab56da7034e.tar.bz2
[X86] Not track size of the boudaryalign fragment during the layout
Summary: Currently the boundaryalign fragment caches its size during the process of layout and then it is relaxed and update the size in each iteration. This behaviour is unnecessary and ugly. Reviewers: annita.zhang, reames, MaskRay, craig.topper, LuoYuanke, jyknight Reviewed By: MaskRay Subscribers: hiraditya, dexonsmith, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75404
Diffstat (limited to 'llvm/lib/MC/MCAssembler.cpp')
-rw-r--r--llvm/lib/MC/MCAssembler.cpp127
1 files changed, 57 insertions, 70 deletions
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index bcfda26..8582d51 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -285,6 +285,43 @@ 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");
@@ -314,8 +351,26 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
case MCFragment::FT_LEB:
return cast<MCLEBFragment>(F).getContents().size();
- case MCFragment::FT_BoundaryAlign:
- return cast<MCBoundaryAlignFragment>(F).getSize();
+ 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_SymbolId:
return 4;
@@ -957,72 +1012,6 @@ 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();
@@ -1123,8 +1112,6 @@ 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: