summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorPeter Smith <peter.smith@linaro.org>2018-06-15 09:48:18 +0000
committerPeter Smith <peter.smith@linaro.org>2018-06-15 09:48:18 +0000
commit1503fc0fd018ad30e02bb8c880330a2e351e4e76 (patch)
tree688756e1c629d0a594bf82223df4c26be422e4e4 /llvm
parent205276bf37dc1e482e5d2d1ff5a9537aa4eb797f (diff)
downloadbcm5719-llvm-1503fc0fd018ad30e02bb8c880330a2e351e4e76.tar.gz
bcm5719-llvm-1503fc0fd018ad30e02bb8c880330a2e351e4e76.zip
[MC] Move bundling and MCSubtargetInfo to MCEncodedFragment [NFC]
Instruction bundling is only supported on descendants of the MCEncodedFragment type. By moving the bundling functionality and MCSubtargetInfo to this class it makes it easier to set and extract the MCSubtargetInfo when it is necessary. This is a refactoring change that will make it easier to pass the MCSubtargetInfo through to writeNops when nop padding is required. Differential Revision: https://reviews.llvm.org/D45959 llvm-svn: 334814
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/MC/MCAssembler.h7
-rw-r--r--llvm/include/llvm/MC/MCFragment.h98
-rw-r--r--llvm/lib/MC/MCAssembler.cpp27
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp1
-rw-r--r--llvm/lib/MC/MCFragment.cpp18
5 files changed, 77 insertions, 74 deletions
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 34bf180be1f..0f9499d705e 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -442,7 +442,7 @@ public:
/// Write the necessary bundle padding to \p OS.
/// Expects a fragment \p F containing instructions and its size \p FSize.
- void writeFragmentPadding(raw_ostream &OS, const MCFragment &F,
+ void writeFragmentPadding(raw_ostream &OS, const MCEncodedFragment &F,
uint64_t FSize) const;
/// @}
@@ -453,8 +453,9 @@ public:
/// Compute the amount of padding required before the fragment \p F to
/// obey bundling restrictions, where \p FOffset is the fragment's offset in
/// its section and \p FSize is the fragment's size.
-uint64_t computeBundlePadding(const MCAssembler &Assembler, const MCFragment *F,
- uint64_t FOffset, uint64_t FSize);
+uint64_t computeBundlePadding(const MCAssembler &Assembler,
+ const MCEncodedFragment *F, uint64_t FOffset,
+ uint64_t FSize);
} // end namespace llvm
diff --git a/llvm/include/llvm/MC/MCFragment.h b/llvm/include/llvm/MC/MCFragment.h
index 16eb124d95e..47b35175fec 100644
--- a/llvm/include/llvm/MC/MCFragment.h
+++ b/llvm/include/llvm/MC/MCFragment.h
@@ -56,11 +56,6 @@ protected:
bool HasInstructions;
private:
- /// Should this fragment be aligned to the end of a bundle?
- bool AlignToBundleEnd;
-
- uint8_t BundlePadding;
-
/// LayoutOrder - The layout order of this fragment.
unsigned LayoutOrder;
@@ -84,7 +79,7 @@ private:
protected:
MCFragment(FragmentType Kind, bool HasInstructions,
- uint8_t BundlePadding, MCSection *Parent = nullptr);
+ MCSection *Parent = nullptr);
~MCFragment();
@@ -114,21 +109,6 @@ public:
/// this is false, but specific fragment types may set it to true.
bool hasInstructions() const { return HasInstructions; }
- /// Should this fragment be placed at the end of an aligned bundle?
- bool alignToBundleEnd() const { return AlignToBundleEnd; }
- void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
-
- /// Get the padding size that must be inserted before this fragment.
- /// Used for bundling. By default, no padding is inserted.
- /// Note that padding size is restricted to 8 bits. This is an optimization
- /// to reduce the amount of space used for each fragment. In practice, larger
- /// padding should never be required.
- uint8_t getBundlePadding() const { return BundlePadding; }
-
- /// Set the padding size for this fragment. By default it's a no-op,
- /// and only some fragments have a meaningful implementation.
- void setBundlePadding(uint8_t N) { BundlePadding = N; }
-
/// Return true if given frgment has FT_Dummy type.
bool isDummy() const { return Kind == FT_Dummy; }
@@ -137,8 +117,7 @@ public:
class MCDummyFragment : public MCFragment {
public:
- explicit MCDummyFragment(MCSection *Sec)
- : MCFragment(FT_Dummy, false, 0, Sec) {}
+ explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {}
static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
};
@@ -147,10 +126,19 @@ public:
/// data.
///
class MCEncodedFragment : public MCFragment {
+ /// Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd = false;
+
+ uint8_t BundlePadding = 0;
+
protected:
MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
MCSection *Sec)
- : MCFragment(FType, HasInstructions, 0, Sec) {}
+ : MCFragment(FType, HasInstructions, Sec) {}
+
+ /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
+ /// must be non-null for instructions.
+ const MCSubtargetInfo *STI = nullptr;
public:
static bool classof(const MCFragment *F) {
@@ -164,6 +152,32 @@ public:
return true;
}
}
+
+ /// Should this fragment be placed at the end of an aligned bundle?
+ bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+
+ /// Get the padding size that must be inserted before this fragment.
+ /// Used for bundling. By default, no padding is inserted.
+ /// Note that padding size is restricted to 8 bits. This is an optimization
+ /// to reduce the amount of space used for each fragment. In practice, larger
+ /// padding should never be required.
+ uint8_t getBundlePadding() const { return BundlePadding; }
+
+ /// Set the padding size for this fragment. By default it's a no-op,
+ /// and only some fragments have a meaningful implementation.
+ void setBundlePadding(uint8_t N) { BundlePadding = N; }
+
+ /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
+ /// Guaranteed to be non-null if hasInstructions() == true
+ const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
+
+ /// Record that the fragment contains instructions with the MCSubtargetInfo in
+ /// effect when the instruction was encoded.
+ void setHasInstructions(const MCSubtargetInfo &STI) {
+ HasInstructions = true;
+ this->STI = &STI;
+ }
};
/// Interface implemented by fragments that contain encoded instructions and/or
@@ -201,16 +215,8 @@ protected:
: MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
Sec) {}
- /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
- /// must be non-null for instructions.
- const MCSubtargetInfo *STI = nullptr;
-
public:
- /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
- /// Guaranteed to be non-null if hasInstructions() == true
- const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
-
using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator;
using fixup_iterator = SmallVectorImpl<MCFixup>::iterator;
@@ -237,13 +243,6 @@ public:
MCDataFragment(MCSection *Sec = nullptr)
: MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
- /// Record that the fragment contains instructions with the MCSubtargetInfo in
- /// effect when the instruction was encoded.
- void setHasInstructions(const MCSubtargetInfo &STI) {
- HasInstructions = true;
- this->STI = &STI;
- }
-
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Data;
}
@@ -309,9 +308,8 @@ class MCAlignFragment : public MCFragment {
public:
MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
- : MCFragment(FT_Align, false, 0, Sec), Alignment(Alignment),
- EmitNops(false), Value(Value),
- ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
+ : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false),
+ Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
/// \name Accessors
/// @{
@@ -379,7 +377,7 @@ public:
};
MCPaddingFragment(MCSection *Sec = nullptr)
- : MCFragment(FT_Padding, false, 0, Sec), PaddingPoliciesMask(PFK_None),
+ : MCFragment(FT_Padding, false, Sec), PaddingPoliciesMask(PFK_None),
IsInsertionPoint(false), Size(UINT64_C(0)),
InstInfo({false, MCInst(), false, {0}}) {}
@@ -439,7 +437,7 @@ class MCFillFragment : public MCFragment {
public:
MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues,
SMLoc Loc, MCSection *Sec = nullptr)
- : MCFragment(FT_Fill, false, 0, Sec), Value(Value), ValueSize(VSize),
+ : MCFragment(FT_Fill, false, Sec), Value(Value), ValueSize(VSize),
NumValues(NumValues), Loc(Loc) {}
uint64_t getValue() const { return Value; }
@@ -466,7 +464,7 @@ class MCOrgFragment : public MCFragment {
public:
MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc,
MCSection *Sec = nullptr)
- : MCFragment(FT_Org, false, 0, Sec), Offset(&Offset), Value(Value), Loc(Loc) {}
+ : MCFragment(FT_Org, false, Sec), Offset(&Offset), Value(Value), Loc(Loc) {}
/// \name Accessors
/// @{
@@ -495,7 +493,7 @@ class MCLEBFragment : public MCFragment {
public:
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
- : MCFragment(FT_LEB, false, 0, Sec), Value(&Value_), IsSigned(IsSigned_) {
+ : MCFragment(FT_LEB, false, Sec), Value(&Value_), IsSigned(IsSigned_) {
Contents.push_back(0);
}
@@ -530,7 +528,7 @@ class MCDwarfLineAddrFragment : public MCFragment {
public:
MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
MCSection *Sec = nullptr)
- : MCFragment(FT_Dwarf, false, 0, Sec), LineDelta(LineDelta),
+ : MCFragment(FT_Dwarf, false, Sec), LineDelta(LineDelta),
AddrDelta(&AddrDelta) {
Contents.push_back(0);
}
@@ -561,7 +559,7 @@ class MCDwarfCallFrameFragment : public MCFragment {
public:
MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
- : MCFragment(FT_DwarfFrame, false, 0, Sec), AddrDelta(&AddrDelta) {
+ : MCFragment(FT_DwarfFrame, false, Sec), AddrDelta(&AddrDelta) {
Contents.push_back(0);
}
@@ -586,7 +584,7 @@ class MCSymbolIdFragment : public MCFragment {
public:
MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
- : MCFragment(FT_SymbolId, false, 0, Sec), Sym(Sym) {}
+ : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {}
/// \name Accessors
/// @{
@@ -620,7 +618,7 @@ public:
unsigned StartLineNum, const MCSymbol *FnStartSym,
const MCSymbol *FnEndSym,
MCSection *Sec = nullptr)
- : MCFragment(FT_CVInlineLines, false, 0, Sec), SiteFuncId(SiteFuncId),
+ : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId),
StartFileId(StartFileId), StartLineNum(StartLineNum),
FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 973311c93f6..1470e026d98 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -426,17 +426,18 @@ void MCAsmLayout::layoutFragment(MCFragment *F) {
if (Assembler.isBundlingEnabled() && F->hasInstructions()) {
assert(isa<MCEncodedFragment>(F) &&
"Only MCEncodedFragment implementations have instructions");
- uint64_t FSize = Assembler.computeFragmentSize(*this, *F);
+ MCEncodedFragment *EF = cast<MCEncodedFragment>(F);
+ uint64_t FSize = Assembler.computeFragmentSize(*this, *EF);
if (!Assembler.getRelaxAll() && FSize > Assembler.getBundleAlignSize())
report_fatal_error("Fragment can't be larger than a bundle size");
- uint64_t RequiredBundlePadding = computeBundlePadding(Assembler, F,
- F->Offset, FSize);
+ uint64_t RequiredBundlePadding =
+ computeBundlePadding(Assembler, EF, EF->Offset, FSize);
if (RequiredBundlePadding > UINT8_MAX)
report_fatal_error("Padding cannot exceed 255 bytes");
- F->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
- F->Offset += RequiredBundlePadding;
+ EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
+ EF->Offset += RequiredBundlePadding;
}
}
@@ -450,19 +451,20 @@ void MCAssembler::registerSymbol(const MCSymbol &Symbol, bool *Created) {
}
}
-void MCAssembler::writeFragmentPadding(raw_ostream &OS, const MCFragment &F,
+void MCAssembler::writeFragmentPadding(raw_ostream &OS,
+ const MCEncodedFragment &EF,
uint64_t FSize) const {
assert(getBackendPtr() && "Expected assembler backend");
// Should NOP padding be written out before this fragment?
- unsigned BundlePadding = F.getBundlePadding();
+ unsigned BundlePadding = EF.getBundlePadding();
if (BundlePadding > 0) {
assert(isBundlingEnabled() &&
"Writing bundle padding with disabled bundling");
- assert(F.hasInstructions() &&
+ assert(EF.hasInstructions() &&
"Writing bundle padding for a fragment without instructions");
unsigned TotalLength = BundlePadding + static_cast<unsigned>(FSize);
- if (F.alignToBundleEnd() && TotalLength > getBundleAlignSize()) {
+ if (EF.alignToBundleEnd() && TotalLength > getBundleAlignSize()) {
// If the padding itself crosses a bundle boundary, it must be emitted
// in 2 pieces, since even nop instructions must not cross boundaries.
// v--------------v <- BundleAlignSize
@@ -473,8 +475,8 @@ void MCAssembler::writeFragmentPadding(raw_ostream &OS, const MCFragment &F,
// ^-------------------^ <- TotalLength
unsigned DistanceToBoundary = TotalLength - getBundleAlignSize();
if (!getBackend().writeNopData(OS, DistanceToBoundary))
- report_fatal_error("unable to write NOP sequence of " +
- Twine(DistanceToBoundary) + " bytes");
+ report_fatal_error("unable to write NOP sequence of " +
+ Twine(DistanceToBoundary) + " bytes");
BundlePadding -= DistanceToBoundary;
}
if (!getBackend().writeNopData(OS, BundlePadding))
@@ -491,7 +493,8 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
support::endianness Endian = Asm.getBackend().Endian;
- Asm.writeFragmentPadding(OS, F, FragmentSize);
+ if (const MCEncodedFragment *EF = dyn_cast<MCEncodedFragment>(&F))
+ Asm.writeFragmentPadding(OS, *EF, FragmentSize);
// This variable (and its dummy usage) is to participate in the assert at
// the end of the function.
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index df11495a954..f44d877e260 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -557,6 +557,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment();
insert(CEIF);
CEIF->getContents().append(Code.begin(), Code.end());
+ CEIF->setHasInstructions(STI);
return;
} else {
DF = new MCDataFragment();
diff --git a/llvm/lib/MC/MCFragment.cpp b/llvm/lib/MC/MCFragment.cpp
index 70118f9c371..01ad640ee22 100644
--- a/llvm/lib/MC/MCFragment.cpp
+++ b/llvm/lib/MC/MCFragment.cpp
@@ -189,7 +189,7 @@ uint64_t MCAsmLayout::getSectionFileSize(const MCSection *Sec) const {
}
uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler,
- const MCFragment *F,
+ const MCEncodedFragment *F,
uint64_t FOffset, uint64_t FSize) {
uint64_t BundleSize = Assembler.getBundleAlignSize();
assert(BundleSize > 0 &&
@@ -236,10 +236,9 @@ void ilist_alloc_traits<MCFragment>::deleteNode(MCFragment *V) { V->destroy(); }
MCFragment::~MCFragment() = default;
MCFragment::MCFragment(FragmentType Kind, bool HasInstructions,
- uint8_t BundlePadding, MCSection *Parent)
- : Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false),
- BundlePadding(BundlePadding), Parent(Parent), Atom(nullptr),
- Offset(~UINT64_C(0)) {
+ MCSection *Parent)
+ : Kind(Kind), HasInstructions(HasInstructions), Parent(Parent),
+ Atom(nullptr), Offset(~UINT64_C(0)) {
if (Parent && !isDummy())
Parent->getFragmentList().push_back(this);
}
@@ -333,10 +332,11 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break;
}
- OS << "<MCFragment " << (const void*) this << " LayoutOrder:" << LayoutOrder
- << " Offset:" << Offset
- << " HasInstructions:" << hasInstructions()
- << " BundlePadding:" << static_cast<unsigned>(getBundlePadding()) << ">";
+ OS << "<MCFragment " << (const void *)this << " LayoutOrder:" << LayoutOrder
+ << " Offset:" << Offset << " HasInstructions:" << hasInstructions();
+ if (const MCEncodedFragment *EF = cast<MCEncodedFragment>(this))
+ OS << " BundlePadding:" << static_cast<unsigned>(EF->getBundlePadding());
+ OS << ">";
switch (getKind()) {
case MCFragment::FT_Align: {
OpenPOWER on IntegriCloud