summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@codeaurora.org>2015-09-03 16:41:28 +0000
committerChad Rosier <mcrosier@codeaurora.org>2015-09-03 16:41:28 +0000
commit08ef462d1583457701da431ce3ca02af43d1a0da (patch)
treee0bbc94d678d74425a60f49745c8bdada8edc525 /llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
parentc9ae9d72f8eeefd2883e2d5eaccca30281898f7e (diff)
downloadbcm5719-llvm-08ef462d1583457701da431ce3ca02af43d1a0da.tar.gz
bcm5719-llvm-08ef462d1583457701da431ce3ca02af43d1a0da.zip
Revert "[AArch64] Improve load/store optimizer to handle LDUR + LDR."
This reverts commit r246769. This appears to have broken Multisource/Benchmarks/tramp3d-v4. llvm-svn: 246782
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp')
-rw-r--r--llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp98
1 files changed, 21 insertions, 77 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
index 87ac4d0eb2c..83dd806421e 100644
--- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
@@ -382,24 +382,10 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
const MachineOperand &BaseRegOp =
MergeForward ? getLdStBaseOp(Paired) : getLdStBaseOp(I);
- int Offset = getLdStOffsetOp(I).getImm();
- int PairedOffset = getLdStOffsetOp(Paired).getImm();
- bool PairedIsUnscaled = isUnscaledLdSt(Paired->getOpcode());
-
- // We're trying to pair instructions that differ in how they are scaled.
- // If I is scaled then scale the offset of Paired accordingly.
- // Otherwise, do the opposite (i.e., make Paired's offset unscaled).
- if (IsUnscaled != PairedIsUnscaled) {
- int MemSize = getMemSize(Paired);
- assert(!(PairedOffset % getMemSize(Paired)) &&
- "Offset should be a multiple of the stride!");
- PairedOffset =
- PairedIsUnscaled ? PairedOffset / MemSize : PairedOffset * MemSize;
- }
-
// Which register is Rt and which is Rt2 depends on the offset order.
MachineInstr *RtMI, *Rt2MI;
- if (Offset == PairedOffset + OffsetStride) {
+ if (getLdStOffsetOp(I).getImm() ==
+ getLdStOffsetOp(Paired).getImm() + OffsetStride) {
RtMI = Paired;
Rt2MI = I;
// Here we swapped the assumption made for SExtIdx.
@@ -411,13 +397,10 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
RtMI = I;
Rt2MI = Paired;
}
- // Scale the immediate offset, if necessary.
+ // Handle Unscaled
int OffsetImm = getLdStOffsetOp(RtMI).getImm();
- if (isUnscaledLdSt(RtMI->getOpcode()) && EnableAArch64UnscaledMemOp) {
- assert(!(OffsetImm % getMemSize(RtMI)) &&
- "Offset should be a multiple of the stride!");
- OffsetImm /= getMemSize(RtMI);
- }
+ if (IsUnscaled && EnableAArch64UnscaledMemOp)
+ OffsetImm /= OffsetStride;
// Construct the new instruction.
MachineInstrBuilder MIB = BuildMI(*I->getParent(), InsertionPoint,
@@ -511,13 +494,8 @@ static void trackRegDefsUses(const MachineInstr *MI, BitVector &ModifiedRegs,
static bool inBoundsForPair(bool IsUnscaled, int Offset, int OffsetStride) {
// Convert the byte-offset used by unscaled into an "element" offset used
// by the scaled pair load/store instructions.
- if (IsUnscaled) {
- // If the byte-offset isn't a multiple of the stride, there's no point
- // trying to match it.
- if (Offset % OffsetStride)
- return false;
+ if (IsUnscaled)
Offset /= OffsetStride;
- }
return Offset <= 63 && Offset >= -64;
}
@@ -553,34 +531,6 @@ static bool mayAlias(MachineInstr *MIa,
return false;
}
-static bool canMergeOpc(unsigned Opc, unsigned PairOpc, LdStPairFlags &Flags) {
- // Opcodes match: nothing more to check.
- if (Opc == PairOpc)
- return true;
-
- // Try to match a sign-extended load/store with a zero-extended load/store.
- Flags.setSExtIdx(-1);
- bool IsValidLdStrOpc, PairIsValidLdStrOpc;
- unsigned NonSExtOpc = getMatchingNonSExtOpcode(Opc, &IsValidLdStrOpc);
- assert(IsValidLdStrOpc &&
- "Given Opc should be a Load or Store with an immediate");
- // Opc will be the first instruction in the pair.
- if (NonSExtOpc == getMatchingNonSExtOpcode(PairOpc, &PairIsValidLdStrOpc)) {
- Flags.setSExtIdx(NonSExtOpc == (unsigned)Opc ? 1 : 0);
- return true;
- }
-
- // FIXME: Can we also match a mixed sext/zext unscaled/scaled pair?
-
- // If the second instruction isn't even a load/store, bail out.
- if (!PairIsValidLdStrOpc)
- return false;
-
- // Try to match an unscaled load/store with a scaled load/store.
- return isUnscaledLdSt(Opc) != isUnscaledLdSt(PairOpc) &&
- getMatchingPairOpcode(Opc) == getMatchingPairOpcode(PairOpc);
-}
-
/// findMatchingInsn - Scan the instructions looking for a load/store that can
/// be combined with the current instruction into a load/store pair.
MachineBasicBlock::iterator
@@ -631,8 +581,19 @@ AArch64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
// Now that we know this is a real instruction, count it.
++Count;
- if (canMergeOpc(Opc, MI->getOpcode(), Flags) &&
- getLdStOffsetOp(MI).isImm()) {
+ bool CanMergeOpc = Opc == MI->getOpcode();
+ Flags.setSExtIdx(-1);
+ if (!CanMergeOpc) {
+ bool IsValidLdStrOpc;
+ unsigned NonSExtOpc = getMatchingNonSExtOpcode(Opc, &IsValidLdStrOpc);
+ assert(IsValidLdStrOpc &&
+ "Given Opc should be a Load or Store with an immediate");
+ // Opc will be the first instruction in the pair.
+ Flags.setSExtIdx(NonSExtOpc == (unsigned)Opc ? 1 : 0);
+ CanMergeOpc = NonSExtOpc == getMatchingNonSExtOpcode(MI->getOpcode());
+ }
+
+ if (CanMergeOpc && getLdStOffsetOp(MI).isImm()) {
assert(MI->mayLoadOrStore() && "Expected memory operation.");
// If we've found another instruction with the same opcode, check to see
// if the base and offset are compatible with our starting instruction.
@@ -646,24 +607,6 @@ AArch64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
// final offset must be in range.
unsigned MIBaseReg = getLdStBaseOp(MI).getReg();
int MIOffset = getLdStOffsetOp(MI).getImm();
-
- // We're trying to pair instructions that differ in how they are scaled.
- // If FirstMI is scaled then scale the offset of MI accordingly.
- // Otherwise, do the opposite (i.e., make MI's offset unscaled).
- bool MIIsUnscaled = isUnscaledLdSt(MI);
- if (IsUnscaled != MIIsUnscaled) {
- int MemSize = getMemSize(MI);
- if (MIIsUnscaled) {
- // If the unscaled offset isn't a multiple of the MemSize, we can't
- // pair the operations together: bail and keep looking.
- if (MIOffset % MemSize)
- continue;
- MIOffset /= MemSize;
- } else {
- MIOffset *= MemSize;
- }
- }
-
if (BaseReg == MIBaseReg && ((Offset == MIOffset + OffsetStride) ||
(Offset + OffsetStride == MIOffset))) {
int MinOffset = Offset < MIOffset ? Offset : MIOffset;
@@ -674,7 +617,8 @@ AArch64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
return E;
// If the resultant immediate offset of merging these instructions
// is out of range for a pairwise instruction, bail and keep looking.
- if (!inBoundsForPair(IsUnscaled, MinOffset, OffsetStride)) {
+ bool MIIsUnscaled = isUnscaledLdSt(MI);
+ if (!inBoundsForPair(MIIsUnscaled, MinOffset, OffsetStride)) {
trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
MemInsns.push_back(MI);
continue;
OpenPOWER on IntegriCloud