blob: 67bd5b69bb0f05b1b8b584d6e9b6fad84a7e1994 [file] [log] [blame]
Nick Lewyckyea08c702014-02-26 03:10:45 +00001//===-- InstrinsicInst.cpp - Intrinsic Instruction Wrappers ---------------===//
Jim Laskey0cf8ed62006-03-23 18:05:12 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Jim Laskey0cf8ed62006-03-23 18:05:12 +00007//
8//===----------------------------------------------------------------------===//
Jim Laskey864e4442006-03-24 10:00:56 +00009//
10// This file implements methods that make it really easy to deal with intrinsic
Devang Patelbe94f232010-01-05 01:10:40 +000011// functions.
Jim Laskey864e4442006-03-24 10:00:56 +000012//
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.
Wei Dinga131d3f2017-08-24 04:18:24 +000017//
Jim Laskey864e4442006-03-24 10:00:56 +000018// 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
Wei Dinga131d3f2017-08-24 04:18:24 +000020// cast instruction needs to be stripped away.
Jim Laskey864e4442006-03-24 10:00:56 +000021//
22//===----------------------------------------------------------------------===//
Jim Laskey0cf8ed62006-03-23 18:05:12 +000023
Chandler Carruth9fb823b2013-01-02 11:36:10 +000024#include "llvm/IR/IntrinsicInst.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000025#include "llvm/ADT/StringSwitch.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000026#include "llvm/IR/Constants.h"
27#include "llvm/IR/GlobalVariable.h"
28#include "llvm/IR/Metadata.h"
Xinliang David Lia754c472016-09-20 19:07:22 +000029#include "llvm/IR/Module.h"
Reid Klecknerc2752da2016-01-26 22:33:19 +000030#include "llvm/Support/raw_ostream.h"
Jim Laskey0cf8ed62006-03-23 18:05:12 +000031using namespace llvm;
32
33//===----------------------------------------------------------------------===//
34/// DbgInfoIntrinsic - This is the common base class for debug info intrinsics
35///
36
Duncan P. N. Exon Smith40b44e12016-03-29 18:56:03 +000037Value *DbgInfoIntrinsic::getVariableLocation(bool AllowNullOp) const {
38 Value *Op = getArgOperand(0);
39 if (AllowNullOp && !Op)
40 return nullptr;
41
Duncan P. N. Exon Smith5bf8fef2014-12-09 18:38:53 +000042 auto *MD = cast<MetadataAsValue>(Op)->getMetadata();
43 if (auto *V = dyn_cast<ValueAsMetadata>(MD))
44 return V->getValue();
45
46 // When the value goes to null, it gets replaced by an empty MDNode.
47 assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
48 return nullptr;
49}
50
Reid Klecknerc2752da2016-01-26 22:33:19 +000051int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
52 StringRef Name) {
53 assert(Name.startswith("llvm."));
54
55 // Do successive binary searches of the dotted name components. For
56 // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
57 // intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then
58 // "llvm.gc.experimental.statepoint", and then we will stop as the range is
59 // size 1. During the search, we can skip the prefix that we already know is
60 // identical. By using strncmp we consider names with differing suffixes to
61 // be part of the equal range.
62 size_t CmpStart = 0;
63 size_t CmpEnd = 4; // Skip the "llvm" component.
64 const char *const *Low = NameTable.begin();
65 const char *const *High = NameTable.end();
66 const char *const *LastLow = Low;
67 while (CmpEnd < Name.size() && High - Low > 0) {
68 CmpStart = CmpEnd;
69 CmpEnd = Name.find('.', CmpStart + 1);
70 CmpEnd = CmpEnd == StringRef::npos ? Name.size() : CmpEnd;
71 auto Cmp = [CmpStart, CmpEnd](const char *LHS, const char *RHS) {
72 return strncmp(LHS + CmpStart, RHS + CmpStart, CmpEnd - CmpStart) < 0;
73 };
74 LastLow = Low;
75 std::tie(Low, High) = std::equal_range(Low, High, Name.data(), Cmp);
76 }
77 if (High - Low > 0)
78 LastLow = Low;
79
80 if (LastLow == NameTable.end())
81 return -1;
82 StringRef NameFound = *LastLow;
83 if (Name == NameFound ||
84 (Name.startswith(NameFound) && Name[NameFound.size()] == '.'))
85 return LastLow - NameTable.begin();
86 return -1;
87}
Xinliang David Lia754c472016-09-20 19:07:22 +000088
89Value *InstrProfIncrementInst::getStep() const {
90 if (InstrProfIncrementInstStep::classof(this)) {
91 return const_cast<Value *>(getArgOperand(4));
92 }
93 const Module *M = getModule();
94 LLVMContext &Context = M->getContext();
95 return ConstantInt::get(Type::getInt64Ty(Context), 1);
96}
Andrew Kaylora0a11642017-01-26 23:27:59 +000097
98ConstrainedFPIntrinsic::RoundingMode
99ConstrainedFPIntrinsic::getRoundingMode() const {
Andrew Kaylorf4660012017-05-25 21:31:00 +0000100 unsigned NumOperands = getNumArgOperands();
Wei Dinga131d3f2017-08-24 04:18:24 +0000101 Metadata *MD =
Andrew Kaylorf4660012017-05-25 21:31:00 +0000102 dyn_cast<MetadataAsValue>(getArgOperand(NumOperands - 2))->getMetadata();
Andrew Kaylora0a11642017-01-26 23:27:59 +0000103 if (!MD || !isa<MDString>(MD))
104 return rmInvalid;
105 StringRef RoundingArg = cast<MDString>(MD)->getString();
106
107 // For dynamic rounding mode, we use round to nearest but we will set the
108 // 'exact' SDNodeFlag so that the value will not be rounded.
109 return StringSwitch<RoundingMode>(RoundingArg)
110 .Case("round.dynamic", rmDynamic)
111 .Case("round.tonearest", rmToNearest)
112 .Case("round.downward", rmDownward)
113 .Case("round.upward", rmUpward)
114 .Case("round.towardzero", rmTowardZero)
115 .Default(rmInvalid);
116}
117
118ConstrainedFPIntrinsic::ExceptionBehavior
119ConstrainedFPIntrinsic::getExceptionBehavior() const {
Andrew Kaylorf4660012017-05-25 21:31:00 +0000120 unsigned NumOperands = getNumArgOperands();
Wei Dinga131d3f2017-08-24 04:18:24 +0000121 Metadata *MD =
Andrew Kaylorf4660012017-05-25 21:31:00 +0000122 dyn_cast<MetadataAsValue>(getArgOperand(NumOperands - 1))->getMetadata();
Andrew Kaylora0a11642017-01-26 23:27:59 +0000123 if (!MD || !isa<MDString>(MD))
124 return ebInvalid;
125 StringRef ExceptionArg = cast<MDString>(MD)->getString();
126 return StringSwitch<ExceptionBehavior>(ExceptionArg)
127 .Case("fpexcept.ignore", ebIgnore)
128 .Case("fpexcept.maytrap", ebMayTrap)
129 .Case("fpexcept.strict", ebStrict)
130 .Default(ebInvalid);
131}
Andrew Kaylorf4660012017-05-25 21:31:00 +0000132
133bool ConstrainedFPIntrinsic::isUnaryOp() const {
134 switch (getIntrinsicID()) {
Wei Dinga131d3f2017-08-24 04:18:24 +0000135 default:
Andrew Kaylorf4660012017-05-25 21:31:00 +0000136 return false;
137 case Intrinsic::experimental_constrained_sqrt:
138 case Intrinsic::experimental_constrained_sin:
139 case Intrinsic::experimental_constrained_cos:
140 case Intrinsic::experimental_constrained_exp:
141 case Intrinsic::experimental_constrained_exp2:
142 case Intrinsic::experimental_constrained_log:
143 case Intrinsic::experimental_constrained_log10:
144 case Intrinsic::experimental_constrained_log2:
145 case Intrinsic::experimental_constrained_rint:
146 case Intrinsic::experimental_constrained_nearbyint:
147 return true;
148 }
149}
Wei Dinga131d3f2017-08-24 04:18:24 +0000150
151bool ConstrainedFPIntrinsic::isTernaryOp() const {
152 switch (getIntrinsicID()) {
153 default:
154 return false;
155 case Intrinsic::experimental_constrained_fma:
156 return true;
157 }
158}
159