Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
Line
Count
Source (jump to first uncovered line)
1
//==- llvm/CodeGen/SelectionDAGAddressAnalysis.cpp - DAG Address Analysis --==//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#include "llvm/CodeGen/SelectionDAGAddressAnalysis.h"
11
#include "llvm/CodeGen/ISDOpcodes.h"
12
#include "llvm/CodeGen/MachineFrameInfo.h"
13
#include "llvm/CodeGen/MachineFunction.h"
14
#include "llvm/CodeGen/SelectionDAG.h"
15
#include "llvm/CodeGen/SelectionDAGNodes.h"
16
#include "llvm/Support/Casting.h"
17
#include "llvm/Target/TargetLowering.h"
18
#include <cstdint>
19
20
using namespace llvm;
21
22
bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other,
23
69.4M
                                     const SelectionDAG &DAG, int64_t &Off) {
24
69.4M
  // Initial Offset difference.
25
69.4M
  Off = Other.Offset - Offset;
26
69.4M
27
69.4M
  if (
(Other.Index == Index) && 69.4M
(Other.IsIndexSignExt == IsIndexSignExt)67.3M
) {
28
67.3M
    // Trivial match.
29
67.3M
    if (Other.Base == Base)
30
62.9M
      return true;
31
4.48M
32
4.48M
    // Match GlobalAddresses
33
4.48M
    
if (auto *4.48M
A4.48M
= dyn_cast<GlobalAddressSDNode>(Base))
34
679k
      
if (auto *679k
B679k
= dyn_cast<GlobalAddressSDNode>(Other.Base))
35
404k
        
if (404k
A->getGlobal() == B->getGlobal()404k
) {
36
5.65k
          Off += B->getOffset() - A->getOffset();
37
5.65k
          return true;
38
5.65k
        }
39
4.47M
40
4.47M
    const MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
41
4.47M
42
4.47M
    // Match non-equal FrameIndexes - If both frame indices are fixed
43
4.47M
    // we know their relative offsets and can compare them. Otherwise
44
4.47M
    // we must be conservative.
45
4.47M
    if (auto *A = dyn_cast<FrameIndexSDNode>(Base))
46
867k
      
if (auto *867k
B867k
= dyn_cast<FrameIndexSDNode>(Other.Base))
47
108k
        
if (108k
MFI.isFixedObjectIndex(A->getIndex()) &&
48
108k
            
MFI.isFixedObjectIndex(B->getIndex())19.7k
) {
49
19.4k
          Off += MFI.getObjectOffset(B->getIndex()) -
50
19.4k
                 MFI.getObjectOffset(A->getIndex());
51
19.4k
          return true;
52
19.4k
        }
53
6.49M
  }
54
6.49M
  return false;
55
6.49M
}
56
57
/// Parses tree in Ptr for base, index, offset addresses.
58
116M
BaseIndexOffset BaseIndexOffset::match(SDValue Ptr, const SelectionDAG &DAG) {
59
116M
  // (((B + I*M) + c)) + c ...
60
116M
  SDValue Base = DAG.getTargetLoweringInfo().unwrapAddress(Ptr);
61
116M
  SDValue Index = SDValue();
62
116M
  int64_t Offset = 0;
63
116M
  bool IsIndexSignExt = false;
64
116M
65
116M
  // Consume constant adds & ors with appropriate masking.
66
279M
  while (
Base->getOpcode() == ISD::ADD || 279M
Base->getOpcode() == ISD::OR111M
) {
67
168M
    if (auto *
C168M
= dyn_cast<ConstantSDNode>(Base->getOperand(1))) {
68
163M
      // Only consider ORs which act as adds.
69
163M
      if (Base->getOpcode() == ISD::OR &&
70
370k
          !DAG.MaskedValueIsZero(Base->getOperand(0), C->getAPIntValue()))
71
0
        break;
72
163M
      Offset += C->getSExtValue();
73
163M
      Base = Base->getOperand(0);
74
163M
      continue;
75
163M
    }
76
5.08M
    break;
77
5.08M
  }
78
116M
79
116M
  if (
Base->getOpcode() == ISD::ADD116M
) {
80
5.05M
    // TODO: The following code appears to be needless as it just
81
5.05M
    //       bails on some Ptrs early, reducing the cases where we
82
5.05M
    //       find equivalence. We should be able to remove this.
83
5.05M
    // Inside a loop the current BASE pointer is calculated using an ADD and a
84
5.05M
    // MUL instruction. In this case Base is the actual BASE pointer.
85
5.05M
    // (i64 add (i64 %array_ptr)
86
5.05M
    //          (i64 mul (i64 %induction_var)
87
5.05M
    //                   (i64 %element_size)))
88
5.05M
    if (Base->getOperand(1)->getOpcode() == ISD::MUL)
89
699k
      return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt);
90
4.35M
91
4.35M
    // Look at Base + Index + Offset cases.
92
4.35M
    Index = Base->getOperand(1);
93
4.35M
    SDValue PotentialBase = Base->getOperand(0);
94
4.35M
95
4.35M
    // Skip signextends.
96
4.35M
    if (
Index->getOpcode() == ISD::SIGN_EXTEND4.35M
) {
97
107k
      Index = Index->getOperand(0);
98
107k
      IsIndexSignExt = true;
99
107k
    }
100
4.35M
101
4.35M
    // Check if Index Offset pattern
102
4.35M
    if (Index->getOpcode() != ISD::ADD ||
103
46.2k
        !isa<ConstantSDNode>(Index->getOperand(1)))
104
4.32M
      return BaseIndexOffset(PotentialBase, Index, Offset, IsIndexSignExt);
105
37.5k
106
37.5k
    Offset += cast<ConstantSDNode>(Index->getOperand(1))->getSExtValue();
107
37.5k
    Index = Index->getOperand(0);
108
37.5k
    if (
Index->getOpcode() == ISD::SIGN_EXTEND37.5k
) {
109
6.34k
      Index = Index->getOperand(0);
110
6.34k
      IsIndexSignExt = true;
111
6.34k
    } else
112
31.1k
      IsIndexSignExt = false;
113
5.05M
    Base = PotentialBase;
114
5.05M
  }
115
110M
  return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt);
116
116M
}