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 38 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 55 Optional<uint64_t> DbgInfoIntrinsic::getFragmentSizeInBits() const { 56 if (auto Fragment = getExpression()->getFragmentInfo()) 57 return Fragment->SizeInBits; 58 return getVariable()->getSizeInBits(); 59 } 60 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 99 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 109 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 129 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 143 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 161 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