blob: 8d371aabb21860f4cb4052918e9773a41efe3458 [file] [log] [blame]
Nick Lewyckyea08c702014-02-26 03:10:45 +00001//===-- InstrinsicInst.cpp - Intrinsic Instruction Wrappers ---------------===//
Jim Laskey0cf8ed62006-03-23 18:05:12 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Jim Laskey0cf8ed62006-03-23 18:05:12 +00006//
7//===----------------------------------------------------------------------===//
Jim Laskey864e4442006-03-24 10:00:56 +00008//
9// This file implements methods that make it really easy to deal with intrinsic
Devang Patelbe94f232010-01-05 01:10:40 +000010// functions.
Jim Laskey864e4442006-03-24 10:00:56 +000011//
12// All intrinsic function calls are instances of the call instruction, so these
13// are all subclasses of the CallInst class. Note that none of these classes
14// has state or virtual methods, which is an important part of this gross/neat
15// hack working.
Wei Dinga131d3f2017-08-24 04:18:24 +000016//
Jim Laskey864e4442006-03-24 10:00:56 +000017// In some cases, arguments to intrinsics need to be generic and are defined as
18// type pointer to empty struct { }*. To access the real item of interest the
Wei Dinga131d3f2017-08-24 04:18:24 +000019// cast instruction needs to be stripped away.
Jim Laskey864e4442006-03-24 10:00:56 +000020//
21//===----------------------------------------------------------------------===//
Jim Laskey0cf8ed62006-03-23 18:05:12 +000022
Chandler Carruth9fb823b2013-01-02 11:36:10 +000023#include "llvm/IR/IntrinsicInst.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000024#include "llvm/ADT/StringSwitch.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000025#include "llvm/IR/Constants.h"
Bjorn Pettersson428caf92018-06-15 13:48:55 +000026#include "llvm/IR/DebugInfoMetadata.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000027#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//===----------------------------------------------------------------------===//
Hsiangkai Wangef72e482018-08-06 03:59:47 +000034/// DbgVariableIntrinsic - This is the common base class for debug info
35/// intrinsics for variables.
Jim Laskey0cf8ed62006-03-23 18:05:12 +000036///
37
Hsiangkai Wangef72e482018-08-06 03:59:47 +000038Value *DbgVariableIntrinsic::getVariableLocation(bool AllowNullOp) const {
Duncan P. N. Exon Smith40b44e12016-03-29 18:56:03 +000039 Value *Op = getArgOperand(0);
40 if (AllowNullOp && !Op)
41 return nullptr;
42
Duncan P. N. Exon Smith5bf8fef2014-12-09 18:38:53 +000043 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.
Hsiangkai Wangef72e482018-08-06 03:59:47 +000048 assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
Duncan P. N. Exon Smith5bf8fef2014-12-09 18:38:53 +000049 return nullptr;
50}
51
Hsiangkai Wangef72e482018-08-06 03:59:47 +000052Optional<uint64_t> DbgVariableIntrinsic::getFragmentSizeInBits() const {
Bjorn Pettersson428caf92018-06-15 13:48:55 +000053 if (auto Fragment = getExpression()->getFragmentInfo())
54 return Fragment->SizeInBits;
55 return getVariable()->getSizeInBits();
56}
57
Reid Klecknerc2752da2016-01-26 22:33:19 +000058int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
59 StringRef Name) {
60 assert(Name.startswith("llvm."));
61
62 // Do successive binary searches of the dotted name components. For
63 // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
64 // intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then
65 // "llvm.gc.experimental.statepoint", and then we will stop as the range is
66 // size 1. During the search, we can skip the prefix that we already know is
67 // identical. By using strncmp we consider names with differing suffixes to
68 // be part of the equal range.
69 size_t CmpStart = 0;
70 size_t CmpEnd = 4; // Skip the "llvm" component.
71 const char *const *Low = NameTable.begin();
72 const char *const *High = NameTable.end();
73 const char *const *LastLow = Low;
74 while (CmpEnd < Name.size() && High - Low > 0) {
75 CmpStart = CmpEnd;
76 CmpEnd = Name.find('.', CmpStart + 1);
77 CmpEnd = CmpEnd == StringRef::npos ? Name.size() : CmpEnd;
78 auto Cmp = [CmpStart, CmpEnd](const char *LHS, const char *RHS) {
79 return strncmp(LHS + CmpStart, RHS + CmpStart, CmpEnd - CmpStart) < 0;
80 };
81 LastLow = Low;
82 std::tie(Low, High) = std::equal_range(Low, High, Name.data(), Cmp);
83 }
84 if (High - Low > 0)
85 LastLow = Low;
86
87 if (LastLow == NameTable.end())
88 return -1;
89 StringRef NameFound = *LastLow;
90 if (Name == NameFound ||
91 (Name.startswith(NameFound) && Name[NameFound.size()] == '.'))
92 return LastLow - NameTable.begin();
93 return -1;
94}
Xinliang David Lia754c472016-09-20 19:07:22 +000095
96Value *InstrProfIncrementInst::getStep() const {
97 if (InstrProfIncrementInstStep::classof(this)) {
98 return const_cast<Value *>(getArgOperand(4));
99 }
100 const Module *M = getModule();
101 LLVMContext &Context = M->getContext();
102 return ConstantInt::get(Type::getInt64Ty(Context), 1);
103}
Andrew Kaylora0a11642017-01-26 23:27:59 +0000104
105ConstrainedFPIntrinsic::RoundingMode
106ConstrainedFPIntrinsic::getRoundingMode() const {
Andrew Kaylorf4660012017-05-25 21:31:00 +0000107 unsigned NumOperands = getNumArgOperands();
Wei Dinga131d3f2017-08-24 04:18:24 +0000108 Metadata *MD =
Andrew Kaylorf4660012017-05-25 21:31:00 +0000109 dyn_cast<MetadataAsValue>(getArgOperand(NumOperands - 2))->getMetadata();
Andrew Kaylora0a11642017-01-26 23:27:59 +0000110 if (!MD || !isa<MDString>(MD))
111 return rmInvalid;
112 StringRef RoundingArg = cast<MDString>(MD)->getString();
113
114 // For dynamic rounding mode, we use round to nearest but we will set the
115 // 'exact' SDNodeFlag so that the value will not be rounded.
116 return StringSwitch<RoundingMode>(RoundingArg)
117 .Case("round.dynamic", rmDynamic)
118 .Case("round.tonearest", rmToNearest)
119 .Case("round.downward", rmDownward)
120 .Case("round.upward", rmUpward)
121 .Case("round.towardzero", rmTowardZero)
122 .Default(rmInvalid);
123}
124
125ConstrainedFPIntrinsic::ExceptionBehavior
126ConstrainedFPIntrinsic::getExceptionBehavior() const {
Andrew Kaylorf4660012017-05-25 21:31:00 +0000127 unsigned NumOperands = getNumArgOperands();
Wei Dinga131d3f2017-08-24 04:18:24 +0000128 Metadata *MD =
Andrew Kaylorf4660012017-05-25 21:31:00 +0000129 dyn_cast<MetadataAsValue>(getArgOperand(NumOperands - 1))->getMetadata();
Andrew Kaylora0a11642017-01-26 23:27:59 +0000130 if (!MD || !isa<MDString>(MD))
131 return ebInvalid;
132 StringRef ExceptionArg = cast<MDString>(MD)->getString();
133 return StringSwitch<ExceptionBehavior>(ExceptionArg)
134 .Case("fpexcept.ignore", ebIgnore)
135 .Case("fpexcept.maytrap", ebMayTrap)
136 .Case("fpexcept.strict", ebStrict)
137 .Default(ebInvalid);
138}
Andrew Kaylorf4660012017-05-25 21:31:00 +0000139
140bool ConstrainedFPIntrinsic::isUnaryOp() const {
141 switch (getIntrinsicID()) {
Wei Dinga131d3f2017-08-24 04:18:24 +0000142 default:
Andrew Kaylorf4660012017-05-25 21:31:00 +0000143 return false;
144 case Intrinsic::experimental_constrained_sqrt:
145 case Intrinsic::experimental_constrained_sin:
146 case Intrinsic::experimental_constrained_cos:
147 case Intrinsic::experimental_constrained_exp:
148 case Intrinsic::experimental_constrained_exp2:
149 case Intrinsic::experimental_constrained_log:
150 case Intrinsic::experimental_constrained_log10:
151 case Intrinsic::experimental_constrained_log2:
152 case Intrinsic::experimental_constrained_rint:
153 case Intrinsic::experimental_constrained_nearbyint:
Cameron McInally9757d5d2018-11-05 15:59:49 +0000154 case Intrinsic::experimental_constrained_ceil:
155 case Intrinsic::experimental_constrained_floor:
156 case Intrinsic::experimental_constrained_round:
157 case Intrinsic::experimental_constrained_trunc:
Andrew Kaylorf4660012017-05-25 21:31:00 +0000158 return true;
159 }
160}
Wei Dinga131d3f2017-08-24 04:18:24 +0000161
162bool ConstrainedFPIntrinsic::isTernaryOp() const {
163 switch (getIntrinsicID()) {
164 default:
165 return false;
166 case Intrinsic::experimental_constrained_fma:
167 return true;
168 }
169}
170