[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