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/DebugInfoMetadata.h"
28 #include "llvm/IR/GlobalVariable.h"
29 #include "llvm/IR/Metadata.h"
30 #include "llvm/IR/Module.h"
31 #include "llvm/Support/raw_ostream.h"
32 using namespace llvm;
33
34 //===----------------------------------------------------------------------===//
35 /// DbgInfoIntrinsic - This is the common base class for debug info intrinsics
36 ///
37
getVariableLocation(bool AllowNullOp) const38 Value *DbgInfoIntrinsic::getVariableLocation(bool AllowNullOp) const {
39 Value *Op = getArgOperand(0);
40 if (AllowNullOp && !Op)
41 return nullptr;
42
43 auto *MD = cast<MetadataAsValue>(Op)->getMetadata();
44 if (auto *V = dyn_cast<ValueAsMetadata>(MD))
45 return V->getValue();
46
47 // When the value goes to null, it gets replaced by an empty MDNode.
48 assert((isa<DbgLabelInst>(this)
49 || !cast<MDNode>(MD)->getNumOperands())
50 && "DbgValueInst Expected an empty MDNode");
51
52 return nullptr;
53 }
54
getFragmentSizeInBits() const55 Optional<uint64_t> DbgInfoIntrinsic::getFragmentSizeInBits() const {
56 if (auto Fragment = getExpression()->getFragmentInfo())
57 return Fragment->SizeInBits;
58 return getVariable()->getSizeInBits();
59 }
60
lookupLLVMIntrinsicByName(ArrayRef<const char * > NameTable,StringRef Name)61 int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
62 StringRef Name) {
63 assert(Name.startswith("llvm."));
64
65 // Do successive binary searches of the dotted name components. For
66 // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
67 // intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then
68 // "llvm.gc.experimental.statepoint", and then we will stop as the range is
69 // size 1. During the search, we can skip the prefix that we already know is
70 // identical. By using strncmp we consider names with differing suffixes to
71 // be part of the equal range.
72 size_t CmpStart = 0;
73 size_t CmpEnd = 4; // Skip the "llvm" component.
74 const char *const *Low = NameTable.begin();
75 const char *const *High = NameTable.end();
76 const char *const *LastLow = Low;
77 while (CmpEnd < Name.size() && High - Low > 0) {
78 CmpStart = CmpEnd;
79 CmpEnd = Name.find('.', CmpStart + 1);
80 CmpEnd = CmpEnd == StringRef::npos ? Name.size() : CmpEnd;
81 auto Cmp = [CmpStart, CmpEnd](const char *LHS, const char *RHS) {
82 return strncmp(LHS + CmpStart, RHS + CmpStart, CmpEnd - CmpStart) < 0;
83 };
84 LastLow = Low;
85 std::tie(Low, High) = std::equal_range(Low, High, Name.data(), Cmp);
86 }
87 if (High - Low > 0)
88 LastLow = Low;
89
90 if (LastLow == NameTable.end())
91 return -1;
92 StringRef NameFound = *LastLow;
93 if (Name == NameFound ||
94 (Name.startswith(NameFound) && Name[NameFound.size()] == '.'))
95 return LastLow - NameTable.begin();
96 return -1;
97 }
98
getStep() const99 Value *InstrProfIncrementInst::getStep() const {
100 if (InstrProfIncrementInstStep::classof(this)) {
101 return const_cast<Value *>(getArgOperand(4));
102 }
103 const Module *M = getModule();
104 LLVMContext &Context = M->getContext();
105 return ConstantInt::get(Type::getInt64Ty(Context), 1);
106 }
107
108 ConstrainedFPIntrinsic::RoundingMode
getRoundingMode() const109 ConstrainedFPIntrinsic::getRoundingMode() const {
110 unsigned NumOperands = getNumArgOperands();
111 Metadata *MD =
112 dyn_cast<MetadataAsValue>(getArgOperand(NumOperands - 2))->getMetadata();
113 if (!MD || !isa<MDString>(MD))
114 return rmInvalid;
115 StringRef RoundingArg = cast<MDString>(MD)->getString();
116
117 // For dynamic rounding mode, we use round to nearest but we will set the
118 // 'exact' SDNodeFlag so that the value will not be rounded.
119 return StringSwitch<RoundingMode>(RoundingArg)
120 .Case("round.dynamic", rmDynamic)
121 .Case("round.tonearest", rmToNearest)
122 .Case("round.downward", rmDownward)
123 .Case("round.upward", rmUpward)
124 .Case("round.towardzero", rmTowardZero)
125 .Default(rmInvalid);
126 }
127
128 ConstrainedFPIntrinsic::ExceptionBehavior
getExceptionBehavior() const129 ConstrainedFPIntrinsic::getExceptionBehavior() const {
130 unsigned NumOperands = getNumArgOperands();
131 Metadata *MD =
132 dyn_cast<MetadataAsValue>(getArgOperand(NumOperands - 1))->getMetadata();
133 if (!MD || !isa<MDString>(MD))
134 return ebInvalid;
135 StringRef ExceptionArg = cast<MDString>(MD)->getString();
136 return StringSwitch<ExceptionBehavior>(ExceptionArg)
137 .Case("fpexcept.ignore", ebIgnore)
138 .Case("fpexcept.maytrap", ebMayTrap)
139 .Case("fpexcept.strict", ebStrict)
140 .Default(ebInvalid);
141 }
142
isUnaryOp() const143 bool ConstrainedFPIntrinsic::isUnaryOp() const {
144 switch (getIntrinsicID()) {
145 default:
146 return false;
147 case Intrinsic::experimental_constrained_sqrt:
148 case Intrinsic::experimental_constrained_sin:
149 case Intrinsic::experimental_constrained_cos:
150 case Intrinsic::experimental_constrained_exp:
151 case Intrinsic::experimental_constrained_exp2:
152 case Intrinsic::experimental_constrained_log:
153 case Intrinsic::experimental_constrained_log10:
154 case Intrinsic::experimental_constrained_log2:
155 case Intrinsic::experimental_constrained_rint:
156 case Intrinsic::experimental_constrained_nearbyint:
157 return true;
158 }
159 }
160
isTernaryOp() const161 bool ConstrainedFPIntrinsic::isTernaryOp() const {
162 switch (getIntrinsicID()) {
163 default:
164 return false;
165 case Intrinsic::experimental_constrained_fma:
166 return true;
167 }
168 }
169
170