diff options
author | Richard Osborne <richard@xmos.com> | 2009-07-16 12:50:48 +0000 |
---|---|---|
committer | Richard Osborne <richard@xmos.com> | 2009-07-16 12:50:48 +0000 |
commit | db9e697725e81edb4c5cb80f8dc7b412431be0d0 (patch) | |
tree | 80f5ef0a5272129d63b9bf48a0254c0f685aa612 /lib/Target/XCore | |
parent | 787e90f8627251fd2c63e2e5e17132e22d5d606a (diff) |
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
Diffstat (limited to 'lib/Target/XCore')
-rw-r--r-- | lib/Target/XCore/XCoreISelLowering.cpp | 52 | ||||
-rw-r--r-- | lib/Target/XCore/XCoreISelLowering.h | 2 |
2 files changed, 54 insertions, 0 deletions
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index 0f503bc7a6..113bfbf8db 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -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:: @@ -1050,6 +1053,55 @@ XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, } //===----------------------------------------------------------------------===// +// 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 //===----------------------------------------------------------------------===// diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h index e7a48a9726..4b244660cc 100644 --- a/lib/Target/XCore/XCoreISelLowering.h +++ b/lib/Target/XCore/XCoreISelLowering.h @@ -122,6 +122,8 @@ namespace llvm { // Expand specifics SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG); + + virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; }; } |