| File: | build/source/llvm/include/llvm/IR/User.h |
| Warning: | line 163, column 12 Branch condition evaluates to a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | //===- Function.cpp - Implement the Global object classes -----------------===// | |||
| 2 | // | |||
| 3 | // 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 | |||
| 6 | // | |||
| 7 | //===----------------------------------------------------------------------===// | |||
| 8 | // | |||
| 9 | // This file implements the Function class for the IR library. | |||
| 10 | // | |||
| 11 | //===----------------------------------------------------------------------===// | |||
| 12 | ||||
| 13 | #include "llvm/IR/Function.h" | |||
| 14 | #include "SymbolTableListTraitsImpl.h" | |||
| 15 | #include "llvm/ADT/ArrayRef.h" | |||
| 16 | #include "llvm/ADT/DenseSet.h" | |||
| 17 | #include "llvm/ADT/STLExtras.h" | |||
| 18 | #include "llvm/ADT/SmallString.h" | |||
| 19 | #include "llvm/ADT/SmallVector.h" | |||
| 20 | #include "llvm/ADT/StringExtras.h" | |||
| 21 | #include "llvm/ADT/StringRef.h" | |||
| 22 | #include "llvm/IR/AbstractCallSite.h" | |||
| 23 | #include "llvm/IR/Argument.h" | |||
| 24 | #include "llvm/IR/Attributes.h" | |||
| 25 | #include "llvm/IR/BasicBlock.h" | |||
| 26 | #include "llvm/IR/Constant.h" | |||
| 27 | #include "llvm/IR/Constants.h" | |||
| 28 | #include "llvm/IR/DerivedTypes.h" | |||
| 29 | #include "llvm/IR/GlobalValue.h" | |||
| 30 | #include "llvm/IR/InstIterator.h" | |||
| 31 | #include "llvm/IR/Instruction.h" | |||
| 32 | #include "llvm/IR/IntrinsicInst.h" | |||
| 33 | #include "llvm/IR/Intrinsics.h" | |||
| 34 | #include "llvm/IR/IntrinsicsAArch64.h" | |||
| 35 | #include "llvm/IR/IntrinsicsAMDGPU.h" | |||
| 36 | #include "llvm/IR/IntrinsicsARM.h" | |||
| 37 | #include "llvm/IR/IntrinsicsBPF.h" | |||
| 38 | #include "llvm/IR/IntrinsicsDirectX.h" | |||
| 39 | #include "llvm/IR/IntrinsicsHexagon.h" | |||
| 40 | #include "llvm/IR/IntrinsicsMips.h" | |||
| 41 | #include "llvm/IR/IntrinsicsNVPTX.h" | |||
| 42 | #include "llvm/IR/IntrinsicsPowerPC.h" | |||
| 43 | #include "llvm/IR/IntrinsicsR600.h" | |||
| 44 | #include "llvm/IR/IntrinsicsRISCV.h" | |||
| 45 | #include "llvm/IR/IntrinsicsS390.h" | |||
| 46 | #include "llvm/IR/IntrinsicsVE.h" | |||
| 47 | #include "llvm/IR/IntrinsicsWebAssembly.h" | |||
| 48 | #include "llvm/IR/IntrinsicsX86.h" | |||
| 49 | #include "llvm/IR/IntrinsicsXCore.h" | |||
| 50 | #include "llvm/IR/LLVMContext.h" | |||
| 51 | #include "llvm/IR/MDBuilder.h" | |||
| 52 | #include "llvm/IR/Metadata.h" | |||
| 53 | #include "llvm/IR/Module.h" | |||
| 54 | #include "llvm/IR/Operator.h" | |||
| 55 | #include "llvm/IR/SymbolTableListTraits.h" | |||
| 56 | #include "llvm/IR/Type.h" | |||
| 57 | #include "llvm/IR/Use.h" | |||
| 58 | #include "llvm/IR/User.h" | |||
| 59 | #include "llvm/IR/Value.h" | |||
| 60 | #include "llvm/IR/ValueSymbolTable.h" | |||
| 61 | #include "llvm/Support/Casting.h" | |||
| 62 | #include "llvm/Support/CommandLine.h" | |||
| 63 | #include "llvm/Support/Compiler.h" | |||
| 64 | #include "llvm/Support/ErrorHandling.h" | |||
| 65 | #include "llvm/Support/ModRef.h" | |||
| 66 | #include <cassert> | |||
| 67 | #include <cstddef> | |||
| 68 | #include <cstdint> | |||
| 69 | #include <cstring> | |||
| 70 | #include <string> | |||
| 71 | ||||
| 72 | using namespace llvm; | |||
| 73 | using ProfileCount = Function::ProfileCount; | |||
| 74 | ||||
| 75 | // Explicit instantiations of SymbolTableListTraits since some of the methods | |||
| 76 | // are not in the public header file... | |||
| 77 | template class llvm::SymbolTableListTraits<BasicBlock>; | |||
| 78 | ||||
| 79 | static cl::opt<unsigned> NonGlobalValueMaxNameSize( | |||
| 80 | "non-global-value-max-name-size", cl::Hidden, cl::init(1024), | |||
| 81 | cl::desc("Maximum size for the name of non-global values.")); | |||
| 82 | ||||
| 83 | //===----------------------------------------------------------------------===// | |||
| 84 | // Argument Implementation | |||
| 85 | //===----------------------------------------------------------------------===// | |||
| 86 | ||||
| 87 | Argument::Argument(Type *Ty, const Twine &Name, Function *Par, unsigned ArgNo) | |||
| 88 | : Value(Ty, Value::ArgumentVal), Parent(Par), ArgNo(ArgNo) { | |||
| 89 | setName(Name); | |||
| 90 | } | |||
| 91 | ||||
| 92 | void Argument::setParent(Function *parent) { | |||
| 93 | Parent = parent; | |||
| 94 | } | |||
| 95 | ||||
| 96 | bool Argument::hasNonNullAttr(bool AllowUndefOrPoison) const { | |||
| 97 | if (!getType()->isPointerTy()) return false; | |||
| 98 | if (getParent()->hasParamAttribute(getArgNo(), Attribute::NonNull) && | |||
| 99 | (AllowUndefOrPoison || | |||
| 100 | getParent()->hasParamAttribute(getArgNo(), Attribute::NoUndef))) | |||
| 101 | return true; | |||
| 102 | else if (getDereferenceableBytes() > 0 && | |||
| 103 | !NullPointerIsDefined(getParent(), | |||
| 104 | getType()->getPointerAddressSpace())) | |||
| 105 | return true; | |||
| 106 | return false; | |||
| 107 | } | |||
| 108 | ||||
| 109 | bool Argument::hasByValAttr() const { | |||
| 110 | if (!getType()->isPointerTy()) return false; | |||
| 111 | return hasAttribute(Attribute::ByVal); | |||
| 112 | } | |||
| 113 | ||||
| 114 | bool Argument::hasByRefAttr() const { | |||
| 115 | if (!getType()->isPointerTy()) | |||
| 116 | return false; | |||
| 117 | return hasAttribute(Attribute::ByRef); | |||
| 118 | } | |||
| 119 | ||||
| 120 | bool Argument::hasSwiftSelfAttr() const { | |||
| 121 | return getParent()->hasParamAttribute(getArgNo(), Attribute::SwiftSelf); | |||
| 122 | } | |||
| 123 | ||||
| 124 | bool Argument::hasSwiftErrorAttr() const { | |||
| 125 | return getParent()->hasParamAttribute(getArgNo(), Attribute::SwiftError); | |||
| 126 | } | |||
| 127 | ||||
| 128 | bool Argument::hasInAllocaAttr() const { | |||
| 129 | if (!getType()->isPointerTy()) return false; | |||
| 130 | return hasAttribute(Attribute::InAlloca); | |||
| 131 | } | |||
| 132 | ||||
| 133 | bool Argument::hasPreallocatedAttr() const { | |||
| 134 | if (!getType()->isPointerTy()) | |||
| 135 | return false; | |||
| 136 | return hasAttribute(Attribute::Preallocated); | |||
| 137 | } | |||
| 138 | ||||
| 139 | bool Argument::hasPassPointeeByValueCopyAttr() const { | |||
| 140 | if (!getType()->isPointerTy()) return false; | |||
| 141 | AttributeList Attrs = getParent()->getAttributes(); | |||
| 142 | return Attrs.hasParamAttr(getArgNo(), Attribute::ByVal) || | |||
| 143 | Attrs.hasParamAttr(getArgNo(), Attribute::InAlloca) || | |||
| 144 | Attrs.hasParamAttr(getArgNo(), Attribute::Preallocated); | |||
| 145 | } | |||
| 146 | ||||
| 147 | bool Argument::hasPointeeInMemoryValueAttr() const { | |||
| 148 | if (!getType()->isPointerTy()) | |||
| 149 | return false; | |||
| 150 | AttributeList Attrs = getParent()->getAttributes(); | |||
| 151 | return Attrs.hasParamAttr(getArgNo(), Attribute::ByVal) || | |||
| 152 | Attrs.hasParamAttr(getArgNo(), Attribute::StructRet) || | |||
| 153 | Attrs.hasParamAttr(getArgNo(), Attribute::InAlloca) || | |||
| 154 | Attrs.hasParamAttr(getArgNo(), Attribute::Preallocated) || | |||
| 155 | Attrs.hasParamAttr(getArgNo(), Attribute::ByRef); | |||
| 156 | } | |||
| 157 | ||||
| 158 | /// For a byval, sret, inalloca, or preallocated parameter, get the in-memory | |||
| 159 | /// parameter type. | |||
| 160 | static Type *getMemoryParamAllocType(AttributeSet ParamAttrs) { | |||
| 161 | // FIXME: All the type carrying attributes are mutually exclusive, so there | |||
| 162 | // should be a single query to get the stored type that handles any of them. | |||
| 163 | if (Type *ByValTy = ParamAttrs.getByValType()) | |||
| 164 | return ByValTy; | |||
| 165 | if (Type *ByRefTy = ParamAttrs.getByRefType()) | |||
| 166 | return ByRefTy; | |||
| 167 | if (Type *PreAllocTy = ParamAttrs.getPreallocatedType()) | |||
| 168 | return PreAllocTy; | |||
| 169 | if (Type *InAllocaTy = ParamAttrs.getInAllocaType()) | |||
| 170 | return InAllocaTy; | |||
| 171 | if (Type *SRetTy = ParamAttrs.getStructRetType()) | |||
| 172 | return SRetTy; | |||
| 173 | ||||
| 174 | return nullptr; | |||
| 175 | } | |||
| 176 | ||||
| 177 | uint64_t Argument::getPassPointeeByValueCopySize(const DataLayout &DL) const { | |||
| 178 | AttributeSet ParamAttrs = | |||
| 179 | getParent()->getAttributes().getParamAttrs(getArgNo()); | |||
| 180 | if (Type *MemTy = getMemoryParamAllocType(ParamAttrs)) | |||
| 181 | return DL.getTypeAllocSize(MemTy); | |||
| 182 | return 0; | |||
| 183 | } | |||
| 184 | ||||
| 185 | Type *Argument::getPointeeInMemoryValueType() const { | |||
| 186 | AttributeSet ParamAttrs = | |||
| 187 | getParent()->getAttributes().getParamAttrs(getArgNo()); | |||
| 188 | return getMemoryParamAllocType(ParamAttrs); | |||
| 189 | } | |||
| 190 | ||||
| 191 | MaybeAlign Argument::getParamAlign() const { | |||
| 192 | assert(getType()->isPointerTy() && "Only pointers have alignments")(static_cast <bool> (getType()->isPointerTy() && "Only pointers have alignments") ? void (0) : __assert_fail ( "getType()->isPointerTy() && \"Only pointers have alignments\"" , "llvm/lib/IR/Function.cpp", 192, __extension__ __PRETTY_FUNCTION__ )); | |||
| 193 | return getParent()->getParamAlign(getArgNo()); | |||
| 194 | } | |||
| 195 | ||||
| 196 | MaybeAlign Argument::getParamStackAlign() const { | |||
| 197 | return getParent()->getParamStackAlign(getArgNo()); | |||
| 198 | } | |||
| 199 | ||||
| 200 | Type *Argument::getParamByValType() const { | |||
| 201 | assert(getType()->isPointerTy() && "Only pointers have byval types")(static_cast <bool> (getType()->isPointerTy() && "Only pointers have byval types") ? void (0) : __assert_fail ("getType()->isPointerTy() && \"Only pointers have byval types\"" , "llvm/lib/IR/Function.cpp", 201, __extension__ __PRETTY_FUNCTION__ )); | |||
| 202 | return getParent()->getParamByValType(getArgNo()); | |||
| 203 | } | |||
| 204 | ||||
| 205 | Type *Argument::getParamStructRetType() const { | |||
| 206 | assert(getType()->isPointerTy() && "Only pointers have sret types")(static_cast <bool> (getType()->isPointerTy() && "Only pointers have sret types") ? void (0) : __assert_fail ( "getType()->isPointerTy() && \"Only pointers have sret types\"" , "llvm/lib/IR/Function.cpp", 206, __extension__ __PRETTY_FUNCTION__ )); | |||
| 207 | return getParent()->getParamStructRetType(getArgNo()); | |||
| 208 | } | |||
| 209 | ||||
| 210 | Type *Argument::getParamByRefType() const { | |||
| 211 | assert(getType()->isPointerTy() && "Only pointers have byref types")(static_cast <bool> (getType()->isPointerTy() && "Only pointers have byref types") ? void (0) : __assert_fail ("getType()->isPointerTy() && \"Only pointers have byref types\"" , "llvm/lib/IR/Function.cpp", 211, __extension__ __PRETTY_FUNCTION__ )); | |||
| 212 | return getParent()->getParamByRefType(getArgNo()); | |||
| 213 | } | |||
| 214 | ||||
| 215 | Type *Argument::getParamInAllocaType() const { | |||
| 216 | assert(getType()->isPointerTy() && "Only pointers have inalloca types")(static_cast <bool> (getType()->isPointerTy() && "Only pointers have inalloca types") ? void (0) : __assert_fail ("getType()->isPointerTy() && \"Only pointers have inalloca types\"" , "llvm/lib/IR/Function.cpp", 216, __extension__ __PRETTY_FUNCTION__ )); | |||
| 217 | return getParent()->getParamInAllocaType(getArgNo()); | |||
| 218 | } | |||
| 219 | ||||
| 220 | uint64_t Argument::getDereferenceableBytes() const { | |||
| 221 | assert(getType()->isPointerTy() &&(static_cast <bool> (getType()->isPointerTy() && "Only pointers have dereferenceable bytes") ? void (0) : __assert_fail ("getType()->isPointerTy() && \"Only pointers have dereferenceable bytes\"" , "llvm/lib/IR/Function.cpp", 222, __extension__ __PRETTY_FUNCTION__ )) | |||
| 222 | "Only pointers have dereferenceable bytes")(static_cast <bool> (getType()->isPointerTy() && "Only pointers have dereferenceable bytes") ? void (0) : __assert_fail ("getType()->isPointerTy() && \"Only pointers have dereferenceable bytes\"" , "llvm/lib/IR/Function.cpp", 222, __extension__ __PRETTY_FUNCTION__ )); | |||
| 223 | return getParent()->getParamDereferenceableBytes(getArgNo()); | |||
| 224 | } | |||
| 225 | ||||
| 226 | uint64_t Argument::getDereferenceableOrNullBytes() const { | |||
| 227 | assert(getType()->isPointerTy() &&(static_cast <bool> (getType()->isPointerTy() && "Only pointers have dereferenceable bytes") ? void (0) : __assert_fail ("getType()->isPointerTy() && \"Only pointers have dereferenceable bytes\"" , "llvm/lib/IR/Function.cpp", 228, __extension__ __PRETTY_FUNCTION__ )) | |||
| 228 | "Only pointers have dereferenceable bytes")(static_cast <bool> (getType()->isPointerTy() && "Only pointers have dereferenceable bytes") ? void (0) : __assert_fail ("getType()->isPointerTy() && \"Only pointers have dereferenceable bytes\"" , "llvm/lib/IR/Function.cpp", 228, __extension__ __PRETTY_FUNCTION__ )); | |||
| 229 | return getParent()->getParamDereferenceableOrNullBytes(getArgNo()); | |||
| 230 | } | |||
| 231 | ||||
| 232 | FPClassTest Argument::getNoFPClass() const { | |||
| 233 | return getParent()->getParamNoFPClass(getArgNo()); | |||
| 234 | } | |||
| 235 | ||||
| 236 | bool Argument::hasNestAttr() const { | |||
| 237 | if (!getType()->isPointerTy()) return false; | |||
| 238 | return hasAttribute(Attribute::Nest); | |||
| 239 | } | |||
| 240 | ||||
| 241 | bool Argument::hasNoAliasAttr() const { | |||
| 242 | if (!getType()->isPointerTy()) return false; | |||
| 243 | return hasAttribute(Attribute::NoAlias); | |||
| 244 | } | |||
| 245 | ||||
| 246 | bool Argument::hasNoCaptureAttr() const { | |||
| 247 | if (!getType()->isPointerTy()) return false; | |||
| 248 | return hasAttribute(Attribute::NoCapture); | |||
| 249 | } | |||
| 250 | ||||
| 251 | bool Argument::hasNoFreeAttr() const { | |||
| 252 | if (!getType()->isPointerTy()) return false; | |||
| 253 | return hasAttribute(Attribute::NoFree); | |||
| 254 | } | |||
| 255 | ||||
| 256 | bool Argument::hasStructRetAttr() const { | |||
| 257 | if (!getType()->isPointerTy()) return false; | |||
| 258 | return hasAttribute(Attribute::StructRet); | |||
| 259 | } | |||
| 260 | ||||
| 261 | bool Argument::hasInRegAttr() const { | |||
| 262 | return hasAttribute(Attribute::InReg); | |||
| 263 | } | |||
| 264 | ||||
| 265 | bool Argument::hasReturnedAttr() const { | |||
| 266 | return hasAttribute(Attribute::Returned); | |||
| 267 | } | |||
| 268 | ||||
| 269 | bool Argument::hasZExtAttr() const { | |||
| 270 | return hasAttribute(Attribute::ZExt); | |||
| 271 | } | |||
| 272 | ||||
| 273 | bool Argument::hasSExtAttr() const { | |||
| 274 | return hasAttribute(Attribute::SExt); | |||
| 275 | } | |||
| 276 | ||||
| 277 | bool Argument::onlyReadsMemory() const { | |||
| 278 | AttributeList Attrs = getParent()->getAttributes(); | |||
| 279 | return Attrs.hasParamAttr(getArgNo(), Attribute::ReadOnly) || | |||
| 280 | Attrs.hasParamAttr(getArgNo(), Attribute::ReadNone); | |||
| 281 | } | |||
| 282 | ||||
| 283 | void Argument::addAttrs(AttrBuilder &B) { | |||
| 284 | AttributeList AL = getParent()->getAttributes(); | |||
| 285 | AL = AL.addParamAttributes(Parent->getContext(), getArgNo(), B); | |||
| 286 | getParent()->setAttributes(AL); | |||
| 287 | } | |||
| 288 | ||||
| 289 | void Argument::addAttr(Attribute::AttrKind Kind) { | |||
| 290 | getParent()->addParamAttr(getArgNo(), Kind); | |||
| 291 | } | |||
| 292 | ||||
| 293 | void Argument::addAttr(Attribute Attr) { | |||
| 294 | getParent()->addParamAttr(getArgNo(), Attr); | |||
| 295 | } | |||
| 296 | ||||
| 297 | void Argument::removeAttr(Attribute::AttrKind Kind) { | |||
| 298 | getParent()->removeParamAttr(getArgNo(), Kind); | |||
| 299 | } | |||
| 300 | ||||
| 301 | void Argument::removeAttrs(const AttributeMask &AM) { | |||
| 302 | AttributeList AL = getParent()->getAttributes(); | |||
| 303 | AL = AL.removeParamAttributes(Parent->getContext(), getArgNo(), AM); | |||
| 304 | getParent()->setAttributes(AL); | |||
| 305 | } | |||
| 306 | ||||
| 307 | bool Argument::hasAttribute(Attribute::AttrKind Kind) const { | |||
| 308 | return getParent()->hasParamAttribute(getArgNo(), Kind); | |||
| 309 | } | |||
| 310 | ||||
| 311 | Attribute Argument::getAttribute(Attribute::AttrKind Kind) const { | |||
| 312 | return getParent()->getParamAttribute(getArgNo(), Kind); | |||
| 313 | } | |||
| 314 | ||||
| 315 | //===----------------------------------------------------------------------===// | |||
| 316 | // Helper Methods in Function | |||
| 317 | //===----------------------------------------------------------------------===// | |||
| 318 | ||||
| 319 | LLVMContext &Function::getContext() const { | |||
| 320 | return getType()->getContext(); | |||
| 321 | } | |||
| 322 | ||||
| 323 | unsigned Function::getInstructionCount() const { | |||
| 324 | unsigned NumInstrs = 0; | |||
| 325 | for (const BasicBlock &BB : BasicBlocks) | |||
| 326 | NumInstrs += std::distance(BB.instructionsWithoutDebug().begin(), | |||
| 327 | BB.instructionsWithoutDebug().end()); | |||
| 328 | return NumInstrs; | |||
| 329 | } | |||
| 330 | ||||
| 331 | Function *Function::Create(FunctionType *Ty, LinkageTypes Linkage, | |||
| 332 | const Twine &N, Module &M) { | |||
| 333 | return Create(Ty, Linkage, M.getDataLayout().getProgramAddressSpace(), N, &M); | |||
| 334 | } | |||
| 335 | ||||
| 336 | Function *Function::createWithDefaultAttr(FunctionType *Ty, | |||
| 337 | LinkageTypes Linkage, | |||
| 338 | unsigned AddrSpace, const Twine &N, | |||
| 339 | Module *M) { | |||
| 340 | auto *F = new Function(Ty, Linkage, AddrSpace, N, M); | |||
| ||||
| 341 | AttrBuilder B(F->getContext()); | |||
| 342 | UWTableKind UWTable = M->getUwtable(); | |||
| 343 | if (UWTable != UWTableKind::None) | |||
| 344 | B.addUWTableAttr(UWTable); | |||
| 345 | switch (M->getFramePointer()) { | |||
| 346 | case FramePointerKind::None: | |||
| 347 | // 0 ("none") is the default. | |||
| 348 | break; | |||
| 349 | case FramePointerKind::NonLeaf: | |||
| 350 | B.addAttribute("frame-pointer", "non-leaf"); | |||
| 351 | break; | |||
| 352 | case FramePointerKind::All: | |||
| 353 | B.addAttribute("frame-pointer", "all"); | |||
| 354 | break; | |||
| 355 | } | |||
| 356 | if (M->getModuleFlag("function_return_thunk_extern")) | |||
| 357 | B.addAttribute(Attribute::FnRetThunkExtern); | |||
| 358 | F->addFnAttrs(B); | |||
| 359 | return F; | |||
| 360 | } | |||
| 361 | ||||
| 362 | void Function::removeFromParent() { | |||
| 363 | getParent()->getFunctionList().remove(getIterator()); | |||
| 364 | } | |||
| 365 | ||||
| 366 | void Function::eraseFromParent() { | |||
| 367 | getParent()->getFunctionList().erase(getIterator()); | |||
| 368 | } | |||
| 369 | ||||
| 370 | void Function::splice(Function::iterator ToIt, Function *FromF, | |||
| 371 | Function::iterator FromBeginIt, | |||
| 372 | Function::iterator FromEndIt) { | |||
| 373 | #ifdef EXPENSIVE_CHECKS | |||
| 374 | // Check that FromBeginIt is before FromEndIt. | |||
| 375 | auto FromFEnd = FromF->end(); | |||
| 376 | for (auto It = FromBeginIt; It != FromEndIt; ++It) | |||
| 377 | assert(It != FromFEnd && "FromBeginIt not before FromEndIt!")(static_cast <bool> (It != FromFEnd && "FromBeginIt not before FromEndIt!" ) ? void (0) : __assert_fail ("It != FromFEnd && \"FromBeginIt not before FromEndIt!\"" , "llvm/lib/IR/Function.cpp", 377, __extension__ __PRETTY_FUNCTION__ )); | |||
| 378 | #endif // EXPENSIVE_CHECKS | |||
| 379 | BasicBlocks.splice(ToIt, FromF->BasicBlocks, FromBeginIt, FromEndIt); | |||
| 380 | } | |||
| 381 | ||||
| 382 | Function::iterator Function::erase(Function::iterator FromIt, | |||
| 383 | Function::iterator ToIt) { | |||
| 384 | return BasicBlocks.erase(FromIt, ToIt); | |||
| 385 | } | |||
| 386 | ||||
| 387 | //===----------------------------------------------------------------------===// | |||
| 388 | // Function Implementation | |||
| 389 | //===----------------------------------------------------------------------===// | |||
| 390 | ||||
| 391 | static unsigned computeAddrSpace(unsigned AddrSpace, Module *M) { | |||
| 392 | // If AS == -1 and we are passed a valid module pointer we place the function | |||
| 393 | // in the program address space. Otherwise we default to AS0. | |||
| 394 | if (AddrSpace == static_cast<unsigned>(-1)) | |||
| 395 | return M ? M->getDataLayout().getProgramAddressSpace() : 0; | |||
| 396 | return AddrSpace; | |||
| 397 | } | |||
| 398 | ||||
| 399 | Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, | |||
| 400 | const Twine &name, Module *ParentModule) | |||
| 401 | : GlobalObject(Ty, Value::FunctionVal, | |||
| 402 | OperandTraits<Function>::op_begin(this), 0, Linkage, name, | |||
| 403 | computeAddrSpace(AddrSpace, ParentModule)), | |||
| 404 | NumArgs(Ty->getNumParams()) { | |||
| 405 | assert(FunctionType::isValidReturnType(getReturnType()) &&(static_cast <bool> (FunctionType::isValidReturnType(getReturnType ()) && "invalid return type") ? void (0) : __assert_fail ("FunctionType::isValidReturnType(getReturnType()) && \"invalid return type\"" , "llvm/lib/IR/Function.cpp", 406, __extension__ __PRETTY_FUNCTION__ )) | |||
| 406 | "invalid return type")(static_cast <bool> (FunctionType::isValidReturnType(getReturnType ()) && "invalid return type") ? void (0) : __assert_fail ("FunctionType::isValidReturnType(getReturnType()) && \"invalid return type\"" , "llvm/lib/IR/Function.cpp", 406, __extension__ __PRETTY_FUNCTION__ )); | |||
| 407 | setGlobalObjectSubClassData(0); | |||
| 408 | ||||
| 409 | // We only need a symbol table for a function if the context keeps value names | |||
| 410 | if (!getContext().shouldDiscardValueNames()) | |||
| 411 | SymTab = std::make_unique<ValueSymbolTable>(NonGlobalValueMaxNameSize); | |||
| 412 | ||||
| 413 | // If the function has arguments, mark them as lazily built. | |||
| 414 | if (Ty->getNumParams()) | |||
| 415 | setValueSubclassData(1); // Set the "has lazy arguments" bit. | |||
| 416 | ||||
| 417 | if (ParentModule) | |||
| 418 | ParentModule->getFunctionList().push_back(this); | |||
| 419 | ||||
| 420 | HasLLVMReservedName = getName().startswith("llvm."); | |||
| 421 | // Ensure intrinsics have the right parameter attributes. | |||
| 422 | // Note, the IntID field will have been set in Value::setName if this function | |||
| 423 | // name is a valid intrinsic ID. | |||
| 424 | if (IntID) | |||
| 425 | setAttributes(Intrinsic::getAttributes(getContext(), IntID)); | |||
| 426 | } | |||
| 427 | ||||
| 428 | Function::~Function() { | |||
| 429 | dropAllReferences(); // After this it is safe to delete instructions. | |||
| 430 | ||||
| 431 | // Delete all of the method arguments and unlink from symbol table... | |||
| 432 | if (Arguments) | |||
| 433 | clearArguments(); | |||
| 434 | ||||
| 435 | // Remove the function from the on-the-side GC table. | |||
| 436 | clearGC(); | |||
| 437 | } | |||
| 438 | ||||
| 439 | void Function::BuildLazyArguments() const { | |||
| 440 | // Create the arguments vector, all arguments start out unnamed. | |||
| 441 | auto *FT = getFunctionType(); | |||
| 442 | if (NumArgs > 0) { | |||
| 443 | Arguments = std::allocator<Argument>().allocate(NumArgs); | |||
| 444 | for (unsigned i = 0, e = NumArgs; i != e; ++i) { | |||
| 445 | Type *ArgTy = FT->getParamType(i); | |||
| 446 | assert(!ArgTy->isVoidTy() && "Cannot have void typed arguments!")(static_cast <bool> (!ArgTy->isVoidTy() && "Cannot have void typed arguments!" ) ? void (0) : __assert_fail ("!ArgTy->isVoidTy() && \"Cannot have void typed arguments!\"" , "llvm/lib/IR/Function.cpp", 446, __extension__ __PRETTY_FUNCTION__ )); | |||
| 447 | new (Arguments + i) Argument(ArgTy, "", const_cast<Function *>(this), i); | |||
| 448 | } | |||
| 449 | } | |||
| 450 | ||||
| 451 | // Clear the lazy arguments bit. | |||
| 452 | unsigned SDC = getSubclassDataFromValue(); | |||
| 453 | SDC &= ~(1 << 0); | |||
| 454 | const_cast<Function*>(this)->setValueSubclassData(SDC); | |||
| 455 | assert(!hasLazyArguments())(static_cast <bool> (!hasLazyArguments()) ? void (0) : __assert_fail ("!hasLazyArguments()", "llvm/lib/IR/Function.cpp", 455, __extension__ __PRETTY_FUNCTION__)); | |||
| 456 | } | |||
| 457 | ||||
| 458 | static MutableArrayRef<Argument> makeArgArray(Argument *Args, size_t Count) { | |||
| 459 | return MutableArrayRef<Argument>(Args, Count); | |||
| 460 | } | |||
| 461 | ||||
| 462 | bool Function::isConstrainedFPIntrinsic() const { | |||
| 463 | switch (getIntrinsicID()) { | |||
| 464 | #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \ | |||
| 465 | case Intrinsic::INTRINSIC: | |||
| 466 | #include "llvm/IR/ConstrainedOps.def" | |||
| 467 | return true; | |||
| 468 | #undef INSTRUCTION | |||
| 469 | default: | |||
| 470 | return false; | |||
| 471 | } | |||
| 472 | } | |||
| 473 | ||||
| 474 | void Function::clearArguments() { | |||
| 475 | for (Argument &A : makeArgArray(Arguments, NumArgs)) { | |||
| 476 | A.setName(""); | |||
| 477 | A.~Argument(); | |||
| 478 | } | |||
| 479 | std::allocator<Argument>().deallocate(Arguments, NumArgs); | |||
| 480 | Arguments = nullptr; | |||
| 481 | } | |||
| 482 | ||||
| 483 | void Function::stealArgumentListFrom(Function &Src) { | |||
| 484 | assert(isDeclaration() && "Expected no references to current arguments")(static_cast <bool> (isDeclaration() && "Expected no references to current arguments" ) ? void (0) : __assert_fail ("isDeclaration() && \"Expected no references to current arguments\"" , "llvm/lib/IR/Function.cpp", 484, __extension__ __PRETTY_FUNCTION__ )); | |||
| 485 | ||||
| 486 | // Drop the current arguments, if any, and set the lazy argument bit. | |||
| 487 | if (!hasLazyArguments()) { | |||
| 488 | assert(llvm::all_of(makeArgArray(Arguments, NumArgs),(static_cast <bool> (llvm::all_of(makeArgArray(Arguments , NumArgs), [](const Argument &A) { return A.use_empty(); }) && "Expected arguments to be unused in declaration" ) ? void (0) : __assert_fail ("llvm::all_of(makeArgArray(Arguments, NumArgs), [](const Argument &A) { return A.use_empty(); }) && \"Expected arguments to be unused in declaration\"" , "llvm/lib/IR/Function.cpp", 490, __extension__ __PRETTY_FUNCTION__ )) | |||
| 489 | [](const Argument &A) { return A.use_empty(); }) &&(static_cast <bool> (llvm::all_of(makeArgArray(Arguments , NumArgs), [](const Argument &A) { return A.use_empty(); }) && "Expected arguments to be unused in declaration" ) ? void (0) : __assert_fail ("llvm::all_of(makeArgArray(Arguments, NumArgs), [](const Argument &A) { return A.use_empty(); }) && \"Expected arguments to be unused in declaration\"" , "llvm/lib/IR/Function.cpp", 490, __extension__ __PRETTY_FUNCTION__ )) | |||
| 490 | "Expected arguments to be unused in declaration")(static_cast <bool> (llvm::all_of(makeArgArray(Arguments , NumArgs), [](const Argument &A) { return A.use_empty(); }) && "Expected arguments to be unused in declaration" ) ? void (0) : __assert_fail ("llvm::all_of(makeArgArray(Arguments, NumArgs), [](const Argument &A) { return A.use_empty(); }) && \"Expected arguments to be unused in declaration\"" , "llvm/lib/IR/Function.cpp", 490, __extension__ __PRETTY_FUNCTION__ )); | |||
| 491 | clearArguments(); | |||
| 492 | setValueSubclassData(getSubclassDataFromValue() | (1 << 0)); | |||
| 493 | } | |||
| 494 | ||||
| 495 | // Nothing to steal if Src has lazy arguments. | |||
| 496 | if (Src.hasLazyArguments()) | |||
| 497 | return; | |||
| 498 | ||||
| 499 | // Steal arguments from Src, and fix the lazy argument bits. | |||
| 500 | assert(arg_size() == Src.arg_size())(static_cast <bool> (arg_size() == Src.arg_size()) ? void (0) : __assert_fail ("arg_size() == Src.arg_size()", "llvm/lib/IR/Function.cpp" , 500, __extension__ __PRETTY_FUNCTION__)); | |||
| 501 | Arguments = Src.Arguments; | |||
| 502 | Src.Arguments = nullptr; | |||
| 503 | for (Argument &A : makeArgArray(Arguments, NumArgs)) { | |||
| 504 | // FIXME: This does the work of transferNodesFromList inefficiently. | |||
| 505 | SmallString<128> Name; | |||
| 506 | if (A.hasName()) | |||
| 507 | Name = A.getName(); | |||
| 508 | if (!Name.empty()) | |||
| 509 | A.setName(""); | |||
| 510 | A.setParent(this); | |||
| 511 | if (!Name.empty()) | |||
| 512 | A.setName(Name); | |||
| 513 | } | |||
| 514 | ||||
| 515 | setValueSubclassData(getSubclassDataFromValue() & ~(1 << 0)); | |||
| 516 | assert(!hasLazyArguments())(static_cast <bool> (!hasLazyArguments()) ? void (0) : __assert_fail ("!hasLazyArguments()", "llvm/lib/IR/Function.cpp", 516, __extension__ __PRETTY_FUNCTION__)); | |||
| 517 | Src.setValueSubclassData(Src.getSubclassDataFromValue() | (1 << 0)); | |||
| 518 | } | |||
| 519 | ||||
| 520 | // dropAllReferences() - This function causes all the subinstructions to "let | |||
| 521 | // go" of all references that they are maintaining. This allows one to | |||
| 522 | // 'delete' a whole class at a time, even though there may be circular | |||
| 523 | // references... first all references are dropped, and all use counts go to | |||
| 524 | // zero. Then everything is deleted for real. Note that no operations are | |||
| 525 | // valid on an object that has "dropped all references", except operator | |||
| 526 | // delete. | |||
| 527 | // | |||
| 528 | void Function::dropAllReferences() { | |||
| 529 | setIsMaterializable(false); | |||
| 530 | ||||
| 531 | for (BasicBlock &BB : *this) | |||
| 532 | BB.dropAllReferences(); | |||
| 533 | ||||
| 534 | // Delete all basic blocks. They are now unused, except possibly by | |||
| 535 | // blockaddresses, but BasicBlock's destructor takes care of those. | |||
| 536 | while (!BasicBlocks.empty()) | |||
| 537 | BasicBlocks.begin()->eraseFromParent(); | |||
| 538 | ||||
| 539 | // Drop uses of any optional data (real or placeholder). | |||
| 540 | if (getNumOperands()) { | |||
| 541 | User::dropAllReferences(); | |||
| 542 | setNumHungOffUseOperands(0); | |||
| 543 | setValueSubclassData(getSubclassDataFromValue() & ~0xe); | |||
| 544 | } | |||
| 545 | ||||
| 546 | // Metadata is stored in a side-table. | |||
| 547 | clearMetadata(); | |||
| 548 | } | |||
| 549 | ||||
| 550 | void Function::addAttributeAtIndex(unsigned i, Attribute Attr) { | |||
| 551 | AttributeSets = AttributeSets.addAttributeAtIndex(getContext(), i, Attr); | |||
| 552 | } | |||
| 553 | ||||
| 554 | void Function::addFnAttr(Attribute::AttrKind Kind) { | |||
| 555 | AttributeSets = AttributeSets.addFnAttribute(getContext(), Kind); | |||
| 556 | } | |||
| 557 | ||||
| 558 | void Function::addFnAttr(StringRef Kind, StringRef Val) { | |||
| 559 | AttributeSets = AttributeSets.addFnAttribute(getContext(), Kind, Val); | |||
| 560 | } | |||
| 561 | ||||
| 562 | void Function::addFnAttr(Attribute Attr) { | |||
| 563 | AttributeSets = AttributeSets.addFnAttribute(getContext(), Attr); | |||
| 564 | } | |||
| 565 | ||||
| 566 | void Function::addFnAttrs(const AttrBuilder &Attrs) { | |||
| 567 | AttributeSets = AttributeSets.addFnAttributes(getContext(), Attrs); | |||
| 568 | } | |||
| 569 | ||||
| 570 | void Function::addRetAttr(Attribute::AttrKind Kind) { | |||
| 571 | AttributeSets = AttributeSets.addRetAttribute(getContext(), Kind); | |||
| 572 | } | |||
| 573 | ||||
| 574 | void Function::addRetAttr(Attribute Attr) { | |||
| 575 | AttributeSets = AttributeSets.addRetAttribute(getContext(), Attr); | |||
| 576 | } | |||
| 577 | ||||
| 578 | void Function::addRetAttrs(const AttrBuilder &Attrs) { | |||
| 579 | AttributeSets = AttributeSets.addRetAttributes(getContext(), Attrs); | |||
| 580 | } | |||
| 581 | ||||
| 582 | void Function::addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) { | |||
| 583 | AttributeSets = AttributeSets.addParamAttribute(getContext(), ArgNo, Kind); | |||
| 584 | } | |||
| 585 | ||||
| 586 | void Function::addParamAttr(unsigned ArgNo, Attribute Attr) { | |||
| 587 | AttributeSets = AttributeSets.addParamAttribute(getContext(), ArgNo, Attr); | |||
| 588 | } | |||
| 589 | ||||
| 590 | void Function::addParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) { | |||
| 591 | AttributeSets = AttributeSets.addParamAttributes(getContext(), ArgNo, Attrs); | |||
| 592 | } | |||
| 593 | ||||
| 594 | void Function::removeAttributeAtIndex(unsigned i, Attribute::AttrKind Kind) { | |||
| 595 | AttributeSets = AttributeSets.removeAttributeAtIndex(getContext(), i, Kind); | |||
| 596 | } | |||
| 597 | ||||
| 598 | void Function::removeAttributeAtIndex(unsigned i, StringRef Kind) { | |||
| 599 | AttributeSets = AttributeSets.removeAttributeAtIndex(getContext(), i, Kind); | |||
| 600 | } | |||
| 601 | ||||
| 602 | void Function::removeFnAttr(Attribute::AttrKind Kind) { | |||
| 603 | AttributeSets = AttributeSets.removeFnAttribute(getContext(), Kind); | |||
| 604 | } | |||
| 605 | ||||
| 606 | void Function::removeFnAttr(StringRef Kind) { | |||
| 607 | AttributeSets = AttributeSets.removeFnAttribute(getContext(), Kind); | |||
| 608 | } | |||
| 609 | ||||
| 610 | void Function::removeFnAttrs(const AttributeMask &AM) { | |||
| 611 | AttributeSets = AttributeSets.removeFnAttributes(getContext(), AM); | |||
| 612 | } | |||
| 613 | ||||
| 614 | void Function::removeRetAttr(Attribute::AttrKind Kind) { | |||
| 615 | AttributeSets = AttributeSets.removeRetAttribute(getContext(), Kind); | |||
| 616 | } | |||
| 617 | ||||
| 618 | void Function::removeRetAttr(StringRef Kind) { | |||
| 619 | AttributeSets = AttributeSets.removeRetAttribute(getContext(), Kind); | |||
| 620 | } | |||
| 621 | ||||
| 622 | void Function::removeRetAttrs(const AttributeMask &Attrs) { | |||
| 623 | AttributeSets = AttributeSets.removeRetAttributes(getContext(), Attrs); | |||
| 624 | } | |||
| 625 | ||||
| 626 | void Function::removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) { | |||
| 627 | AttributeSets = AttributeSets.removeParamAttribute(getContext(), ArgNo, Kind); | |||
| 628 | } | |||
| 629 | ||||
| 630 | void Function::removeParamAttr(unsigned ArgNo, StringRef Kind) { | |||
| 631 | AttributeSets = AttributeSets.removeParamAttribute(getContext(), ArgNo, Kind); | |||
| 632 | } | |||
| 633 | ||||
| 634 | void Function::removeParamAttrs(unsigned ArgNo, const AttributeMask &Attrs) { | |||
| 635 | AttributeSets = | |||
| 636 | AttributeSets.removeParamAttributes(getContext(), ArgNo, Attrs); | |||
| 637 | } | |||
| 638 | ||||
| 639 | void Function::addDereferenceableParamAttr(unsigned ArgNo, uint64_t Bytes) { | |||
| 640 | AttributeSets = | |||
| 641 | AttributeSets.addDereferenceableParamAttr(getContext(), ArgNo, Bytes); | |||
| 642 | } | |||
| 643 | ||||
| 644 | bool Function::hasFnAttribute(Attribute::AttrKind Kind) const { | |||
| 645 | return AttributeSets.hasFnAttr(Kind); | |||
| 646 | } | |||
| 647 | ||||
| 648 | bool Function::hasFnAttribute(StringRef Kind) const { | |||
| 649 | return AttributeSets.hasFnAttr(Kind); | |||
| 650 | } | |||
| 651 | ||||
| 652 | bool Function::hasRetAttribute(Attribute::AttrKind Kind) const { | |||
| 653 | return AttributeSets.hasRetAttr(Kind); | |||
| 654 | } | |||
| 655 | ||||
| 656 | bool Function::hasParamAttribute(unsigned ArgNo, | |||
| 657 | Attribute::AttrKind Kind) const { | |||
| 658 | return AttributeSets.hasParamAttr(ArgNo, Kind); | |||
| 659 | } | |||
| 660 | ||||
| 661 | Attribute Function::getAttributeAtIndex(unsigned i, | |||
| 662 | Attribute::AttrKind Kind) const { | |||
| 663 | return AttributeSets.getAttributeAtIndex(i, Kind); | |||
| 664 | } | |||
| 665 | ||||
| 666 | Attribute Function::getAttributeAtIndex(unsigned i, StringRef Kind) const { | |||
| 667 | return AttributeSets.getAttributeAtIndex(i, Kind); | |||
| 668 | } | |||
| 669 | ||||
| 670 | Attribute Function::getFnAttribute(Attribute::AttrKind Kind) const { | |||
| 671 | return AttributeSets.getFnAttr(Kind); | |||
| 672 | } | |||
| 673 | ||||
| 674 | Attribute Function::getFnAttribute(StringRef Kind) const { | |||
| 675 | return AttributeSets.getFnAttr(Kind); | |||
| 676 | } | |||
| 677 | ||||
| 678 | uint64_t Function::getFnAttributeAsParsedInteger(StringRef Name, | |||
| 679 | uint64_t Default) const { | |||
| 680 | Attribute A = getFnAttribute(Name); | |||
| 681 | uint64_t Result = Default; | |||
| 682 | if (A.isStringAttribute()) { | |||
| 683 | StringRef Str = A.getValueAsString(); | |||
| 684 | if (Str.getAsInteger(0, Result)) | |||
| 685 | getContext().emitError("cannot parse integer attribute " + Name); | |||
| 686 | } | |||
| 687 | ||||
| 688 | return Result; | |||
| 689 | } | |||
| 690 | ||||
| 691 | /// gets the specified attribute from the list of attributes. | |||
| 692 | Attribute Function::getParamAttribute(unsigned ArgNo, | |||
| 693 | Attribute::AttrKind Kind) const { | |||
| 694 | return AttributeSets.getParamAttr(ArgNo, Kind); | |||
| 695 | } | |||
| 696 | ||||
| 697 | void Function::addDereferenceableOrNullParamAttr(unsigned ArgNo, | |||
| 698 | uint64_t Bytes) { | |||
| 699 | AttributeSets = AttributeSets.addDereferenceableOrNullParamAttr(getContext(), | |||
| 700 | ArgNo, Bytes); | |||
| 701 | } | |||
| 702 | ||||
| 703 | DenormalMode Function::getDenormalMode(const fltSemantics &FPType) const { | |||
| 704 | if (&FPType == &APFloat::IEEEsingle()) { | |||
| 705 | DenormalMode Mode = getDenormalModeF32Raw(); | |||
| 706 | // If the f32 variant of the attribute isn't specified, try to use the | |||
| 707 | // generic one. | |||
| 708 | if (Mode.isValid()) | |||
| 709 | return Mode; | |||
| 710 | } | |||
| 711 | ||||
| 712 | return getDenormalModeRaw(); | |||
| 713 | } | |||
| 714 | ||||
| 715 | DenormalMode Function::getDenormalModeRaw() const { | |||
| 716 | Attribute Attr = getFnAttribute("denormal-fp-math"); | |||
| 717 | StringRef Val = Attr.getValueAsString(); | |||
| 718 | return parseDenormalFPAttribute(Val); | |||
| 719 | } | |||
| 720 | ||||
| 721 | DenormalMode Function::getDenormalModeF32Raw() const { | |||
| 722 | Attribute Attr = getFnAttribute("denormal-fp-math-f32"); | |||
| 723 | if (Attr.isValid()) { | |||
| 724 | StringRef Val = Attr.getValueAsString(); | |||
| 725 | return parseDenormalFPAttribute(Val); | |||
| 726 | } | |||
| 727 | ||||
| 728 | return DenormalMode::getInvalid(); | |||
| 729 | } | |||
| 730 | ||||
| 731 | const std::string &Function::getGC() const { | |||
| 732 | assert(hasGC() && "Function has no collector")(static_cast <bool> (hasGC() && "Function has no collector" ) ? void (0) : __assert_fail ("hasGC() && \"Function has no collector\"" , "llvm/lib/IR/Function.cpp", 732, __extension__ __PRETTY_FUNCTION__ )); | |||
| 733 | return getContext().getGC(*this); | |||
| 734 | } | |||
| 735 | ||||
| 736 | void Function::setGC(std::string Str) { | |||
| 737 | setValueSubclassDataBit(14, !Str.empty()); | |||
| 738 | getContext().setGC(*this, std::move(Str)); | |||
| 739 | } | |||
| 740 | ||||
| 741 | void Function::clearGC() { | |||
| 742 | if (!hasGC()) | |||
| 743 | return; | |||
| 744 | getContext().deleteGC(*this); | |||
| 745 | setValueSubclassDataBit(14, false); | |||
| 746 | } | |||
| 747 | ||||
| 748 | bool Function::hasStackProtectorFnAttr() const { | |||
| 749 | return hasFnAttribute(Attribute::StackProtect) || | |||
| 750 | hasFnAttribute(Attribute::StackProtectStrong) || | |||
| 751 | hasFnAttribute(Attribute::StackProtectReq); | |||
| 752 | } | |||
| 753 | ||||
| 754 | /// Copy all additional attributes (those not needed to create a Function) from | |||
| 755 | /// the Function Src to this one. | |||
| 756 | void Function::copyAttributesFrom(const Function *Src) { | |||
| 757 | GlobalObject::copyAttributesFrom(Src); | |||
| 758 | setCallingConv(Src->getCallingConv()); | |||
| 759 | setAttributes(Src->getAttributes()); | |||
| 760 | if (Src->hasGC()) | |||
| 761 | setGC(Src->getGC()); | |||
| 762 | else | |||
| 763 | clearGC(); | |||
| 764 | if (Src->hasPersonalityFn()) | |||
| 765 | setPersonalityFn(Src->getPersonalityFn()); | |||
| 766 | if (Src->hasPrefixData()) | |||
| 767 | setPrefixData(Src->getPrefixData()); | |||
| 768 | if (Src->hasPrologueData()) | |||
| 769 | setPrologueData(Src->getPrologueData()); | |||
| 770 | } | |||
| 771 | ||||
| 772 | MemoryEffects Function::getMemoryEffects() const { | |||
| 773 | return getAttributes().getMemoryEffects(); | |||
| 774 | } | |||
| 775 | void Function::setMemoryEffects(MemoryEffects ME) { | |||
| 776 | addFnAttr(Attribute::getWithMemoryEffects(getContext(), ME)); | |||
| 777 | } | |||
| 778 | ||||
| 779 | /// Determine if the function does not access memory. | |||
| 780 | bool Function::doesNotAccessMemory() const { | |||
| 781 | return getMemoryEffects().doesNotAccessMemory(); | |||
| 782 | } | |||
| 783 | void Function::setDoesNotAccessMemory() { | |||
| 784 | setMemoryEffects(MemoryEffects::none()); | |||
| 785 | } | |||
| 786 | ||||
| 787 | /// Determine if the function does not access or only reads memory. | |||
| 788 | bool Function::onlyReadsMemory() const { | |||
| 789 | return getMemoryEffects().onlyReadsMemory(); | |||
| 790 | } | |||
| 791 | void Function::setOnlyReadsMemory() { | |||
| 792 | setMemoryEffects(getMemoryEffects() & MemoryEffects::readOnly()); | |||
| 793 | } | |||
| 794 | ||||
| 795 | /// Determine if the function does not access or only writes memory. | |||
| 796 | bool Function::onlyWritesMemory() const { | |||
| 797 | return getMemoryEffects().onlyWritesMemory(); | |||
| 798 | } | |||
| 799 | void Function::setOnlyWritesMemory() { | |||
| 800 | setMemoryEffects(getMemoryEffects() & MemoryEffects::writeOnly()); | |||
| 801 | } | |||
| 802 | ||||
| 803 | /// Determine if the call can access memmory only using pointers based | |||
| 804 | /// on its arguments. | |||
| 805 | bool Function::onlyAccessesArgMemory() const { | |||
| 806 | return getMemoryEffects().onlyAccessesArgPointees(); | |||
| 807 | } | |||
| 808 | void Function::setOnlyAccessesArgMemory() { | |||
| 809 | setMemoryEffects(getMemoryEffects() & MemoryEffects::argMemOnly()); | |||
| 810 | } | |||
| 811 | ||||
| 812 | /// Determine if the function may only access memory that is | |||
| 813 | /// inaccessible from the IR. | |||
| 814 | bool Function::onlyAccessesInaccessibleMemory() const { | |||
| 815 | return getMemoryEffects().onlyAccessesInaccessibleMem(); | |||
| 816 | } | |||
| 817 | void Function::setOnlyAccessesInaccessibleMemory() { | |||
| 818 | setMemoryEffects(getMemoryEffects() & MemoryEffects::inaccessibleMemOnly()); | |||
| 819 | } | |||
| 820 | ||||
| 821 | /// Determine if the function may only access memory that is | |||
| 822 | /// either inaccessible from the IR or pointed to by its arguments. | |||
| 823 | bool Function::onlyAccessesInaccessibleMemOrArgMem() const { | |||
| 824 | return getMemoryEffects().onlyAccessesInaccessibleOrArgMem(); | |||
| 825 | } | |||
| 826 | void Function::setOnlyAccessesInaccessibleMemOrArgMem() { | |||
| 827 | setMemoryEffects(getMemoryEffects() & | |||
| 828 | MemoryEffects::inaccessibleOrArgMemOnly()); | |||
| 829 | } | |||
| 830 | ||||
| 831 | /// Table of string intrinsic names indexed by enum value. | |||
| 832 | static const char * const IntrinsicNameTable[] = { | |||
| 833 | "not_intrinsic", | |||
| 834 | #define GET_INTRINSIC_NAME_TABLE | |||
| 835 | #include "llvm/IR/IntrinsicImpl.inc" | |||
| 836 | #undef GET_INTRINSIC_NAME_TABLE | |||
| 837 | }; | |||
| 838 | ||||
| 839 | /// Table of per-target intrinsic name tables. | |||
| 840 | #define GET_INTRINSIC_TARGET_DATA | |||
| 841 | #include "llvm/IR/IntrinsicImpl.inc" | |||
| 842 | #undef GET_INTRINSIC_TARGET_DATA | |||
| 843 | ||||
| 844 | bool Function::isTargetIntrinsic(Intrinsic::ID IID) { | |||
| 845 | return IID > TargetInfos[0].Count; | |||
| 846 | } | |||
| 847 | ||||
| 848 | bool Function::isTargetIntrinsic() const { | |||
| 849 | return isTargetIntrinsic(IntID); | |||
| 850 | } | |||
| 851 | ||||
| 852 | /// Find the segment of \c IntrinsicNameTable for intrinsics with the same | |||
| 853 | /// target as \c Name, or the generic table if \c Name is not target specific. | |||
| 854 | /// | |||
| 855 | /// Returns the relevant slice of \c IntrinsicNameTable | |||
| 856 | static ArrayRef<const char *> findTargetSubtable(StringRef Name) { | |||
| 857 | assert(Name.startswith("llvm."))(static_cast <bool> (Name.startswith("llvm.")) ? void ( 0) : __assert_fail ("Name.startswith(\"llvm.\")", "llvm/lib/IR/Function.cpp" , 857, __extension__ __PRETTY_FUNCTION__)); | |||
| 858 | ||||
| 859 | ArrayRef<IntrinsicTargetInfo> Targets(TargetInfos); | |||
| 860 | // Drop "llvm." and take the first dotted component. That will be the target | |||
| 861 | // if this is target specific. | |||
| 862 | StringRef Target = Name.drop_front(5).split('.').first; | |||
| 863 | auto It = partition_point( | |||
| 864 | Targets, [=](const IntrinsicTargetInfo &TI) { return TI.Name < Target; }); | |||
| 865 | // We've either found the target or just fall back to the generic set, which | |||
| 866 | // is always first. | |||
| 867 | const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0]; | |||
| 868 | return ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count); | |||
| 869 | } | |||
| 870 | ||||
| 871 | /// This does the actual lookup of an intrinsic ID which | |||
| 872 | /// matches the given function name. | |||
| 873 | Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) { | |||
| 874 | ArrayRef<const char *> NameTable = findTargetSubtable(Name); | |||
| 875 | int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name); | |||
| 876 | if (Idx == -1) | |||
| 877 | return Intrinsic::not_intrinsic; | |||
| 878 | ||||
| 879 | // Intrinsic IDs correspond to the location in IntrinsicNameTable, but we have | |||
| 880 | // an index into a sub-table. | |||
| 881 | int Adjust = NameTable.data() - IntrinsicNameTable; | |||
| 882 | Intrinsic::ID ID = static_cast<Intrinsic::ID>(Idx + Adjust); | |||
| 883 | ||||
| 884 | // If the intrinsic is not overloaded, require an exact match. If it is | |||
| 885 | // overloaded, require either exact or prefix match. | |||
| 886 | const auto MatchSize = strlen(NameTable[Idx]); | |||
| 887 | assert(Name.size() >= MatchSize && "Expected either exact or prefix match")(static_cast <bool> (Name.size() >= MatchSize && "Expected either exact or prefix match") ? void (0) : __assert_fail ("Name.size() >= MatchSize && \"Expected either exact or prefix match\"" , "llvm/lib/IR/Function.cpp", 887, __extension__ __PRETTY_FUNCTION__ )); | |||
| 888 | bool IsExactMatch = Name.size() == MatchSize; | |||
| 889 | return IsExactMatch || Intrinsic::isOverloaded(ID) ? ID | |||
| 890 | : Intrinsic::not_intrinsic; | |||
| 891 | } | |||
| 892 | ||||
| 893 | void Function::recalculateIntrinsicID() { | |||
| 894 | StringRef Name = getName(); | |||
| 895 | if (!Name.startswith("llvm.")) { | |||
| 896 | HasLLVMReservedName = false; | |||
| 897 | IntID = Intrinsic::not_intrinsic; | |||
| 898 | return; | |||
| 899 | } | |||
| 900 | HasLLVMReservedName = true; | |||
| 901 | IntID = lookupIntrinsicID(Name); | |||
| 902 | } | |||
| 903 | ||||
| 904 | /// Returns a stable mangling for the type specified for use in the name | |||
| 905 | /// mangling scheme used by 'any' types in intrinsic signatures. The mangling | |||
| 906 | /// of named types is simply their name. Manglings for unnamed types consist | |||
| 907 | /// of a prefix ('p' for pointers, 'a' for arrays, 'f_' for functions) | |||
| 908 | /// combined with the mangling of their component types. A vararg function | |||
| 909 | /// type will have a suffix of 'vararg'. Since function types can contain | |||
| 910 | /// other function types, we close a function type mangling with suffix 'f' | |||
| 911 | /// which can't be confused with it's prefix. This ensures we don't have | |||
| 912 | /// collisions between two unrelated function types. Otherwise, you might | |||
| 913 | /// parse ffXX as f(fXX) or f(fX)X. (X is a placeholder for any other type.) | |||
| 914 | /// The HasUnnamedType boolean is set if an unnamed type was encountered, | |||
| 915 | /// indicating that extra care must be taken to ensure a unique name. | |||
| 916 | static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType) { | |||
| 917 | std::string Result; | |||
| 918 | if (PointerType *PTyp = dyn_cast<PointerType>(Ty)) { | |||
| 919 | Result += "p" + utostr(PTyp->getAddressSpace()); | |||
| 920 | // Opaque pointer doesn't have pointee type information, so we just mangle | |||
| 921 | // address space for opaque pointer. | |||
| 922 | if (!PTyp->isOpaque()) | |||
| 923 | Result += getMangledTypeStr(PTyp->getNonOpaquePointerElementType(), | |||
| 924 | HasUnnamedType); | |||
| 925 | } else if (ArrayType *ATyp = dyn_cast<ArrayType>(Ty)) { | |||
| 926 | Result += "a" + utostr(ATyp->getNumElements()) + | |||
| 927 | getMangledTypeStr(ATyp->getElementType(), HasUnnamedType); | |||
| 928 | } else if (StructType *STyp = dyn_cast<StructType>(Ty)) { | |||
| 929 | if (!STyp->isLiteral()) { | |||
| 930 | Result += "s_"; | |||
| 931 | if (STyp->hasName()) | |||
| 932 | Result += STyp->getName(); | |||
| 933 | else | |||
| 934 | HasUnnamedType = true; | |||
| 935 | } else { | |||
| 936 | Result += "sl_"; | |||
| 937 | for (auto *Elem : STyp->elements()) | |||
| 938 | Result += getMangledTypeStr(Elem, HasUnnamedType); | |||
| 939 | } | |||
| 940 | // Ensure nested structs are distinguishable. | |||
| 941 | Result += "s"; | |||
| 942 | } else if (FunctionType *FT = dyn_cast<FunctionType>(Ty)) { | |||
| 943 | Result += "f_" + getMangledTypeStr(FT->getReturnType(), HasUnnamedType); | |||
| 944 | for (size_t i = 0; i < FT->getNumParams(); i++) | |||
| 945 | Result += getMangledTypeStr(FT->getParamType(i), HasUnnamedType); | |||
| 946 | if (FT->isVarArg()) | |||
| 947 | Result += "vararg"; | |||
| 948 | // Ensure nested function types are distinguishable. | |||
| 949 | Result += "f"; | |||
| 950 | } else if (VectorType *VTy = dyn_cast<VectorType>(Ty)) { | |||
| 951 | ElementCount EC = VTy->getElementCount(); | |||
| 952 | if (EC.isScalable()) | |||
| 953 | Result += "nx"; | |||
| 954 | Result += "v" + utostr(EC.getKnownMinValue()) + | |||
| 955 | getMangledTypeStr(VTy->getElementType(), HasUnnamedType); | |||
| 956 | } else if (TargetExtType *TETy = dyn_cast<TargetExtType>(Ty)) { | |||
| 957 | Result += "t"; | |||
| 958 | Result += TETy->getName(); | |||
| 959 | for (Type *ParamTy : TETy->type_params()) | |||
| 960 | Result += "_" + getMangledTypeStr(ParamTy, HasUnnamedType); | |||
| 961 | for (unsigned IntParam : TETy->int_params()) | |||
| 962 | Result += "_" + utostr(IntParam); | |||
| 963 | // Ensure nested target extension types are distinguishable. | |||
| 964 | Result += "t"; | |||
| 965 | } else if (Ty) { | |||
| 966 | switch (Ty->getTypeID()) { | |||
| 967 | default: llvm_unreachable("Unhandled type")::llvm::llvm_unreachable_internal("Unhandled type", "llvm/lib/IR/Function.cpp" , 967); | |||
| 968 | case Type::VoidTyID: Result += "isVoid"; break; | |||
| 969 | case Type::MetadataTyID: Result += "Metadata"; break; | |||
| 970 | case Type::HalfTyID: Result += "f16"; break; | |||
| 971 | case Type::BFloatTyID: Result += "bf16"; break; | |||
| 972 | case Type::FloatTyID: Result += "f32"; break; | |||
| 973 | case Type::DoubleTyID: Result += "f64"; break; | |||
| 974 | case Type::X86_FP80TyID: Result += "f80"; break; | |||
| 975 | case Type::FP128TyID: Result += "f128"; break; | |||
| 976 | case Type::PPC_FP128TyID: Result += "ppcf128"; break; | |||
| 977 | case Type::X86_MMXTyID: Result += "x86mmx"; break; | |||
| 978 | case Type::X86_AMXTyID: Result += "x86amx"; break; | |||
| 979 | case Type::IntegerTyID: | |||
| 980 | Result += "i" + utostr(cast<IntegerType>(Ty)->getBitWidth()); | |||
| 981 | break; | |||
| 982 | } | |||
| 983 | } | |||
| 984 | return Result; | |||
| 985 | } | |||
| 986 | ||||
| 987 | StringRef Intrinsic::getBaseName(ID id) { | |||
| 988 | assert(id < num_intrinsics && "Invalid intrinsic ID!")(static_cast <bool> (id < num_intrinsics && "Invalid intrinsic ID!" ) ? void (0) : __assert_fail ("id < num_intrinsics && \"Invalid intrinsic ID!\"" , "llvm/lib/IR/Function.cpp", 988, __extension__ __PRETTY_FUNCTION__ )); | |||
| 989 | return IntrinsicNameTable[id]; | |||
| 990 | } | |||
| 991 | ||||
| 992 | StringRef Intrinsic::getName(ID id) { | |||
| 993 | assert(id < num_intrinsics && "Invalid intrinsic ID!")(static_cast <bool> (id < num_intrinsics && "Invalid intrinsic ID!" ) ? void (0) : __assert_fail ("id < num_intrinsics && \"Invalid intrinsic ID!\"" , "llvm/lib/IR/Function.cpp", 993, __extension__ __PRETTY_FUNCTION__ )); | |||
| 994 | assert(!Intrinsic::isOverloaded(id) &&(static_cast <bool> (!Intrinsic::isOverloaded(id) && "This version of getName does not support overloading") ? void (0) : __assert_fail ("!Intrinsic::isOverloaded(id) && \"This version of getName does not support overloading\"" , "llvm/lib/IR/Function.cpp", 995, __extension__ __PRETTY_FUNCTION__ )) | |||
| 995 | "This version of getName does not support overloading")(static_cast <bool> (!Intrinsic::isOverloaded(id) && "This version of getName does not support overloading") ? void (0) : __assert_fail ("!Intrinsic::isOverloaded(id) && \"This version of getName does not support overloading\"" , "llvm/lib/IR/Function.cpp", 995, __extension__ __PRETTY_FUNCTION__ )); | |||
| 996 | return getBaseName(id); | |||
| 997 | } | |||
| 998 | ||||
| 999 | static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef<Type *> Tys, | |||
| 1000 | Module *M, FunctionType *FT, | |||
| 1001 | bool EarlyModuleCheck) { | |||
| 1002 | ||||
| 1003 | assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!")(static_cast <bool> (Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!") ? void (0) : __assert_fail ("Id < Intrinsic::num_intrinsics && \"Invalid intrinsic ID!\"" , "llvm/lib/IR/Function.cpp", 1003, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1004 | assert((Tys.empty() || Intrinsic::isOverloaded(Id)) &&(static_cast <bool> ((Tys.empty() || Intrinsic::isOverloaded (Id)) && "This version of getName is for overloaded intrinsics only" ) ? void (0) : __assert_fail ("(Tys.empty() || Intrinsic::isOverloaded(Id)) && \"This version of getName is for overloaded intrinsics only\"" , "llvm/lib/IR/Function.cpp", 1005, __extension__ __PRETTY_FUNCTION__ )) | |||
| 1005 | "This version of getName is for overloaded intrinsics only")(static_cast <bool> ((Tys.empty() || Intrinsic::isOverloaded (Id)) && "This version of getName is for overloaded intrinsics only" ) ? void (0) : __assert_fail ("(Tys.empty() || Intrinsic::isOverloaded(Id)) && \"This version of getName is for overloaded intrinsics only\"" , "llvm/lib/IR/Function.cpp", 1005, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1006 | (void)EarlyModuleCheck; | |||
| 1007 | assert((!EarlyModuleCheck || M ||(static_cast <bool> ((!EarlyModuleCheck || M || !any_of (Tys, [](Type *T) { return isa<PointerType>(T); })) && "Intrinsic overloading on pointer types need to provide a Module" ) ? void (0) : __assert_fail ("(!EarlyModuleCheck || M || !any_of(Tys, [](Type *T) { return isa<PointerType>(T); })) && \"Intrinsic overloading on pointer types need to provide a Module\"" , "llvm/lib/IR/Function.cpp", 1009, __extension__ __PRETTY_FUNCTION__ )) | |||
| 1008 | !any_of(Tys, [](Type *T) { return isa<PointerType>(T); })) &&(static_cast <bool> ((!EarlyModuleCheck || M || !any_of (Tys, [](Type *T) { return isa<PointerType>(T); })) && "Intrinsic overloading on pointer types need to provide a Module" ) ? void (0) : __assert_fail ("(!EarlyModuleCheck || M || !any_of(Tys, [](Type *T) { return isa<PointerType>(T); })) && \"Intrinsic overloading on pointer types need to provide a Module\"" , "llvm/lib/IR/Function.cpp", 1009, __extension__ __PRETTY_FUNCTION__ )) | |||
| 1009 | "Intrinsic overloading on pointer types need to provide a Module")(static_cast <bool> ((!EarlyModuleCheck || M || !any_of (Tys, [](Type *T) { return isa<PointerType>(T); })) && "Intrinsic overloading on pointer types need to provide a Module" ) ? void (0) : __assert_fail ("(!EarlyModuleCheck || M || !any_of(Tys, [](Type *T) { return isa<PointerType>(T); })) && \"Intrinsic overloading on pointer types need to provide a Module\"" , "llvm/lib/IR/Function.cpp", 1009, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1010 | bool HasUnnamedType = false; | |||
| 1011 | std::string Result(Intrinsic::getBaseName(Id)); | |||
| 1012 | for (Type *Ty : Tys) | |||
| 1013 | Result += "." + getMangledTypeStr(Ty, HasUnnamedType); | |||
| 1014 | if (HasUnnamedType) { | |||
| 1015 | assert(M && "unnamed types need a module")(static_cast <bool> (M && "unnamed types need a module" ) ? void (0) : __assert_fail ("M && \"unnamed types need a module\"" , "llvm/lib/IR/Function.cpp", 1015, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1016 | if (!FT) | |||
| 1017 | FT = Intrinsic::getType(M->getContext(), Id, Tys); | |||
| 1018 | else | |||
| 1019 | assert((FT == Intrinsic::getType(M->getContext(), Id, Tys)) &&(static_cast <bool> ((FT == Intrinsic::getType(M->getContext (), Id, Tys)) && "Provided FunctionType must match arguments" ) ? void (0) : __assert_fail ("(FT == Intrinsic::getType(M->getContext(), Id, Tys)) && \"Provided FunctionType must match arguments\"" , "llvm/lib/IR/Function.cpp", 1020, __extension__ __PRETTY_FUNCTION__ )) | |||
| 1020 | "Provided FunctionType must match arguments")(static_cast <bool> ((FT == Intrinsic::getType(M->getContext (), Id, Tys)) && "Provided FunctionType must match arguments" ) ? void (0) : __assert_fail ("(FT == Intrinsic::getType(M->getContext(), Id, Tys)) && \"Provided FunctionType must match arguments\"" , "llvm/lib/IR/Function.cpp", 1020, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1021 | return M->getUniqueIntrinsicName(Result, Id, FT); | |||
| 1022 | } | |||
| 1023 | return Result; | |||
| 1024 | } | |||
| 1025 | ||||
| 1026 | std::string Intrinsic::getName(ID Id, ArrayRef<Type *> Tys, Module *M, | |||
| 1027 | FunctionType *FT) { | |||
| 1028 | assert(M && "We need to have a Module")(static_cast <bool> (M && "We need to have a Module" ) ? void (0) : __assert_fail ("M && \"We need to have a Module\"" , "llvm/lib/IR/Function.cpp", 1028, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1029 | return getIntrinsicNameImpl(Id, Tys, M, FT, true); | |||
| 1030 | } | |||
| 1031 | ||||
| 1032 | std::string Intrinsic::getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys) { | |||
| 1033 | return getIntrinsicNameImpl(Id, Tys, nullptr, nullptr, false); | |||
| 1034 | } | |||
| 1035 | ||||
| 1036 | /// IIT_Info - These are enumerators that describe the entries returned by the | |||
| 1037 | /// getIntrinsicInfoTableEntries function. | |||
| 1038 | /// | |||
| 1039 | /// Defined in Intrinsics.td. | |||
| 1040 | enum IIT_Info { | |||
| 1041 | #define GET_INTRINSIC_IITINFO | |||
| 1042 | #include "llvm/IR/IntrinsicImpl.inc" | |||
| 1043 | #undef GET_INTRINSIC_IITINFO | |||
| 1044 | }; | |||
| 1045 | ||||
| 1046 | static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, | |||
| 1047 | IIT_Info LastInfo, | |||
| 1048 | SmallVectorImpl<Intrinsic::IITDescriptor> &OutputTable) { | |||
| 1049 | using namespace Intrinsic; | |||
| 1050 | ||||
| 1051 | bool IsScalableVector = (LastInfo == IIT_SCALABLE_VEC); | |||
| 1052 | ||||
| 1053 | IIT_Info Info = IIT_Info(Infos[NextElt++]); | |||
| 1054 | unsigned StructElts = 2; | |||
| 1055 | ||||
| 1056 | switch (Info) { | |||
| 1057 | case IIT_Done: | |||
| 1058 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0)); | |||
| 1059 | return; | |||
| 1060 | case IIT_VARARG: | |||
| 1061 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0)); | |||
| 1062 | return; | |||
| 1063 | case IIT_MMX: | |||
| 1064 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0)); | |||
| 1065 | return; | |||
| 1066 | case IIT_AMX: | |||
| 1067 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::AMX, 0)); | |||
| 1068 | return; | |||
| 1069 | case IIT_TOKEN: | |||
| 1070 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Token, 0)); | |||
| 1071 | return; | |||
| 1072 | case IIT_METADATA: | |||
| 1073 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Metadata, 0)); | |||
| 1074 | return; | |||
| 1075 | case IIT_F16: | |||
| 1076 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Half, 0)); | |||
| 1077 | return; | |||
| 1078 | case IIT_BF16: | |||
| 1079 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::BFloat, 0)); | |||
| 1080 | return; | |||
| 1081 | case IIT_F32: | |||
| 1082 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Float, 0)); | |||
| 1083 | return; | |||
| 1084 | case IIT_F64: | |||
| 1085 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Double, 0)); | |||
| 1086 | return; | |||
| 1087 | case IIT_F128: | |||
| 1088 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Quad, 0)); | |||
| 1089 | return; | |||
| 1090 | case IIT_PPCF128: | |||
| 1091 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::PPCQuad, 0)); | |||
| 1092 | return; | |||
| 1093 | case IIT_I1: | |||
| 1094 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 1)); | |||
| 1095 | return; | |||
| 1096 | case IIT_I2: | |||
| 1097 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 2)); | |||
| 1098 | return; | |||
| 1099 | case IIT_I4: | |||
| 1100 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 4)); | |||
| 1101 | return; | |||
| 1102 | case IIT_I8: | |||
| 1103 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 8)); | |||
| 1104 | return; | |||
| 1105 | case IIT_I16: | |||
| 1106 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer,16)); | |||
| 1107 | return; | |||
| 1108 | case IIT_I32: | |||
| 1109 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 32)); | |||
| 1110 | return; | |||
| 1111 | case IIT_I64: | |||
| 1112 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 64)); | |||
| 1113 | return; | |||
| 1114 | case IIT_I128: | |||
| 1115 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 128)); | |||
| 1116 | return; | |||
| 1117 | case IIT_V1: | |||
| 1118 | OutputTable.push_back(IITDescriptor::getVector(1, IsScalableVector)); | |||
| 1119 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1120 | return; | |||
| 1121 | case IIT_V2: | |||
| 1122 | OutputTable.push_back(IITDescriptor::getVector(2, IsScalableVector)); | |||
| 1123 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1124 | return; | |||
| 1125 | case IIT_V3: | |||
| 1126 | OutputTable.push_back(IITDescriptor::getVector(3, IsScalableVector)); | |||
| 1127 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1128 | return; | |||
| 1129 | case IIT_V4: | |||
| 1130 | OutputTable.push_back(IITDescriptor::getVector(4, IsScalableVector)); | |||
| 1131 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1132 | return; | |||
| 1133 | case IIT_V8: | |||
| 1134 | OutputTable.push_back(IITDescriptor::getVector(8, IsScalableVector)); | |||
| 1135 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1136 | return; | |||
| 1137 | case IIT_V16: | |||
| 1138 | OutputTable.push_back(IITDescriptor::getVector(16, IsScalableVector)); | |||
| 1139 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1140 | return; | |||
| 1141 | case IIT_V32: | |||
| 1142 | OutputTable.push_back(IITDescriptor::getVector(32, IsScalableVector)); | |||
| 1143 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1144 | return; | |||
| 1145 | case IIT_V64: | |||
| 1146 | OutputTable.push_back(IITDescriptor::getVector(64, IsScalableVector)); | |||
| 1147 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1148 | return; | |||
| 1149 | case IIT_V128: | |||
| 1150 | OutputTable.push_back(IITDescriptor::getVector(128, IsScalableVector)); | |||
| 1151 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1152 | return; | |||
| 1153 | case IIT_V256: | |||
| 1154 | OutputTable.push_back(IITDescriptor::getVector(256, IsScalableVector)); | |||
| 1155 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1156 | return; | |||
| 1157 | case IIT_V512: | |||
| 1158 | OutputTable.push_back(IITDescriptor::getVector(512, IsScalableVector)); | |||
| 1159 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1160 | return; | |||
| 1161 | case IIT_V1024: | |||
| 1162 | OutputTable.push_back(IITDescriptor::getVector(1024, IsScalableVector)); | |||
| 1163 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1164 | return; | |||
| 1165 | case IIT_EXTERNREF: | |||
| 1166 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 10)); | |||
| 1167 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0)); | |||
| 1168 | return; | |||
| 1169 | case IIT_FUNCREF: | |||
| 1170 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 20)); | |||
| 1171 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 8)); | |||
| 1172 | return; | |||
| 1173 | case IIT_PTR: | |||
| 1174 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0)); | |||
| 1175 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1176 | return; | |||
| 1177 | case IIT_ANYPTR: { // [ANYPTR addrspace, subtype] | |||
| 1178 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, | |||
| 1179 | Infos[NextElt++])); | |||
| 1180 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1181 | return; | |||
| 1182 | } | |||
| 1183 | case IIT_ARG: { | |||
| 1184 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1185 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo)); | |||
| 1186 | return; | |||
| 1187 | } | |||
| 1188 | case IIT_EXTEND_ARG: { | |||
| 1189 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1190 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::ExtendArgument, | |||
| 1191 | ArgInfo)); | |||
| 1192 | return; | |||
| 1193 | } | |||
| 1194 | case IIT_TRUNC_ARG: { | |||
| 1195 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1196 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncArgument, | |||
| 1197 | ArgInfo)); | |||
| 1198 | return; | |||
| 1199 | } | |||
| 1200 | case IIT_HALF_VEC_ARG: { | |||
| 1201 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1202 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::HalfVecArgument, | |||
| 1203 | ArgInfo)); | |||
| 1204 | return; | |||
| 1205 | } | |||
| 1206 | case IIT_SAME_VEC_WIDTH_ARG: { | |||
| 1207 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1208 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::SameVecWidthArgument, | |||
| 1209 | ArgInfo)); | |||
| 1210 | return; | |||
| 1211 | } | |||
| 1212 | case IIT_PTR_TO_ARG: { | |||
| 1213 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1214 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::PtrToArgument, | |||
| 1215 | ArgInfo)); | |||
| 1216 | return; | |||
| 1217 | } | |||
| 1218 | case IIT_PTR_TO_ELT: { | |||
| 1219 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1220 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::PtrToElt, ArgInfo)); | |||
| 1221 | return; | |||
| 1222 | } | |||
| 1223 | case IIT_ANYPTR_TO_ELT: { | |||
| 1224 | unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1225 | unsigned short RefNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1226 | OutputTable.push_back( | |||
| 1227 | IITDescriptor::get(IITDescriptor::AnyPtrToElt, ArgNo, RefNo)); | |||
| 1228 | return; | |||
| 1229 | } | |||
| 1230 | case IIT_VEC_OF_ANYPTRS_TO_ELT: { | |||
| 1231 | unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1232 | unsigned short RefNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1233 | OutputTable.push_back( | |||
| 1234 | IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt, ArgNo, RefNo)); | |||
| 1235 | return; | |||
| 1236 | } | |||
| 1237 | case IIT_EMPTYSTRUCT: | |||
| 1238 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0)); | |||
| 1239 | return; | |||
| 1240 | case IIT_STRUCT9: ++StructElts; [[fallthrough]]; | |||
| 1241 | case IIT_STRUCT8: ++StructElts; [[fallthrough]]; | |||
| 1242 | case IIT_STRUCT7: ++StructElts; [[fallthrough]]; | |||
| 1243 | case IIT_STRUCT6: ++StructElts; [[fallthrough]]; | |||
| 1244 | case IIT_STRUCT5: ++StructElts; [[fallthrough]]; | |||
| 1245 | case IIT_STRUCT4: ++StructElts; [[fallthrough]]; | |||
| 1246 | case IIT_STRUCT3: ++StructElts; [[fallthrough]]; | |||
| 1247 | case IIT_STRUCT2: { | |||
| 1248 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct,StructElts)); | |||
| 1249 | ||||
| 1250 | for (unsigned i = 0; i != StructElts; ++i) | |||
| 1251 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1252 | return; | |||
| 1253 | } | |||
| 1254 | case IIT_SUBDIVIDE2_ARG: { | |||
| 1255 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1256 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Subdivide2Argument, | |||
| 1257 | ArgInfo)); | |||
| 1258 | return; | |||
| 1259 | } | |||
| 1260 | case IIT_SUBDIVIDE4_ARG: { | |||
| 1261 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1262 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::Subdivide4Argument, | |||
| 1263 | ArgInfo)); | |||
| 1264 | return; | |||
| 1265 | } | |||
| 1266 | case IIT_VEC_ELEMENT: { | |||
| 1267 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1268 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecElementArgument, | |||
| 1269 | ArgInfo)); | |||
| 1270 | return; | |||
| 1271 | } | |||
| 1272 | case IIT_SCALABLE_VEC: { | |||
| 1273 | DecodeIITType(NextElt, Infos, Info, OutputTable); | |||
| 1274 | return; | |||
| 1275 | } | |||
| 1276 | case IIT_VEC_OF_BITCASTS_TO_INT: { | |||
| 1277 | unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); | |||
| 1278 | OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt, | |||
| 1279 | ArgInfo)); | |||
| 1280 | return; | |||
| 1281 | } | |||
| 1282 | } | |||
| 1283 | llvm_unreachable("unhandled")::llvm::llvm_unreachable_internal("unhandled", "llvm/lib/IR/Function.cpp" , 1283); | |||
| 1284 | } | |||
| 1285 | ||||
| 1286 | #define GET_INTRINSIC_GENERATOR_GLOBAL | |||
| 1287 | #include "llvm/IR/IntrinsicImpl.inc" | |||
| 1288 | #undef GET_INTRINSIC_GENERATOR_GLOBAL | |||
| 1289 | ||||
| 1290 | void Intrinsic::getIntrinsicInfoTableEntries(ID id, | |||
| 1291 | SmallVectorImpl<IITDescriptor> &T){ | |||
| 1292 | // Check to see if the intrinsic's type was expressible by the table. | |||
| 1293 | unsigned TableVal = IIT_Table[id-1]; | |||
| 1294 | ||||
| 1295 | // Decode the TableVal into an array of IITValues. | |||
| 1296 | SmallVector<unsigned char, 8> IITValues; | |||
| 1297 | ArrayRef<unsigned char> IITEntries; | |||
| 1298 | unsigned NextElt = 0; | |||
| 1299 | if ((TableVal >> 31) != 0) { | |||
| 1300 | // This is an offset into the IIT_LongEncodingTable. | |||
| 1301 | IITEntries = IIT_LongEncodingTable; | |||
| 1302 | ||||
| 1303 | // Strip sentinel bit. | |||
| 1304 | NextElt = (TableVal << 1) >> 1; | |||
| 1305 | } else { | |||
| 1306 | // Decode the TableVal into an array of IITValues. If the entry was encoded | |||
| 1307 | // into a single word in the table itself, decode it now. | |||
| 1308 | do { | |||
| 1309 | IITValues.push_back(TableVal & 0xF); | |||
| 1310 | TableVal >>= 4; | |||
| 1311 | } while (TableVal); | |||
| 1312 | ||||
| 1313 | IITEntries = IITValues; | |||
| 1314 | NextElt = 0; | |||
| 1315 | } | |||
| 1316 | ||||
| 1317 | // Okay, decode the table into the output vector of IITDescriptors. | |||
| 1318 | DecodeIITType(NextElt, IITEntries, IIT_Done, T); | |||
| 1319 | while (NextElt != IITEntries.size() && IITEntries[NextElt] != 0) | |||
| 1320 | DecodeIITType(NextElt, IITEntries, IIT_Done, T); | |||
| 1321 | } | |||
| 1322 | ||||
| 1323 | static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, | |||
| 1324 | ArrayRef<Type*> Tys, LLVMContext &Context) { | |||
| 1325 | using namespace Intrinsic; | |||
| 1326 | ||||
| 1327 | IITDescriptor D = Infos.front(); | |||
| 1328 | Infos = Infos.slice(1); | |||
| 1329 | ||||
| 1330 | switch (D.Kind) { | |||
| 1331 | case IITDescriptor::Void: return Type::getVoidTy(Context); | |||
| 1332 | case IITDescriptor::VarArg: return Type::getVoidTy(Context); | |||
| 1333 | case IITDescriptor::MMX: return Type::getX86_MMXTy(Context); | |||
| 1334 | case IITDescriptor::AMX: return Type::getX86_AMXTy(Context); | |||
| 1335 | case IITDescriptor::Token: return Type::getTokenTy(Context); | |||
| 1336 | case IITDescriptor::Metadata: return Type::getMetadataTy(Context); | |||
| 1337 | case IITDescriptor::Half: return Type::getHalfTy(Context); | |||
| 1338 | case IITDescriptor::BFloat: return Type::getBFloatTy(Context); | |||
| 1339 | case IITDescriptor::Float: return Type::getFloatTy(Context); | |||
| 1340 | case IITDescriptor::Double: return Type::getDoubleTy(Context); | |||
| 1341 | case IITDescriptor::Quad: return Type::getFP128Ty(Context); | |||
| 1342 | case IITDescriptor::PPCQuad: return Type::getPPC_FP128Ty(Context); | |||
| 1343 | ||||
| 1344 | case IITDescriptor::Integer: | |||
| 1345 | return IntegerType::get(Context, D.Integer_Width); | |||
| 1346 | case IITDescriptor::Vector: | |||
| 1347 | return VectorType::get(DecodeFixedType(Infos, Tys, Context), | |||
| 1348 | D.Vector_Width); | |||
| 1349 | case IITDescriptor::Pointer: | |||
| 1350 | return PointerType::get(DecodeFixedType(Infos, Tys, Context), | |||
| 1351 | D.Pointer_AddressSpace); | |||
| 1352 | case IITDescriptor::Struct: { | |||
| 1353 | SmallVector<Type *, 8> Elts; | |||
| 1354 | for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i) | |||
| 1355 | Elts.push_back(DecodeFixedType(Infos, Tys, Context)); | |||
| 1356 | return StructType::get(Context, Elts); | |||
| 1357 | } | |||
| 1358 | case IITDescriptor::Argument: | |||
| 1359 | return Tys[D.getArgumentNumber()]; | |||
| 1360 | case IITDescriptor::ExtendArgument: { | |||
| 1361 | Type *Ty = Tys[D.getArgumentNumber()]; | |||
| 1362 | if (VectorType *VTy = dyn_cast<VectorType>(Ty)) | |||
| 1363 | return VectorType::getExtendedElementVectorType(VTy); | |||
| 1364 | ||||
| 1365 | return IntegerType::get(Context, 2 * cast<IntegerType>(Ty)->getBitWidth()); | |||
| 1366 | } | |||
| 1367 | case IITDescriptor::TruncArgument: { | |||
| 1368 | Type *Ty = Tys[D.getArgumentNumber()]; | |||
| 1369 | if (VectorType *VTy = dyn_cast<VectorType>(Ty)) | |||
| 1370 | return VectorType::getTruncatedElementVectorType(VTy); | |||
| 1371 | ||||
| 1372 | IntegerType *ITy = cast<IntegerType>(Ty); | |||
| 1373 | assert(ITy->getBitWidth() % 2 == 0)(static_cast <bool> (ITy->getBitWidth() % 2 == 0) ? void (0) : __assert_fail ("ITy->getBitWidth() % 2 == 0", "llvm/lib/IR/Function.cpp" , 1373, __extension__ __PRETTY_FUNCTION__)); | |||
| 1374 | return IntegerType::get(Context, ITy->getBitWidth() / 2); | |||
| 1375 | } | |||
| 1376 | case IITDescriptor::Subdivide2Argument: | |||
| 1377 | case IITDescriptor::Subdivide4Argument: { | |||
| 1378 | Type *Ty = Tys[D.getArgumentNumber()]; | |||
| 1379 | VectorType *VTy = dyn_cast<VectorType>(Ty); | |||
| 1380 | assert(VTy && "Expected an argument of Vector Type")(static_cast <bool> (VTy && "Expected an argument of Vector Type" ) ? void (0) : __assert_fail ("VTy && \"Expected an argument of Vector Type\"" , "llvm/lib/IR/Function.cpp", 1380, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1381 | int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2; | |||
| 1382 | return VectorType::getSubdividedVectorType(VTy, SubDivs); | |||
| 1383 | } | |||
| 1384 | case IITDescriptor::HalfVecArgument: | |||
| 1385 | return VectorType::getHalfElementsVectorType(cast<VectorType>( | |||
| 1386 | Tys[D.getArgumentNumber()])); | |||
| 1387 | case IITDescriptor::SameVecWidthArgument: { | |||
| 1388 | Type *EltTy = DecodeFixedType(Infos, Tys, Context); | |||
| 1389 | Type *Ty = Tys[D.getArgumentNumber()]; | |||
| 1390 | if (auto *VTy = dyn_cast<VectorType>(Ty)) | |||
| 1391 | return VectorType::get(EltTy, VTy->getElementCount()); | |||
| 1392 | return EltTy; | |||
| 1393 | } | |||
| 1394 | case IITDescriptor::PtrToArgument: { | |||
| 1395 | Type *Ty = Tys[D.getArgumentNumber()]; | |||
| 1396 | return PointerType::getUnqual(Ty); | |||
| 1397 | } | |||
| 1398 | case IITDescriptor::PtrToElt: { | |||
| 1399 | Type *Ty = Tys[D.getArgumentNumber()]; | |||
| 1400 | VectorType *VTy = dyn_cast<VectorType>(Ty); | |||
| 1401 | if (!VTy) | |||
| 1402 | llvm_unreachable("Expected an argument of Vector Type")::llvm::llvm_unreachable_internal("Expected an argument of Vector Type" , "llvm/lib/IR/Function.cpp", 1402); | |||
| 1403 | Type *EltTy = VTy->getElementType(); | |||
| 1404 | return PointerType::getUnqual(EltTy); | |||
| 1405 | } | |||
| 1406 | case IITDescriptor::VecElementArgument: { | |||
| 1407 | Type *Ty = Tys[D.getArgumentNumber()]; | |||
| 1408 | if (VectorType *VTy = dyn_cast<VectorType>(Ty)) | |||
| 1409 | return VTy->getElementType(); | |||
| 1410 | llvm_unreachable("Expected an argument of Vector Type")::llvm::llvm_unreachable_internal("Expected an argument of Vector Type" , "llvm/lib/IR/Function.cpp", 1410); | |||
| 1411 | } | |||
| 1412 | case IITDescriptor::VecOfBitcastsToInt: { | |||
| 1413 | Type *Ty = Tys[D.getArgumentNumber()]; | |||
| 1414 | VectorType *VTy = dyn_cast<VectorType>(Ty); | |||
| 1415 | assert(VTy && "Expected an argument of Vector Type")(static_cast <bool> (VTy && "Expected an argument of Vector Type" ) ? void (0) : __assert_fail ("VTy && \"Expected an argument of Vector Type\"" , "llvm/lib/IR/Function.cpp", 1415, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1416 | return VectorType::getInteger(VTy); | |||
| 1417 | } | |||
| 1418 | case IITDescriptor::VecOfAnyPtrsToElt: | |||
| 1419 | // Return the overloaded type (which determines the pointers address space) | |||
| 1420 | return Tys[D.getOverloadArgNumber()]; | |||
| 1421 | case IITDescriptor::AnyPtrToElt: | |||
| 1422 | // Return the overloaded type (which determines the pointers address space) | |||
| 1423 | return Tys[D.getOverloadArgNumber()]; | |||
| 1424 | } | |||
| 1425 | llvm_unreachable("unhandled")::llvm::llvm_unreachable_internal("unhandled", "llvm/lib/IR/Function.cpp" , 1425); | |||
| 1426 | } | |||
| 1427 | ||||
| 1428 | FunctionType *Intrinsic::getType(LLVMContext &Context, | |||
| 1429 | ID id, ArrayRef<Type*> Tys) { | |||
| 1430 | SmallVector<IITDescriptor, 8> Table; | |||
| 1431 | getIntrinsicInfoTableEntries(id, Table); | |||
| 1432 | ||||
| 1433 | ArrayRef<IITDescriptor> TableRef = Table; | |||
| 1434 | Type *ResultTy = DecodeFixedType(TableRef, Tys, Context); | |||
| 1435 | ||||
| 1436 | SmallVector<Type*, 8> ArgTys; | |||
| 1437 | while (!TableRef.empty()) | |||
| 1438 | ArgTys.push_back(DecodeFixedType(TableRef, Tys, Context)); | |||
| 1439 | ||||
| 1440 | // DecodeFixedType returns Void for IITDescriptor::Void and IITDescriptor::VarArg | |||
| 1441 | // If we see void type as the type of the last argument, it is vararg intrinsic | |||
| 1442 | if (!ArgTys.empty() && ArgTys.back()->isVoidTy()) { | |||
| 1443 | ArgTys.pop_back(); | |||
| 1444 | return FunctionType::get(ResultTy, ArgTys, true); | |||
| 1445 | } | |||
| 1446 | return FunctionType::get(ResultTy, ArgTys, false); | |||
| 1447 | } | |||
| 1448 | ||||
| 1449 | bool Intrinsic::isOverloaded(ID id) { | |||
| 1450 | #define GET_INTRINSIC_OVERLOAD_TABLE | |||
| 1451 | #include "llvm/IR/IntrinsicImpl.inc" | |||
| 1452 | #undef GET_INTRINSIC_OVERLOAD_TABLE | |||
| 1453 | } | |||
| 1454 | ||||
| 1455 | /// This defines the "Intrinsic::getAttributes(ID id)" method. | |||
| 1456 | #define GET_INTRINSIC_ATTRIBUTES | |||
| 1457 | #include "llvm/IR/IntrinsicImpl.inc" | |||
| 1458 | #undef GET_INTRINSIC_ATTRIBUTES | |||
| 1459 | ||||
| 1460 | Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) { | |||
| 1461 | // There can never be multiple globals with the same name of different types, | |||
| 1462 | // because intrinsics must be a specific type. | |||
| 1463 | auto *FT = getType(M->getContext(), id, Tys); | |||
| 1464 | return cast<Function>( | |||
| 1465 | M->getOrInsertFunction( | |||
| 1466 | Tys.empty() ? getName(id) : getName(id, Tys, M, FT), FT) | |||
| 1467 | .getCallee()); | |||
| 1468 | } | |||
| 1469 | ||||
| 1470 | // This defines the "Intrinsic::getIntrinsicForClangBuiltin()" method. | |||
| 1471 | #define GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN | |||
| 1472 | #include "llvm/IR/IntrinsicImpl.inc" | |||
| 1473 | #undef GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN | |||
| 1474 | ||||
| 1475 | // This defines the "Intrinsic::getIntrinsicForMSBuiltin()" method. | |||
| 1476 | #define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN | |||
| 1477 | #include "llvm/IR/IntrinsicImpl.inc" | |||
| 1478 | #undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN | |||
| 1479 | ||||
| 1480 | using DeferredIntrinsicMatchPair = | |||
| 1481 | std::pair<Type *, ArrayRef<Intrinsic::IITDescriptor>>; | |||
| 1482 | ||||
| 1483 | static bool matchIntrinsicType( | |||
| 1484 | Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos, | |||
| 1485 | SmallVectorImpl<Type *> &ArgTys, | |||
| 1486 | SmallVectorImpl<DeferredIntrinsicMatchPair> &DeferredChecks, | |||
| 1487 | bool IsDeferredCheck) { | |||
| 1488 | using namespace Intrinsic; | |||
| 1489 | ||||
| 1490 | // If we ran out of descriptors, there are too many arguments. | |||
| 1491 | if (Infos.empty()) return true; | |||
| 1492 | ||||
| 1493 | // Do this before slicing off the 'front' part | |||
| 1494 | auto InfosRef = Infos; | |||
| 1495 | auto DeferCheck = [&DeferredChecks, &InfosRef](Type *T) { | |||
| 1496 | DeferredChecks.emplace_back(T, InfosRef); | |||
| 1497 | return false; | |||
| 1498 | }; | |||
| 1499 | ||||
| 1500 | IITDescriptor D = Infos.front(); | |||
| 1501 | Infos = Infos.slice(1); | |||
| 1502 | ||||
| 1503 | switch (D.Kind) { | |||
| 1504 | case IITDescriptor::Void: return !Ty->isVoidTy(); | |||
| 1505 | case IITDescriptor::VarArg: return true; | |||
| 1506 | case IITDescriptor::MMX: return !Ty->isX86_MMXTy(); | |||
| 1507 | case IITDescriptor::AMX: return !Ty->isX86_AMXTy(); | |||
| 1508 | case IITDescriptor::Token: return !Ty->isTokenTy(); | |||
| 1509 | case IITDescriptor::Metadata: return !Ty->isMetadataTy(); | |||
| 1510 | case IITDescriptor::Half: return !Ty->isHalfTy(); | |||
| 1511 | case IITDescriptor::BFloat: return !Ty->isBFloatTy(); | |||
| 1512 | case IITDescriptor::Float: return !Ty->isFloatTy(); | |||
| 1513 | case IITDescriptor::Double: return !Ty->isDoubleTy(); | |||
| 1514 | case IITDescriptor::Quad: return !Ty->isFP128Ty(); | |||
| 1515 | case IITDescriptor::PPCQuad: return !Ty->isPPC_FP128Ty(); | |||
| 1516 | case IITDescriptor::Integer: return !Ty->isIntegerTy(D.Integer_Width); | |||
| 1517 | case IITDescriptor::Vector: { | |||
| 1518 | VectorType *VT = dyn_cast<VectorType>(Ty); | |||
| 1519 | return !VT || VT->getElementCount() != D.Vector_Width || | |||
| 1520 | matchIntrinsicType(VT->getElementType(), Infos, ArgTys, | |||
| 1521 | DeferredChecks, IsDeferredCheck); | |||
| 1522 | } | |||
| 1523 | case IITDescriptor::Pointer: { | |||
| 1524 | PointerType *PT = dyn_cast<PointerType>(Ty); | |||
| 1525 | if (!PT || PT->getAddressSpace() != D.Pointer_AddressSpace) | |||
| 1526 | return true; | |||
| 1527 | if (!PT->isOpaque()) { | |||
| 1528 | /* Manually consume a pointer to empty struct descriptor, which is | |||
| 1529 | * used for externref. We don't want to enforce that the struct is | |||
| 1530 | * anonymous in this case. (This renders externref intrinsics | |||
| 1531 | * non-unique, but this will go away with opaque pointers anyway.) */ | |||
| 1532 | if (Infos.front().Kind == IITDescriptor::Struct && | |||
| 1533 | Infos.front().Struct_NumElements == 0) { | |||
| 1534 | Infos = Infos.slice(1); | |||
| 1535 | return false; | |||
| 1536 | } | |||
| 1537 | return matchIntrinsicType(PT->getNonOpaquePointerElementType(), Infos, | |||
| 1538 | ArgTys, DeferredChecks, IsDeferredCheck); | |||
| 1539 | } | |||
| 1540 | // Consume IIT descriptors relating to the pointer element type. | |||
| 1541 | // FIXME: Intrinsic type matching of nested single value types or even | |||
| 1542 | // aggregates doesn't work properly with opaque pointers but hopefully | |||
| 1543 | // doesn't happen in practice. | |||
| 1544 | while (Infos.front().Kind == IITDescriptor::Pointer || | |||
| 1545 | Infos.front().Kind == IITDescriptor::Vector) | |||
| 1546 | Infos = Infos.slice(1); | |||
| 1547 | assert((Infos.front().Kind != IITDescriptor::Argument ||(static_cast <bool> ((Infos.front().Kind != IITDescriptor ::Argument || Infos.front().getArgumentKind() == IITDescriptor ::AK_MatchType) && "Unsupported polymorphic pointer type with opaque pointer" ) ? void (0) : __assert_fail ("(Infos.front().Kind != IITDescriptor::Argument || Infos.front().getArgumentKind() == IITDescriptor::AK_MatchType) && \"Unsupported polymorphic pointer type with opaque pointer\"" , "llvm/lib/IR/Function.cpp", 1549, __extension__ __PRETTY_FUNCTION__ )) | |||
| 1548 | Infos.front().getArgumentKind() == IITDescriptor::AK_MatchType) &&(static_cast <bool> ((Infos.front().Kind != IITDescriptor ::Argument || Infos.front().getArgumentKind() == IITDescriptor ::AK_MatchType) && "Unsupported polymorphic pointer type with opaque pointer" ) ? void (0) : __assert_fail ("(Infos.front().Kind != IITDescriptor::Argument || Infos.front().getArgumentKind() == IITDescriptor::AK_MatchType) && \"Unsupported polymorphic pointer type with opaque pointer\"" , "llvm/lib/IR/Function.cpp", 1549, __extension__ __PRETTY_FUNCTION__ )) | |||
| 1549 | "Unsupported polymorphic pointer type with opaque pointer")(static_cast <bool> ((Infos.front().Kind != IITDescriptor ::Argument || Infos.front().getArgumentKind() == IITDescriptor ::AK_MatchType) && "Unsupported polymorphic pointer type with opaque pointer" ) ? void (0) : __assert_fail ("(Infos.front().Kind != IITDescriptor::Argument || Infos.front().getArgumentKind() == IITDescriptor::AK_MatchType) && \"Unsupported polymorphic pointer type with opaque pointer\"" , "llvm/lib/IR/Function.cpp", 1549, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1550 | Infos = Infos.slice(1); | |||
| 1551 | return false; | |||
| 1552 | } | |||
| 1553 | ||||
| 1554 | case IITDescriptor::Struct: { | |||
| 1555 | StructType *ST = dyn_cast<StructType>(Ty); | |||
| 1556 | if (!ST || !ST->isLiteral() || ST->isPacked() || | |||
| 1557 | ST->getNumElements() != D.Struct_NumElements) | |||
| 1558 | return true; | |||
| 1559 | ||||
| 1560 | for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i) | |||
| 1561 | if (matchIntrinsicType(ST->getElementType(i), Infos, ArgTys, | |||
| 1562 | DeferredChecks, IsDeferredCheck)) | |||
| 1563 | return true; | |||
| 1564 | return false; | |||
| 1565 | } | |||
| 1566 | ||||
| 1567 | case IITDescriptor::Argument: | |||
| 1568 | // If this is the second occurrence of an argument, | |||
| 1569 | // verify that the later instance matches the previous instance. | |||
| 1570 | if (D.getArgumentNumber() < ArgTys.size()) | |||
| 1571 | return Ty != ArgTys[D.getArgumentNumber()]; | |||
| 1572 | ||||
| 1573 | if (D.getArgumentNumber() > ArgTys.size() || | |||
| 1574 | D.getArgumentKind() == IITDescriptor::AK_MatchType) | |||
| 1575 | return IsDeferredCheck || DeferCheck(Ty); | |||
| 1576 | ||||
| 1577 | assert(D.getArgumentNumber() == ArgTys.size() && !IsDeferredCheck &&(static_cast <bool> (D.getArgumentNumber() == ArgTys.size () && !IsDeferredCheck && "Table consistency error" ) ? void (0) : __assert_fail ("D.getArgumentNumber() == ArgTys.size() && !IsDeferredCheck && \"Table consistency error\"" , "llvm/lib/IR/Function.cpp", 1578, __extension__ __PRETTY_FUNCTION__ )) | |||
| 1578 | "Table consistency error")(static_cast <bool> (D.getArgumentNumber() == ArgTys.size () && !IsDeferredCheck && "Table consistency error" ) ? void (0) : __assert_fail ("D.getArgumentNumber() == ArgTys.size() && !IsDeferredCheck && \"Table consistency error\"" , "llvm/lib/IR/Function.cpp", 1578, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1579 | ArgTys.push_back(Ty); | |||
| 1580 | ||||
| 1581 | switch (D.getArgumentKind()) { | |||
| 1582 | case IITDescriptor::AK_Any: return false; // Success | |||
| 1583 | case IITDescriptor::AK_AnyInteger: return !Ty->isIntOrIntVectorTy(); | |||
| 1584 | case IITDescriptor::AK_AnyFloat: return !Ty->isFPOrFPVectorTy(); | |||
| 1585 | case IITDescriptor::AK_AnyVector: return !isa<VectorType>(Ty); | |||
| 1586 | case IITDescriptor::AK_AnyPointer: return !isa<PointerType>(Ty); | |||
| 1587 | default: break; | |||
| 1588 | } | |||
| 1589 | llvm_unreachable("all argument kinds not covered")::llvm::llvm_unreachable_internal("all argument kinds not covered" , "llvm/lib/IR/Function.cpp", 1589); | |||
| 1590 | ||||
| 1591 | case IITDescriptor::ExtendArgument: { | |||
| 1592 | // If this is a forward reference, defer the check for later. | |||
| 1593 | if (D.getArgumentNumber() >= ArgTys.size()) | |||
| 1594 | return IsDeferredCheck || DeferCheck(Ty); | |||
| 1595 | ||||
| 1596 | Type *NewTy = ArgTys[D.getArgumentNumber()]; | |||
| 1597 | if (VectorType *VTy = dyn_cast<VectorType>(NewTy)) | |||
| 1598 | NewTy = VectorType::getExtendedElementVectorType(VTy); | |||
| 1599 | else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy)) | |||
| 1600 | NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth()); | |||
| 1601 | else | |||
| 1602 | return true; | |||
| 1603 | ||||
| 1604 | return Ty != NewTy; | |||
| 1605 | } | |||
| 1606 | case IITDescriptor::TruncArgument: { | |||
| 1607 | // If this is a forward reference, defer the check for later. | |||
| 1608 | if (D.getArgumentNumber() >= ArgTys.size()) | |||
| 1609 | return IsDeferredCheck || DeferCheck(Ty); | |||
| 1610 | ||||
| 1611 | Type *NewTy = ArgTys[D.getArgumentNumber()]; | |||
| 1612 | if (VectorType *VTy = dyn_cast<VectorType>(NewTy)) | |||
| 1613 | NewTy = VectorType::getTruncatedElementVectorType(VTy); | |||
| 1614 | else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy)) | |||
| 1615 | NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2); | |||
| 1616 | else | |||
| 1617 | return true; | |||
| 1618 | ||||
| 1619 | return Ty != NewTy; | |||
| 1620 | } | |||
| 1621 | case IITDescriptor::HalfVecArgument: | |||
| 1622 | // If this is a forward reference, defer the check for later. | |||
| 1623 | if (D.getArgumentNumber() >= ArgTys.size()) | |||
| 1624 | return IsDeferredCheck || DeferCheck(Ty); | |||
| 1625 | return !isa<VectorType>(ArgTys[D.getArgumentNumber()]) || | |||
| 1626 | VectorType::getHalfElementsVectorType( | |||
| 1627 | cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty; | |||
| 1628 | case IITDescriptor::SameVecWidthArgument: { | |||
| 1629 | if (D.getArgumentNumber() >= ArgTys.size()) { | |||
| 1630 | // Defer check and subsequent check for the vector element type. | |||
| 1631 | Infos = Infos.slice(1); | |||
| 1632 | return IsDeferredCheck || DeferCheck(Ty); | |||
| 1633 | } | |||
| 1634 | auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]); | |||
| 1635 | auto *ThisArgType = dyn_cast<VectorType>(Ty); | |||
| 1636 | // Both must be vectors of the same number of elements or neither. | |||
| 1637 | if ((ReferenceType != nullptr) != (ThisArgType != nullptr)) | |||
| 1638 | return true; | |||
| 1639 | Type *EltTy = Ty; | |||
| 1640 | if (ThisArgType) { | |||
| 1641 | if (ReferenceType->getElementCount() != | |||
| 1642 | ThisArgType->getElementCount()) | |||
| 1643 | return true; | |||
| 1644 | EltTy = ThisArgType->getElementType(); | |||
| 1645 | } | |||
| 1646 | return matchIntrinsicType(EltTy, Infos, ArgTys, DeferredChecks, | |||
| 1647 | IsDeferredCheck); | |||
| 1648 | } | |||
| 1649 | case IITDescriptor::PtrToArgument: { | |||
| 1650 | if (D.getArgumentNumber() >= ArgTys.size()) | |||
| 1651 | return IsDeferredCheck || DeferCheck(Ty); | |||
| 1652 | Type * ReferenceType = ArgTys[D.getArgumentNumber()]; | |||
| 1653 | PointerType *ThisArgType = dyn_cast<PointerType>(Ty); | |||
| 1654 | return (!ThisArgType || | |||
| 1655 | !ThisArgType->isOpaqueOrPointeeTypeMatches(ReferenceType)); | |||
| 1656 | } | |||
| 1657 | case IITDescriptor::PtrToElt: { | |||
| 1658 | if (D.getArgumentNumber() >= ArgTys.size()) | |||
| 1659 | return IsDeferredCheck || DeferCheck(Ty); | |||
| 1660 | VectorType * ReferenceType = | |||
| 1661 | dyn_cast<VectorType> (ArgTys[D.getArgumentNumber()]); | |||
| 1662 | PointerType *ThisArgType = dyn_cast<PointerType>(Ty); | |||
| 1663 | ||||
| 1664 | if (!ThisArgType || !ReferenceType) | |||
| 1665 | return true; | |||
| 1666 | return !ThisArgType->isOpaqueOrPointeeTypeMatches( | |||
| 1667 | ReferenceType->getElementType()); | |||
| 1668 | } | |||
| 1669 | case IITDescriptor::AnyPtrToElt: { | |||
| 1670 | unsigned RefArgNumber = D.getRefArgNumber(); | |||
| 1671 | if (RefArgNumber >= ArgTys.size()) { | |||
| 1672 | if (IsDeferredCheck) | |||
| 1673 | return true; | |||
| 1674 | // If forward referencing, already add the pointer type and | |||
| 1675 | // defer the checks for later. | |||
| 1676 | ArgTys.push_back(Ty); | |||
| 1677 | return DeferCheck(Ty); | |||
| 1678 | } | |||
| 1679 | ||||
| 1680 | if (!IsDeferredCheck) { | |||
| 1681 | assert(D.getOverloadArgNumber() == ArgTys.size() &&(static_cast <bool> (D.getOverloadArgNumber() == ArgTys .size() && "Table consistency error") ? void (0) : __assert_fail ("D.getOverloadArgNumber() == ArgTys.size() && \"Table consistency error\"" , "llvm/lib/IR/Function.cpp", 1682, __extension__ __PRETTY_FUNCTION__ )) | |||
| 1682 | "Table consistency error")(static_cast <bool> (D.getOverloadArgNumber() == ArgTys .size() && "Table consistency error") ? void (0) : __assert_fail ("D.getOverloadArgNumber() == ArgTys.size() && \"Table consistency error\"" , "llvm/lib/IR/Function.cpp", 1682, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1683 | ArgTys.push_back(Ty); | |||
| 1684 | } | |||
| 1685 | ||||
| 1686 | auto *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]); | |||
| 1687 | auto *ThisArgType = dyn_cast<PointerType>(Ty); | |||
| 1688 | if (!ThisArgType || !ReferenceType) | |||
| 1689 | return true; | |||
| 1690 | return !ThisArgType->isOpaqueOrPointeeTypeMatches( | |||
| 1691 | ReferenceType->getElementType()); | |||
| 1692 | } | |||
| 1693 | case IITDescriptor::VecOfAnyPtrsToElt: { | |||
| 1694 | unsigned RefArgNumber = D.getRefArgNumber(); | |||
| 1695 | if (RefArgNumber >= ArgTys.size()) { | |||
| 1696 | if (IsDeferredCheck) | |||
| 1697 | return true; | |||
| 1698 | // If forward referencing, already add the pointer-vector type and | |||
| 1699 | // defer the checks for later. | |||
| 1700 | ArgTys.push_back(Ty); | |||
| 1701 | return DeferCheck(Ty); | |||
| 1702 | } | |||
| 1703 | ||||
| 1704 | if (!IsDeferredCheck){ | |||
| 1705 | assert(D.getOverloadArgNumber() == ArgTys.size() &&(static_cast <bool> (D.getOverloadArgNumber() == ArgTys .size() && "Table consistency error") ? void (0) : __assert_fail ("D.getOverloadArgNumber() == ArgTys.size() && \"Table consistency error\"" , "llvm/lib/IR/Function.cpp", 1706, __extension__ __PRETTY_FUNCTION__ )) | |||
| 1706 | "Table consistency error")(static_cast <bool> (D.getOverloadArgNumber() == ArgTys .size() && "Table consistency error") ? void (0) : __assert_fail ("D.getOverloadArgNumber() == ArgTys.size() && \"Table consistency error\"" , "llvm/lib/IR/Function.cpp", 1706, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1707 | ArgTys.push_back(Ty); | |||
| 1708 | } | |||
| 1709 | ||||
| 1710 | // Verify the overloaded type "matches" the Ref type. | |||
| 1711 | // i.e. Ty is a vector with the same width as Ref. | |||
| 1712 | // Composed of pointers to the same element type as Ref. | |||
| 1713 | auto *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]); | |||
| 1714 | auto *ThisArgVecTy = dyn_cast<VectorType>(Ty); | |||
| 1715 | if (!ThisArgVecTy || !ReferenceType || | |||
| 1716 | (ReferenceType->getElementCount() != ThisArgVecTy->getElementCount())) | |||
| 1717 | return true; | |||
| 1718 | PointerType *ThisArgEltTy = | |||
| 1719 | dyn_cast<PointerType>(ThisArgVecTy->getElementType()); | |||
| 1720 | if (!ThisArgEltTy) | |||
| 1721 | return true; | |||
| 1722 | return !ThisArgEltTy->isOpaqueOrPointeeTypeMatches( | |||
| 1723 | ReferenceType->getElementType()); | |||
| 1724 | } | |||
| 1725 | case IITDescriptor::VecElementArgument: { | |||
| 1726 | if (D.getArgumentNumber() >= ArgTys.size()) | |||
| 1727 | return IsDeferredCheck ? true : DeferCheck(Ty); | |||
| 1728 | auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]); | |||
| 1729 | return !ReferenceType || Ty != ReferenceType->getElementType(); | |||
| 1730 | } | |||
| 1731 | case IITDescriptor::Subdivide2Argument: | |||
| 1732 | case IITDescriptor::Subdivide4Argument: { | |||
| 1733 | // If this is a forward reference, defer the check for later. | |||
| 1734 | if (D.getArgumentNumber() >= ArgTys.size()) | |||
| 1735 | return IsDeferredCheck || DeferCheck(Ty); | |||
| 1736 | ||||
| 1737 | Type *NewTy = ArgTys[D.getArgumentNumber()]; | |||
| 1738 | if (auto *VTy = dyn_cast<VectorType>(NewTy)) { | |||
| 1739 | int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2; | |||
| 1740 | NewTy = VectorType::getSubdividedVectorType(VTy, SubDivs); | |||
| 1741 | return Ty != NewTy; | |||
| 1742 | } | |||
| 1743 | return true; | |||
| 1744 | } | |||
| 1745 | case IITDescriptor::VecOfBitcastsToInt: { | |||
| 1746 | if (D.getArgumentNumber() >= ArgTys.size()) | |||
| 1747 | return IsDeferredCheck || DeferCheck(Ty); | |||
| 1748 | auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]); | |||
| 1749 | auto *ThisArgVecTy = dyn_cast<VectorType>(Ty); | |||
| 1750 | if (!ThisArgVecTy || !ReferenceType) | |||
| 1751 | return true; | |||
| 1752 | return ThisArgVecTy != VectorType::getInteger(ReferenceType); | |||
| 1753 | } | |||
| 1754 | } | |||
| 1755 | llvm_unreachable("unhandled")::llvm::llvm_unreachable_internal("unhandled", "llvm/lib/IR/Function.cpp" , 1755); | |||
| 1756 | } | |||
| 1757 | ||||
| 1758 | Intrinsic::MatchIntrinsicTypesResult | |||
| 1759 | Intrinsic::matchIntrinsicSignature(FunctionType *FTy, | |||
| 1760 | ArrayRef<Intrinsic::IITDescriptor> &Infos, | |||
| 1761 | SmallVectorImpl<Type *> &ArgTys) { | |||
| 1762 | SmallVector<DeferredIntrinsicMatchPair, 2> DeferredChecks; | |||
| 1763 | if (matchIntrinsicType(FTy->getReturnType(), Infos, ArgTys, DeferredChecks, | |||
| 1764 | false)) | |||
| 1765 | return MatchIntrinsicTypes_NoMatchRet; | |||
| 1766 | ||||
| 1767 | unsigned NumDeferredReturnChecks = DeferredChecks.size(); | |||
| 1768 | ||||
| 1769 | for (auto *Ty : FTy->params()) | |||
| 1770 | if (matchIntrinsicType(Ty, Infos, ArgTys, DeferredChecks, false)) | |||
| 1771 | return MatchIntrinsicTypes_NoMatchArg; | |||
| 1772 | ||||
| 1773 | for (unsigned I = 0, E = DeferredChecks.size(); I != E; ++I) { | |||
| 1774 | DeferredIntrinsicMatchPair &Check = DeferredChecks[I]; | |||
| 1775 | if (matchIntrinsicType(Check.first, Check.second, ArgTys, DeferredChecks, | |||
| 1776 | true)) | |||
| 1777 | return I < NumDeferredReturnChecks ? MatchIntrinsicTypes_NoMatchRet | |||
| 1778 | : MatchIntrinsicTypes_NoMatchArg; | |||
| 1779 | } | |||
| 1780 | ||||
| 1781 | return MatchIntrinsicTypes_Match; | |||
| 1782 | } | |||
| 1783 | ||||
| 1784 | bool | |||
| 1785 | Intrinsic::matchIntrinsicVarArg(bool isVarArg, | |||
| 1786 | ArrayRef<Intrinsic::IITDescriptor> &Infos) { | |||
| 1787 | // If there are no descriptors left, then it can't be a vararg. | |||
| 1788 | if (Infos.empty()) | |||
| 1789 | return isVarArg; | |||
| 1790 | ||||
| 1791 | // There should be only one descriptor remaining at this point. | |||
| 1792 | if (Infos.size() != 1) | |||
| 1793 | return true; | |||
| 1794 | ||||
| 1795 | // Check and verify the descriptor. | |||
| 1796 | IITDescriptor D = Infos.front(); | |||
| 1797 | Infos = Infos.slice(1); | |||
| 1798 | if (D.Kind == IITDescriptor::VarArg) | |||
| 1799 | return !isVarArg; | |||
| 1800 | ||||
| 1801 | return true; | |||
| 1802 | } | |||
| 1803 | ||||
| 1804 | bool Intrinsic::getIntrinsicSignature(Function *F, | |||
| 1805 | SmallVectorImpl<Type *> &ArgTys) { | |||
| 1806 | Intrinsic::ID ID = F->getIntrinsicID(); | |||
| 1807 | if (!ID) | |||
| 1808 | return false; | |||
| 1809 | ||||
| 1810 | SmallVector<Intrinsic::IITDescriptor, 8> Table; | |||
| 1811 | getIntrinsicInfoTableEntries(ID, Table); | |||
| 1812 | ArrayRef<Intrinsic::IITDescriptor> TableRef = Table; | |||
| 1813 | ||||
| 1814 | if (Intrinsic::matchIntrinsicSignature(F->getFunctionType(), TableRef, | |||
| 1815 | ArgTys) != | |||
| 1816 | Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) { | |||
| 1817 | return false; | |||
| 1818 | } | |||
| 1819 | if (Intrinsic::matchIntrinsicVarArg(F->getFunctionType()->isVarArg(), | |||
| 1820 | TableRef)) | |||
| 1821 | return false; | |||
| 1822 | return true; | |||
| 1823 | } | |||
| 1824 | ||||
| 1825 | std::optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) { | |||
| 1826 | SmallVector<Type *, 4> ArgTys; | |||
| 1827 | if (!getIntrinsicSignature(F, ArgTys)) | |||
| 1828 | return std::nullopt; | |||
| 1829 | ||||
| 1830 | Intrinsic::ID ID = F->getIntrinsicID(); | |||
| 1831 | StringRef Name = F->getName(); | |||
| 1832 | std::string WantedName = | |||
| 1833 | Intrinsic::getName(ID, ArgTys, F->getParent(), F->getFunctionType()); | |||
| 1834 | if (Name == WantedName) | |||
| 1835 | return std::nullopt; | |||
| 1836 | ||||
| 1837 | Function *NewDecl = [&] { | |||
| 1838 | if (auto *ExistingGV = F->getParent()->getNamedValue(WantedName)) { | |||
| 1839 | if (auto *ExistingF = dyn_cast<Function>(ExistingGV)) | |||
| 1840 | if (ExistingF->getFunctionType() == F->getFunctionType()) | |||
| 1841 | return ExistingF; | |||
| 1842 | ||||
| 1843 | // The name already exists, but is not a function or has the wrong | |||
| 1844 | // prototype. Make place for the new one by renaming the old version. | |||
| 1845 | // Either this old version will be removed later on or the module is | |||
| 1846 | // invalid and we'll get an error. | |||
| 1847 | ExistingGV->setName(WantedName + ".renamed"); | |||
| 1848 | } | |||
| 1849 | return Intrinsic::getDeclaration(F->getParent(), ID, ArgTys); | |||
| 1850 | }(); | |||
| 1851 | ||||
| 1852 | NewDecl->setCallingConv(F->getCallingConv()); | |||
| 1853 | assert(NewDecl->getFunctionType() == F->getFunctionType() &&(static_cast <bool> (NewDecl->getFunctionType() == F ->getFunctionType() && "Shouldn't change the signature" ) ? void (0) : __assert_fail ("NewDecl->getFunctionType() == F->getFunctionType() && \"Shouldn't change the signature\"" , "llvm/lib/IR/Function.cpp", 1854, __extension__ __PRETTY_FUNCTION__ )) | |||
| 1854 | "Shouldn't change the signature")(static_cast <bool> (NewDecl->getFunctionType() == F ->getFunctionType() && "Shouldn't change the signature" ) ? void (0) : __assert_fail ("NewDecl->getFunctionType() == F->getFunctionType() && \"Shouldn't change the signature\"" , "llvm/lib/IR/Function.cpp", 1854, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1855 | return NewDecl; | |||
| 1856 | } | |||
| 1857 | ||||
| 1858 | /// hasAddressTaken - returns true if there are any uses of this function | |||
| 1859 | /// other than direct calls or invokes to it. Optionally ignores callback | |||
| 1860 | /// uses, assume like pointer annotation calls, and references in llvm.used | |||
| 1861 | /// and llvm.compiler.used variables. | |||
| 1862 | bool Function::hasAddressTaken(const User **PutOffender, | |||
| 1863 | bool IgnoreCallbackUses, | |||
| 1864 | bool IgnoreAssumeLikeCalls, bool IgnoreLLVMUsed, | |||
| 1865 | bool IgnoreARCAttachedCall) const { | |||
| 1866 | for (const Use &U : uses()) { | |||
| 1867 | const User *FU = U.getUser(); | |||
| 1868 | if (isa<BlockAddress>(FU)) | |||
| 1869 | continue; | |||
| 1870 | ||||
| 1871 | if (IgnoreCallbackUses) { | |||
| 1872 | AbstractCallSite ACS(&U); | |||
| 1873 | if (ACS && ACS.isCallbackCall()) | |||
| 1874 | continue; | |||
| 1875 | } | |||
| 1876 | ||||
| 1877 | const auto *Call = dyn_cast<CallBase>(FU); | |||
| 1878 | if (!Call) { | |||
| 1879 | if (IgnoreAssumeLikeCalls && | |||
| 1880 | isa<BitCastOperator, AddrSpaceCastOperator>(FU) && | |||
| 1881 | all_of(FU->users(), [](const User *U) { | |||
| 1882 | if (const auto *I = dyn_cast<IntrinsicInst>(U)) | |||
| 1883 | return I->isAssumeLikeIntrinsic(); | |||
| 1884 | return false; | |||
| 1885 | })) { | |||
| 1886 | continue; | |||
| 1887 | } | |||
| 1888 | ||||
| 1889 | if (IgnoreLLVMUsed && !FU->user_empty()) { | |||
| 1890 | const User *FUU = FU; | |||
| 1891 | if (isa<BitCastOperator, AddrSpaceCastOperator>(FU) && | |||
| 1892 | FU->hasOneUse() && !FU->user_begin()->user_empty()) | |||
| 1893 | FUU = *FU->user_begin(); | |||
| 1894 | if (llvm::all_of(FUU->users(), [](const User *U) { | |||
| 1895 | if (const auto *GV = dyn_cast<GlobalVariable>(U)) | |||
| 1896 | return GV->hasName() && | |||
| 1897 | (GV->getName().equals("llvm.compiler.used") || | |||
| 1898 | GV->getName().equals("llvm.used")); | |||
| 1899 | return false; | |||
| 1900 | })) | |||
| 1901 | continue; | |||
| 1902 | } | |||
| 1903 | if (PutOffender) | |||
| 1904 | *PutOffender = FU; | |||
| 1905 | return true; | |||
| 1906 | } | |||
| 1907 | ||||
| 1908 | if (IgnoreAssumeLikeCalls) { | |||
| 1909 | if (const auto *I = dyn_cast<IntrinsicInst>(Call)) | |||
| 1910 | if (I->isAssumeLikeIntrinsic()) | |||
| 1911 | continue; | |||
| 1912 | } | |||
| 1913 | ||||
| 1914 | if (!Call->isCallee(&U) || Call->getFunctionType() != getFunctionType()) { | |||
| 1915 | if (IgnoreARCAttachedCall && | |||
| 1916 | Call->isOperandBundleOfType(LLVMContext::OB_clang_arc_attachedcall, | |||
| 1917 | U.getOperandNo())) | |||
| 1918 | continue; | |||
| 1919 | ||||
| 1920 | if (PutOffender) | |||
| 1921 | *PutOffender = FU; | |||
| 1922 | return true; | |||
| 1923 | } | |||
| 1924 | } | |||
| 1925 | return false; | |||
| 1926 | } | |||
| 1927 | ||||
| 1928 | bool Function::isDefTriviallyDead() const { | |||
| 1929 | // Check the linkage | |||
| 1930 | if (!hasLinkOnceLinkage() && !hasLocalLinkage() && | |||
| 1931 | !hasAvailableExternallyLinkage()) | |||
| 1932 | return false; | |||
| 1933 | ||||
| 1934 | // Check if the function is used by anything other than a blockaddress. | |||
| 1935 | for (const User *U : users()) | |||
| 1936 | if (!isa<BlockAddress>(U)) | |||
| 1937 | return false; | |||
| 1938 | ||||
| 1939 | return true; | |||
| 1940 | } | |||
| 1941 | ||||
| 1942 | /// callsFunctionThatReturnsTwice - Return true if the function has a call to | |||
| 1943 | /// setjmp or other function that gcc recognizes as "returning twice". | |||
| 1944 | bool Function::callsFunctionThatReturnsTwice() const { | |||
| 1945 | for (const Instruction &I : instructions(this)) | |||
| 1946 | if (const auto *Call = dyn_cast<CallBase>(&I)) | |||
| 1947 | if (Call->hasFnAttr(Attribute::ReturnsTwice)) | |||
| 1948 | return true; | |||
| 1949 | ||||
| 1950 | return false; | |||
| 1951 | } | |||
| 1952 | ||||
| 1953 | Constant *Function::getPersonalityFn() const { | |||
| 1954 | assert(hasPersonalityFn() && getNumOperands())(static_cast <bool> (hasPersonalityFn() && getNumOperands ()) ? void (0) : __assert_fail ("hasPersonalityFn() && getNumOperands()" , "llvm/lib/IR/Function.cpp", 1954, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1955 | return cast<Constant>(Op<0>()); | |||
| 1956 | } | |||
| 1957 | ||||
| 1958 | void Function::setPersonalityFn(Constant *Fn) { | |||
| 1959 | setHungoffOperand<0>(Fn); | |||
| 1960 | setValueSubclassDataBit(3, Fn != nullptr); | |||
| 1961 | } | |||
| 1962 | ||||
| 1963 | Constant *Function::getPrefixData() const { | |||
| 1964 | assert(hasPrefixData() && getNumOperands())(static_cast <bool> (hasPrefixData() && getNumOperands ()) ? void (0) : __assert_fail ("hasPrefixData() && getNumOperands()" , "llvm/lib/IR/Function.cpp", 1964, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1965 | return cast<Constant>(Op<1>()); | |||
| 1966 | } | |||
| 1967 | ||||
| 1968 | void Function::setPrefixData(Constant *PrefixData) { | |||
| 1969 | setHungoffOperand<1>(PrefixData); | |||
| 1970 | setValueSubclassDataBit(1, PrefixData != nullptr); | |||
| 1971 | } | |||
| 1972 | ||||
| 1973 | Constant *Function::getPrologueData() const { | |||
| 1974 | assert(hasPrologueData() && getNumOperands())(static_cast <bool> (hasPrologueData() && getNumOperands ()) ? void (0) : __assert_fail ("hasPrologueData() && getNumOperands()" , "llvm/lib/IR/Function.cpp", 1974, __extension__ __PRETTY_FUNCTION__ )); | |||
| 1975 | return cast<Constant>(Op<2>()); | |||
| 1976 | } | |||
| 1977 | ||||
| 1978 | void Function::setPrologueData(Constant *PrologueData) { | |||
| 1979 | setHungoffOperand<2>(PrologueData); | |||
| 1980 | setValueSubclassDataBit(2, PrologueData != nullptr); | |||
| 1981 | } | |||
| 1982 | ||||
| 1983 | void Function::allocHungoffUselist() { | |||
| 1984 | // If we've already allocated a uselist, stop here. | |||
| 1985 | if (getNumOperands()) | |||
| 1986 | return; | |||
| 1987 | ||||
| 1988 | allocHungoffUses(3, /*IsPhi=*/ false); | |||
| 1989 | setNumHungOffUseOperands(3); | |||
| 1990 | ||||
| 1991 | // Initialize the uselist with placeholder operands to allow traversal. | |||
| 1992 | auto *CPN = ConstantPointerNull::get(Type::getInt1PtrTy(getContext(), 0)); | |||
| 1993 | Op<0>().set(CPN); | |||
| 1994 | Op<1>().set(CPN); | |||
| 1995 | Op<2>().set(CPN); | |||
| 1996 | } | |||
| 1997 | ||||
| 1998 | template <int Idx> | |||
| 1999 | void Function::setHungoffOperand(Constant *C) { | |||
| 2000 | if (C) { | |||
| 2001 | allocHungoffUselist(); | |||
| 2002 | Op<Idx>().set(C); | |||
| 2003 | } else if (getNumOperands()) { | |||
| 2004 | Op<Idx>().set( | |||
| 2005 | ConstantPointerNull::get(Type::getInt1PtrTy(getContext(), 0))); | |||
| 2006 | } | |||
| 2007 | } | |||
| 2008 | ||||
| 2009 | void Function::setValueSubclassDataBit(unsigned Bit, bool On) { | |||
| 2010 | assert(Bit < 16 && "SubclassData contains only 16 bits")(static_cast <bool> (Bit < 16 && "SubclassData contains only 16 bits" ) ? void (0) : __assert_fail ("Bit < 16 && \"SubclassData contains only 16 bits\"" , "llvm/lib/IR/Function.cpp", 2010, __extension__ __PRETTY_FUNCTION__ )); | |||
| 2011 | if (On) | |||
| 2012 | setValueSubclassData(getSubclassDataFromValue() | (1 << Bit)); | |||
| 2013 | else | |||
| 2014 | setValueSubclassData(getSubclassDataFromValue() & ~(1 << Bit)); | |||
| 2015 | } | |||
| 2016 | ||||
| 2017 | void Function::setEntryCount(ProfileCount Count, | |||
| 2018 | const DenseSet<GlobalValue::GUID> *S) { | |||
| 2019 | #if !defined(NDEBUG) | |||
| 2020 | auto PrevCount = getEntryCount(); | |||
| 2021 | assert(!PrevCount || PrevCount->getType() == Count.getType())(static_cast <bool> (!PrevCount || PrevCount->getType () == Count.getType()) ? void (0) : __assert_fail ("!PrevCount || PrevCount->getType() == Count.getType()" , "llvm/lib/IR/Function.cpp", 2021, __extension__ __PRETTY_FUNCTION__ )); | |||
| 2022 | #endif | |||
| 2023 | ||||
| 2024 | auto ImportGUIDs = getImportGUIDs(); | |||
| 2025 | if (S == nullptr && ImportGUIDs.size()) | |||
| 2026 | S = &ImportGUIDs; | |||
| 2027 | ||||
| 2028 | MDBuilder MDB(getContext()); | |||
| 2029 | setMetadata( | |||
| 2030 | LLVMContext::MD_prof, | |||
| 2031 | MDB.createFunctionEntryCount(Count.getCount(), Count.isSynthetic(), S)); | |||
| 2032 | } | |||
| 2033 | ||||
| 2034 | void Function::setEntryCount(uint64_t Count, Function::ProfileCountType Type, | |||
| 2035 | const DenseSet<GlobalValue::GUID> *Imports) { | |||
| 2036 | setEntryCount(ProfileCount(Count, Type), Imports); | |||
| 2037 | } | |||
| 2038 | ||||
| 2039 | std::optional<ProfileCount> Function::getEntryCount(bool AllowSynthetic) const { | |||
| 2040 | MDNode *MD = getMetadata(LLVMContext::MD_prof); | |||
| 2041 | if (MD && MD->getOperand(0)) | |||
| 2042 | if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) { | |||
| 2043 | if (MDS->getString().equals("function_entry_count")) { | |||
| 2044 | ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1)); | |||
| 2045 | uint64_t Count = CI->getValue().getZExtValue(); | |||
| 2046 | // A value of -1 is used for SamplePGO when there were no samples. | |||
| 2047 | // Treat this the same as unknown. | |||
| 2048 | if (Count == (uint64_t)-1) | |||
| 2049 | return std::nullopt; | |||
| 2050 | return ProfileCount(Count, PCT_Real); | |||
| 2051 | } else if (AllowSynthetic && | |||
| 2052 | MDS->getString().equals("synthetic_function_entry_count")) { | |||
| 2053 | ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1)); | |||
| 2054 | uint64_t Count = CI->getValue().getZExtValue(); | |||
| 2055 | return ProfileCount(Count, PCT_Synthetic); | |||
| 2056 | } | |||
| 2057 | } | |||
| 2058 | return std::nullopt; | |||
| 2059 | } | |||
| 2060 | ||||
| 2061 | DenseSet<GlobalValue::GUID> Function::getImportGUIDs() const { | |||
| 2062 | DenseSet<GlobalValue::GUID> R; | |||
| 2063 | if (MDNode *MD = getMetadata(LLVMContext::MD_prof)) | |||
| 2064 | if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) | |||
| 2065 | if (MDS->getString().equals("function_entry_count")) | |||
| 2066 | for (unsigned i = 2; i < MD->getNumOperands(); i++) | |||
| 2067 | R.insert(mdconst::extract<ConstantInt>(MD->getOperand(i)) | |||
| 2068 | ->getValue() | |||
| 2069 | .getZExtValue()); | |||
| 2070 | return R; | |||
| 2071 | } | |||
| 2072 | ||||
| 2073 | void Function::setSectionPrefix(StringRef Prefix) { | |||
| 2074 | MDBuilder MDB(getContext()); | |||
| 2075 | setMetadata(LLVMContext::MD_section_prefix, | |||
| 2076 | MDB.createFunctionSectionPrefix(Prefix)); | |||
| 2077 | } | |||
| 2078 | ||||
| 2079 | std::optional<StringRef> Function::getSectionPrefix() const { | |||
| 2080 | if (MDNode *MD = getMetadata(LLVMContext::MD_section_prefix)) { | |||
| 2081 | assert(cast<MDString>(MD->getOperand(0))(static_cast <bool> (cast<MDString>(MD->getOperand (0)) ->getString() .equals("function_section_prefix") && "Metadata not match") ? void (0) : __assert_fail ("cast<MDString>(MD->getOperand(0)) ->getString() .equals(\"function_section_prefix\") && \"Metadata not match\"" , "llvm/lib/IR/Function.cpp", 2084, __extension__ __PRETTY_FUNCTION__ )) | |||
| 2082 | ->getString()(static_cast <bool> (cast<MDString>(MD->getOperand (0)) ->getString() .equals("function_section_prefix") && "Metadata not match") ? void (0) : __assert_fail ("cast<MDString>(MD->getOperand(0)) ->getString() .equals(\"function_section_prefix\") && \"Metadata not match\"" , "llvm/lib/IR/Function.cpp", 2084, __extension__ __PRETTY_FUNCTION__ )) | |||
| 2083 | .equals("function_section_prefix") &&(static_cast <bool> (cast<MDString>(MD->getOperand (0)) ->getString() .equals("function_section_prefix") && "Metadata not match") ? void (0) : __assert_fail ("cast<MDString>(MD->getOperand(0)) ->getString() .equals(\"function_section_prefix\") && \"Metadata not match\"" , "llvm/lib/IR/Function.cpp", 2084, __extension__ __PRETTY_FUNCTION__ )) | |||
| 2084 | "Metadata not match")(static_cast <bool> (cast<MDString>(MD->getOperand (0)) ->getString() .equals("function_section_prefix") && "Metadata not match") ? void (0) : __assert_fail ("cast<MDString>(MD->getOperand(0)) ->getString() .equals(\"function_section_prefix\") && \"Metadata not match\"" , "llvm/lib/IR/Function.cpp", 2084, __extension__ __PRETTY_FUNCTION__ )); | |||
| 2085 | return cast<MDString>(MD->getOperand(1))->getString(); | |||
| 2086 | } | |||
| 2087 | return std::nullopt; | |||
| 2088 | } | |||
| 2089 | ||||
| 2090 | bool Function::nullPointerIsDefined() const { | |||
| 2091 | return hasFnAttribute(Attribute::NullPointerIsValid); | |||
| 2092 | } | |||
| 2093 | ||||
| 2094 | bool llvm::NullPointerIsDefined(const Function *F, unsigned AS) { | |||
| 2095 | if (F && F->nullPointerIsDefined()) | |||
| 2096 | return true; | |||
| 2097 | ||||
| 2098 | if (AS != 0) | |||
| 2099 | return true; | |||
| 2100 | ||||
| 2101 | return false; | |||
| 2102 | } |
| 1 | //===-- llvm/OperandTraits.h - OperandTraits class definition ---*- C++ -*-===// |
| 2 | // |
| 3 | // 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 |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file defines the traits classes that are handy for enforcing the correct |
| 10 | // layout of various User subclasses. It also provides the means for accessing |
| 11 | // the operands in the most efficient manner. |
| 12 | // |
| 13 | |
| 14 | #ifndef LLVM_IR_OPERANDTRAITS_H |
| 15 | #define LLVM_IR_OPERANDTRAITS_H |
| 16 | |
| 17 | #include "llvm/IR/User.h" |
| 18 | |
| 19 | namespace llvm { |
| 20 | |
| 21 | //===----------------------------------------------------------------------===// |
| 22 | // FixedNumOperand Trait Class |
| 23 | //===----------------------------------------------------------------------===// |
| 24 | |
| 25 | /// FixedNumOperandTraits - determine the allocation regime of the Use array |
| 26 | /// when it is a prefix to the User object, and the number of Use objects is |
| 27 | /// known at compile time. |
| 28 | |
| 29 | template <typename SubClass, unsigned ARITY> |
| 30 | struct FixedNumOperandTraits { |
| 31 | static Use *op_begin(SubClass* U) { |
| 32 | static_assert( |
| 33 | !std::is_polymorphic<SubClass>::value, |
| 34 | "adding virtual methods to subclasses of User breaks use lists"); |
| 35 | return reinterpret_cast<Use*>(U) - ARITY; |
| 36 | } |
| 37 | static Use *op_end(SubClass* U) { |
| 38 | return reinterpret_cast<Use*>(U); |
| 39 | } |
| 40 | static unsigned operands(const User*) { |
| 41 | return ARITY; |
| 42 | } |
| 43 | }; |
| 44 | |
| 45 | //===----------------------------------------------------------------------===// |
| 46 | // OptionalOperand Trait Class |
| 47 | //===----------------------------------------------------------------------===// |
| 48 | |
| 49 | /// OptionalOperandTraits - when the number of operands may change at runtime. |
| 50 | /// Naturally it may only decrease, because the allocations may not change. |
| 51 | |
| 52 | template <typename SubClass, unsigned ARITY = 1> |
| 53 | struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> { |
| 54 | static unsigned operands(const User *U) { |
| 55 | return U->getNumOperands(); |
| 56 | } |
| 57 | }; |
| 58 | |
| 59 | //===----------------------------------------------------------------------===// |
| 60 | // VariadicOperand Trait Class |
| 61 | //===----------------------------------------------------------------------===// |
| 62 | |
| 63 | /// VariadicOperandTraits - determine the allocation regime of the Use array |
| 64 | /// when it is a prefix to the User object, and the number of Use objects is |
| 65 | /// only known at allocation time. |
| 66 | |
| 67 | template <typename SubClass, unsigned MINARITY = 0> |
| 68 | struct VariadicOperandTraits { |
| 69 | static Use *op_begin(SubClass* U) { |
| 70 | static_assert( |
| 71 | !std::is_polymorphic<SubClass>::value, |
| 72 | "adding virtual methods to subclasses of User breaks use lists"); |
| 73 | return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands(); |
| 74 | } |
| 75 | static Use *op_end(SubClass* U) { |
| 76 | return reinterpret_cast<Use*>(U); |
| 77 | } |
| 78 | static unsigned operands(const User *U) { |
| 79 | return U->getNumOperands(); |
| 80 | } |
| 81 | }; |
| 82 | |
| 83 | //===----------------------------------------------------------------------===// |
| 84 | // HungoffOperand Trait Class |
| 85 | //===----------------------------------------------------------------------===// |
| 86 | |
| 87 | /// HungoffOperandTraits - determine the allocation regime of the Use array |
| 88 | /// when it is not a prefix to the User object, but allocated at an unrelated |
| 89 | /// heap address. |
| 90 | /// |
| 91 | /// This is the traits class that is needed when the Use array must be |
| 92 | /// resizable. |
| 93 | |
| 94 | template <unsigned MINARITY = 1> |
| 95 | struct HungoffOperandTraits { |
| 96 | static Use *op_begin(User* U) { |
| 97 | return U->getOperandList(); |
| 98 | } |
| 99 | static Use *op_end(User* U) { |
| 100 | return U->getOperandList() + U->getNumOperands(); |
| 101 | } |
| 102 | static unsigned operands(const User *U) { |
| 103 | return U->getNumOperands(); |
| 104 | } |
| 105 | }; |
| 106 | |
| 107 | /// Macro for generating in-class operand accessor declarations. |
| 108 | /// It should only be called in the public section of the interface. |
| 109 | /// |
| 110 | #define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS)public: inline VALUECLASS *getOperand(unsigned) const; inline void setOperand(unsigned, VALUECLASS*); inline op_iterator op_begin (); inline const_op_iterator op_begin() const; inline op_iterator op_end(); inline const_op_iterator op_end() const; protected : template <int> inline Use &Op(); template <int > inline const Use &Op() const; public: inline unsigned getNumOperands() const \ |
| 111 | public: \ |
| 112 | inline VALUECLASS *getOperand(unsigned) const; \ |
| 113 | inline void setOperand(unsigned, VALUECLASS*); \ |
| 114 | inline op_iterator op_begin(); \ |
| 115 | inline const_op_iterator op_begin() const; \ |
| 116 | inline op_iterator op_end(); \ |
| 117 | inline const_op_iterator op_end() const; \ |
| 118 | protected: \ |
| 119 | template <int> inline Use &Op(); \ |
| 120 | template <int> inline const Use &Op() const; \ |
| 121 | public: \ |
| 122 | inline unsigned getNumOperands() const |
| 123 | |
| 124 | /// Macro for generating out-of-class operand accessor definitions |
| 125 | #define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS)CLASS::op_iterator CLASS::op_begin() { return OperandTraits< CLASS>::op_begin(this); } CLASS::const_op_iterator CLASS:: op_begin() const { return OperandTraits<CLASS>::op_begin (const_cast<CLASS*>(this)); } CLASS::op_iterator CLASS:: op_end() { return OperandTraits<CLASS>::op_end(this); } CLASS::const_op_iterator CLASS::op_end() const { return OperandTraits <CLASS>::op_end(const_cast<CLASS*>(this)); } VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { (static_cast <bool> (i_nocapture < OperandTraits<CLASS>::operands (this) && "getOperand() out of range!") ? void (0) : __assert_fail ("i_nocapture < OperandTraits<CLASS>::operands(this) && \"getOperand() out of range!\"" , "llvm/include/llvm/IR/OperandTraits.h", 125, __extension__ __PRETTY_FUNCTION__ )); return cast_or_null<VALUECLASS>( OperandTraits<CLASS >::op_begin(const_cast<CLASS*>(this))[i_nocapture].get ()); } void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { (static_cast <bool> (i_nocapture < OperandTraits<CLASS>::operands(this) && "setOperand() out of range!" ) ? void (0) : __assert_fail ("i_nocapture < OperandTraits<CLASS>::operands(this) && \"setOperand() out of range!\"" , "llvm/include/llvm/IR/OperandTraits.h", 125, __extension__ __PRETTY_FUNCTION__ )); OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; } unsigned CLASS::getNumOperands() const { return OperandTraits<CLASS>::operands(this); } template <int Idx_nocapture> Use &CLASS::Op() { return this->OpFrom <Idx_nocapture>(this); } template <int Idx_nocapture > const Use &CLASS::Op() const { return this->OpFrom <Idx_nocapture>(this); } \ |
| 126 | CLASS::op_iterator CLASS::op_begin() { \ |
| 127 | return OperandTraits<CLASS>::op_begin(this); \ |
| 128 | } \ |
| 129 | CLASS::const_op_iterator CLASS::op_begin() const { \ |
| 130 | return OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this)); \ |
| 131 | } \ |
| 132 | CLASS::op_iterator CLASS::op_end() { \ |
| 133 | return OperandTraits<CLASS>::op_end(this); \ |
| 134 | } \ |
| 135 | CLASS::const_op_iterator CLASS::op_end() const { \ |
| 136 | return OperandTraits<CLASS>::op_end(const_cast<CLASS*>(this)); \ |
| 137 | } \ |
| 138 | VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \ |
| 139 | assert(i_nocapture < OperandTraits<CLASS>::operands(this) \(static_cast <bool> (i_nocapture < OperandTraits< CLASS>::operands(this) && "getOperand() out of range!" ) ? void (0) : __assert_fail ("i_nocapture < OperandTraits<CLASS>::operands(this) && \"getOperand() out of range!\"" , "llvm/include/llvm/IR/OperandTraits.h", 140, __extension__ __PRETTY_FUNCTION__ )) |
| 140 | && "getOperand() out of range!")(static_cast <bool> (i_nocapture < OperandTraits< CLASS>::operands(this) && "getOperand() out of range!" ) ? void (0) : __assert_fail ("i_nocapture < OperandTraits<CLASS>::operands(this) && \"getOperand() out of range!\"" , "llvm/include/llvm/IR/OperandTraits.h", 140, __extension__ __PRETTY_FUNCTION__ )); \ |
| 141 | return cast_or_null<VALUECLASS>( \ |
| 142 | OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture].get()); \ |
| 143 | } \ |
| 144 | void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \ |
| 145 | assert(i_nocapture < OperandTraits<CLASS>::operands(this) \(static_cast <bool> (i_nocapture < OperandTraits< CLASS>::operands(this) && "setOperand() out of range!" ) ? void (0) : __assert_fail ("i_nocapture < OperandTraits<CLASS>::operands(this) && \"setOperand() out of range!\"" , "llvm/include/llvm/IR/OperandTraits.h", 146, __extension__ __PRETTY_FUNCTION__ )) |
| 146 | && "setOperand() out of range!")(static_cast <bool> (i_nocapture < OperandTraits< CLASS>::operands(this) && "setOperand() out of range!" ) ? void (0) : __assert_fail ("i_nocapture < OperandTraits<CLASS>::operands(this) && \"setOperand() out of range!\"" , "llvm/include/llvm/IR/OperandTraits.h", 146, __extension__ __PRETTY_FUNCTION__ )); \ |
| 147 | OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \ |
| 148 | } \ |
| 149 | unsigned CLASS::getNumOperands() const { \ |
| 150 | return OperandTraits<CLASS>::operands(this); \ |
| 151 | } \ |
| 152 | template <int Idx_nocapture> Use &CLASS::Op() { \ |
| 153 | return this->OpFrom<Idx_nocapture>(this); \ |
| 154 | } \ |
| 155 | template <int Idx_nocapture> const Use &CLASS::Op() const { \ |
| 156 | return this->OpFrom<Idx_nocapture>(this); \ |
| 157 | } |
| 158 | |
| 159 | |
| 160 | } // End llvm namespace |
| 161 | |
| 162 | #endif |
| 1 | //===- llvm/User.h - User class definition ----------------------*- C++ -*-===// | |||
| 2 | // | |||
| 3 | // 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 | |||
| 6 | // | |||
| 7 | //===----------------------------------------------------------------------===// | |||
| 8 | // | |||
| 9 | // This class defines the interface that one who uses a Value must implement. | |||
| 10 | // Each instance of the Value class keeps track of what User's have handles | |||
| 11 | // to it. | |||
| 12 | // | |||
| 13 | // * Instructions are the largest class of Users. | |||
| 14 | // * Constants may be users of other constants (think arrays and stuff) | |||
| 15 | // | |||
| 16 | //===----------------------------------------------------------------------===// | |||
| 17 | ||||
| 18 | #ifndef LLVM_IR_USER_H | |||
| 19 | #define LLVM_IR_USER_H | |||
| 20 | ||||
| 21 | #include "llvm/ADT/iterator.h" | |||
| 22 | #include "llvm/ADT/iterator_range.h" | |||
| 23 | #include "llvm/IR/Use.h" | |||
| 24 | #include "llvm/IR/Value.h" | |||
| 25 | #include "llvm/Support/Casting.h" | |||
| 26 | #include "llvm/Support/Compiler.h" | |||
| 27 | #include "llvm/Support/ErrorHandling.h" | |||
| 28 | #include <cassert> | |||
| 29 | #include <cstddef> | |||
| 30 | #include <cstdint> | |||
| 31 | #include <iterator> | |||
| 32 | ||||
| 33 | namespace llvm { | |||
| 34 | ||||
| 35 | template <typename T> class ArrayRef; | |||
| 36 | template <typename T> class MutableArrayRef; | |||
| 37 | ||||
| 38 | /// Compile-time customization of User operands. | |||
| 39 | /// | |||
| 40 | /// Customizes operand-related allocators and accessors. | |||
| 41 | template <class> | |||
| 42 | struct OperandTraits; | |||
| 43 | ||||
| 44 | class User : public Value { | |||
| 45 | template <unsigned> | |||
| 46 | friend struct HungoffOperandTraits; | |||
| 47 | ||||
| 48 | LLVM_ATTRIBUTE_ALWAYS_INLINEinline __attribute__((always_inline)) static void * | |||
| 49 | allocateFixedOperandUser(size_t, unsigned, unsigned); | |||
| 50 | ||||
| 51 | protected: | |||
| 52 | /// Allocate a User with an operand pointer co-allocated. | |||
| 53 | /// | |||
| 54 | /// This is used for subclasses which need to allocate a variable number | |||
| 55 | /// of operands, ie, 'hung off uses'. | |||
| 56 | void *operator new(size_t Size); | |||
| 57 | ||||
| 58 | /// Allocate a User with the operands co-allocated. | |||
| 59 | /// | |||
| 60 | /// This is used for subclasses which have a fixed number of operands. | |||
| 61 | void *operator new(size_t Size, unsigned Us); | |||
| 62 | ||||
| 63 | /// Allocate a User with the operands co-allocated. If DescBytes is non-zero | |||
| 64 | /// then allocate an additional DescBytes bytes before the operands. These | |||
| 65 | /// bytes can be accessed by calling getDescriptor. | |||
| 66 | /// | |||
| 67 | /// DescBytes needs to be divisible by sizeof(void *). The allocated | |||
| 68 | /// descriptor, if any, is aligned to sizeof(void *) bytes. | |||
| 69 | /// | |||
| 70 | /// This is used for subclasses which have a fixed number of operands. | |||
| 71 | void *operator new(size_t Size, unsigned Us, unsigned DescBytes); | |||
| 72 | ||||
| 73 | User(Type *ty, unsigned vty, Use *, unsigned NumOps) | |||
| 74 | : Value(ty, vty) { | |||
| 75 | assert(NumOps < (1u << NumUserOperandsBits) && "Too many operands")(static_cast <bool> (NumOps < (1u << NumUserOperandsBits ) && "Too many operands") ? void (0) : __assert_fail ( "NumOps < (1u << NumUserOperandsBits) && \"Too many operands\"" , "llvm/include/llvm/IR/User.h", 75, __extension__ __PRETTY_FUNCTION__ )); | |||
| 76 | NumUserOperands = NumOps; | |||
| 77 | // If we have hung off uses, then the operand list should initially be | |||
| 78 | // null. | |||
| 79 | assert((!HasHungOffUses || !getOperandList()) &&(static_cast <bool> ((!HasHungOffUses || !getOperandList ()) && "Error in initializing hung off uses for User" ) ? void (0) : __assert_fail ("(!HasHungOffUses || !getOperandList()) && \"Error in initializing hung off uses for User\"" , "llvm/include/llvm/IR/User.h", 80, __extension__ __PRETTY_FUNCTION__ )) | |||
| 80 | "Error in initializing hung off uses for User")(static_cast <bool> ((!HasHungOffUses || !getOperandList ()) && "Error in initializing hung off uses for User" ) ? void (0) : __assert_fail ("(!HasHungOffUses || !getOperandList()) && \"Error in initializing hung off uses for User\"" , "llvm/include/llvm/IR/User.h", 80, __extension__ __PRETTY_FUNCTION__ )); | |||
| 81 | } | |||
| 82 | ||||
| 83 | /// Allocate the array of Uses, followed by a pointer | |||
| 84 | /// (with bottom bit set) to the User. | |||
| 85 | /// \param IsPhi identifies callers which are phi nodes and which need | |||
| 86 | /// N BasicBlock* allocated along with N | |||
| 87 | void allocHungoffUses(unsigned N, bool IsPhi = false); | |||
| 88 | ||||
| 89 | /// Grow the number of hung off uses. Note that allocHungoffUses | |||
| 90 | /// should be called if there are no uses. | |||
| 91 | void growHungoffUses(unsigned N, bool IsPhi = false); | |||
| 92 | ||||
| 93 | protected: | |||
| 94 | ~User() = default; // Use deleteValue() to delete a generic Instruction. | |||
| 95 | ||||
| 96 | public: | |||
| 97 | User(const User &) = delete; | |||
| 98 | ||||
| 99 | /// Free memory allocated for User and Use objects. | |||
| 100 | void operator delete(void *Usr); | |||
| 101 | /// Placement delete - required by std, called if the ctor throws. | |||
| 102 | void operator delete(void *Usr, unsigned) { | |||
| 103 | // Note: If a subclass manipulates the information which is required to calculate the | |||
| 104 | // Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has | |||
| 105 | // to restore the changed information to the original value, since the dtor of that class | |||
| 106 | // is not called if the ctor fails. | |||
| 107 | User::operator delete(Usr); | |||
| 108 | ||||
| 109 | #ifndef LLVM_ENABLE_EXCEPTIONS | |||
| 110 | llvm_unreachable("Constructor throws?")::llvm::llvm_unreachable_internal("Constructor throws?", "llvm/include/llvm/IR/User.h" , 110); | |||
| 111 | #endif | |||
| 112 | } | |||
| 113 | /// Placement delete - required by std, called if the ctor throws. | |||
| 114 | void operator delete(void *Usr, unsigned, unsigned) { | |||
| 115 | // Note: If a subclass manipulates the information which is required to calculate the | |||
| 116 | // Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has | |||
| 117 | // to restore the changed information to the original value, since the dtor of that class | |||
| 118 | // is not called if the ctor fails. | |||
| 119 | User::operator delete(Usr); | |||
| 120 | ||||
| 121 | #ifndef LLVM_ENABLE_EXCEPTIONS | |||
| 122 | llvm_unreachable("Constructor throws?")::llvm::llvm_unreachable_internal("Constructor throws?", "llvm/include/llvm/IR/User.h" , 122); | |||
| 123 | #endif | |||
| 124 | } | |||
| 125 | ||||
| 126 | protected: | |||
| 127 | template <int Idx, typename U> static Use &OpFrom(const U *that) { | |||
| 128 | return Idx < 0 | |||
| 129 | ? OperandTraits<U>::op_end(const_cast<U*>(that))[Idx] | |||
| 130 | : OperandTraits<U>::op_begin(const_cast<U*>(that))[Idx]; | |||
| 131 | } | |||
| 132 | ||||
| 133 | template <int Idx> Use &Op() { | |||
| 134 | return OpFrom<Idx>(this); | |||
| 135 | } | |||
| 136 | template <int Idx> const Use &Op() const { | |||
| 137 | return OpFrom<Idx>(this); | |||
| 138 | } | |||
| 139 | ||||
| 140 | private: | |||
| 141 | const Use *getHungOffOperands() const { | |||
| 142 | return *(reinterpret_cast<const Use *const *>(this) - 1); | |||
| 143 | } | |||
| 144 | ||||
| 145 | Use *&getHungOffOperands() { return *(reinterpret_cast<Use **>(this) - 1); } | |||
| 146 | ||||
| 147 | const Use *getIntrusiveOperands() const { | |||
| 148 | return reinterpret_cast<const Use *>(this) - NumUserOperands; | |||
| 149 | } | |||
| 150 | ||||
| 151 | Use *getIntrusiveOperands() { | |||
| 152 | return reinterpret_cast<Use *>(this) - NumUserOperands; | |||
| 153 | } | |||
| 154 | ||||
| 155 | void setOperandList(Use *NewList) { | |||
| 156 | assert(HasHungOffUses &&(static_cast <bool> (HasHungOffUses && "Setting operand list only required for hung off uses" ) ? void (0) : __assert_fail ("HasHungOffUses && \"Setting operand list only required for hung off uses\"" , "llvm/include/llvm/IR/User.h", 157, __extension__ __PRETTY_FUNCTION__ )) | |||
| 157 | "Setting operand list only required for hung off uses")(static_cast <bool> (HasHungOffUses && "Setting operand list only required for hung off uses" ) ? void (0) : __assert_fail ("HasHungOffUses && \"Setting operand list only required for hung off uses\"" , "llvm/include/llvm/IR/User.h", 157, __extension__ __PRETTY_FUNCTION__ )); | |||
| 158 | getHungOffOperands() = NewList; | |||
| 159 | } | |||
| 160 | ||||
| 161 | public: | |||
| 162 | const Use *getOperandList() const { | |||
| 163 | return HasHungOffUses ? getHungOffOperands() : getIntrusiveOperands(); | |||
| ||||
| 164 | } | |||
| 165 | Use *getOperandList() { | |||
| 166 | return const_cast<Use *>(static_cast<const User *>(this)->getOperandList()); | |||
| 167 | } | |||
| 168 | ||||
| 169 | Value *getOperand(unsigned i) const { | |||
| 170 | assert(i < NumUserOperands && "getOperand() out of range!")(static_cast <bool> (i < NumUserOperands && "getOperand() out of range!" ) ? void (0) : __assert_fail ("i < NumUserOperands && \"getOperand() out of range!\"" , "llvm/include/llvm/IR/User.h", 170, __extension__ __PRETTY_FUNCTION__ )); | |||
| 171 | return getOperandList()[i]; | |||
| 172 | } | |||
| 173 | ||||
| 174 | void setOperand(unsigned i, Value *Val) { | |||
| 175 | assert(i < NumUserOperands && "setOperand() out of range!")(static_cast <bool> (i < NumUserOperands && "setOperand() out of range!" ) ? void (0) : __assert_fail ("i < NumUserOperands && \"setOperand() out of range!\"" , "llvm/include/llvm/IR/User.h", 175, __extension__ __PRETTY_FUNCTION__ )); | |||
| 176 | assert((!isa<Constant>((const Value*)this) ||(static_cast <bool> ((!isa<Constant>((const Value *)this) || isa<GlobalValue>((const Value*)this)) && "Cannot mutate a constant with setOperand!") ? void (0) : __assert_fail ("(!isa<Constant>((const Value*)this) || isa<GlobalValue>((const Value*)this)) && \"Cannot mutate a constant with setOperand!\"" , "llvm/include/llvm/IR/User.h", 178, __extension__ __PRETTY_FUNCTION__ )) | |||
| 177 | isa<GlobalValue>((const Value*)this)) &&(static_cast <bool> ((!isa<Constant>((const Value *)this) || isa<GlobalValue>((const Value*)this)) && "Cannot mutate a constant with setOperand!") ? void (0) : __assert_fail ("(!isa<Constant>((const Value*)this) || isa<GlobalValue>((const Value*)this)) && \"Cannot mutate a constant with setOperand!\"" , "llvm/include/llvm/IR/User.h", 178, __extension__ __PRETTY_FUNCTION__ )) | |||
| 178 | "Cannot mutate a constant with setOperand!")(static_cast <bool> ((!isa<Constant>((const Value *)this) || isa<GlobalValue>((const Value*)this)) && "Cannot mutate a constant with setOperand!") ? void (0) : __assert_fail ("(!isa<Constant>((const Value*)this) || isa<GlobalValue>((const Value*)this)) && \"Cannot mutate a constant with setOperand!\"" , "llvm/include/llvm/IR/User.h", 178, __extension__ __PRETTY_FUNCTION__ )); | |||
| 179 | getOperandList()[i] = Val; | |||
| 180 | } | |||
| 181 | ||||
| 182 | const Use &getOperandUse(unsigned i) const { | |||
| 183 | assert(i < NumUserOperands && "getOperandUse() out of range!")(static_cast <bool> (i < NumUserOperands && "getOperandUse() out of range!" ) ? void (0) : __assert_fail ("i < NumUserOperands && \"getOperandUse() out of range!\"" , "llvm/include/llvm/IR/User.h", 183, __extension__ __PRETTY_FUNCTION__ )); | |||
| 184 | return getOperandList()[i]; | |||
| 185 | } | |||
| 186 | Use &getOperandUse(unsigned i) { | |||
| 187 | assert(i < NumUserOperands && "getOperandUse() out of range!")(static_cast <bool> (i < NumUserOperands && "getOperandUse() out of range!" ) ? void (0) : __assert_fail ("i < NumUserOperands && \"getOperandUse() out of range!\"" , "llvm/include/llvm/IR/User.h", 187, __extension__ __PRETTY_FUNCTION__ )); | |||
| 188 | return getOperandList()[i]; | |||
| 189 | } | |||
| 190 | ||||
| 191 | unsigned getNumOperands() const { return NumUserOperands; } | |||
| 192 | ||||
| 193 | /// Returns the descriptor co-allocated with this User instance. | |||
| 194 | ArrayRef<const uint8_t> getDescriptor() const; | |||
| 195 | ||||
| 196 | /// Returns the descriptor co-allocated with this User instance. | |||
| 197 | MutableArrayRef<uint8_t> getDescriptor(); | |||
| 198 | ||||
| 199 | /// Set the number of operands on a GlobalVariable. | |||
| 200 | /// | |||
| 201 | /// GlobalVariable always allocates space for a single operands, but | |||
| 202 | /// doesn't always use it. | |||
| 203 | /// | |||
| 204 | /// FIXME: As that the number of operands is used to find the start of | |||
| 205 | /// the allocated memory in operator delete, we need to always think we have | |||
| 206 | /// 1 operand before delete. | |||
| 207 | void setGlobalVariableNumOperands(unsigned NumOps) { | |||
| 208 | assert(NumOps <= 1 && "GlobalVariable can only have 0 or 1 operands")(static_cast <bool> (NumOps <= 1 && "GlobalVariable can only have 0 or 1 operands" ) ? void (0) : __assert_fail ("NumOps <= 1 && \"GlobalVariable can only have 0 or 1 operands\"" , "llvm/include/llvm/IR/User.h", 208, __extension__ __PRETTY_FUNCTION__ )); | |||
| 209 | NumUserOperands = NumOps; | |||
| 210 | } | |||
| 211 | ||||
| 212 | /// Subclasses with hung off uses need to manage the operand count | |||
| 213 | /// themselves. In these instances, the operand count isn't used to find the | |||
| 214 | /// OperandList, so there's no issue in having the operand count change. | |||
| 215 | void setNumHungOffUseOperands(unsigned NumOps) { | |||
| 216 | assert(HasHungOffUses && "Must have hung off uses to use this method")(static_cast <bool> (HasHungOffUses && "Must have hung off uses to use this method" ) ? void (0) : __assert_fail ("HasHungOffUses && \"Must have hung off uses to use this method\"" , "llvm/include/llvm/IR/User.h", 216, __extension__ __PRETTY_FUNCTION__ )); | |||
| 217 | assert(NumOps < (1u << NumUserOperandsBits) && "Too many operands")(static_cast <bool> (NumOps < (1u << NumUserOperandsBits ) && "Too many operands") ? void (0) : __assert_fail ( "NumOps < (1u << NumUserOperandsBits) && \"Too many operands\"" , "llvm/include/llvm/IR/User.h", 217, __extension__ __PRETTY_FUNCTION__ )); | |||
| 218 | NumUserOperands = NumOps; | |||
| 219 | } | |||
| 220 | ||||
| 221 | /// A droppable user is a user for which uses can be dropped without affecting | |||
| 222 | /// correctness and should be dropped rather than preventing a transformation | |||
| 223 | /// from happening. | |||
| 224 | bool isDroppable() const; | |||
| 225 | ||||
| 226 | // --------------------------------------------------------------------------- | |||
| 227 | // Operand Iterator interface... | |||
| 228 | // | |||
| 229 | using op_iterator = Use*; | |||
| 230 | using const_op_iterator = const Use*; | |||
| 231 | using op_range = iterator_range<op_iterator>; | |||
| 232 | using const_op_range = iterator_range<const_op_iterator>; | |||
| 233 | ||||
| 234 | op_iterator op_begin() { return getOperandList(); } | |||
| 235 | const_op_iterator op_begin() const { return getOperandList(); } | |||
| 236 | op_iterator op_end() { | |||
| 237 | return getOperandList() + NumUserOperands; | |||
| 238 | } | |||
| 239 | const_op_iterator op_end() const { | |||
| 240 | return getOperandList() + NumUserOperands; | |||
| 241 | } | |||
| 242 | op_range operands() { | |||
| 243 | return op_range(op_begin(), op_end()); | |||
| 244 | } | |||
| 245 | const_op_range operands() const { | |||
| 246 | return const_op_range(op_begin(), op_end()); | |||
| 247 | } | |||
| 248 | ||||
| 249 | /// Iterator for directly iterating over the operand Values. | |||
| 250 | struct value_op_iterator | |||
| 251 | : iterator_adaptor_base<value_op_iterator, op_iterator, | |||
| 252 | std::random_access_iterator_tag, Value *, | |||
| 253 | ptrdiff_t, Value *, Value *> { | |||
| 254 | explicit value_op_iterator(Use *U = nullptr) : iterator_adaptor_base(U) {} | |||
| 255 | ||||
| 256 | Value *operator*() const { return *I; } | |||
| 257 | Value *operator->() const { return operator*(); } | |||
| 258 | }; | |||
| 259 | ||||
| 260 | value_op_iterator value_op_begin() { | |||
| 261 | return value_op_iterator(op_begin()); | |||
| 262 | } | |||
| 263 | value_op_iterator value_op_end() { | |||
| 264 | return value_op_iterator(op_end()); | |||
| 265 | } | |||
| 266 | iterator_range<value_op_iterator> operand_values() { | |||
| 267 | return make_range(value_op_begin(), value_op_end()); | |||
| 268 | } | |||
| 269 | ||||
| 270 | struct const_value_op_iterator | |||
| 271 | : iterator_adaptor_base<const_value_op_iterator, const_op_iterator, | |||
| 272 | std::random_access_iterator_tag, const Value *, | |||
| 273 | ptrdiff_t, const Value *, const Value *> { | |||
| 274 | explicit const_value_op_iterator(const Use *U = nullptr) : | |||
| 275 | iterator_adaptor_base(U) {} | |||
| 276 | ||||
| 277 | const Value *operator*() const { return *I; } | |||
| 278 | const Value *operator->() const { return operator*(); } | |||
| 279 | }; | |||
| 280 | ||||
| 281 | const_value_op_iterator value_op_begin() const { | |||
| 282 | return const_value_op_iterator(op_begin()); | |||
| 283 | } | |||
| 284 | const_value_op_iterator value_op_end() const { | |||
| 285 | return const_value_op_iterator(op_end()); | |||
| 286 | } | |||
| 287 | iterator_range<const_value_op_iterator> operand_values() const { | |||
| 288 | return make_range(value_op_begin(), value_op_end()); | |||
| 289 | } | |||
| 290 | ||||
| 291 | /// Drop all references to operands. | |||
| 292 | /// | |||
| 293 | /// This function is in charge of "letting go" of all objects that this User | |||
| 294 | /// refers to. This allows one to 'delete' a whole class at a time, even | |||
| 295 | /// though there may be circular references... First all references are | |||
| 296 | /// dropped, and all use counts go to zero. Then everything is deleted for | |||
| 297 | /// real. Note that no operations are valid on an object that has "dropped | |||
| 298 | /// all references", except operator delete. | |||
| 299 | void dropAllReferences() { | |||
| 300 | for (Use &U : operands()) | |||
| 301 | U.set(nullptr); | |||
| 302 | } | |||
| 303 | ||||
| 304 | /// Replace uses of one Value with another. | |||
| 305 | /// | |||
| 306 | /// Replaces all references to the "From" definition with references to the | |||
| 307 | /// "To" definition. Returns whether any uses were replaced. | |||
| 308 | bool replaceUsesOfWith(Value *From, Value *To); | |||
| 309 | ||||
| 310 | // Methods for support type inquiry through isa, cast, and dyn_cast: | |||
| 311 | static bool classof(const Value *V) { | |||
| 312 | return isa<Instruction>(V) || isa<Constant>(V); | |||
| 313 | } | |||
| 314 | }; | |||
| 315 | ||||
| 316 | // Either Use objects, or a Use pointer can be prepended to User. | |||
| 317 | static_assert(alignof(Use) >= alignof(User), | |||
| 318 | "Alignment is insufficient after objects prepended to User"); | |||
| 319 | static_assert(alignof(Use *) >= alignof(User), | |||
| 320 | "Alignment is insufficient after objects prepended to User"); | |||
| 321 | ||||
| 322 | template<> struct simplify_type<User::op_iterator> { | |||
| 323 | using SimpleType = Value*; | |||
| 324 | ||||
| 325 | static SimpleType getSimplifiedValue(User::op_iterator &Val) { | |||
| 326 | return Val->get(); | |||
| 327 | } | |||
| 328 | }; | |||
| 329 | template<> struct simplify_type<User::const_op_iterator> { | |||
| 330 | using SimpleType = /*const*/ Value*; | |||
| 331 | ||||
| 332 | static SimpleType getSimplifiedValue(User::const_op_iterator &Val) { | |||
| 333 | return Val->get(); | |||
| 334 | } | |||
| 335 | }; | |||
| 336 | ||||
| 337 | } // end namespace llvm | |||
| 338 | ||||
| 339 | #endif // LLVM_IR_USER_H |