[PATCH] ARMLoadStoreOptimizer: Create LDRD/STRD on thumb2

John Brawn john.brawn at arm.com
Wed Jun 24 10:15:18 PDT 2015


REPOSITORY
  rL LLVM

================
Comment at: lib/Target/ARM/ARMLoadStoreOptimizer.cpp:935
@@ +934,3 @@
+    // register when interrupted or faulted.
+      && (!STI->isCortexM3() || PReg != getLoadStoreBaseOp(*MI).getReg());
+    bool CanMergeToLoadStoreMulti = true;
----------------
Only LDRD and not STRD, so should have || !isi32Load(Opcode)

================
Comment at: lib/Target/ARM/ARMLoadStoreOptimizer.cpp:945-961
@@ -900,24 +944,19 @@
         unsigned RegNum = MO.isUndef() ? UINT_MAX : TRI->getEncodingValue(Reg);
+        bool CanMergeThisToLoadStoreMulti = false;
+        bool CanMergeThisToLoadStoreDouble = false;
         // Register numbers must be in ascending order. For VFP / NEON load and
         // store multiples, the registers must also be consecutive and within
         // the limit on the number of registers per instruction.
-        if (Reg != ARM::SP &&
-            NewOffset == Offset + (int)Size &&
-            ((isNotVFP && RegNum > PRegNum) ||
-             ((Count < Limit) && RegNum == PRegNum+1)) &&
-            // On Swift we don't want vldm/vstm to start with a odd register num
-            // because Q register unaligned vldm/vstm need more uops.
-            (!STI->isSwift() || isNotVFP || Count != 1 || !(PRegNum & 0x1))) {
-          // Track MemOp with latest and earliest position (Positions are
-          // counted in reverse).
-          unsigned Position = MemOps[I].Position;
-          if (Position < MemOps[Latest].Position)
-            Latest = I;
-          else if (Position > MemOps[Earliest].Position)
-            Earliest = I;
-          // Prepare for next MemOp.
-          Offset += Size;
-          PRegNum = RegNum;
-          ++Count;
-          ++I;
-          continue;
+        if (NewOffset == Offset + (int)Size) {
+          if (CanMergeToLoadStoreMulti && Reg != ARM::SP &&
+              ((isNotVFP && RegNum > PRegNum) ||
+               ((Count < Limit) && RegNum == PRegNum+1)) &&
+              // On Swift we don't want vldm/vstm to start with a odd register
+              // num because Q register unaligned vldm/vstm need more uops.
+              (!STI->isSwift() || isNotVFP || Count != 1 || !(PRegNum & 0x1))) {
+            CanMergeThisToLoadStoreMulti = true;
+          }
+          if (CanMergeToLoadStoreDouble && Count <= 1) {
+            CanMergeThisToLoadStoreDouble = true;
+          }
+          if (CanMergeThisToLoadStoreMulti || CanMergeThisToLoadStoreDouble) {
----------------
rengolin wrote:
> nitpick: variable name too close to CanMergeToLoadStoreMulti, confusing.
I think the logic here could be made much clearer by splitting it up something like
```
// Must access sequential ascending memory addresses
if (NewOffset != Offset + (int)Size)
  continue;
// Cannot load SP
if (Reg == ARM::SP)
  continue;
// VFP must load contiguous ascending registers, non-VFP must load ascending registers
CanMergeThisToLoadStoreMulti = (isNotVFP ? RegNum <= PRegNum : (Count < Limit) && RegNum == PRegNum+1))
```
The swift check I think can be done outside the loop, as it depends only on the first register. Instead of having CanMergeThisToLoadStoreDouble maybe just later set Candidate->CanMergeToLoadStoreDouble = CanMergeToLoadStoreDouble && Count == 2.

http://reviews.llvm.org/D10623

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/






More information about the llvm-commits mailing list