[llvm-commits] [llvm] r171797 - in /llvm/trunk: include/llvm/MC/MCAssembler.h include/llvm/MC/MCELFStreamer.h include/llvm/MC/MCObjectStreamer.h include/llvm/MC/MCStreamer.h lib/MC/MCAsmStreamer.cpp lib/MC/MCAssembler.cpp lib/MC/MCELFStreamer.cpp lib/MC/MCNullStreamer.cpp lib/MC/MCObjectStreamer.cpp lib/MC/MCParser/AsmParser.cpp test/MC/ARM/AlignedBundling/group-bundle-arm.s test/MC/X86/AlignedBundling/asm-printing-bundle-directives.s tools/lto/LTOModule.cpp
Eli Bendersky
eliben at google.com
Mon Jan 7 13:51:09 PST 2013
Author: eliben
Date: Mon Jan 7 15:51:08 2013
New Revision: 171797
URL: http://llvm.org/viewvc/llvm-project?rev=171797&view=rev
Log:
Add the align_to_end option to .bundle_lock in the MC implementation of aligned
bundling. The document describing this feature and the implementation has also
been updated:
https://sites.google.com/a/chromium.org/dev/nativeclient/pnacl/aligned-bundling-support-in-llvm
Modified:
llvm/trunk/include/llvm/MC/MCAssembler.h
llvm/trunk/include/llvm/MC/MCELFStreamer.h
llvm/trunk/include/llvm/MC/MCObjectStreamer.h
llvm/trunk/include/llvm/MC/MCStreamer.h
llvm/trunk/lib/MC/MCAsmStreamer.cpp
llvm/trunk/lib/MC/MCAssembler.cpp
llvm/trunk/lib/MC/MCELFStreamer.cpp
llvm/trunk/lib/MC/MCNullStreamer.cpp
llvm/trunk/lib/MC/MCObjectStreamer.cpp
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
llvm/trunk/test/MC/ARM/AlignedBundling/group-bundle-arm.s
llvm/trunk/test/MC/X86/AlignedBundling/asm-printing-bundle-directives.s
llvm/trunk/tools/lto/LTOModule.cpp
Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Mon Jan 7 15:51:08 2013
@@ -100,9 +100,12 @@
void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
/// \brief Does this fragment have instructions emitted into it? By default
- /// this is false, but specific fragment types may set it to true.
+ /// this is false, but specific fragment types may set it to true.
virtual bool hasInstructions() const { return false; }
+ /// \brief Should this fragment be placed at the end of an aligned bundle?
+ virtual bool alignToBundleEnd() const { return false; }
+
/// \brief 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
@@ -165,6 +168,9 @@
/// \brief Does this fragment contain encoded instructions anywhere in it?
bool HasInstructions;
+ /// \brief Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd;
+
SmallVector<char, 32> Contents;
/// Fixups - The list of fixups in this fragment.
@@ -172,7 +178,7 @@
public:
MCDataFragment(MCSectionData *SD = 0)
: MCEncodedFragment(FT_Data, SD),
- HasInstructions(false)
+ HasInstructions(false), AlignToBundleEnd(false)
{
}
@@ -190,6 +196,9 @@
virtual bool hasInstructions() const { return HasInstructions; }
virtual void setHasInstructions(bool V) { HasInstructions = V; }
+ virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+
fixup_iterator fixup_begin() { return Fixups.begin(); }
const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
@@ -476,6 +485,12 @@
typedef FragmentListType::const_reverse_iterator const_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:
FragmentListType Fragments;
const MCSection *Section;
@@ -489,8 +504,8 @@
/// Alignment - The maximum alignment seen in this section.
unsigned Alignment;
- /// \brief We're currently inside a bundle-locked group.
- bool BundleLocked;
+ /// \brief Keeping track of bundle-locked state.
+ BundleLockStateType BundleLockState;
/// \brief We've seen a bundle_lock directive but not its first instruction
/// yet.
@@ -549,11 +564,15 @@
bool empty() const { return Fragments.empty(); }
bool isBundleLocked() const {
- return BundleLocked;
+ return BundleLockState != NotBundleLocked;
+ }
+
+ BundleLockStateType getBundleLockState() const {
+ return BundleLockState;
}
- void setBundleLocked(bool IsLocked) {
- BundleLocked = IsLocked;
+ void setBundleLockState(BundleLockStateType NewState) {
+ BundleLockState = NewState;
}
bool isBundleGroupBeforeFirstInst() const {
Modified: llvm/trunk/include/llvm/MC/MCELFStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCELFStreamer.h?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCELFStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCELFStreamer.h Mon Jan 7 15:51:08 2013
@@ -85,7 +85,7 @@
virtual void EmitInstToData(const MCInst &Inst);
virtual void EmitBundleAlignMode(unsigned AlignPow2);
- virtual void EmitBundleLock();
+ virtual void EmitBundleLock(bool AlignToEnd);
virtual void EmitBundleUnlock();
void fixSymbolsInTLSFixups(const MCExpr *expr);
Modified: llvm/trunk/include/llvm/MC/MCObjectStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectStreamer.h?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCObjectStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCObjectStreamer.h Mon Jan 7 15:51:08 2013
@@ -84,7 +84,7 @@
virtual void EmitInstToFragment(const MCInst &Inst);
virtual void EmitBundleAlignMode(unsigned AlignPow2);
- virtual void EmitBundleLock();
+ virtual void EmitBundleLock(bool AlignToEnd);
virtual void EmitBundleUnlock();
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
virtual void EmitValueToAlignment(unsigned ByteAlignment,
Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Mon Jan 7 15:51:08 2013
@@ -562,7 +562,10 @@
virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0;
/// \brief The following instructions are a bundle-locked group.
- virtual void EmitBundleLock() = 0;
+ ///
+ /// \param AlignToEnd - If true, the bundle-locked group will be aligned to
+ /// the end of a bundle.
+ virtual void EmitBundleLock(bool AlignToEnd) = 0;
/// \brief Ends a bundle-locked group.
virtual void EmitBundleUnlock() = 0;
Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Mon Jan 7 15:51:08 2013
@@ -260,7 +260,7 @@
virtual void EmitInstruction(const MCInst &Inst);
virtual void EmitBundleAlignMode(unsigned AlignPow2);
- virtual void EmitBundleLock();
+ virtual void EmitBundleLock(bool AlignToEnd);
virtual void EmitBundleUnlock();
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
@@ -1370,8 +1370,10 @@
EmitEOL();
}
-void MCAsmStreamer::EmitBundleLock() {
+void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) {
OS << "\t.bundle_lock";
+ if (AlignToEnd)
+ OS << " align_to_end";
EmitEOL();
}
Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Jan 7 15:51:08 2013
@@ -167,10 +167,34 @@
"computeBundlePadding should only be called if bundling is enabled");
uint64_t BundleMask = BundleSize - 1;
uint64_t OffsetInBundle = FOffset & BundleMask;
+ uint64_t EndOfFragment = OffsetInBundle + FSize;
- // If the fragment would cross a bundle boundary, add enough padding until
- // the end of the current bundle.
- if (OffsetInBundle + FSize > BundleSize)
+ // There are two kinds of bundling restrictions:
+ //
+ // 1) For alignToBundleEnd(), add padding to ensure that the fragment will
+ // *end* on a bundle boundary.
+ // 2) Otherwise, check if the fragment would cross a bundle boundary. If it
+ // would, add padding until the end of the bundle so that the fragment
+ // will start in a new one.
+ if (F->alignToBundleEnd()) {
+ // Three possibilities here:
+ //
+ // A) The fragment just happens to end at a bundle boundary, so we're good.
+ // B) The fragment ends before the current bundle boundary: pad it just
+ // enough to reach the boundary.
+ // C) The fragment ends after the current bundle boundary: pad it until it
+ // reaches the end of the next bundle boundary.
+ //
+ // Note: this code could be made shorter with some modulo trickery, but it's
+ // intentionally kept in its more explicit form for simplicity.
+ if (EndOfFragment == BundleSize)
+ return 0;
+ else if (EndOfFragment < BundleSize)
+ return BundleSize - EndOfFragment;
+ else { // EndOfFragment > BundleSize
+ return 2 * BundleSize - EndOfFragment;
+ }
+ } else if (EndOfFragment > BundleSize)
return BundleSize - OffsetInBundle;
else
return 0;
@@ -204,7 +228,7 @@
: Section(&_Section),
Ordinal(~UINT32_C(0)),
Alignment(1),
- BundleLocked(false), BundleGroupBeforeFirstInst(false),
+ BundleLockState(NotBundleLocked), BundleGroupBeforeFirstInst(false),
HasInstructions(false)
{
if (A)
Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCELFStreamer.cpp Mon Jan 7 15:51:08 2013
@@ -379,8 +379,14 @@
MCSectionData *SD = getCurrentSectionData();
if (SD->isBundleLocked() && !SD->isBundleGroupBeforeFirstInst())
DF = getOrCreateDataFragment();
- else
+ else {
DF = new MCDataFragment(SD);
+ if (SD->getBundleLockState() == MCSectionData::BundleLockedAlignToEnd) {
+ // If this is a new fragment created for a bundle-locked group, and the
+ // group was marked as "align_to_end", set a flag in the fragment.
+ DF->setAlignToBundleEnd(true);
+ }
+ }
// We're now emitting an instruction in a bundle group, so this flag has
// to be turned off.
@@ -407,7 +413,7 @@
report_fatal_error(".bundle_align_mode should be only set once per file");
}
-void MCELFStreamer::EmitBundleLock() {
+void MCELFStreamer::EmitBundleLock(bool AlignToEnd) {
MCSectionData *SD = getCurrentSectionData();
// Sanity checks
@@ -417,7 +423,8 @@
else if (SD->isBundleLocked())
report_fatal_error("Nesting of .bundle_lock is forbidden");
- SD->setBundleLocked(true);
+ SD->setBundleLockState(AlignToEnd ? MCSectionData::BundleLockedAlignToEnd :
+ MCSectionData::BundleLocked);
SD->setBundleGroupBeforeFirstInst(true);
}
@@ -432,7 +439,7 @@
else if (SD->isBundleGroupBeforeFirstInst())
report_fatal_error("Empty bundle-locked group is forbidden");
- SD->setBundleLocked(false);
+ SD->setBundleLockState(MCSectionData::NotBundleLocked);
}
void MCELFStreamer::FinishImpl() {
Modified: llvm/trunk/lib/MC/MCNullStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCNullStreamer.cpp?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCNullStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCNullStreamer.cpp Mon Jan 7 15:51:08 2013
@@ -96,7 +96,7 @@
virtual void EmitInstruction(const MCInst &Inst) {}
virtual void EmitBundleAlignMode(unsigned AlignPow2) {}
- virtual void EmitBundleLock() {}
+ virtual void EmitBundleLock(bool AlignToEnd) {}
virtual void EmitBundleUnlock() {}
virtual void FinishImpl() {}
Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Mon Jan 7 15:51:08 2013
@@ -233,7 +233,7 @@
llvm_unreachable(BundlingNotImplementedMsg);
}
-void MCObjectStreamer::EmitBundleLock() {
+void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
llvm_unreachable(BundlingNotImplementedMsg);
}
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Mon Jan 7 15:51:08 2013
@@ -2473,15 +2473,31 @@
}
/// ParseDirectiveBundleLock
-/// ::= {.bundle_lock}
+/// ::= {.bundle_lock} [align_to_end]
bool AsmParser::ParseDirectiveBundleLock() {
CheckForValidSection();
+ bool AlignToEnd = false;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ StringRef Option;
+ SMLoc Loc = getTok().getLoc();
+ const char *kInvalidOptionError =
+ "invalid option for '.bundle_lock' directive";
+
+ if (ParseIdentifier(Option))
+ return Error(Loc, kInvalidOptionError);
+
+ if (Option != "align_to_end")
+ return Error(Loc, kInvalidOptionError);
+ else if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(Loc,
+ "unexpected token after '.bundle_lock' directive option");
+ AlignToEnd = true;
+ }
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.bundle_lock' directive");
Lex();
- getStreamer().EmitBundleLock();
+ getStreamer().EmitBundleLock(AlignToEnd);
return false;
}
Modified: llvm/trunk/test/MC/ARM/AlignedBundling/group-bundle-arm.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/AlignedBundling/group-bundle-arm.s?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/AlignedBundling/group-bundle-arm.s (original)
+++ llvm/trunk/test/MC/ARM/AlignedBundling/group-bundle-arm.s Mon Jan 7 15:51:08 2013
@@ -2,7 +2,7 @@
# RUN: | llvm-objdump -no-show-raw-insn -triple armv7 -disassemble - | FileCheck %s
# On ARM each instruction is 4 bytes long so padding for individual
-# instructions should not be inserted. However, for bundle=locked groups
+# instructions should not be inserted. However, for bundle-locked groups
# it can be.
.syntax unified
Modified: llvm/trunk/test/MC/X86/AlignedBundling/asm-printing-bundle-directives.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/AlignedBundling/asm-printing-bundle-directives.s?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/AlignedBundling/asm-printing-bundle-directives.s (original)
+++ llvm/trunk/test/MC/X86/AlignedBundling/asm-printing-bundle-directives.s Mon Jan 7 15:51:08 2013
@@ -14,5 +14,9 @@
jle .L_ELSE
.bundle_unlock
# CHECK: .bundle_unlock
+ .bundle_lock align_to_end
+# CHECK: .bundle_lock align_to_end
+ add %rbx, %rdx
+ .bundle_unlock
Modified: llvm/trunk/tools/lto/LTOModule.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOModule.cpp?rev=171797&r1=171796&r2=171797&view=diff
==============================================================================
--- llvm/trunk/tools/lto/LTOModule.cpp (original)
+++ llvm/trunk/tools/lto/LTOModule.cpp Mon Jan 7 15:51:08 2013
@@ -766,7 +766,7 @@
}
virtual void EmitBundleAlignMode(unsigned AlignPow2) {}
- virtual void EmitBundleLock() {}
+ virtual void EmitBundleLock(bool AlignToEnd) {}
virtual void EmitBundleUnlock() {}
// Noop calls.
More information about the llvm-commits
mailing list