1 //===-- HexagonSelectionDAGInfo.cpp - Hexagon SelectionDAG Info -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the HexagonSelectionDAGInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "HexagonTargetMachine.h"
14 #include "llvm/CodeGen/SelectionDAG.h"
15 using namespace llvm;
16 
17 #define DEBUG_TYPE "hexagon-selectiondag-info"
18 
EmitTargetCodeForMemcpy(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Dst,SDValue Src,SDValue Size,Align Alignment,bool isVolatile,bool AlwaysInline,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo) const19 SDValue HexagonSelectionDAGInfo::EmitTargetCodeForMemcpy(
20     SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
21     SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
22     MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
23   ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
24   if (AlwaysInline || Alignment < Align(4) || !ConstantSize)
25     return SDValue();
26 
27   uint64_t SizeVal = ConstantSize->getZExtValue();
28   if (SizeVal < 32 || (SizeVal % 8) != 0)
29     return SDValue();
30 
31   // Special case aligned memcpys with size >= 32 bytes and a multiple of 8.
32   //
33   const TargetLowering &TLI = *DAG.getSubtarget().getTargetLowering();
34   TargetLowering::ArgListTy Args;
35   TargetLowering::ArgListEntry Entry;
36   Entry.Ty = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
37   Entry.Node = Dst;
38   Args.push_back(Entry);
39   Entry.Node = Src;
40   Args.push_back(Entry);
41   Entry.Node = Size;
42   Args.push_back(Entry);
43 
44   const char *SpecialMemcpyName =
45       "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes";
46   const MachineFunction &MF = DAG.getMachineFunction();
47   bool LongCalls = MF.getSubtarget<HexagonSubtarget>().useLongCalls();
48   unsigned Flags = LongCalls ? HexagonII::HMOTF_ConstExtended : 0;
49 
50   TargetLowering::CallLoweringInfo CLI(DAG);
51   CLI.setDebugLoc(dl)
52       .setChain(Chain)
53       .setLibCallee(
54           TLI.getLibcallCallingConv(RTLIB::MEMCPY),
55           Type::getVoidTy(*DAG.getContext()),
56           DAG.getTargetExternalSymbol(
57               SpecialMemcpyName, TLI.getPointerTy(DAG.getDataLayout()), Flags),
58           std::move(Args))
59       .setDiscardResult();
60 
61   std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
62   return CallResult.second;
63 }
64