[llvm] r202395 - [XCore] Target optimized library function __memcpy_4()
Richard Osborne
richard at xmos.com
Thu Feb 27 05:39:07 PST 2014
Author: friedgold
Date: Thu Feb 27 07:39:07 2014
New Revision: 202395
URL: http://llvm.org/viewvc/llvm-project?rev=202395&view=rev
Log:
[XCore] Target optimized library function __memcpy_4()
Summary:
If the src, dst and size of a memcpy are known to be 4 byte aligned we
can call __memcpy_4() instead of memcpy().
Reviewers: robertlytton
Reviewed By: robertlytton
CC: llvm-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D2871
Added:
llvm/trunk/test/CodeGen/XCore/memcpy.ll
Modified:
llvm/trunk/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
llvm/trunk/lib/Target/XCore/XCoreSelectionDAGInfo.h
llvm/trunk/test/CodeGen/XCore/byVal.ll
Modified: llvm/trunk/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreSelectionDAGInfo.cpp?rev=202395&r1=202394&r2=202395&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreSelectionDAGInfo.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreSelectionDAGInfo.cpp Thu Feb 27 07:39:07 2014
@@ -21,3 +21,36 @@ XCoreSelectionDAGInfo::XCoreSelectionDAG
XCoreSelectionDAGInfo::~XCoreSelectionDAGInfo() {
}
+
+SDValue XCoreSelectionDAGInfo::
+EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl, SDValue Chain,
+ SDValue Dst, SDValue Src, SDValue Size, unsigned Align,
+ bool isVolatile, bool AlwaysInline,
+ MachinePointerInfo DstPtrInfo,
+ MachinePointerInfo SrcPtrInfo) const
+{
+ unsigned SizeBitWidth = Size.getValueType().getSizeInBits();
+ // Call __memcpy_4 if the src, dst and size are all 4 byte aligned.
+ if (!AlwaysInline && (Align & 3) == 0 &&
+ DAG.MaskedValueIsZero(Size, APInt(SizeBitWidth, 3))) {
+ const TargetLowering &TLI = *DAG.getTarget().getTargetLowering();
+ TargetLowering::ArgListTy Args;
+ TargetLowering::ArgListEntry Entry;
+ Entry.Ty = TLI.getDataLayout()->getIntPtrType(*DAG.getContext());
+ Entry.Node = Dst; Args.push_back(Entry);
+ Entry.Node = Src; Args.push_back(Entry);
+ Entry.Node = Size; Args.push_back(Entry);
+
+ TargetLowering::CallLoweringInfo
+ CLI(Chain, Type::getVoidTy(*DAG.getContext()), false, false, false, false,
+ 0, TLI.getLibcallCallingConv(RTLIB::MEMCPY), /*isTailCall=*/false,
+ /*doesNotRet=*/false, /*isReturnValueUsed=*/false,
+ DAG.getExternalSymbol("__memcpy_4", TLI.getPointerTy()), Args, DAG, dl);
+ std::pair<SDValue,SDValue> CallResult =
+ TLI.LowerCallTo(CLI);
+ return CallResult.second;
+ }
+
+ // Otherwise have the target-independent code call memcpy.
+ return SDValue();
+}
Modified: llvm/trunk/lib/Target/XCore/XCoreSelectionDAGInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreSelectionDAGInfo.h?rev=202395&r1=202394&r2=202395&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreSelectionDAGInfo.h (original)
+++ llvm/trunk/lib/Target/XCore/XCoreSelectionDAGInfo.h Thu Feb 27 07:39:07 2014
@@ -24,6 +24,15 @@ class XCoreSelectionDAGInfo : public Tar
public:
explicit XCoreSelectionDAGInfo(const XCoreTargetMachine &TM);
~XCoreSelectionDAGInfo();
+
+ virtual SDValue
+ EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, unsigned Align, bool isVolatile,
+ bool AlwaysInline,
+ MachinePointerInfo DstPtrInfo,
+ MachinePointerInfo SrcPtrInfo) const;
};
}
Modified: llvm/trunk/test/CodeGen/XCore/byVal.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/byVal.ll?rev=202395&r1=202394&r2=202395&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/XCore/byVal.ll (original)
+++ llvm/trunk/test/CodeGen/XCore/byVal.ll Thu Feb 27 07:39:07 2014
@@ -20,7 +20,7 @@ entry:
; CHECK: ldaw r5, sp[1]
; CHECK: ldc r2, 40
; CHECK: mov r0, r5
-; CHECK: bl memcpy
+; CHECK: bl __memcpy_4
; CHECK: mov r0, r5
; CHECK: bl f1
; CHECK: mov r0, r4
Added: llvm/trunk/test/CodeGen/XCore/memcpy.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/memcpy.ll?rev=202395&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/XCore/memcpy.ll (added)
+++ llvm/trunk/test/CodeGen/XCore/memcpy.ll Thu Feb 27 07:39:07 2014
@@ -0,0 +1,32 @@
+; RUN: llc < %s -march=xcore | FileCheck %s
+
+; Optimize memcpy to __memcpy_4 if src, dst and size are all 4 byte aligned.
+define void @f1(i8* %dst, i8* %src, i32 %n) nounwind {
+; CHECK-LABEL: f1:
+; CHECK: bl __memcpy_4
+entry:
+ %0 = shl i32 %n, 2
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %0, i32 4, i1 false)
+ ret void
+}
+
+; Can't optimize - size is not a multiple of 4.
+define void @f2(i8* %dst, i8* %src, i32 %n) nounwind {
+; CHECK-LABEL: f2:
+; CHECK: bl memcpy
+entry:
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %n, i32 4, i1 false)
+ ret void
+}
+
+; Can't optimize - alignment is not a multiple of 4.
+define void @f3(i8* %dst, i8* %src, i32 %n) nounwind {
+; CHECK-LABEL: f3:
+; CHECK: bl memcpy
+entry:
+ %0 = shl i32 %n, 2
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %0, i32 2, i1 false)
+ ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
More information about the llvm-commits
mailing list