Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/IR/IntrinsicInst.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- InstrinsicInst.cpp - Intrinsic Instruction Wrappers ---------------===//
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 methods that make it really easy to deal with intrinsic
11
// functions.
12
//
13
// All intrinsic function calls are instances of the call instruction, so these
14
// are all subclasses of the CallInst class.  Note that none of these classes
15
// has state or virtual methods, which is an important part of this gross/neat
16
// hack working.
17
//
18
// In some cases, arguments to intrinsics need to be generic and are defined as
19
// type pointer to empty struct { }*.  To access the real item of interest the
20
// cast instruction needs to be stripped away.
21
//
22
//===----------------------------------------------------------------------===//
23
24
#include "llvm/IR/IntrinsicInst.h"
25
#include "llvm/ADT/StringSwitch.h"
26
#include "llvm/IR/Constants.h"
27
#include "llvm/IR/GlobalVariable.h"
28
#include "llvm/IR/Metadata.h"
29
#include "llvm/IR/Module.h"
30
#include "llvm/Support/raw_ostream.h"
31
using namespace llvm;
32
33
//===----------------------------------------------------------------------===//
34
/// DbgInfoIntrinsic - This is the common base class for debug info intrinsics
35
///
36
37
4.79k
Value *DbgInfoIntrinsic::getVariableLocation(bool AllowNullOp) const {
38
4.79k
  Value *Op = getArgOperand(0);
39
4.79k
  if (
AllowNullOp && 4.79k
!Op1.61k
)
40
0
    return nullptr;
41
4.79k
42
4.79k
  auto *MD = cast<MetadataAsValue>(Op)->getMetadata();
43
4.79k
  if (auto *V = dyn_cast<ValueAsMetadata>(MD))
44
4.76k
    return V->getValue();
45
34
46
34
  // When the value goes to null, it gets replaced by an empty MDNode.
47
4.79k
  assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
48
34
  return nullptr;
49
34
}
50
51
int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
52
592k
                                               StringRef Name) {
53
592k
  assert(Name.startswith("llvm."));
54
592k
55
592k
  // Do successive binary searches of the dotted name components. For
56
592k
  // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
57
592k
  // intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then
58
592k
  // "llvm.gc.experimental.statepoint", and then we will stop as the range is
59
592k
  // size 1. During the search, we can skip the prefix that we already know is
60
592k
  // identical. By using strncmp we consider names with differing suffixes to
61
592k
  // be part of the equal range.
62
592k
  size_t CmpStart = 0;
63
592k
  size_t CmpEnd = 4; // Skip the "llvm" component.
64
592k
  const char *const *Low = NameTable.begin();
65
592k
  const char *const *High = NameTable.end();
66
592k
  const char *const *LastLow = Low;
67
2.28M
  while (
CmpEnd < Name.size() && 2.28M
High - Low > 01.72M
) {
68
1.69M
    CmpStart = CmpEnd;
69
1.69M
    CmpEnd = Name.find('.', CmpStart + 1);
70
1.69M
    CmpEnd = CmpEnd == StringRef::npos ? 
Name.size()557k
:
CmpEnd1.13M
;
71
16.8M
    auto Cmp = [CmpStart, CmpEnd](const char *LHS, const char *RHS) {
72
16.8M
      return strncmp(LHS + CmpStart, RHS + CmpStart, CmpEnd - CmpStart) < 0;
73
16.8M
    };
74
1.69M
    LastLow = Low;
75
1.69M
    std::tie(Low, High) = std::equal_range(Low, High, Name.data(), Cmp);
76
1.69M
  }
77
592k
  if (High - Low > 0)
78
83.7k
    LastLow = Low;
79
592k
80
592k
  if (LastLow == NameTable.end())
81
0
    return -1;
82
592k
  StringRef NameFound = *LastLow;
83
592k
  if (Name == NameFound ||
84
509k
      
(Name.startswith(NameFound) && 509k
Name[NameFound.size()] == '.'495k
))
85
579k
    return LastLow - NameTable.begin();
86
13.4k
  return -1;
87
13.4k
}
88
89
762
Value *InstrProfIncrementInst::getStep() const {
90
762
  if (
InstrProfIncrementInstStep::classof(this)762
) {
91
1
    return const_cast<Value *>(getArgOperand(4));
92
1
  }
93
761
  const Module *M = getModule();
94
761
  LLVMContext &Context = M->getContext();
95
761
  return ConstantInt::get(Type::getInt64Ty(Context), 1);
96
761
}
97
98
ConstrainedFPIntrinsic::RoundingMode
99
195
ConstrainedFPIntrinsic::getRoundingMode() const {
100
195
  unsigned NumOperands = getNumArgOperands();
101
195
  Metadata *MD =
102
195
      dyn_cast<MetadataAsValue>(getArgOperand(NumOperands - 2))->getMetadata();
103
195
  if (
!MD || 195
!isa<MDString>(MD)195
)
104
0
    return rmInvalid;
105
195
  StringRef RoundingArg = cast<MDString>(MD)->getString();
106
195
107
195
  // For dynamic rounding mode, we use round to nearest but we will set the
108
195
  // 'exact' SDNodeFlag so that the value will not be rounded.
109
195
  return StringSwitch<RoundingMode>(RoundingArg)
110
195
    .Case("round.dynamic",    rmDynamic)
111
195
    .Case("round.tonearest",  rmToNearest)
112
195
    .Case("round.downward",   rmDownward)
113
195
    .Case("round.upward",     rmUpward)
114
195
    .Case("round.towardzero", rmTowardZero)
115
195
    .Default(rmInvalid);
116
195
}
117
118
ConstrainedFPIntrinsic::ExceptionBehavior
119
193
ConstrainedFPIntrinsic::getExceptionBehavior() const {
120
193
  unsigned NumOperands = getNumArgOperands();
121
193
  Metadata *MD =
122
193
      dyn_cast<MetadataAsValue>(getArgOperand(NumOperands - 1))->getMetadata();
123
193
  if (
!MD || 193
!isa<MDString>(MD)193
)
124
0
    return ebInvalid;
125
193
  StringRef ExceptionArg = cast<MDString>(MD)->getString();
126
193
  return StringSwitch<ExceptionBehavior>(ExceptionArg)
127
193
    .Case("fpexcept.ignore",  ebIgnore)
128
193
    .Case("fpexcept.maytrap", ebMayTrap)
129
193
    .Case("fpexcept.strict",  ebStrict)
130
193
    .Default(ebInvalid);
131
193
}
132
133
139
bool ConstrainedFPIntrinsic::isUnaryOp() const {
134
139
  switch (getIntrinsicID()) {
135
20
    default:
136
20
      return false;
137
119
    case Intrinsic::experimental_constrained_sqrt:
138
119
    case Intrinsic::experimental_constrained_sin:
139
119
    case Intrinsic::experimental_constrained_cos:
140
119
    case Intrinsic::experimental_constrained_exp:
141
119
    case Intrinsic::experimental_constrained_exp2:
142
119
    case Intrinsic::experimental_constrained_log:
143
119
    case Intrinsic::experimental_constrained_log10:
144
119
    case Intrinsic::experimental_constrained_log2:
145
119
    case Intrinsic::experimental_constrained_rint:
146
119
    case Intrinsic::experimental_constrained_nearbyint:
147
119
      return true;
148
0
  }
149
0
}
150
151
35
bool ConstrainedFPIntrinsic::isTernaryOp() const {
152
35
  switch (getIntrinsicID()) {
153
16
    default:
154
16
      return false;
155
19
    case Intrinsic::experimental_constrained_fma:
156
19
      return true;
157
0
  }
158
0
}
159