Move bundle info from MCSectionData to MCSection.

llvm-svn: 238143
This commit is contained in:
Rafael Espindola 2015-05-25 15:04:26 +00:00
parent abd1521d88
commit 07cf6d285a
6 changed files with 62 additions and 65 deletions

View File

@ -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();
/// @} /// @}

View File

@ -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;

View File

@ -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_,

View File

@ -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() {

View File

@ -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))

View File

@ -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;
}