Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
Line
Count
Source (jump to first uncovered line)
1
//==- llvm/CodeGen/SelectionDAGAddressAnalysis.cpp - DAG Address Analysis --==//
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
#include "llvm/CodeGen/SelectionDAGAddressAnalysis.h"
10
#include "llvm/CodeGen/ISDOpcodes.h"
11
#include "llvm/CodeGen/MachineFrameInfo.h"
12
#include "llvm/CodeGen/MachineFunction.h"
13
#include "llvm/CodeGen/SelectionDAG.h"
14
#include "llvm/CodeGen/SelectionDAGNodes.h"
15
#include "llvm/CodeGen/TargetLowering.h"
16
#include "llvm/Support/Casting.h"
17
#include <cstdint>
18
19
using namespace llvm;
20
21
bool BaseIndexOffset::equalBaseIndex(const BaseIndexOffset &Other,
22
                                     const SelectionDAG &DAG,
23
6.12M
                                     int64_t &Off) const {
24
6.12M
  // Conservatively fail if we a match failed..
25
6.12M
  if (!Base.getNode() || !Other.Base.getNode())
26
0
    return false;
27
6.12M
  if (!hasValidOffset() || !Other.hasValidOffset())
28
0
    return false;
29
6.12M
  // Initial Offset difference.
30
6.12M
  Off = *Other.Offset - *Offset;
31
6.12M
32
6.12M
  if ((Other.Index == Index) && 
(Other.IsIndexSignExt == IsIndexSignExt)5.67M
) {
33
5.67M
    // Trivial match.
34
5.67M
    if (Other.Base == Base)
35
3.01M
      return true;
36
2.66M
37
2.66M
    // Match GlobalAddresses
38
2.66M
    if (auto *A = dyn_cast<GlobalAddressSDNode>(Base))
39
163k
      if (auto *B = dyn_cast<GlobalAddressSDNode>(Other.Base))
40
73.9k
        if (A->getGlobal() == B->getGlobal()) {
41
3.73k
          Off += B->getOffset() - A->getOffset();
42
3.73k
          return true;
43
3.73k
        }
44
2.66M
45
2.66M
    // Match Constants
46
2.66M
    if (auto *A = dyn_cast<ConstantPoolSDNode>(Base))
47
0
      if (auto *B = dyn_cast<ConstantPoolSDNode>(Other.Base)) {
48
0
        bool IsMatch =
49
0
            A->isMachineConstantPoolEntry() == B->isMachineConstantPoolEntry();
50
0
        if (IsMatch) {
51
0
          if (A->isMachineConstantPoolEntry())
52
0
            IsMatch = A->getMachineCPVal() == B->getMachineCPVal();
53
0
          else
54
0
            IsMatch = A->getConstVal() == B->getConstVal();
55
0
        }
56
0
        if (IsMatch) {
57
0
          Off += B->getOffset() - A->getOffset();
58
0
          return true;
59
0
        }
60
2.66M
      }
61
2.66M
62
2.66M
    const MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
63
2.66M
64
2.66M
    // Match FrameIndexes.
65
2.66M
    if (auto *A = dyn_cast<FrameIndexSDNode>(Base))
66
977k
      if (auto *B = dyn_cast<FrameIndexSDNode>(Other.Base)) {
67
549k
        // Equal FrameIndexes - offsets are directly comparable.
68
549k
        if (A->getIndex() == B->getIndex())
69
215k
          return true;
70
333k
        // Non-equal FrameIndexes - If both frame indices are fixed
71
333k
        // we know their relative offsets and can compare them. Otherwise
72
333k
        // we must be conservative.
73
333k
        if (MFI.isFixedObjectIndex(A->getIndex()) &&
74
333k
            
MFI.isFixedObjectIndex(B->getIndex())27.3k
) {
75
26.8k
          Off += MFI.getObjectOffset(B->getIndex()) -
76
26.8k
                 MFI.getObjectOffset(A->getIndex());
77
26.8k
          return true;
78
26.8k
        }
79
2.86M
      }
80
2.66M
  }
81
2.86M
  return false;
82
2.86M
}
83
84
bool BaseIndexOffset::computeAliasing(const SDNode *Op0,
85
                                      const Optional<int64_t> NumBytes0,
86
                                      const SDNode *Op1,
87
                                      const Optional<int64_t> NumBytes1,
88
3.31M
                                      const SelectionDAG &DAG, bool &IsAlias) {
89
3.31M
90
3.31M
  BaseIndexOffset BasePtr0 = match(Op0, DAG);
91
3.31M
  BaseIndexOffset BasePtr1 = match(Op1, DAG);
92
3.31M
93
3.31M
  if (!(BasePtr0.getBase().getNode() && BasePtr1.getBase().getNode()))
94
2
    return false;
95
3.31M
  int64_t PtrDiff;
96
3.31M
  if (NumBytes0.hasValue() && 
NumBytes1.hasValue()3.31M
&&
97
3.31M
      
BasePtr0.equalBaseIndex(BasePtr1, DAG, PtrDiff)3.31M
) {
98
800k
    // BasePtr1 is PtrDiff away from BasePtr0. They alias if none of the
99
800k
    // following situations arise:
100
800k
    IsAlias = !(
101
800k
        // [----BasePtr0----]
102
800k
        //                         [---BasePtr1--]
103
800k
        // ========PtrDiff========>
104
800k
        (*NumBytes0 <= PtrDiff) ||
105
800k
        //                     [----BasePtr0----]
106
800k
        // [---BasePtr1--]
107
800k
        // =====(-PtrDiff)====>
108
800k
        
(PtrDiff + *NumBytes1 <= 0)635k
); // i.e. *NumBytes1 < -PtrDiff.
109
800k
    return true;
110
800k
  }
111
2.51M
  // If both BasePtr0 and BasePtr1 are FrameIndexes, we will not be
112
2.51M
  // able to calculate their relative offset if at least one arises
113
2.51M
  // from an alloca. However, these allocas cannot overlap and we
114
2.51M
  // can infer there is no alias.
115
2.51M
  if (auto *A = dyn_cast<FrameIndexSDNode>(BasePtr0.getBase()))
116
629k
    if (auto *B = dyn_cast<FrameIndexSDNode>(BasePtr1.getBase())) {
117
235k
      MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
118
235k
      // If the base are the same frame index but the we couldn't find a
119
235k
      // constant offset, (indices are different) be conservative.
120
235k
      if (A != B && 
(230k
!MFI.isFixedObjectIndex(A->getIndex())230k
||
121
230k
                     
!MFI.isFixedObjectIndex(B->getIndex())375
)) {
122
230k
        IsAlias = false;
123
230k
        return true;
124
230k
      }
125
2.28M
    }
126
2.28M
127
2.28M
  bool IsFI0 = isa<FrameIndexSDNode>(BasePtr0.getBase());
128
2.28M
  bool IsFI1 = isa<FrameIndexSDNode>(BasePtr1.getBase());
129
2.28M
  bool IsGV0 = isa<GlobalAddressSDNode>(BasePtr0.getBase());
130
2.28M
  bool IsGV1 = isa<GlobalAddressSDNode>(BasePtr1.getBase());
131
2.28M
  bool IsCV0 = isa<ConstantPoolSDNode>(BasePtr0.getBase());
132
2.28M
  bool IsCV1 = isa<ConstantPoolSDNode>(BasePtr1.getBase());
133
2.28M
134
2.28M
  // If of mismatched base types or checkable indices we can check
135
2.28M
  // they do not alias.
136
2.28M
  if ((BasePtr0.getIndex() == BasePtr1.getIndex() || 
(IsFI0 != IsFI1)364k
||
137
2.28M
       
(IsGV0 != IsGV1)322k
||
(IsCV0 != IsCV1)274k
) &&
138
2.28M
      
(2.00M
IsFI02.00M
||
IsGV01.61M
||
IsCV01.44M
) &&
(559k
IsFI1559k
||
IsGV1541k
||
IsCV1467k
)) {
139
91.5k
    IsAlias = false;
140
91.5k
    return true;
141
91.5k
  }
142
2.19M
  return false; // Cannot determine whether the pointers alias.
143
2.19M
}
144
145
bool BaseIndexOffset::contains(const SelectionDAG &DAG, int64_t BitSize,
146
                               const BaseIndexOffset &Other,
147
102k
                               int64_t OtherBitSize, int64_t &BitOffset) const {
148
102k
  int64_t Offset;
149
102k
  if (!equalBaseIndex(Other, DAG, Offset))
150
97.7k
    return false;
151
4.33k
  if (Offset >= 0) {
152
3.12k
    // Other is after *this:
153
3.12k
    // [-------*this---------]
154
3.12k
    //            [---Other--]
155
3.12k
    // ==Offset==>
156
3.12k
    BitOffset = 8 * Offset;
157
3.12k
    return BitOffset + OtherBitSize <= BitSize;
158
3.12k
  }
159
1.20k
  // Other starts strictly before *this, it cannot be fully contained.
160
1.20k
  //    [-------*this---------]
161
1.20k
  // [--Other--]
162
1.20k
  return false;
163
1.20k
}
164
165
/// Parses tree in Ptr for base, index, offset addresses.
166
static BaseIndexOffset matchLSNode(const LSBaseSDNode *N,
167
16.9M
                                   const SelectionDAG &DAG) {
168
16.9M
  SDValue Ptr = N->getBasePtr();
169
16.9M
170
16.9M
  // (((B + I*M) + c)) + c ...
171
16.9M
  SDValue Base = DAG.getTargetLoweringInfo().unwrapAddress(Ptr);
172
16.9M
  SDValue Index = SDValue();
173
16.9M
  int64_t Offset = 0;
174
16.9M
  bool IsIndexSignExt = false;
175
16.9M
176
16.9M
  // pre-inc/pre-dec ops are components of EA.
177
16.9M
  if (N->getAddressingMode() == ISD::PRE_INC) {
178
1.75k
    if (auto *C = dyn_cast<ConstantSDNode>(N->getOffset()))
179
1.74k
      Offset += C->getSExtValue();
180
14
    else // If unknown, give up now.
181
14
      return BaseIndexOffset(SDValue(), SDValue(), 0, false);
182
16.9M
  } else if (N->getAddressingMode() == ISD::PRE_DEC) {
183
0
    if (auto *C = dyn_cast<ConstantSDNode>(N->getOffset()))
184
0
      Offset -= C->getSExtValue();
185
0
    else // If unknown, give up now.
186
0
      return BaseIndexOffset(SDValue(), SDValue(), 0, false);
187
16.9M
  }
188
16.9M
189
16.9M
  // Consume constant adds & ors with appropriate masking.
190
57.7M
  
while (16.9M
true) {
191
57.7M
    switch (Base->getOpcode()) {
192
57.7M
    case ISD::OR:
193
721k
      // Only consider ORs which act as adds.
194
721k
      if (auto *C = dyn_cast<ConstantSDNode>(Base->getOperand(1)))
195
685k
        if (DAG.MaskedValueIsZero(Base->getOperand(0), C->getAPIntValue())) {
196
685k
          Offset += C->getSExtValue();
197
685k
          Base = DAG.getTargetLoweringInfo().unwrapAddress(Base->getOperand(0));
198
685k
          continue;
199
685k
        }
200
35.9k
      break;
201
41.6M
    case ISD::ADD:
202
41.6M
      if (auto *C = dyn_cast<ConstantSDNode>(Base->getOperand(1))) {
203
40.0M
        Offset += C->getSExtValue();
204
40.0M
        Base = DAG.getTargetLoweringInfo().unwrapAddress(Base->getOperand(0));
205
40.0M
        continue;
206
40.0M
      }
207
1.56M
      break;
208
1.56M
    case ISD::LOAD:
209
1.37M
    case ISD::STORE: {
210
1.37M
      auto *LSBase = cast<LSBaseSDNode>(Base.getNode());
211
1.37M
      unsigned int IndexResNo = (Base->getOpcode() == ISD::LOAD) ? 
11.34M
:
022.7k
;
212
1.37M
      if (LSBase->isIndexed() && 
Base.getResNo() == IndexResNo30.2k
)
213
30.2k
        if (auto *C = dyn_cast<ConstantSDNode>(LSBase->getOffset())) {
214
30.2k
          auto Off = C->getSExtValue();
215
30.2k
          if (LSBase->getAddressingMode() == ISD::PRE_DEC ||
216
30.2k
              LSBase->getAddressingMode() == ISD::POST_DEC)
217
0
            Offset -= Off;
218
30.2k
          else
219
30.2k
            Offset += Off;
220
30.2k
          Base = DAG.getTargetLoweringInfo().unwrapAddress(LSBase->getBasePtr());
221
30.2k
          continue;
222
30.2k
        }
223
1.34M
      break;
224
1.34M
    }
225
16.9M
    }
226
16.9M
    // If we get here break out of the loop.
227
16.9M
    break;
228
16.9M
  }
229
16.9M
230
16.9M
  if (Base->getOpcode() == ISD::ADD) {
231
1.56M
    // TODO: The following code appears to be needless as it just
232
1.56M
    //       bails on some Ptrs early, reducing the cases where we
233
1.56M
    //       find equivalence. We should be able to remove this.
234
1.56M
    // Inside a loop the current BASE pointer is calculated using an ADD and a
235
1.56M
    // MUL instruction. In this case Base is the actual BASE pointer.
236
1.56M
    // (i64 add (i64 %array_ptr)
237
1.56M
    //          (i64 mul (i64 %induction_var)
238
1.56M
    //                   (i64 %element_size)))
239
1.56M
    if (Base->getOperand(1)->getOpcode() == ISD::MUL)
240
255k
      return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt);
241
1.30M
242
1.30M
    // Look at Base + Index + Offset cases.
243
1.30M
    Index = Base->getOperand(1);
244
1.30M
    SDValue PotentialBase = Base->getOperand(0);
245
1.30M
246
1.30M
    // Skip signextends.
247
1.30M
    if (Index->getOpcode() == ISD::SIGN_EXTEND) {
248
10.1k
      Index = Index->getOperand(0);
249
10.1k
      IsIndexSignExt = true;
250
10.1k
    }
251
1.30M
252
1.30M
    // Check if Index Offset pattern
253
1.30M
    if (Index->getOpcode() != ISD::ADD ||
254
1.30M
        
!isa<ConstantSDNode>(Index->getOperand(1))12.8k
)
255
1.29M
      return BaseIndexOffset(PotentialBase, Index, Offset, IsIndexSignExt);
256
9.73k
257
9.73k
    Offset += cast<ConstantSDNode>(Index->getOperand(1))->getSExtValue();
258
9.73k
    Index = Index->getOperand(0);
259
9.73k
    if (Index->getOpcode() == ISD::SIGN_EXTEND) {
260
880
      Index = Index->getOperand(0);
261
880
      IsIndexSignExt = true;
262
880
    } else
263
8.85k
      IsIndexSignExt = false;
264
9.73k
    Base = PotentialBase;
265
9.73k
  }
266
16.9M
  
return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt)15.4M
;
267
16.9M
}
268
269
BaseIndexOffset BaseIndexOffset::match(const SDNode *N,
270
17.3M
                                       const SelectionDAG &DAG) {
271
17.3M
  if (const auto *LS0 = dyn_cast<LSBaseSDNode>(N))
272
16.9M
    return matchLSNode(LS0, DAG);
273
338k
  if (const auto *LN = dyn_cast<LifetimeSDNode>(N)) {
274
338k
    if (LN->hasOffset())
275
337k
      return BaseIndexOffset(LN->getOperand(1), SDValue(), LN->getOffset(),
276
337k
                             false);
277
457
    return BaseIndexOffset(LN->getOperand(1), SDValue(), false);
278
457
  }
279
0
  return BaseIndexOffset();
280
0
}
281
282
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
283
284
LLVM_DUMP_METHOD void BaseIndexOffset::dump() const {
285
  print(dbgs());
286
}
287
288
void BaseIndexOffset::print(raw_ostream& OS) const {
289
  OS << "BaseIndexOffset base=[";
290
  Base->print(OS);
291
  OS << "] index=[";
292
  if (Index)
293
    Index->print(OS);
294
  OS << "] offset=" << Offset;
295
}
296
297
#endif