summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
diff options
context:
space:
mode:
authorIgor Laevsky <igmyrj@gmail.com>2016-12-29 14:31:07 +0000
committerIgor Laevsky <igmyrj@gmail.com>2016-12-29 14:31:07 +0000
commit4f31e52f9456a78d579506736cd6620d3370fcd8 (patch)
tree7ff965b4319d7d2322df6adfd72fbc7777930eb1 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
parent17b5568bc7b7cd79dc80a8e359cf39e3a8e5a31a (diff)
downloadbcm5719-llvm-4f31e52f9456a78d579506736cd6620d3370fcd8.tar.gz
bcm5719-llvm-4f31e52f9456a78d579506736cd6620d3370fcd8.zip
Introduce element-wise atomic memcpy intrinsic
This change adds a new intrinsic which is intended to provide memcpy functionality with additional atomicity guarantees. Please refer to the review thread or language reference for further details. Differential Revision: https://reviews.llvm.org/D27133 llvm-svn: 290708
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index da68fe87a32..cb803585282 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4896,6 +4896,51 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
updateDAGForMaybeTailCall(MM);
return nullptr;
}
+ case Intrinsic::memcpy_element_atomic: {
+ SDValue Dst = getValue(I.getArgOperand(0));
+ SDValue Src = getValue(I.getArgOperand(1));
+ SDValue NumElements = getValue(I.getArgOperand(2));
+ SDValue ElementSize = getValue(I.getArgOperand(3));
+
+ // Emit a library call.
+ TargetLowering::ArgListTy Args;
+ TargetLowering::ArgListEntry Entry;
+ Entry.Ty = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
+ Entry.Node = Dst;
+ Args.push_back(Entry);
+
+ Entry.Node = Src;
+ Args.push_back(Entry);
+
+ Entry.Ty = I.getArgOperand(2)->getType();
+ Entry.Node = NumElements;
+ Args.push_back(Entry);
+
+ Entry.Ty = Type::getInt32Ty(*DAG.getContext());
+ Entry.Node = ElementSize;
+ Args.push_back(Entry);
+
+ uint64_t ElementSizeConstant =
+ cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();
+ RTLIB::Libcall LibraryCall =
+ RTLIB::getMEMCPY_ELEMENT_ATOMIC(ElementSizeConstant);
+ if (LibraryCall == RTLIB::UNKNOWN_LIBCALL)
+ report_fatal_error("Unsupported element size");
+
+ TargetLowering::CallLoweringInfo CLI(DAG);
+ CLI.setDebugLoc(sdl)
+ .setChain(getRoot())
+ .setCallee(TLI.getLibcallCallingConv(LibraryCall),
+ Type::getVoidTy(*DAG.getContext()),
+ DAG.getExternalSymbol(
+ TLI.getLibcallName(LibraryCall),
+ TLI.getPointerTy(DAG.getDataLayout())),
+ std::move(Args));
+
+ std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
+ DAG.setRoot(CallResult.second);
+ return nullptr;
+ }
case Intrinsic::dbg_declare: {
const DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
DILocalVariable *Variable = DI.getVariable();
OpenPOWER on IntegriCloud