mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-26 22:34:39 +00:00
Move bundle info from MCSectionData to MCSection.
llvm-svn: 238143
This commit is contained in:
parent
abd1521d88
commit
07cf6d285a
@ -548,27 +548,10 @@ public:
|
|||||||
typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
|
typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
|
||||||
typedef FragmentListType::reverse_iterator reverse_iterator;
|
typedef FragmentListType::reverse_iterator reverse_iterator;
|
||||||
|
|
||||||
/// \brief Express the state of bundle locked groups while emitting code.
|
|
||||||
enum BundleLockStateType {
|
|
||||||
NotBundleLocked,
|
|
||||||
BundleLocked,
|
|
||||||
BundleLockedAlignToEnd
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FragmentListType Fragments;
|
FragmentListType Fragments;
|
||||||
MCSection *Section;
|
MCSection *Section;
|
||||||
|
|
||||||
/// \brief Keeping track of bundle-locked state.
|
|
||||||
BundleLockStateType BundleLockState;
|
|
||||||
|
|
||||||
/// \brief Current nesting depth of bundle_lock directives.
|
|
||||||
unsigned BundleLockNestingDepth;
|
|
||||||
|
|
||||||
/// \brief We've seen a bundle_lock directive but not its first instruction
|
|
||||||
/// yet.
|
|
||||||
bool BundleGroupBeforeFirstInst;
|
|
||||||
|
|
||||||
/// \name Assembler Backend Data
|
/// \name Assembler Backend Data
|
||||||
/// @{
|
/// @{
|
||||||
//
|
//
|
||||||
@ -618,20 +601,6 @@ public:
|
|||||||
|
|
||||||
iterator getSubsectionInsertionPoint(unsigned Subsection);
|
iterator getSubsectionInsertionPoint(unsigned Subsection);
|
||||||
|
|
||||||
bool isBundleLocked() const { return BundleLockState != NotBundleLocked; }
|
|
||||||
|
|
||||||
BundleLockStateType getBundleLockState() const { return BundleLockState; }
|
|
||||||
|
|
||||||
void setBundleLockState(BundleLockStateType NewState);
|
|
||||||
|
|
||||||
bool isBundleGroupBeforeFirstInst() const {
|
|
||||||
return BundleGroupBeforeFirstInst;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBundleGroupBeforeFirstInst(bool IsFirst) {
|
|
||||||
BundleGroupBeforeFirstInst = IsFirst;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump();
|
void dump();
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -31,6 +31,13 @@ class MCSection {
|
|||||||
public:
|
public:
|
||||||
enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO };
|
enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO };
|
||||||
|
|
||||||
|
/// \brief Express the state of bundle locked groups while emitting code.
|
||||||
|
enum BundleLockStateType {
|
||||||
|
NotBundleLocked,
|
||||||
|
BundleLocked,
|
||||||
|
BundleLockedAlignToEnd
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MCSection(const MCSection &) = delete;
|
MCSection(const MCSection &) = delete;
|
||||||
void operator=(const MCSection &) = delete;
|
void operator=(const MCSection &) = delete;
|
||||||
@ -44,6 +51,16 @@ private:
|
|||||||
/// The index of this section in the layout order.
|
/// The index of this section in the layout order.
|
||||||
unsigned LayoutOrder;
|
unsigned LayoutOrder;
|
||||||
|
|
||||||
|
/// \brief Keeping track of bundle-locked state.
|
||||||
|
BundleLockStateType BundleLockState = NotBundleLocked;
|
||||||
|
|
||||||
|
/// \brief Current nesting depth of bundle_lock directives.
|
||||||
|
unsigned BundleLockNestingDepth = 0;
|
||||||
|
|
||||||
|
/// \brief We've seen a bundle_lock directive but not its first instruction
|
||||||
|
/// yet.
|
||||||
|
bool BundleGroupBeforeFirstInst = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin)
|
MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin)
|
||||||
: Begin(Begin), Variant(V), Kind(K) {}
|
: Begin(Begin), Variant(V), Kind(K) {}
|
||||||
@ -77,6 +94,17 @@ public:
|
|||||||
unsigned getLayoutOrder() const { return LayoutOrder; }
|
unsigned getLayoutOrder() const { return LayoutOrder; }
|
||||||
void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
|
void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
|
||||||
|
|
||||||
|
BundleLockStateType getBundleLockState() const { return BundleLockState; }
|
||||||
|
void setBundleLockState(BundleLockStateType NewState);
|
||||||
|
bool isBundleLocked() const { return BundleLockState != NotBundleLocked; }
|
||||||
|
|
||||||
|
bool isBundleGroupBeforeFirstInst() const {
|
||||||
|
return BundleGroupBeforeFirstInst;
|
||||||
|
}
|
||||||
|
void setBundleGroupBeforeFirstInst(bool IsFirst) {
|
||||||
|
BundleGroupBeforeFirstInst = IsFirst;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
|
virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
|
||||||
const MCExpr *Subsection) const = 0;
|
const MCExpr *Subsection) const = 0;
|
||||||
|
|
||||||
|
@ -293,9 +293,7 @@ MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() {
|
|||||||
MCSectionData::MCSectionData() : Section(nullptr) {}
|
MCSectionData::MCSectionData() : Section(nullptr) {}
|
||||||
|
|
||||||
MCSectionData::MCSectionData(MCSection &Section, MCAssembler *A)
|
MCSectionData::MCSectionData(MCSection &Section, MCAssembler *A)
|
||||||
: Section(&Section), BundleLockState(NotBundleLocked),
|
: Section(&Section), HasInstructions(false) {
|
||||||
BundleLockNestingDepth(0), BundleGroupBeforeFirstInst(false),
|
|
||||||
HasInstructions(false) {
|
|
||||||
if (A)
|
if (A)
|
||||||
A->getSectionList().push_back(this);
|
A->getSectionList().push_back(this);
|
||||||
}
|
}
|
||||||
@ -331,25 +329,6 @@ MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) {
|
|||||||
return IP;
|
return IP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCSectionData::setBundleLockState(BundleLockStateType NewState) {
|
|
||||||
if (NewState == NotBundleLocked) {
|
|
||||||
if (BundleLockNestingDepth == 0) {
|
|
||||||
report_fatal_error("Mismatched bundle_lock/unlock directives");
|
|
||||||
}
|
|
||||||
if (--BundleLockNestingDepth == 0) {
|
|
||||||
BundleLockState = NotBundleLocked;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If any of the directives is an align_to_end directive, the whole nested
|
|
||||||
// group is align_to_end. So don't downgrade from align_to_end to just locked.
|
|
||||||
if (BundleLockState != BundleLockedAlignToEnd) {
|
|
||||||
BundleLockState = NewState;
|
|
||||||
}
|
|
||||||
++BundleLockNestingDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* *** */
|
/* *** */
|
||||||
|
|
||||||
MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
|
MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
bool MCELFStreamer::isBundleLocked() const {
|
bool MCELFStreamer::isBundleLocked() const {
|
||||||
return getCurrentSectionData()->isBundleLocked();
|
return getCurrentSectionData()->getSection().isBundleLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
MCELFStreamer::~MCELFStreamer() {
|
MCELFStreamer::~MCELFStreamer() {
|
||||||
@ -507,6 +507,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
|
|||||||
|
|
||||||
if (Assembler.isBundlingEnabled()) {
|
if (Assembler.isBundlingEnabled()) {
|
||||||
MCSectionData *SD = getCurrentSectionData();
|
MCSectionData *SD = getCurrentSectionData();
|
||||||
|
MCSection &Sec = SD->getSection();
|
||||||
if (Assembler.getRelaxAll() && isBundleLocked())
|
if (Assembler.getRelaxAll() && isBundleLocked())
|
||||||
// If the -mc-relax-all flag is used and we are bundle-locked, we re-use
|
// If the -mc-relax-all flag is used and we are bundle-locked, we re-use
|
||||||
// the current bundle group.
|
// the current bundle group.
|
||||||
@ -516,7 +517,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
|
|||||||
// we create a new temporary fragment which will be later merged into
|
// we create a new temporary fragment which will be later merged into
|
||||||
// the current fragment.
|
// the current fragment.
|
||||||
DF = new MCDataFragment();
|
DF = new MCDataFragment();
|
||||||
else if (isBundleLocked() && !SD->isBundleGroupBeforeFirstInst())
|
else if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst())
|
||||||
// If we are bundle-locked, we re-use the current fragment.
|
// If we are bundle-locked, we re-use the current fragment.
|
||||||
// The bundle-locking directive ensures this is a new data fragment.
|
// The bundle-locking directive ensures this is a new data fragment.
|
||||||
DF = cast<MCDataFragment>(getCurrentFragment());
|
DF = cast<MCDataFragment>(getCurrentFragment());
|
||||||
@ -532,7 +533,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
|
|||||||
DF = new MCDataFragment();
|
DF = new MCDataFragment();
|
||||||
insert(DF);
|
insert(DF);
|
||||||
}
|
}
|
||||||
if (SD->getBundleLockState() == MCSectionData::BundleLockedAlignToEnd) {
|
if (Sec.getBundleLockState() == MCSection::BundleLockedAlignToEnd) {
|
||||||
// If this fragment is for a group marked "align_to_end", set a flag
|
// If this fragment is for a group marked "align_to_end", set a flag
|
||||||
// in the fragment. This can happen after the fragment has already been
|
// in the fragment. This can happen after the fragment has already been
|
||||||
// created if there are nested bundle_align groups and an inner one
|
// created if there are nested bundle_align groups and an inner one
|
||||||
@ -542,7 +543,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
|
|||||||
|
|
||||||
// We're now emitting an instruction in a bundle group, so this flag has
|
// We're now emitting an instruction in a bundle group, so this flag has
|
||||||
// to be turned off.
|
// to be turned off.
|
||||||
SD->setBundleGroupBeforeFirstInst(false);
|
Sec.setBundleGroupBeforeFirstInst(false);
|
||||||
} else {
|
} else {
|
||||||
DF = getOrCreateDataFragment();
|
DF = getOrCreateDataFragment();
|
||||||
}
|
}
|
||||||
@ -575,6 +576,7 @@ void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
|
|||||||
|
|
||||||
void MCELFStreamer::EmitBundleLock(bool AlignToEnd) {
|
void MCELFStreamer::EmitBundleLock(bool AlignToEnd) {
|
||||||
MCSectionData *SD = getCurrentSectionData();
|
MCSectionData *SD = getCurrentSectionData();
|
||||||
|
MCSection &Sec = SD->getSection();
|
||||||
|
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
//
|
//
|
||||||
@ -582,7 +584,7 @@ void MCELFStreamer::EmitBundleLock(bool AlignToEnd) {
|
|||||||
report_fatal_error(".bundle_lock forbidden when bundling is disabled");
|
report_fatal_error(".bundle_lock forbidden when bundling is disabled");
|
||||||
|
|
||||||
if (!isBundleLocked())
|
if (!isBundleLocked())
|
||||||
SD->setBundleGroupBeforeFirstInst(true);
|
Sec.setBundleGroupBeforeFirstInst(true);
|
||||||
|
|
||||||
if (getAssembler().getRelaxAll() && !isBundleLocked()) {
|
if (getAssembler().getRelaxAll() && !isBundleLocked()) {
|
||||||
// TODO: drop the lock state and set directly in the fragment
|
// TODO: drop the lock state and set directly in the fragment
|
||||||
@ -590,19 +592,20 @@ void MCELFStreamer::EmitBundleLock(bool AlignToEnd) {
|
|||||||
BundleGroups.push_back(DF);
|
BundleGroups.push_back(DF);
|
||||||
}
|
}
|
||||||
|
|
||||||
SD->setBundleLockState(AlignToEnd ? MCSectionData::BundleLockedAlignToEnd :
|
Sec.setBundleLockState(AlignToEnd ? MCSection::BundleLockedAlignToEnd
|
||||||
MCSectionData::BundleLocked);
|
: MCSection::BundleLocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCELFStreamer::EmitBundleUnlock() {
|
void MCELFStreamer::EmitBundleUnlock() {
|
||||||
MCSectionData *SD = getCurrentSectionData();
|
MCSectionData *SD = getCurrentSectionData();
|
||||||
|
MCSection &Sec = SD->getSection();
|
||||||
|
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
if (!getAssembler().isBundlingEnabled())
|
if (!getAssembler().isBundlingEnabled())
|
||||||
report_fatal_error(".bundle_unlock forbidden when bundling is disabled");
|
report_fatal_error(".bundle_unlock forbidden when bundling is disabled");
|
||||||
else if (!isBundleLocked())
|
else if (!isBundleLocked())
|
||||||
report_fatal_error(".bundle_unlock without matching lock");
|
report_fatal_error(".bundle_unlock without matching lock");
|
||||||
else if (SD->isBundleGroupBeforeFirstInst())
|
else if (Sec.isBundleGroupBeforeFirstInst())
|
||||||
report_fatal_error("Empty bundle-locked group is forbidden");
|
report_fatal_error("Empty bundle-locked group is forbidden");
|
||||||
|
|
||||||
// When the -mc-relax-all flag is used, we emit instructions to fragments
|
// When the -mc-relax-all flag is used, we emit instructions to fragments
|
||||||
@ -613,7 +616,7 @@ void MCELFStreamer::EmitBundleUnlock() {
|
|||||||
MCDataFragment *DF = BundleGroups.back();
|
MCDataFragment *DF = BundleGroups.back();
|
||||||
|
|
||||||
// FIXME: Use BundleGroups to track the lock state instead.
|
// FIXME: Use BundleGroups to track the lock state instead.
|
||||||
SD->setBundleLockState(MCSectionData::NotBundleLocked);
|
Sec.setBundleLockState(MCSection::NotBundleLocked);
|
||||||
|
|
||||||
// FIXME: Use more separate fragments for nested groups.
|
// FIXME: Use more separate fragments for nested groups.
|
||||||
if (!isBundleLocked()) {
|
if (!isBundleLocked()) {
|
||||||
@ -622,10 +625,10 @@ void MCELFStreamer::EmitBundleUnlock() {
|
|||||||
delete DF;
|
delete DF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SD->getBundleLockState() != MCSectionData::BundleLockedAlignToEnd)
|
if (Sec.getBundleLockState() != MCSection::BundleLockedAlignToEnd)
|
||||||
getOrCreateDataFragment()->setAlignToBundleEnd(false);
|
getOrCreateDataFragment()->setAlignToBundleEnd(false);
|
||||||
} else
|
} else
|
||||||
SD->setBundleLockState(MCSectionData::NotBundleLocked);
|
Sec.setBundleLockState(MCSection::NotBundleLocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCELFStreamer::Flush() {
|
void MCELFStreamer::Flush() {
|
||||||
|
@ -254,7 +254,7 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
|
|||||||
// group. We want to emit all such instructions into the same data
|
// group. We want to emit all such instructions into the same data
|
||||||
// fragment.
|
// fragment.
|
||||||
if (Assembler.getRelaxAll() ||
|
if (Assembler.getRelaxAll() ||
|
||||||
(Assembler.isBundlingEnabled() && SD->isBundleLocked())) {
|
(Assembler.isBundlingEnabled() && SD->getSection().isBundleLocked())) {
|
||||||
MCInst Relaxed;
|
MCInst Relaxed;
|
||||||
getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
|
getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
|
||||||
while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
|
while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
|
||||||
|
@ -29,3 +29,21 @@ bool MCSection::hasEnded() const { return End && End->isInSection(); }
|
|||||||
MCSection::~MCSection() {
|
MCSection::~MCSection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCSection::setBundleLockState(BundleLockStateType NewState) {
|
||||||
|
if (NewState == NotBundleLocked) {
|
||||||
|
if (BundleLockNestingDepth == 0) {
|
||||||
|
report_fatal_error("Mismatched bundle_lock/unlock directives");
|
||||||
|
}
|
||||||
|
if (--BundleLockNestingDepth == 0) {
|
||||||
|
BundleLockState = NotBundleLocked;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If any of the directives is an align_to_end directive, the whole nested
|
||||||
|
// group is align_to_end. So don't downgrade from align_to_end to just locked.
|
||||||
|
if (BundleLockState != BundleLockedAlignToEnd) {
|
||||||
|
BundleLockState = NewState;
|
||||||
|
}
|
||||||
|
++BundleLockNestingDepth;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user