Combine an unaligned store of unaligned load into a memmove.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75908 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Osborne 2009-07-16 12:50:48 +00:00
parent 787e90f862
commit db9e697725
3 changed files with 66 additions and 0 deletions

View File

@ -153,6 +153,9 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM)
maxStoresPerMemset = 4;
maxStoresPerMemmove = maxStoresPerMemcpy = 2;
// We have target-specific dag combine patterns for the following nodes:
setTargetDAGCombine(ISD::STORE);
}
SDValue XCoreTargetLowering::
@ -1049,6 +1052,55 @@ XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
return BB;
}
//===----------------------------------------------------------------------===//
// Target Optimization Hooks
//===----------------------------------------------------------------------===//
SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
SelectionDAG &DAG = DCI.DAG;
DebugLoc dl = N->getDebugLoc();
switch (N->getOpcode()) {
default: break;
case ISD::STORE: {
// Replace unaligned store of unaligned load with memmove.
StoreSDNode *ST = cast<StoreSDNode>(N);
if (!DCI.isBeforeLegalize() || allowsUnalignedMemoryAccesses() ||
ST->isVolatile() || ST->isIndexed()) {
break;
}
SDValue Chain = ST->getChain();
unsigned StoreBits = ST->getMemoryVT().getStoreSizeInBits();
if (StoreBits % 8) {
break;
}
unsigned ABIAlignment = getTargetData()->
getABITypeAlignment(ST->getMemoryVT().getTypeForMVT(*DAG.getContext()));
unsigned Alignment = ST->getAlignment();
if (Alignment >= ABIAlignment) {
break;
}
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(ST->getValue())) {
if (LD->hasNUsesOfValue(1, 0) && ST->getMemoryVT() == LD->getMemoryVT() &&
LD->getAlignment() == Alignment &&
!LD->isVolatile() && !LD->isIndexed() &&
Chain.reachesChainWithoutSideEffects(SDValue(LD, 1))) {
return DAG.getMemmove(Chain, dl, ST->getBasePtr(),
LD->getBasePtr(),
DAG.getConstant(StoreBits/8, MVT::i32),
Alignment, ST->getSrcValue(),
ST->getSrcValueOffset(), LD->getSrcValue(),
LD->getSrcValueOffset());
}
}
break;
}
}
return SDValue();
}
//===----------------------------------------------------------------------===//
// Addressing mode description hooks
//===----------------------------------------------------------------------===//

View File

@ -122,6 +122,8 @@ namespace llvm {
// Expand specifics
SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG);
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
};
}

View File

@ -0,0 +1,12 @@
; RUN: llvm-as < %s | llc -march=xcore > %t1.s
; RUN: grep "bl memmove" %t1.s | count 1
; RUN: grep "ldc r., 8" %t1.s | count 1
; Unaligned load / store pair. Should be combined into a memmove
; of size 8
define void @f(i64* %dst, i64* %src) nounwind {
entry:
%0 = load i64* %src, align 1
store i64 %0, i64* %dst, align 1
ret void
}