[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