Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
Line
Count
Source
1
//===-- AArch64SelectionDAGInfo.cpp - AArch64 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 AArch64SelectionDAGInfo class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "AArch64TargetMachine.h"
14
using namespace llvm;
15
16
#define DEBUG_TYPE "aarch64-selectiondag-info"
17
18
SDValue AArch64SelectionDAGInfo::EmitTargetCodeForMemset(
19
    SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
20
    SDValue Size, unsigned Align, bool isVolatile,
21
4.90k
    MachinePointerInfo DstPtrInfo) const {
22
4.90k
  // Check to see if there is a specialized entry-point for memory zeroing.
23
4.90k
  ConstantSDNode *V = dyn_cast<ConstantSDNode>(Src);
24
4.90k
  ConstantSDNode *SizeValue = dyn_cast<ConstantSDNode>(Size);
25
4.90k
  const AArch64Subtarget &STI =
26
4.90k
      DAG.getMachineFunction().getSubtarget<AArch64Subtarget>();
27
4.90k
  const char *bzeroName = (V && 
V->isNullValue()4.89k
)
28
4.90k
      ? 
DAG.getTargetLoweringInfo().getLibcallName(RTLIB::BZERO)4.79k
:
nullptr114
;
29
4.90k
  // For small size (< 256), it is not beneficial to use bzero
30
4.90k
  // instead of memset.
31
4.90k
  if (bzeroName && 
(4.78k
!SizeValue4.78k
||
SizeValue->getZExtValue() > 2561.69k
)) {
32
4.78k
    const AArch64TargetLowering &TLI = *STI.getTargetLowering();
33
4.78k
34
4.78k
    EVT IntPtr = TLI.getPointerTy(DAG.getDataLayout());
35
4.78k
    Type *IntPtrTy = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
36
4.78k
    TargetLowering::ArgListTy Args;
37
4.78k
    TargetLowering::ArgListEntry Entry;
38
4.78k
    Entry.Node = Dst;
39
4.78k
    Entry.Ty = IntPtrTy;
40
4.78k
    Args.push_back(Entry);
41
4.78k
    Entry.Node = Size;
42
4.78k
    Args.push_back(Entry);
43
4.78k
    TargetLowering::CallLoweringInfo CLI(DAG);
44
4.78k
    CLI.setDebugLoc(dl)
45
4.78k
        .setChain(Chain)
46
4.78k
        .setLibCallee(CallingConv::C, Type::getVoidTy(*DAG.getContext()),
47
4.78k
                      DAG.getExternalSymbol(bzeroName, IntPtr),
48
4.78k
                      std::move(Args))
49
4.78k
        .setDiscardResult();
50
4.78k
    std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
51
4.78k
    return CallResult.second;
52
4.78k
  }
53
122
  return SDValue();
54
122
}
55
bool AArch64SelectionDAGInfo::generateFMAsInMachineCombiner(
56
633
    CodeGenOpt::Level OptLevel) const {
57
633
  return OptLevel >= CodeGenOpt::Aggressive;
58
633
}
59
60
static const int kSetTagLoopThreshold = 176;
61
62
static SDValue EmitUnrolledSetTag(SelectionDAG &DAG, const SDLoc &dl,
63
                                  SDValue Chain, SDValue Ptr, uint64_t ObjSize,
64
                                  const MachineMemOperand *BaseMemOperand,
65
8
                                  bool ZeroData) {
66
8
  MachineFunction &MF = DAG.getMachineFunction();
67
8
  unsigned ObjSizeScaled = ObjSize / 16;
68
8
69
8
  SDValue TagSrc = Ptr;
70
8
  if (Ptr.getOpcode() == ISD::FrameIndex) {
71
2
    int FI = cast<FrameIndexSDNode>(Ptr)->getIndex();
72
2
    Ptr = DAG.getTargetFrameIndex(FI, MVT::i64);
73
2
    // A frame index operand may end up as [SP + offset] => it is fine to use SP
74
2
    // register as the tag source.
75
2
    TagSrc = DAG.getRegister(AArch64::SP, MVT::i64);
76
2
  }
77
8
78
8
  const unsigned OpCode1 = ZeroData ? 
AArch64ISD::STZG1
:
AArch64ISD::STG7
;
79
8
  const unsigned OpCode2 = ZeroData ? 
AArch64ISD::STZ2G1
:
AArch64ISD::ST2G7
;
80
8
81
8
  SmallVector<SDValue, 8> OutChains;
82
8
  unsigned OffsetScaled = 0;
83
23
  while (OffsetScaled < ObjSizeScaled) {
84
15
    if (ObjSizeScaled - OffsetScaled >= 2) {
85
9
      SDValue AddrNode = DAG.getMemBasePlusOffset(Ptr, OffsetScaled * 16, dl);
86
9
      SDValue St = DAG.getMemIntrinsicNode(
87
9
          OpCode2, dl, DAG.getVTList(MVT::Other),
88
9
          {Chain, TagSrc, AddrNode},
89
9
          MVT::v4i64,
90
9
          MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16 * 2));
91
9
      OffsetScaled += 2;
92
9
      OutChains.push_back(St);
93
9
      continue;
94
9
    }
95
6
96
6
    if (ObjSizeScaled - OffsetScaled > 0) {
97
6
      SDValue AddrNode = DAG.getMemBasePlusOffset(Ptr, OffsetScaled * 16, dl);
98
6
      SDValue St = DAG.getMemIntrinsicNode(
99
6
          OpCode1, dl, DAG.getVTList(MVT::Other),
100
6
          {Chain, TagSrc, AddrNode},
101
6
          MVT::v2i64,
102
6
          MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16));
103
6
      OffsetScaled += 1;
104
6
      OutChains.push_back(St);
105
6
    }
106
6
  }
107
8
108
8
  SDValue Res = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
109
8
  return Res;
110
8
}
111
112
SDValue AArch64SelectionDAGInfo::EmitTargetCodeForSetTag(
113
    SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Addr,
114
12
    SDValue Size, MachinePointerInfo DstPtrInfo, bool ZeroData) const {
115
12
  uint64_t ObjSize = cast<ConstantSDNode>(Size)->getZExtValue();
116
12
  assert(ObjSize % 16 == 0);
117
12
118
12
  MachineFunction &MF = DAG.getMachineFunction();
119
12
  MachineMemOperand *BaseMemOperand = MF.getMachineMemOperand(
120
12
      DstPtrInfo, MachineMemOperand::MOStore, ObjSize, 16);
121
12
122
12
  bool UseSetTagRangeLoop =
123
12
      kSetTagLoopThreshold >= 0 && (int)ObjSize >= kSetTagLoopThreshold;
124
12
  if (!UseSetTagRangeLoop)
125
8
    return EmitUnrolledSetTag(DAG, dl, Chain, Addr, ObjSize, BaseMemOperand,
126
8
                              ZeroData);
127
4
128
4
  if (ObjSize % 32 != 0) {
129
3
    SDNode *St1 = DAG.getMachineNode(
130
3
        ZeroData ? 
AArch64::STZGPostIndex1
:
AArch64::STGPostIndex2
, dl,
131
3
        {MVT::i64, MVT::Other},
132
3
        {Addr, Addr, DAG.getTargetConstant(1, dl, MVT::i64), Chain});
133
3
    DAG.setNodeMemRefs(cast<MachineSDNode>(St1), {BaseMemOperand});
134
3
    ObjSize -= 16;
135
3
    Addr = SDValue(St1, 0);
136
3
    Chain = SDValue(St1, 1);
137
3
  }
138
4
139
4
  const EVT ResTys[] = {MVT::i64, MVT::i64, MVT::Other};
140
4
  SDValue Ops[] = {DAG.getConstant(ObjSize, dl, MVT::i64), Addr, Chain};
141
4
  SDNode *St = DAG.getMachineNode(
142
4
      ZeroData ? 
AArch64::STZGloop1
:
AArch64::STGloop3
, dl, ResTys, Ops);
143
4
144
4
  DAG.setNodeMemRefs(cast<MachineSDNode>(St), {BaseMemOperand});
145
4
  return SDValue(St, 2);
146
4
}