Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
Line
Count
Source
1
//===- GetElementPtrTypeIterator.h ------------------------------*- C++ -*-===//
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
// This file implements an iterator for walking through the types indexed by
11
// getelementptr instructions.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
16
#define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
17
18
#include "llvm/ADT/ArrayRef.h"
19
#include "llvm/ADT/PointerUnion.h"
20
#include "llvm/IR/DerivedTypes.h"
21
#include "llvm/IR/Operator.h"
22
#include "llvm/IR/User.h"
23
#include "llvm/Support/Casting.h"
24
#include <cassert>
25
#include <cstddef>
26
#include <cstdint>
27
#include <iterator>
28
29
namespace llvm {
30
31
  template<typename ItTy = User::const_op_iterator>
32
  class generic_gep_type_iterator
33
    : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
34
    using super = std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t>;
35
36
    ItTy OpIt;
37
    PointerUnion<StructType *, Type *> CurTy;
38
    enum : uint64_t { Unbounded = -1ull };
39
    uint64_t NumElements = Unbounded;
40
41
317M
    generic_gep_type_iterator() = default;
llvm::generic_gep_type_iterator<llvm::Use const*>::generic_gep_type_iterator()
Line
Count
Source
41
268M
    generic_gep_type_iterator() = default;
llvm::generic_gep_type_iterator<llvm::Value const* const*>::generic_gep_type_iterator()
Line
Count
Source
41
6.17M
    generic_gep_type_iterator() = default;
llvm::generic_gep_type_iterator<llvm::Value* const*>::generic_gep_type_iterator()
Line
Count
Source
41
42.5M
    generic_gep_type_iterator() = default;
42
43
  public:
44
264M
    static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
45
264M
      generic_gep_type_iterator I;
46
264M
      I.CurTy = Ty;
47
264M
      I.OpIt = It;
48
264M
      return I;
49
264M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::begin(llvm::Type*, llvm::Value* const*)
Line
Count
Source
44
21.2M
    static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
45
21.2M
      generic_gep_type_iterator I;
46
21.2M
      I.CurTy = Ty;
47
21.2M
      I.OpIt = It;
48
21.2M
      return I;
49
21.2M
    }
llvm::generic_gep_type_iterator<llvm::Value const* const*>::begin(llvm::Type*, llvm::Value const* const*)
Line
Count
Source
44
6.17M
    static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
45
6.17M
      generic_gep_type_iterator I;
46
6.17M
      I.CurTy = Ty;
47
6.17M
      I.OpIt = It;
48
6.17M
      return I;
49
6.17M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::begin(llvm::Type*, llvm::Use const*)
Line
Count
Source
44
236M
    static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
45
236M
      generic_gep_type_iterator I;
46
236M
      I.CurTy = Ty;
47
236M
      I.OpIt = It;
48
236M
      return I;
49
236M
    }
50
51
52.8M
    static generic_gep_type_iterator end(ItTy It) {
52
52.8M
      generic_gep_type_iterator I;
53
52.8M
      I.OpIt = It;
54
52.8M
      return I;
55
52.8M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::end(llvm::Value* const*)
Line
Count
Source
51
21.2M
    static generic_gep_type_iterator end(ItTy It) {
52
21.2M
      generic_gep_type_iterator I;
53
21.2M
      I.OpIt = It;
54
21.2M
      return I;
55
21.2M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::end(llvm::Use const*)
Line
Count
Source
51
31.6M
    static generic_gep_type_iterator end(ItTy It) {
52
31.6M
      generic_gep_type_iterator I;
53
31.6M
      I.OpIt = It;
54
31.6M
      return I;
55
31.6M
    }
56
57
164M
    bool operator==(const generic_gep_type_iterator& x) const {
58
164M
      return OpIt == x.OpIt;
59
164M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::operator==(llvm::generic_gep_type_iterator<llvm::Value* const*> const&) const
Line
Count
Source
57
64.7M
    bool operator==(const generic_gep_type_iterator& x) const {
58
64.7M
      return OpIt == x.OpIt;
59
64.7M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::operator==(llvm::generic_gep_type_iterator<llvm::Use const*> const&) const
Line
Count
Source
57
99.3M
    bool operator==(const generic_gep_type_iterator& x) const {
58
99.3M
      return OpIt == x.OpIt;
59
99.3M
    }
60
61
164M
    bool operator!=(const generic_gep_type_iterator& x) const {
62
164M
      return !operator==(x);
63
164M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::operator!=(llvm::generic_gep_type_iterator<llvm::Value* const*> const&) const
Line
Count
Source
61
64.7M
    bool operator!=(const generic_gep_type_iterator& x) const {
62
64.7M
      return !operator==(x);
63
64.7M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::operator!=(llvm::generic_gep_type_iterator<llvm::Use const*> const&) const
Line
Count
Source
61
99.3M
    bool operator!=(const generic_gep_type_iterator& x) const {
62
99.3M
      return !operator==(x);
63
99.3M
    }
64
65
    // FIXME: Make this the iterator's operator*() after the 4.0 release.
66
    // operator*() had a different meaning in earlier releases, so we're
67
    // temporarily not giving this iterator an operator*() to avoid a subtle
68
    // semantics break.
69
813M
    Type *getIndexedType() const {
70
813M
      if (auto *T = CurTy.dyn_cast<Type *>())
71
633M
        return T;
72
180M
      return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
73
813M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::getIndexedType() const
Line
Count
Source
69
738M
    Type *getIndexedType() const {
70
738M
      if (auto *T = CurTy.dyn_cast<Type *>())
71
574M
        return T;
72
163M
      return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
73
738M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::getIndexedType() const
Line
Count
Source
69
45.1M
    Type *getIndexedType() const {
70
45.1M
      if (auto *T = CurTy.dyn_cast<Type *>())
71
35.1M
        return T;
72
9.95M
      return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
73
45.1M
    }
llvm::generic_gep_type_iterator<llvm::Value const* const*>::getIndexedType() const
Line
Count
Source
69
30.0M
    Type *getIndexedType() const {
70
30.0M
      if (auto *T = CurTy.dyn_cast<Type *>())
71
23.2M
        return T;
72
6.79M
      return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
73
30.0M
    }
74
75
288M
    Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
llvm::generic_gep_type_iterator<llvm::Use const*>::getOperand() const
Line
Count
Source
75
228M
    Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
llvm::generic_gep_type_iterator<llvm::Value const* const*>::getOperand() const
Line
Count
Source
75
6.79M
    Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
llvm::generic_gep_type_iterator<llvm::Value* const*>::getOperand() const
Line
Count
Source
75
53.4M
    Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
76
77
566M
    generic_gep_type_iterator& operator++() {   // Preincrement
78
566M
      Type *Ty = getIndexedType();
79
566M
      if (auto *
STy566M
= dyn_cast<SequentialType>(Ty)) {
80
129M
        CurTy = STy->getElementType();
81
129M
        NumElements = STy->getNumElements();
82
129M
      } else
83
437M
        CurTy = dyn_cast<StructType>(Ty);
84
566M
      ++OpIt;
85
566M
      return *this;
86
566M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::operator++()
Line
Count
Source
77
43.5M
    generic_gep_type_iterator& operator++() {   // Preincrement
78
43.5M
      Type *Ty = getIndexedType();
79
43.5M
      if (auto *
STy43.5M
= dyn_cast<SequentialType>(Ty)) {
80
12.3M
        CurTy = STy->getElementType();
81
12.3M
        NumElements = STy->getNumElements();
82
12.3M
      } else
83
31.2M
        CurTy = dyn_cast<StructType>(Ty);
84
43.5M
      ++OpIt;
85
43.5M
      return *this;
86
43.5M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::operator++()
Line
Count
Source
77
512M
    generic_gep_type_iterator& operator++() {   // Preincrement
78
512M
      Type *Ty = getIndexedType();
79
512M
      if (auto *
STy512M
= dyn_cast<SequentialType>(Ty)) {
80
115M
        CurTy = STy->getElementType();
81
115M
        NumElements = STy->getNumElements();
82
115M
      } else
83
396M
        CurTy = dyn_cast<StructType>(Ty);
84
512M
      ++OpIt;
85
512M
      return *this;
86
512M
    }
llvm::generic_gep_type_iterator<llvm::Value const* const*>::operator++()
Line
Count
Source
77
11.0M
    generic_gep_type_iterator& operator++() {   // Preincrement
78
11.0M
      Type *Ty = getIndexedType();
79
11.0M
      if (auto *
STy11.0M
= dyn_cast<SequentialType>(Ty)) {
80
1.65M
        CurTy = STy->getElementType();
81
1.65M
        NumElements = STy->getNumElements();
82
1.65M
      } else
83
9.38M
        CurTy = dyn_cast<StructType>(Ty);
84
11.0M
      ++OpIt;
85
11.0M
      return *this;
86
11.0M
    }
87
88
    generic_gep_type_iterator operator++(int) { // Postincrement
89
      generic_gep_type_iterator tmp = *this; ++*this; return tmp;
90
    }
91
92
    // All of the below API is for querying properties of the "outer type", i.e.
93
    // the type that contains the indexed type. Most of the time this is just
94
    // the type that was visited immediately prior to the indexed type, but for
95
    // the first element this is an unbounded array of the GEP's source element
96
    // type, for which there is no clearly corresponding IR type (we've
97
    // historically used a pointer type as the outer type in this case, but
98
    // pointers will soon lose their element type).
99
    //
100
    // FIXME: Most current users of this class are just interested in byte
101
    // offsets (a few need to know whether the outer type is a struct because
102
    // they are trying to replace a constant with a variable, which is only
103
    // legal for arrays, e.g. canReplaceOperandWithVariable in SimplifyCFG.cpp);
104
    // we should provide a more minimal API here that exposes not much more than
105
    // that.
106
107
74.5M
    bool isStruct() const { return CurTy.is<StructType *>(); }
108
1.30M
    bool isSequential() const { return CurTy.is<Type *>(); }
109
110
86
    StructType *getStructType() const { return CurTy.get<StructType *>(); }
111
112
466M
    StructType *getStructTypeOrNull() const {
113
466M
      return CurTy.dyn_cast<StructType *>();
114
466M
    }
llvm::generic_gep_type_iterator<llvm::Value const* const*>::getStructTypeOrNull() const
Line
Count
Source
112
11.2M
    StructType *getStructTypeOrNull() const {
113
11.2M
      return CurTy.dyn_cast<StructType *>();
114
11.2M
    }
llvm::generic_gep_type_iterator<llvm::Value* const*>::getStructTypeOrNull() const
Line
Count
Source
112
43.5M
    StructType *getStructTypeOrNull() const {
113
43.5M
      return CurTy.dyn_cast<StructType *>();
114
43.5M
    }
llvm::generic_gep_type_iterator<llvm::Use const*>::getStructTypeOrNull() const
Line
Count
Source
112
412M
    StructType *getStructTypeOrNull() const {
113
412M
      return CurTy.dyn_cast<StructType *>();
114
412M
    }
115
116
47.7k
    bool isBoundedSequential() const {
117
45.4k
      return isSequential() && NumElements != Unbounded;
118
47.7k
    }
119
120
28.2k
    uint64_t getSequentialNumElements() const {
121
28.2k
      assert(isBoundedSequential());
122
28.2k
      return NumElements;
123
28.2k
    }
124
  };
125
126
  using gep_type_iterator = generic_gep_type_iterator<>;
127
128
201M
  inline gep_type_iterator gep_type_begin(const User *GEP) {
129
201M
    auto *GEPOp = cast<GEPOperator>(GEP);
130
201M
    return gep_type_iterator::begin(
131
201M
        GEPOp->getSourceElementType(),
132
201M
        GEP->op_begin() + 1);
133
201M
  }
134
135
28.8M
  inline gep_type_iterator gep_type_end(const User *GEP) {
136
28.8M
    return gep_type_iterator::end(GEP->op_end());
137
28.8M
  }
138
139
35.1M
  inline gep_type_iterator gep_type_begin(const User &GEP) {
140
35.1M
    auto &GEPOp = cast<GEPOperator>(GEP);
141
35.1M
    return gep_type_iterator::begin(
142
35.1M
        GEPOp.getSourceElementType(),
143
35.1M
        GEP.op_begin() + 1);
144
35.1M
  }
145
146
2.74M
  inline gep_type_iterator gep_type_end(const User &GEP) {
147
2.74M
    return gep_type_iterator::end(GEP.op_end());
148
2.74M
  }
149
150
  template<typename T>
151
  inline generic_gep_type_iterator<const T *>
152
27.4M
  gep_type_begin(Type *Op0, ArrayRef<T> A) {
153
27.4M
    return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
154
27.4M
  }
llvm::generic_gep_type_iterator<llvm::Value* const*> llvm::gep_type_begin<llvm::Value*>(llvm::Type*, llvm::ArrayRef<llvm::Value*>)
Line
Count
Source
152
21.2M
  gep_type_begin(Type *Op0, ArrayRef<T> A) {
153
21.2M
    return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
154
21.2M
  }
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
152
6.17M
  gep_type_begin(Type *Op0, ArrayRef<T> A) {
153
6.17M
    return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
154
6.17M
  }
155
156
  template<typename T>
157
  inline generic_gep_type_iterator<const T *>
158
21.2M
  gep_type_end(Type * /*Op0*/, ArrayRef<T> A) {
159
21.2M
    return generic_gep_type_iterator<const T *>::end(A.end());
160
21.2M
  }
161
162
} // end namespace llvm
163
164
#endif // LLVM_IR_GETELEMENTPTRTYPEITERATOR_H