mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-20 14:29:27 +00:00
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:
parent
787e90f862
commit
db9e697725
@ -153,6 +153,9 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM)
|
|||||||
|
|
||||||
maxStoresPerMemset = 4;
|
maxStoresPerMemset = 4;
|
||||||
maxStoresPerMemmove = maxStoresPerMemcpy = 2;
|
maxStoresPerMemmove = maxStoresPerMemcpy = 2;
|
||||||
|
|
||||||
|
// We have target-specific dag combine patterns for the following nodes:
|
||||||
|
setTargetDAGCombine(ISD::STORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue XCoreTargetLowering::
|
SDValue XCoreTargetLowering::
|
||||||
@ -1049,6 +1052,55 @@ XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
|||||||
return BB;
|
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
|
// Addressing mode description hooks
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -122,6 +122,8 @@ namespace llvm {
|
|||||||
|
|
||||||
// Expand specifics
|
// Expand specifics
|
||||||
SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG);
|
SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG);
|
||||||
|
|
||||||
|
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
test/CodeGen/XCore/unaligned_store_combine.ll
Normal file
12
test/CodeGen/XCore/unaligned_store_combine.ll
Normal 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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user