Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
Line
Count
Source
1
//===- GetElementPtrTypeIterator.h ------------------------------*- C++ -*-===//
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 an iterator for walking through the types indexed by
10
// getelementptr instructions.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
15
#define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
16
17
#include "llvm/ADT/ArrayRef.h"
18
#include "llvm/ADT/PointerUnion.h"
19
#include "llvm/IR/DerivedTypes.h"
20
#include "llvm/IR/Operator.h"
21
#include "llvm/IR/User.h"
22
#include "llvm/Support/Casting.h"
23
#include <cassert>
24
#include <cstddef>
25
#include <cstdint>
26
#include <iterator>
27
28
namespace llvm {
29
30
  template<typename ItTy = User::const_op_iterator>
31
  class generic_gep_type_iterator
32
    : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
33
    using super = std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t>;
34
35
    ItTy OpIt;
36
    PointerUnion<StructType *, Type *> CurTy;
37
    enum : uint64_t { Unbounded = -1ull };
38
    uint64_t NumElements = Unbounded;
39
40
224M
    generic_gep_type_iterator() = default;
llvm::generic_gep_type_iterator<llvm::Use const*>::generic_gep_type_iterator()
Line
Count
Source
40
192M
    generic_gep_type_iterator() = default;
llvm::generic_gep_type_iterator<llvm::Value const* const*>::generic_gep_type_iterator()
Line
Count
Source
40
6.07M
    generic_gep_type_iterator() = default;
llvm::generic_gep_type_iterator<llvm::Value* const*>::generic_gep_type_iterator()
Line
Count
Source
40
26.0M
    generic_gep_type_iterator() = default;
41
42
  public:
43
188M
    static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
44
188M
      generic_gep_type_iterator I;
45
188M
      I.CurTy = Ty;
46
188M
      I.OpIt = It;
47
188M
      return I;
48
188M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::begin(llvm::Type*, llvm::Use const*)
Line
Count
Source
43
169M
    static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
44
169M
      generic_gep_type_iterator I;
45
169M
      I.CurTy = Ty;
46
169M
      I.OpIt = It;
47
169M
      return I;
48
169M
    }
llvm::generic_gep_type_iterator<llvm::Value const* const*>::begin(llvm::Type*, llvm::Value const* const*)
Line
Count
Source
43
6.07M
    static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
44
6.07M
      generic_gep_type_iterator I;
45
6.07M
      I.CurTy = Ty;
46
6.07M
      I.OpIt = It;
47
6.07M
      return I;
48
6.07M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::begin(llvm::Type*, llvm::Value* const*)
Line
Count
Source
43
13.0M
    static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
44
13.0M
      generic_gep_type_iterator I;
45
13.0M
      I.CurTy = Ty;
46
13.0M
      I.OpIt = It;
47
13.0M
      return I;
48
13.0M
    }
49
50
36.0M
    static generic_gep_type_iterator end(ItTy It) {
51
36.0M
      generic_gep_type_iterator I;
52
36.0M
      I.OpIt = It;
53
36.0M
      return I;
54
36.0M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::end(llvm::Use const*)
Line
Count
Source
50
22.9M
    static generic_gep_type_iterator end(ItTy It) {
51
22.9M
      generic_gep_type_iterator I;
52
22.9M
      I.OpIt = It;
53
22.9M
      return I;
54
22.9M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::end(llvm::Value* const*)
Line
Count
Source
50
13.0M
    static generic_gep_type_iterator end(ItTy It) {
51
13.0M
      generic_gep_type_iterator I;
52
13.0M
      I.OpIt = It;
53
13.0M
      return I;
54
13.0M
    }
55
56
117M
    bool operator==(const generic_gep_type_iterator& x) const {
57
117M
      return OpIt == x.OpIt;
58
117M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::operator==(llvm::generic_gep_type_iterator<llvm::Use const*> const&) const
Line
Count
Source
56
76.9M
    bool operator==(const generic_gep_type_iterator& x) const {
57
76.9M
      return OpIt == x.OpIt;
58
76.9M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::operator==(llvm::generic_gep_type_iterator<llvm::Value* const*> const&) const
Line
Count
Source
56
40.1M
    bool operator==(const generic_gep_type_iterator& x) const {
57
40.1M
      return OpIt == x.OpIt;
58
40.1M
    }
59
60
117M
    bool operator!=(const generic_gep_type_iterator& x) const {
61
117M
      return !operator==(x);
62
117M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::operator!=(llvm::generic_gep_type_iterator<llvm::Use const*> const&) const
Line
Count
Source
60
76.9M
    bool operator!=(const generic_gep_type_iterator& x) const {
61
76.9M
      return !operator==(x);
62
76.9M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::operator!=(llvm::generic_gep_type_iterator<llvm::Value* const*> const&) const
Line
Count
Source
60
40.1M
    bool operator!=(const generic_gep_type_iterator& x) const {
61
40.1M
      return !operator==(x);
62
40.1M
    }
63
64
    // FIXME: Make this the iterator's operator*() after the 4.0 release.
65
    // operator*() had a different meaning in earlier releases, so we're
66
    // temporarily not giving this iterator an operator*() to avoid a subtle
67
    // semantics break.
68
612M
    Type *getIndexedType() const {
69
612M
      if (auto *T = CurTy.dyn_cast<Type *>())
70
445M
        return T;
71
167M
      return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
72
167M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::getIndexedType() const
Line
Count
Source
68
553M
    Type *getIndexedType() const {
69
553M
      if (auto *T = CurTy.dyn_cast<Type *>())
70
401M
        return T;
71
152M
      return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
72
152M
    }
llvm::generic_gep_type_iterator<llvm::Value const* const*>::getIndexedType() const
Line
Count
Source
68
31.1M
    Type *getIndexedType() const {
69
31.1M
      if (auto *T = CurTy.dyn_cast<Type *>())
70
22.3M
        return T;
71
8.78M
      return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
72
8.78M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::getIndexedType() const
Line
Count
Source
68
28.2M
    Type *getIndexedType() const {
69
28.2M
      if (auto *T = CurTy.dyn_cast<Type *>())
70
21.6M
        return T;
71
6.61M
      return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
72
6.61M
    }
73
74
245M
    Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
llvm::generic_gep_type_iterator<llvm::Use const*>::getOperand() const
Line
Count
Source
74
203M
    Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
llvm::generic_gep_type_iterator<llvm::Value const* const*>::getOperand() const
Line
Count
Source
74
8.78M
    Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
llvm::generic_gep_type_iterator<llvm::Value* const*>::getOperand() const
Line
Count
Source
74
33.7M
    Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
75
76
433M
    generic_gep_type_iterator& operator++() {   // Preincrement
77
433M
      Type *Ty = getIndexedType();
78
433M
      if (auto *STy = dyn_cast<SequentialType>(Ty)) {
79
85.0M
        CurTy = STy->getElementType();
80
85.0M
        NumElements = STy->getNumElements();
81
85.0M
      } else
82
348M
        CurTy = dyn_cast<StructType>(Ty);
83
433M
      ++OpIt;
84
433M
      return *this;
85
433M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::operator++()
Line
Count
Source
76
394M
    generic_gep_type_iterator& operator++() {   // Preincrement
77
394M
      Type *Ty = getIndexedType();
78
394M
      if (auto *STy = dyn_cast<SequentialType>(Ty)) {
79
76.0M
        CurTy = STy->getElementType();
80
76.0M
        NumElements = STy->getNumElements();
81
76.0M
      } else
82
318M
        CurTy = dyn_cast<StructType>(Ty);
83
394M
      ++OpIt;
84
394M
      return *this;
85
394M
    }
llvm::generic_gep_type_iterator<llvm::Value const* const*>::operator++()
Line
Count
Source
76
11.7M
    generic_gep_type_iterator& operator++() {   // Preincrement
77
11.7M
      Type *Ty = getIndexedType();
78
11.7M
      if (auto *STy = dyn_cast<SequentialType>(Ty)) {
79
1.43M
        CurTy = STy->getElementType();
80
1.43M
        NumElements = STy->getNumElements();
81
1.43M
      } else
82
10.3M
        CurTy = dyn_cast<StructType>(Ty);
83
11.7M
      ++OpIt;
84
11.7M
      return *this;
85
11.7M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::operator++()
Line
Count
Source
76
27.1M
    generic_gep_type_iterator& operator++() {   // Preincrement
77
27.1M
      Type *Ty = getIndexedType();
78
27.1M
      if (auto *STy = dyn_cast<SequentialType>(Ty)) {
79
7.47M
        CurTy = STy->getElementType();
80
7.47M
        NumElements = STy->getNumElements();
81
7.47M
      } else
82
19.6M
        CurTy = dyn_cast<StructType>(Ty);
83
27.1M
      ++OpIt;
84
27.1M
      return *this;
85
27.1M
    }
86
87
1.48k
    generic_gep_type_iterator operator++(int) { // Postincrement
88
1.48k
      generic_gep_type_iterator tmp = *this; ++*this; return tmp;
89
1.48k
    }
90
91
    // All of the below API is for querying properties of the "outer type", i.e.
92
    // the type that contains the indexed type. Most of the time this is just
93
    // the type that was visited immediately prior to the indexed type, but for
94
    // the first element this is an unbounded array of the GEP's source element
95
    // type, for which there is no clearly corresponding IR type (we've
96
    // historically used a pointer type as the outer type in this case, but
97
    // pointers will soon lose their element type).
98
    //
99
    // FIXME: Most current users of this class are just interested in byte
100
    // offsets (a few need to know whether the outer type is a struct because
101
    // they are trying to replace a constant with a variable, which is only
102
    // legal for arrays, e.g. canReplaceOperandWithVariable in SimplifyCFG.cpp);
103
    // we should provide a more minimal API here that exposes not much more than
104
    // that.
105
106
64.7M
    bool isStruct() const { return CurTy.is<StructType *>(); }
107
1.37M
    bool isSequential() const { return CurTy.is<Type *>(); }
108
109
103
    StructType *getStructType() const { return CurTy.get<StructType *>(); }
110
111
343M
    StructType *getStructTypeOrNull() const {
112
343M
      return CurTy.dyn_cast<StructType *>();
113
343M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::getStructTypeOrNull() const
Line
Count
Source
111
304M
    StructType *getStructTypeOrNull() const {
112
304M
      return CurTy.dyn_cast<StructType *>();
113
304M
    }
llvm::generic_gep_type_iterator<llvm::Value const* const*>::getStructTypeOrNull() const
Line
Count
Source
111
11.8M
    StructType *getStructTypeOrNull() const {
112
11.8M
      return CurTy.dyn_cast<StructType *>();
113
11.8M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::getStructTypeOrNull() const
Line
Count
Source
111
27.1M
    StructType *getStructTypeOrNull() const {
112
27.1M
      return CurTy.dyn_cast<StructType *>();
113
27.1M
    }
114
115
54.6k
    bool isBoundedSequential() const {
116
54.6k
      return isSequential() && 
NumElements != Unbounded46.0k
;
117
54.6k
    }
118
119
26.4k
    uint64_t getSequentialNumElements() const {
120
26.4k
      assert(isBoundedSequential());
121
26.4k
      return NumElements;
122
26.4k
    }
123
  };
124
125
  using gep_type_iterator = generic_gep_type_iterator<>;
126
127
141M
  inline gep_type_iterator gep_type_begin(const User *GEP) {
128
141M
    auto *GEPOp = cast<GEPOperator>(GEP);
129
141M
    return gep_type_iterator::begin(
130
141M
        GEPOp->getSourceElementType(),
131
141M
        GEP->op_begin() + 1);
132
141M
  }
133
134
19.6M
  inline gep_type_iterator gep_type_end(const User *GEP) {
135
19.6M
    return gep_type_iterator::end(GEP->op_end());
136
19.6M
  }
137
138
28.1M
  inline gep_type_iterator gep_type_begin(const User &GEP) {
139
28.1M
    auto &GEPOp = cast<GEPOperator>(GEP);
140
28.1M
    return gep_type_iterator::begin(
141
28.1M
        GEPOp.getSourceElementType(),
142
28.1M
        GEP.op_begin() + 1);
143
28.1M
  }
144
145
3.35M
  inline gep_type_iterator gep_type_end(const User &GEP) {
146
3.35M
    return gep_type_iterator::end(GEP.op_end());
147
3.35M
  }
148
149
  template<typename T>
150
  inline generic_gep_type_iterator<const T *>
151
19.1M
  gep_type_begin(Type *Op0, ArrayRef<T> A) {
152
19.1M
    return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
153
19.1M
  }
llvm::generic_gep_type_iterator<llvm::Value const* const*> llvm::gep_type_begin<llvm::Value const*>(llvm::Type*, llvm::ArrayRef<llvm::Value const*>)
Line
Count
Source
151
6.07M
  gep_type_begin(Type *Op0, ArrayRef<T> A) {
152
6.07M
    return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
153
6.07M
  }
llvm::generic_gep_type_iterator<llvm::Value* const*> llvm::gep_type_begin<llvm::Value*>(llvm::Type*, llvm::ArrayRef<llvm::Value*>)
Line
Count
Source
151
13.0M
  gep_type_begin(Type *Op0, ArrayRef<T> A) {
152
13.0M
    return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
153
13.0M
  }
154
155
  template<typename T>
156
  inline generic_gep_type_iterator<const T *>
157
13.0M
  gep_type_end(Type * /*Op0*/, ArrayRef<T> A) {
158
13.0M
    return generic_gep_type_iterator<const T *>::end(A.end());
159
13.0M
  }
160
161
} // end namespace llvm
162
163
#endif // LLVM_IR_GETELEMENTPTRTYPEITERATOR_H