[llvm] r267798 - [Hexagon] Merging nops in to previous packet rather than always creating a new one.

Colin LeMahieu via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 27 14:37:44 PDT 2016


Author: colinl
Date: Wed Apr 27 16:37:44 2016
New Revision: 267798

URL: http://llvm.org/viewvc/llvm-project?rev=267798&view=rev
Log:
[Hexagon] Merging nops in to previous packet rather than always creating a new one.

Added:
    llvm/trunk/test/MC/Hexagon/align.s
Modified:
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp?rev=267798&r1=267797&r2=267798&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp Wed Apr 27 16:37:44 2016
@@ -11,7 +11,10 @@
 #include "HexagonFixupKinds.h"
 #include "HexagonMCTargetDesc.h"
 #include "MCTargetDesc/HexagonBaseInfo.h"
+#include "MCTargetDesc/HexagonMCChecker.h"
+#include "MCTargetDesc/HexagonMCCodeEmitter.h"
 #include "MCTargetDesc/HexagonMCInstrInfo.h"
+#include "MCTargetDesc/HexagonMCShuffler.h"
 #include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCAsmLayout.h"
 #include "llvm/MC/MCAssembler.h"
@@ -41,6 +44,19 @@ class HexagonAsmBackend : public MCAsmBa
   std::unique_ptr <MCInstrInfo> MCII;
   std::unique_ptr <MCInst *> RelaxTarget;
   MCInst * Extender;
+
+  void ReplaceInstruction(MCCodeEmitter &E, MCRelaxableFragment &RF,
+                          MCInst &HMB) const {
+    SmallVector<MCFixup, 4> Fixups;
+    SmallString<256> Code;
+    raw_svector_ostream VecOS(Code);
+    E.encodeInstruction(HMB, VecOS, Fixups, RF.getSubtargetInfo());
+
+    // Update the fragment.
+    RF.setInst(HMB);
+    RF.getContents() = Code;
+    RF.getFixups() = Fixups;
+  }
 public:
   HexagonAsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) :
     OSABI(OSABI), MCII (T.createMCInstrInfo()), RelaxTarget(new MCInst *),
@@ -530,23 +546,7 @@ public:
   ///
   /// \param Inst - The instruction to test.
   bool mayNeedRelaxation(MCInst const &Inst) const override {
-    assert(HexagonMCInstrInfo::isBundle(Inst));
-    bool PreviousIsExtender = false;
-    for (auto const &I : HexagonMCInstrInfo::bundleInstructions(Inst)) {
-      auto const &Inst = *I.getInst();
-      if (!PreviousIsExtender) {
-        if (HexagonMCInstrInfo::isDuplex(*MCII, Inst)) {
-          if (isInstRelaxable(*Inst.getOperand(0).getInst()) ||
-              isInstRelaxable(*Inst.getOperand(1).getInst()))
-            return true;
-        } else {
-          if (isInstRelaxable(Inst))
-            return true;
-        }
-      }
-      PreviousIsExtender = HexagonMCInstrInfo::isImmext(Inst);
-    }
-    return false;
+    return true;
   }
 
   /// fixupNeedsRelaxation - Target specific predicate for whether a given
@@ -686,6 +686,58 @@ public:
     }
     return true;
   }
+
+  void finishLayout(MCAssembler const &Asm,
+                    MCAsmLayout &Layout) const override {
+    for (auto I : Layout.getSectionOrder()) {
+      auto &Fragments = I->getFragmentList();
+      for (auto &J : Fragments) {
+        switch (J.getKind()) {
+        default:
+          break;
+        case MCFragment::FT_Align: {
+          auto Size = Asm.computeFragmentSize(Layout, J);
+          for (auto K = J.getIterator();
+               K != Fragments.begin() && Size >= HEXAGON_PACKET_SIZE;) {
+            --K;
+            switch (K->getKind()) {
+            default:
+              break;
+            case MCFragment::FT_Align: {
+              // Don't pad before other alignments
+              Size = 0;
+              break;
+            }
+            case MCFragment::FT_Relaxable: {
+              auto &RF = cast<MCRelaxableFragment>(*K);
+              auto &Inst = const_cast<MCInst &>(RF.getInst());
+              while (Size > 0 && HexagonMCInstrInfo::bundleSize(Inst) < 4) {
+                MCInst *Nop = new (Asm.getContext()) MCInst;
+                Nop->setOpcode(Hexagon::A2_nop);
+                Inst.addOperand(MCOperand::createInst(Nop));
+                Size -= 4;
+                if (!HexagonMCChecker(
+                           *MCII, RF.getSubtargetInfo(), Inst, Inst,
+                           *Asm.getContext().getRegisterInfo()).check()) {
+                  Inst.erase(Inst.end() - 1);
+                  Size = 0;
+                }
+              }
+              bool Error = HexagonMCShuffle(*MCII, RF.getSubtargetInfo(), Inst);
+              //assert(!Error);
+              (void)Error;
+              ReplaceInstruction(Asm.getEmitter(), RF, Inst);
+              Layout.invalidateFragmentsFrom(&RF);
+              Size = 0; // Only look back one instruction
+              break;
+            }
+            }
+          }
+        }
+        }
+      }
+    }
+  }
 };
 } // end anonymous namespace
 

Added: llvm/trunk/test/MC/Hexagon/align.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/align.s?rev=267798&view=auto
==============================================================================
--- llvm/trunk/test/MC/Hexagon/align.s (added)
+++ llvm/trunk/test/MC/Hexagon/align.s Wed Apr 27 16:37:44 2016
@@ -0,0 +1,60 @@
+# RUN: llvm-mc -triple=hexagon -filetype=obj %s | llvm-objdump -d - | FileCheck %s
+
+# Verify that the .align directive emits the proper insn packets.
+
+{ r1 = sub(#1, r1) }
+# CHECK: 76414021 { r1 = sub(#1, r1)
+# CHECK-NEXT: 7f004000   nop
+# CHECK-NEXT: 7f004000   nop
+# CHECK-NEXT: 7f00c000   nop }
+
+.align 16
+{ r1 = sub(#1, r1)
+  r2 = sub(#1, r2) }
+# CHECK: 76414021 { r1 = sub(#1, r1)
+# CHECK-NEXT: 76424022   r2 = sub(#1, r2)
+# CHECK-NEXT: 7f004000  nop
+# CHECK-NEXT: 7f00c000   nop }
+
+.p2align 5
+{ r1 = sub(#1, r1)
+  r2 = sub(#1, r2)
+  r3 = sub(#1, r3) }
+# CHECK: 76434023   r3 = sub(#1, r3)
+# CHECK-NEXT: 7f00c000 nop }
+
+.align 16
+{ r1 = sub(#1, r1)
+  r2 = sub(#1, r2)
+  r3 = sub(#1, r3)
+  r4 = sub(#1, r4) }
+
+# Don't pad packets that can't be padded e.g. solo insts
+# CHECK: 9200c020 {  r0 = vextract(v0,r0) }
+r0 = vextract(v0, r0)
+.align 128
+# CHECK: 76414021 { r1 = sub(#1, r1)
+# CHECK-NEXT: 7f00c000   nop }
+{ r1 = sub(#1, r1) }
+
+#CHECK: { r1 = sub(#1, r1)
+#CHECK:   r2 = sub(#1, r2)
+#CHECK:   r3 = sub(#1, r3) }
+.falign
+.align 8
+{ r1 = sub(#1, r1)
+  r2 = sub(#1, r2)
+  r3 = sub(#1, r3)  }
+
+# CHECK: { immext(#0)
+# CHECK:   r0 = sub(##1, r0)
+# CHECK:   immext(#0)
+# CHECK:   r1 = sub(##1, r1) }
+# CHECK: { nop
+# CHECK:   nop
+# CHECK:   nop }
+# CHECK: { r0 = sub(#1, r0) }
+{ r0 = sub (##1, r0)
+  r1 = sub (##1, r1) }
+.align 16
+{ r0 = sub (#1, r0) }
\ No newline at end of file




More information about the llvm-commits mailing list