summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@codeaurora.org>2015-09-29 16:07:32 +0000
committerChad Rosier <mcrosier@codeaurora.org>2015-09-29 16:07:32 +0000
commit32d4d37e614f005e981f61ad278808f6da213bca (patch)
tree61c8d7c22c3109eb707bbfcf2d0e9dc78a0c7c35 /llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
parentdc0541f12f6dfa2c4a91d2f12bd86ed6f0f65bd5 (diff)
downloadbcm5719-llvm-32d4d37e614f005e981f61ad278808f6da213bca.tar.gz
bcm5719-llvm-32d4d37e614f005e981f61ad278808f6da213bca.zip
[AArch64] Scale offsets by the size of the memory operation. NFC.
The immediate in the load/store should be scaled by the size of the memory operation, not the size of the register being loaded/stored. This change gets us one step closer to forming LDPSW instructions. This change also enables pre- and post-indexing for halfword and byte loads and stores. llvm-svn: 248804
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp')
-rw-r--r--llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp38
1 files changed, 21 insertions, 17 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
index 7a7688bd5ac..d767c9ec805 100644
--- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
@@ -164,8 +164,8 @@ static bool isUnscaledLdSt(MachineInstr *MI) {
return isUnscaledLdSt(MI->getOpcode());
}
-// Size in bytes of the data moved by an unscaled load or store.
-static int getMemSize(MachineInstr *MI) {
+// Scaling factor for unscaled load or store.
+static int getMemScale(MachineInstr *MI) {
switch (MI->getOpcode()) {
default:
llvm_unreachable("Opcode has unknown size!");
@@ -179,6 +179,10 @@ static int getMemSize(MachineInstr *MI) {
case AArch64::STURSi:
case AArch64::STRWui:
case AArch64::STURWi:
+ case AArch64::LDPSi:
+ case AArch64::LDPWi:
+ case AArch64::STPSi:
+ case AArch64::STPWi:
return 4;
case AArch64::LDRDui:
case AArch64::LDURDi:
@@ -188,11 +192,17 @@ static int getMemSize(MachineInstr *MI) {
case AArch64::STURDi:
case AArch64::STRXui:
case AArch64::STURXi:
+ case AArch64::LDPDi:
+ case AArch64::LDPXi:
+ case AArch64::STPDi:
+ case AArch64::STPXi:
return 8;
case AArch64::LDRQui:
case AArch64::LDURQi:
case AArch64::STRQui:
case AArch64::STURQi:
+ case AArch64::LDPQi:
+ case AArch64::STPQi:
return 16;
}
}
@@ -425,7 +435,7 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
SExtIdx == -1 ? I->getOpcode() : getMatchingNonSExtOpcode(I->getOpcode());
bool IsUnscaled = isUnscaledLdSt(Opc);
int OffsetStride =
- IsUnscaled && EnableAArch64UnscaledMemOp ? getMemSize(I) : 1;
+ IsUnscaled && EnableAArch64UnscaledMemOp ? getMemScale(I) : 1;
bool MergeForward = Flags.getMergeForward();
unsigned NewOpc = getMatchingPairOpcode(Opc);
@@ -613,7 +623,7 @@ AArch64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
// range, plus allow an extra one in case we find a later insn that matches
// with Offset-1)
int OffsetStride =
- IsUnscaled && EnableAArch64UnscaledMemOp ? getMemSize(FirstMI) : 1;
+ IsUnscaled && EnableAArch64UnscaledMemOp ? getMemScale(FirstMI) : 1;
if (!inBoundsForPair(IsUnscaled, Offset, OffsetStride))
return E;
@@ -774,8 +784,7 @@ AArch64LoadStoreOpt::mergeUpdateInsn(MachineBasicBlock::iterator I,
.addImm(Value);
} else {
// Paired instruction.
- const MachineFunction &MF = *I->getParent()->getParent();
- int Scale = TII->getRegClass(I->getDesc(), 0, TRI, MF)->getSize();
+ int Scale = getMemScale(I);
MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), TII->get(NewOpc))
.addOperand(getLdStRegOp(Update))
.addOperand(getLdStRegOp(I, 0))
@@ -840,8 +849,7 @@ bool AArch64LoadStoreOpt::isMatchingUpdateInsn(MachineInstr *MemMI,
// the scaling factor. The scaled offset must also fit into a signed 7-bit
// integer.
if (IsPairedInsn) {
- const MachineFunction &MF = *MemMI->getParent()->getParent();
- int Scale = TII->getRegClass(MemMI->getDesc(), 0, TRI, MF)->getSize();
+ int Scale = getMemScale(MemMI);
if (UpdateOffset % Scale != 0)
break;
@@ -864,11 +872,9 @@ MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnForward(
MachineBasicBlock::iterator E = I->getParent()->end();
MachineInstr *MemMI = I;
MachineBasicBlock::iterator MBBI = I;
- const MachineFunction &MF = *MemMI->getParent()->getParent();
unsigned BaseReg = getLdStBaseOp(MemMI).getReg();
- int Offset = getLdStOffsetOp(MemMI).getImm() *
- TII->getRegClass(MemMI->getDesc(), 0, TRI, MF)->getSize();
+ int Offset = getLdStOffsetOp(MemMI).getImm() * getMemScale(MemMI);
// If the base register overlaps a destination register, we can't
// merge the update.
@@ -922,11 +928,10 @@ MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnBackward(
MachineBasicBlock::iterator E = I->getParent()->end();
MachineInstr *MemMI = I;
MachineBasicBlock::iterator MBBI = I;
- const MachineFunction &MF = *MemMI->getParent()->getParent();
unsigned BaseReg = getLdStBaseOp(MemMI).getReg();
int Offset = getLdStOffsetOp(MemMI).getImm();
- unsigned RegSize = TII->getRegClass(MemMI->getDesc(), 0, TRI, MF)->getSize();
+ unsigned MemSize = getMemScale(MemMI);
// If the load/store is the first instruction in the block, there's obviously
// not any matching update. Ditto if the memory offset isn't zero.
@@ -958,7 +963,7 @@ MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnBackward(
++Count;
// If we found a match, return it.
- if (isMatchingUpdateInsn(I, MI, BaseReg, RegSize))
+ if (isMatchingUpdateInsn(I, MI, BaseReg, MemSize))
return MBBI;
// Update the status of what the instruction clobbered and used.
@@ -1147,9 +1152,8 @@ bool AArch64LoadStoreOpt::optimizeBlock(MachineBasicBlock &MBB) {
// The immediate in the load/store is scaled by the size of the register
// being loaded. The immediate in the add we're looking for,
// however, is not, so adjust here.
- int Value = MI->getOperand(isPairedLdSt(MI) ? 3 : 2).getImm() *
- TII->getRegClass(MI->getDesc(), 0, TRI, *(MBB.getParent()))
- ->getSize();
+ int Value =
+ MI->getOperand(isPairedLdSt(MI) ? 3 : 2).getImm() * getMemScale(MI);
// FIXME: The immediate in the load/store should be scaled by the size of
// the memory operation, not the size of the register being loaded/stored.
OpenPOWER on IntegriCloud