summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
diff options
context:
space:
mode:
authorTobias Edler von Koch <tobias@codeaurora.org>2015-12-16 17:29:37 +0000
committerTobias Edler von Koch <tobias@codeaurora.org>2015-12-16 17:29:37 +0000
commitb51460cf86e730c502a6d6116862a72ed25f5b78 (patch)
treee369b02e4a1740f856a055c9c7b44e49f682b8ca /llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
parentd083b9a8f67a10d24e2ccceb96b92a9a0dd119bc (diff)
downloadbcm5719-llvm-b51460cf86e730c502a6d6116862a72ed25f5b78.tar.gz
bcm5719-llvm-b51460cf86e730c502a6d6116862a72ed25f5b78.zip
[Hexagon] Make memcpy lowering thread-safe
This removes an unpleasant hack involving a global variable for special lowering of certain memcpy calls. These are now lowered as intended in EmitTargetCodeForMemcpy in the same way that other targets do it. llvm-svn: 255785
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp50
1 files changed, 37 insertions, 13 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
index 276cc69eed0..239dbda8f27 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
@@ -12,12 +12,11 @@
//===----------------------------------------------------------------------===//
#include "HexagonTargetMachine.h"
+#include "llvm/CodeGen/SelectionDAG.h"
using namespace llvm;
#define DEBUG_TYPE "hexagon-selectiondag-info"
-bool llvm::flag_aligned_memcpy;
-
SDValue
HexagonSelectionDAGInfo::
EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl, SDValue Chain,
@@ -25,15 +24,40 @@ EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl, SDValue Chain,
bool isVolatile, bool AlwaysInline,
MachinePointerInfo DstPtrInfo,
MachinePointerInfo SrcPtrInfo) const {
- flag_aligned_memcpy = false;
- if ((Align & 0x3) == 0) {
- ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
- if (ConstantSize) {
- uint64_t SizeVal = ConstantSize->getZExtValue();
- if ((SizeVal > 32) && ((SizeVal % 8) == 0))
- flag_aligned_memcpy = true;
- }
- }
-
- return SDValue();
+ ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
+ if (AlwaysInline || (Align & 0x3) != 0 || !ConstantSize)
+ return SDValue();
+
+ uint64_t SizeVal = ConstantSize->getZExtValue();
+ if (SizeVal < 32 || (SizeVal % 8) != 0)
+ return SDValue();
+
+ // Special case aligned memcpys with size >= 32 bytes and a multiple of 8.
+ //
+ const TargetLowering &TLI = *DAG.getSubtarget().getTargetLowering();
+ 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.Node = Size;
+ Args.push_back(Entry);
+
+ const char *SpecialMemcpyName =
+ "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes";
+
+ TargetLowering::CallLoweringInfo CLI(DAG);
+ CLI.setDebugLoc(dl)
+ .setChain(Chain)
+ .setCallee(TLI.getLibcallCallingConv(RTLIB::MEMCPY),
+ Type::getVoidTy(*DAG.getContext()),
+ DAG.getTargetExternalSymbol(
+ SpecialMemcpyName, TLI.getPointerTy(DAG.getDataLayout())),
+ std::move(Args), 0)
+ .setDiscardResult();
+
+ std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
+ return CallResult.second;
}
OpenPOWER on IntegriCloud