forked from OSchip/llvm-project
Combine an unaligned store of unaligned load into a memmove.
llvm-svn: 75908
This commit is contained in:
parent
efe3f9c9f4
commit
0cceec520c
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -122,6 +122,8 @@ namespace llvm {
|
|||
|
||||
// Expand specifics
|
||||
SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG);
|
||||
|
||||
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue