Skip to content

Commit

Permalink
Revert "[AArch64] Improve load/store optimizer to handle LDUR + LDR (…
Browse files Browse the repository at this point in the history
…take 3)."

This reverts commit r259812 as it broke AArch64 self-hosting.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@259881 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
rengolin committed Feb 5, 2016
1 parent f5861b0 commit 7849210
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 181 deletions.
97 changes: 21 additions & 76 deletions lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,24 +651,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 = getMemScale(Paired);
assert(!(PairedOffset % getMemScale(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.
Expand Down Expand Up @@ -795,12 +781,9 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
.addImm(OffsetImm)
.setMemRefs(I->mergeMemRefsWith(*Paired));
} else {
// Scale the immediate offset, if necessary.
if (isUnscaledLdSt(RtMI->getOpcode())) {
assert(!(OffsetImm % getMemScale(RtMI)) &&
"Offset should be a multiple of the stride!");
OffsetImm /= getMemScale(RtMI);
}
// Handle Unscaled
if (IsUnscaled)
OffsetImm /= OffsetStride;
MIB = BuildMI(*I->getParent(), InsertionPoint, I->getDebugLoc(),
TII->get(NewOpc))
.addOperand(getLdStRegOp(RtMI))
Expand Down Expand Up @@ -994,13 +977,9 @@ 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;
}

Expand Down Expand Up @@ -1090,33 +1069,6 @@ bool AArch64LoadStoreOpt::findMatchingStore(
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.
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
Expand Down Expand Up @@ -1170,9 +1122,19 @@ AArch64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
// Now that we know this is a real instruction, count it.
++Count;

bool CanMergeOpc = Opc == MI->getOpcode();
Flags.setSExtIdx(-1);
if (canMergeOpc(Opc, MI->getOpcode(), Flags) &&
getLdStOffsetOp(MI).isImm()) {
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.
Expand All @@ -1186,24 +1148,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 = getMemScale(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;
Expand All @@ -1214,9 +1158,10 @@ 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.
bool MIIsUnscaled = isUnscaledLdSt(MI);
bool IsNarrowLoad = isNarrowLoad(MI->getOpcode());
if (!IsNarrowLoad &&
!inBoundsForPair(IsUnscaled, MinOffset, OffsetStride)) {
!inBoundsForPair(MIIsUnscaled, MinOffset, OffsetStride)) {
trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
MemInsns.push_back(MI);
continue;
Expand Down
105 changes: 0 additions & 105 deletions test/CodeGen/AArch64/ldp-stp-scaled-unscaled-pairs.ll

This file was deleted.

0 comments on commit 7849210

Please sign in to comment.