brintos

brintos / llvm-project-archived public Read only

0
0
Text · 40.3 KiB · 31a2944 Raw
1267 lines · cpp
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-exception6//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/BitVector.h"17#include "llvm/ADT/DenseSet.h"18#include "llvm/ADT/STLExtras.h"19#include "llvm/ADT/SmallString.h"20#include "llvm/ADT/SmallVector.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/ConstantRange.h"28#include "llvm/IR/Constants.h"29#include "llvm/IR/DerivedTypes.h"30#include "llvm/IR/GlobalValue.h"31#include "llvm/IR/InstIterator.h"32#include "llvm/IR/Instruction.h"33#include "llvm/IR/IntrinsicInst.h"34#include "llvm/IR/Intrinsics.h"35#include "llvm/IR/LLVMContext.h"36#include "llvm/IR/MDBuilder.h"37#include "llvm/IR/Metadata.h"38#include "llvm/IR/Module.h"39#include "llvm/IR/Operator.h"40#include "llvm/IR/ProfDataUtils.h"41#include "llvm/IR/SymbolTableListTraits.h"42#include "llvm/IR/Type.h"43#include "llvm/IR/Use.h"44#include "llvm/IR/User.h"45#include "llvm/IR/Value.h"46#include "llvm/IR/ValueSymbolTable.h"47#include "llvm/Support/Casting.h"48#include "llvm/Support/CommandLine.h"49#include "llvm/Support/Compiler.h"50#include "llvm/Support/ErrorHandling.h"51#include "llvm/Support/ModRef.h"52#include <cassert>53#include <cstddef>54#include <cstdint>55#include <cstring>56#include <string>57 58using namespace llvm;59using ProfileCount = Function::ProfileCount;60 61// Explicit instantiations of SymbolTableListTraits since some of the methods62// are not in the public header file...63template class LLVM_EXPORT_TEMPLATE llvm::SymbolTableListTraits<BasicBlock>;64 65static cl::opt<int> NonGlobalValueMaxNameSize(66    "non-global-value-max-name-size", cl::Hidden, cl::init(1024),67    cl::desc("Maximum size for the name of non-global values."));68 69void Function::renumberBlocks() {70  validateBlockNumbers();71 72  NextBlockNum = 0;73  for (auto &BB : *this)74    BB.Number = NextBlockNum++;75  BlockNumEpoch++;76}77 78void Function::validateBlockNumbers() const {79#ifndef NDEBUG80  BitVector Numbers(NextBlockNum);81  for (const auto &BB : *this) {82    unsigned Num = BB.getNumber();83    assert(Num < NextBlockNum && "out of range block number");84    assert(!Numbers[Num] && "duplicate block numbers");85    Numbers.set(Num);86  }87#endif88}89 90void Function::convertToNewDbgValues() {91  for (auto &BB : *this) {92    BB.convertToNewDbgValues();93  }94}95 96void Function::convertFromNewDbgValues() {97  for (auto &BB : *this) {98    BB.convertFromNewDbgValues();99  }100}101 102//===----------------------------------------------------------------------===//103// Argument Implementation104//===----------------------------------------------------------------------===//105 106Argument::Argument(Type *Ty, const Twine &Name, Function *Par, unsigned ArgNo)107    : Value(Ty, Value::ArgumentVal), Parent(Par), ArgNo(ArgNo) {108  setName(Name);109}110 111void Argument::setParent(Function *parent) {112  Parent = parent;113}114 115bool Argument::hasNonNullAttr(bool AllowUndefOrPoison) const {116  if (!getType()->isPointerTy()) return false;117  if (getParent()->hasParamAttribute(getArgNo(), Attribute::NonNull) &&118      (AllowUndefOrPoison ||119       getParent()->hasParamAttribute(getArgNo(), Attribute::NoUndef)))120    return true;121  else if (getDereferenceableBytes() > 0 &&122           !NullPointerIsDefined(getParent(),123                                 getType()->getPointerAddressSpace()))124    return true;125  return false;126}127 128bool Argument::hasByValAttr() const {129  if (!getType()->isPointerTy()) return false;130  return hasAttribute(Attribute::ByVal);131}132 133bool Argument::hasDeadOnReturnAttr() const {134  if (!getType()->isPointerTy())135    return false;136  return hasAttribute(Attribute::DeadOnReturn);137}138 139bool Argument::hasByRefAttr() const {140  if (!getType()->isPointerTy())141    return false;142  return hasAttribute(Attribute::ByRef);143}144 145bool Argument::hasSwiftSelfAttr() const {146  return getParent()->hasParamAttribute(getArgNo(), Attribute::SwiftSelf);147}148 149bool Argument::hasSwiftErrorAttr() const {150  return getParent()->hasParamAttribute(getArgNo(), Attribute::SwiftError);151}152 153bool Argument::hasInAllocaAttr() const {154  if (!getType()->isPointerTy()) return false;155  return hasAttribute(Attribute::InAlloca);156}157 158bool Argument::hasPreallocatedAttr() const {159  if (!getType()->isPointerTy())160    return false;161  return hasAttribute(Attribute::Preallocated);162}163 164bool Argument::hasPassPointeeByValueCopyAttr() const {165  if (!getType()->isPointerTy()) return false;166  AttributeList Attrs = getParent()->getAttributes();167  return Attrs.hasParamAttr(getArgNo(), Attribute::ByVal) ||168         Attrs.hasParamAttr(getArgNo(), Attribute::InAlloca) ||169         Attrs.hasParamAttr(getArgNo(), Attribute::Preallocated);170}171 172bool Argument::hasPointeeInMemoryValueAttr() const {173  if (!getType()->isPointerTy())174    return false;175  AttributeList Attrs = getParent()->getAttributes();176  return Attrs.hasParamAttr(getArgNo(), Attribute::ByVal) ||177         Attrs.hasParamAttr(getArgNo(), Attribute::StructRet) ||178         Attrs.hasParamAttr(getArgNo(), Attribute::InAlloca) ||179         Attrs.hasParamAttr(getArgNo(), Attribute::Preallocated) ||180         Attrs.hasParamAttr(getArgNo(), Attribute::ByRef);181}182 183/// For a byval, sret, inalloca, or preallocated parameter, get the in-memory184/// parameter type.185static Type *getMemoryParamAllocType(AttributeSet ParamAttrs) {186  // FIXME: All the type carrying attributes are mutually exclusive, so there187  // should be a single query to get the stored type that handles any of them.188  if (Type *ByValTy = ParamAttrs.getByValType())189    return ByValTy;190  if (Type *ByRefTy = ParamAttrs.getByRefType())191    return ByRefTy;192  if (Type *PreAllocTy = ParamAttrs.getPreallocatedType())193    return PreAllocTy;194  if (Type *InAllocaTy = ParamAttrs.getInAllocaType())195    return InAllocaTy;196  if (Type *SRetTy = ParamAttrs.getStructRetType())197    return SRetTy;198 199  return nullptr;200}201 202uint64_t Argument::getPassPointeeByValueCopySize(const DataLayout &DL) const {203  AttributeSet ParamAttrs =204      getParent()->getAttributes().getParamAttrs(getArgNo());205  if (Type *MemTy = getMemoryParamAllocType(ParamAttrs))206    return DL.getTypeAllocSize(MemTy);207  return 0;208}209 210Type *Argument::getPointeeInMemoryValueType() const {211  AttributeSet ParamAttrs =212      getParent()->getAttributes().getParamAttrs(getArgNo());213  return getMemoryParamAllocType(ParamAttrs);214}215 216MaybeAlign Argument::getParamAlign() const {217  assert(getType()->isPointerTy() && "Only pointers have alignments");218  return getParent()->getParamAlign(getArgNo());219}220 221MaybeAlign Argument::getParamStackAlign() const {222  return getParent()->getParamStackAlign(getArgNo());223}224 225Type *Argument::getParamByValType() const {226  assert(getType()->isPointerTy() && "Only pointers have byval types");227  return getParent()->getParamByValType(getArgNo());228}229 230Type *Argument::getParamStructRetType() const {231  assert(getType()->isPointerTy() && "Only pointers have sret types");232  return getParent()->getParamStructRetType(getArgNo());233}234 235Type *Argument::getParamByRefType() const {236  assert(getType()->isPointerTy() && "Only pointers have byref types");237  return getParent()->getParamByRefType(getArgNo());238}239 240Type *Argument::getParamInAllocaType() const {241  assert(getType()->isPointerTy() && "Only pointers have inalloca types");242  return getParent()->getParamInAllocaType(getArgNo());243}244 245uint64_t Argument::getDereferenceableBytes() const {246  assert(getType()->isPointerTy() &&247         "Only pointers have dereferenceable bytes");248  return getParent()->getParamDereferenceableBytes(getArgNo());249}250 251uint64_t Argument::getDereferenceableOrNullBytes() const {252  assert(getType()->isPointerTy() &&253         "Only pointers have dereferenceable bytes");254  return getParent()->getParamDereferenceableOrNullBytes(getArgNo());255}256 257FPClassTest Argument::getNoFPClass() const {258  return getParent()->getParamNoFPClass(getArgNo());259}260 261std::optional<ConstantRange> Argument::getRange() const {262  const Attribute RangeAttr = getAttribute(llvm::Attribute::Range);263  if (RangeAttr.isValid())264    return RangeAttr.getRange();265  return std::nullopt;266}267 268bool Argument::hasNestAttr() const {269  if (!getType()->isPointerTy()) return false;270  return hasAttribute(Attribute::Nest);271}272 273bool Argument::hasNoAliasAttr() const {274  if (!getType()->isPointerTy()) return false;275  return hasAttribute(Attribute::NoAlias);276}277 278bool Argument::hasNoCaptureAttr() const {279  if (!getType()->isPointerTy()) return false;280  return capturesNothing(getAttributes().getCaptureInfo());281}282 283bool Argument::hasNoFreeAttr() const {284  if (!getType()->isPointerTy()) return false;285  return hasAttribute(Attribute::NoFree);286}287 288bool Argument::hasStructRetAttr() const {289  if (!getType()->isPointerTy()) return false;290  return hasAttribute(Attribute::StructRet);291}292 293bool Argument::hasInRegAttr() const {294  return hasAttribute(Attribute::InReg);295}296 297bool Argument::hasReturnedAttr() const {298  return hasAttribute(Attribute::Returned);299}300 301bool Argument::hasZExtAttr() const {302  return hasAttribute(Attribute::ZExt);303}304 305bool Argument::hasSExtAttr() const {306  return hasAttribute(Attribute::SExt);307}308 309bool Argument::onlyReadsMemory() const {310  AttributeList Attrs = getParent()->getAttributes();311  return Attrs.hasParamAttr(getArgNo(), Attribute::ReadOnly) ||312         Attrs.hasParamAttr(getArgNo(), Attribute::ReadNone);313}314 315void Argument::addAttrs(AttrBuilder &B) {316  AttributeList AL = getParent()->getAttributes();317  AL = AL.addParamAttributes(Parent->getContext(), getArgNo(), B);318  getParent()->setAttributes(AL);319}320 321void Argument::addAttr(Attribute::AttrKind Kind) {322  getParent()->addParamAttr(getArgNo(), Kind);323}324 325void Argument::addAttr(Attribute Attr) {326  getParent()->addParamAttr(getArgNo(), Attr);327}328 329void Argument::removeAttr(Attribute::AttrKind Kind) {330  getParent()->removeParamAttr(getArgNo(), Kind);331}332 333void Argument::removeAttrs(const AttributeMask &AM) {334  AttributeList AL = getParent()->getAttributes();335  AL = AL.removeParamAttributes(Parent->getContext(), getArgNo(), AM);336  getParent()->setAttributes(AL);337}338 339bool Argument::hasAttribute(Attribute::AttrKind Kind) const {340  return getParent()->hasParamAttribute(getArgNo(), Kind);341}342 343bool Argument::hasAttribute(StringRef Kind) const {344  return getParent()->hasParamAttribute(getArgNo(), Kind);345}346 347Attribute Argument::getAttribute(Attribute::AttrKind Kind) const {348  return getParent()->getParamAttribute(getArgNo(), Kind);349}350 351AttributeSet Argument::getAttributes() const {352  return getParent()->getAttributes().getParamAttrs(getArgNo());353}354 355//===----------------------------------------------------------------------===//356// Helper Methods in Function357//===----------------------------------------------------------------------===//358 359LLVMContext &Function::getContext() const {360  return getType()->getContext();361}362 363const DataLayout &Function::getDataLayout() const {364  return getParent()->getDataLayout();365}366 367unsigned Function::getInstructionCount() const {368  unsigned NumInstrs = 0;369  for (const BasicBlock &BB : BasicBlocks)370    NumInstrs += std::distance(BB.instructionsWithoutDebug().begin(),371                               BB.instructionsWithoutDebug().end());372  return NumInstrs;373}374 375Function *Function::Create(FunctionType *Ty, LinkageTypes Linkage,376                           const Twine &N, Module &M) {377  return Create(Ty, Linkage, M.getDataLayout().getProgramAddressSpace(), N, &M);378}379 380Function *Function::createWithDefaultAttr(FunctionType *Ty,381                                          LinkageTypes Linkage,382                                          unsigned AddrSpace, const Twine &N,383                                          Module *M) {384  auto *F = new (AllocMarker) Function(Ty, Linkage, AddrSpace, N, M);385  AttrBuilder B(F->getContext());386  UWTableKind UWTable = M->getUwtable();387  if (UWTable != UWTableKind::None)388    B.addUWTableAttr(UWTable);389  switch (M->getFramePointer()) {390  case FramePointerKind::None:391    // 0 ("none") is the default.392    break;393  case FramePointerKind::Reserved:394    B.addAttribute("frame-pointer", "reserved");395    break;396  case FramePointerKind::NonLeaf:397    B.addAttribute("frame-pointer", "non-leaf");398    break;399  case FramePointerKind::NonLeafNoReserve:400    B.addAttribute("frame-pointer", "non-leaf-no-reserve");401    break;402  case FramePointerKind::All:403    B.addAttribute("frame-pointer", "all");404    break;405  }406  if (M->getModuleFlag("function_return_thunk_extern"))407    B.addAttribute(Attribute::FnRetThunkExtern);408  StringRef DefaultCPU = F->getContext().getDefaultTargetCPU();409  if (!DefaultCPU.empty())410    B.addAttribute("target-cpu", DefaultCPU);411  StringRef DefaultFeatures = F->getContext().getDefaultTargetFeatures();412  if (!DefaultFeatures.empty())413    B.addAttribute("target-features", DefaultFeatures);414 415  // Check if the module attribute is present and not zero.416  auto isModuleAttributeSet = [&](const StringRef &ModAttr) -> bool {417    const auto *Attr =418        mdconst::extract_or_null<ConstantInt>(M->getModuleFlag(ModAttr));419    return Attr && !Attr->isZero();420  };421 422  auto AddAttributeIfSet = [&](const StringRef &ModAttr) {423    if (isModuleAttributeSet(ModAttr))424      B.addAttribute(ModAttr);425  };426 427  StringRef SignType = "none";428  if (isModuleAttributeSet("sign-return-address"))429    SignType = "non-leaf";430  if (isModuleAttributeSet("sign-return-address-all"))431    SignType = "all";432  if (SignType != "none") {433    B.addAttribute("sign-return-address", SignType);434    B.addAttribute("sign-return-address-key",435                   isModuleAttributeSet("sign-return-address-with-bkey")436                       ? "b_key"437                       : "a_key");438  }439  AddAttributeIfSet("branch-target-enforcement");440  AddAttributeIfSet("branch-protection-pauth-lr");441  AddAttributeIfSet("guarded-control-stack");442 443  F->addFnAttrs(B);444  return F;445}446 447void Function::removeFromParent() {448  getParent()->getFunctionList().remove(getIterator());449}450 451void Function::eraseFromParent() {452  getParent()->getFunctionList().erase(getIterator());453}454 455void Function::splice(Function::iterator ToIt, Function *FromF,456                      Function::iterator FromBeginIt,457                      Function::iterator FromEndIt) {458#ifdef EXPENSIVE_CHECKS459  // Check that FromBeginIt is before FromEndIt.460  auto FromFEnd = FromF->end();461  for (auto It = FromBeginIt; It != FromEndIt; ++It)462    assert(It != FromFEnd && "FromBeginIt not before FromEndIt!");463#endif // EXPENSIVE_CHECKS464  BasicBlocks.splice(ToIt, FromF->BasicBlocks, FromBeginIt, FromEndIt);465}466 467Function::iterator Function::erase(Function::iterator FromIt,468                                   Function::iterator ToIt) {469  return BasicBlocks.erase(FromIt, ToIt);470}471 472//===----------------------------------------------------------------------===//473// Function Implementation474//===----------------------------------------------------------------------===//475 476static unsigned computeAddrSpace(unsigned AddrSpace, Module *M) {477  // If AS == -1 and we are passed a valid module pointer we place the function478  // in the program address space. Otherwise we default to AS0.479  if (AddrSpace == static_cast<unsigned>(-1))480    return M ? M->getDataLayout().getProgramAddressSpace() : 0;481  return AddrSpace;482}483 484Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace,485                   const Twine &name, Module *ParentModule)486    : GlobalObject(Ty, Value::FunctionVal, AllocMarker, Linkage, name,487                   computeAddrSpace(AddrSpace, ParentModule)),488      NumArgs(Ty->getNumParams()) {489  assert(FunctionType::isValidReturnType(getReturnType()) &&490         "invalid return type");491  setGlobalObjectSubClassData(0);492 493  // We only need a symbol table for a function if the context keeps value names494  if (!getContext().shouldDiscardValueNames())495    SymTab = std::make_unique<ValueSymbolTable>(NonGlobalValueMaxNameSize);496 497  // If the function has arguments, mark them as lazily built.498  if (Ty->getNumParams())499    setValueSubclassData(1);   // Set the "has lazy arguments" bit.500 501  if (ParentModule) {502    ParentModule->getFunctionList().push_back(this);503  }504 505  HasLLVMReservedName = getName().starts_with("llvm.");506  // Ensure intrinsics have the right parameter attributes.507  // Note, the IntID field will have been set in Value::setName if this function508  // name is a valid intrinsic ID.509  if (IntID) {510    // Don't set the attributes if the intrinsic signature is invalid. This511    // case will either be auto-upgraded or fail verification.512    SmallVector<Type *> OverloadTys;513    if (!Intrinsic::getIntrinsicSignature(IntID, Ty, OverloadTys))514      return;515 516    setAttributes(Intrinsic::getAttributes(getContext(), IntID, Ty));517  }518}519 520Function::~Function() {521  validateBlockNumbers();522 523  dropAllReferences();    // After this it is safe to delete instructions.524 525  // Delete all of the method arguments and unlink from symbol table...526  if (Arguments)527    clearArguments();528 529  // Remove the function from the on-the-side GC table.530  clearGC();531}532 533void Function::BuildLazyArguments() const {534  // Create the arguments vector, all arguments start out unnamed.535  auto *FT = getFunctionType();536  if (NumArgs > 0) {537    Arguments = std::allocator<Argument>().allocate(NumArgs);538    for (unsigned i = 0, e = NumArgs; i != e; ++i) {539      Type *ArgTy = FT->getParamType(i);540      assert(!ArgTy->isVoidTy() && "Cannot have void typed arguments!");541      new (Arguments + i) Argument(ArgTy, "", const_cast<Function *>(this), i);542    }543  }544 545  // Clear the lazy arguments bit.546  unsigned SDC = getSubclassDataFromValue();547  SDC &= ~(1 << 0);548  const_cast<Function*>(this)->setValueSubclassData(SDC);549  assert(!hasLazyArguments());550}551 552static MutableArrayRef<Argument> makeArgArray(Argument *Args, size_t Count) {553  return MutableArrayRef<Argument>(Args, Count);554}555 556bool Function::isConstrainedFPIntrinsic() const {557  return Intrinsic::isConstrainedFPIntrinsic(getIntrinsicID());558}559 560void Function::clearArguments() {561  for (Argument &A : makeArgArray(Arguments, NumArgs)) {562    A.setName("");563    A.~Argument();564  }565  std::allocator<Argument>().deallocate(Arguments, NumArgs);566  Arguments = nullptr;567}568 569void Function::stealArgumentListFrom(Function &Src) {570  assert(isDeclaration() && "Expected no references to current arguments");571 572  // Drop the current arguments, if any, and set the lazy argument bit.573  if (!hasLazyArguments()) {574    assert(llvm::all_of(makeArgArray(Arguments, NumArgs),575                        [](const Argument &A) { return A.use_empty(); }) &&576           "Expected arguments to be unused in declaration");577    clearArguments();578    setValueSubclassData(getSubclassDataFromValue() | (1 << 0));579  }580 581  // Nothing to steal if Src has lazy arguments.582  if (Src.hasLazyArguments())583    return;584 585  // Steal arguments from Src, and fix the lazy argument bits.586  assert(arg_size() == Src.arg_size());587  Arguments = Src.Arguments;588  Src.Arguments = nullptr;589  for (Argument &A : makeArgArray(Arguments, NumArgs)) {590    // FIXME: This does the work of transferNodesFromList inefficiently.591    SmallString<128> Name;592    if (A.hasName())593      Name = A.getName();594    if (!Name.empty())595      A.setName("");596    A.setParent(this);597    if (!Name.empty())598      A.setName(Name);599  }600 601  setValueSubclassData(getSubclassDataFromValue() & ~(1 << 0));602  assert(!hasLazyArguments());603  Src.setValueSubclassData(Src.getSubclassDataFromValue() | (1 << 0));604}605 606void Function::deleteBodyImpl(bool ShouldDrop) {607  setIsMaterializable(false);608 609  for (BasicBlock &BB : *this)610    BB.dropAllReferences();611 612  // Delete all basic blocks. They are now unused, except possibly by613  // blockaddresses, but BasicBlock's destructor takes care of those.614  while (!BasicBlocks.empty())615    BasicBlocks.begin()->eraseFromParent();616 617  if (getNumOperands()) {618    if (ShouldDrop) {619      // Drop uses of any optional data (real or placeholder).620      User::dropAllReferences();621      setNumHungOffUseOperands(0);622    } else {623      // The code needs to match Function::allocHungoffUselist().624      auto *CPN = ConstantPointerNull::get(PointerType::get(getContext(), 0));625      Op<0>().set(CPN);626      Op<1>().set(CPN);627      Op<2>().set(CPN);628    }629    setValueSubclassData(getSubclassDataFromValue() & ~0xe);630  }631 632  // Metadata is stored in a side-table.633  clearMetadata();634}635 636void Function::addAttributeAtIndex(unsigned i, Attribute Attr) {637  AttributeSets = AttributeSets.addAttributeAtIndex(getContext(), i, Attr);638}639 640void Function::addFnAttr(Attribute::AttrKind Kind) {641  AttributeSets = AttributeSets.addFnAttribute(getContext(), Kind);642}643 644void Function::addFnAttr(StringRef Kind, StringRef Val) {645  AttributeSets = AttributeSets.addFnAttribute(getContext(), Kind, Val);646}647 648void Function::addFnAttr(Attribute Attr) {649  AttributeSets = AttributeSets.addFnAttribute(getContext(), Attr);650}651 652void Function::addFnAttrs(const AttrBuilder &Attrs) {653  AttributeSets = AttributeSets.addFnAttributes(getContext(), Attrs);654}655 656void Function::addRetAttr(Attribute::AttrKind Kind) {657  AttributeSets = AttributeSets.addRetAttribute(getContext(), Kind);658}659 660void Function::addRetAttr(Attribute Attr) {661  AttributeSets = AttributeSets.addRetAttribute(getContext(), Attr);662}663 664void Function::addRetAttrs(const AttrBuilder &Attrs) {665  AttributeSets = AttributeSets.addRetAttributes(getContext(), Attrs);666}667 668void Function::addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {669  AttributeSets = AttributeSets.addParamAttribute(getContext(), ArgNo, Kind);670}671 672void Function::addParamAttr(unsigned ArgNo, Attribute Attr) {673  AttributeSets = AttributeSets.addParamAttribute(getContext(), ArgNo, Attr);674}675 676void Function::addParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) {677  AttributeSets = AttributeSets.addParamAttributes(getContext(), ArgNo, Attrs);678}679 680void Function::removeAttributeAtIndex(unsigned i, Attribute::AttrKind Kind) {681  AttributeSets = AttributeSets.removeAttributeAtIndex(getContext(), i, Kind);682}683 684void Function::removeAttributeAtIndex(unsigned i, StringRef Kind) {685  AttributeSets = AttributeSets.removeAttributeAtIndex(getContext(), i, Kind);686}687 688void Function::removeFnAttr(Attribute::AttrKind Kind) {689  AttributeSets = AttributeSets.removeFnAttribute(getContext(), Kind);690}691 692void Function::removeFnAttr(StringRef Kind) {693  AttributeSets = AttributeSets.removeFnAttribute(getContext(), Kind);694}695 696void Function::removeFnAttrs(const AttributeMask &AM) {697  AttributeSets = AttributeSets.removeFnAttributes(getContext(), AM);698}699 700void Function::removeRetAttr(Attribute::AttrKind Kind) {701  AttributeSets = AttributeSets.removeRetAttribute(getContext(), Kind);702}703 704void Function::removeRetAttr(StringRef Kind) {705  AttributeSets = AttributeSets.removeRetAttribute(getContext(), Kind);706}707 708void Function::removeRetAttrs(const AttributeMask &Attrs) {709  AttributeSets = AttributeSets.removeRetAttributes(getContext(), Attrs);710}711 712void Function::removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {713  AttributeSets = AttributeSets.removeParamAttribute(getContext(), ArgNo, Kind);714}715 716void Function::removeParamAttr(unsigned ArgNo, StringRef Kind) {717  AttributeSets = AttributeSets.removeParamAttribute(getContext(), ArgNo, Kind);718}719 720void Function::removeParamAttrs(unsigned ArgNo, const AttributeMask &Attrs) {721  AttributeSets =722      AttributeSets.removeParamAttributes(getContext(), ArgNo, Attrs);723}724 725void Function::addDereferenceableParamAttr(unsigned ArgNo, uint64_t Bytes) {726  AttributeSets =727      AttributeSets.addDereferenceableParamAttr(getContext(), ArgNo, Bytes);728}729 730bool Function::hasFnAttribute(Attribute::AttrKind Kind) const {731  return AttributeSets.hasFnAttr(Kind);732}733 734bool Function::hasFnAttribute(StringRef Kind) const {735  return AttributeSets.hasFnAttr(Kind);736}737 738bool Function::hasRetAttribute(Attribute::AttrKind Kind) const {739  return AttributeSets.hasRetAttr(Kind);740}741 742bool Function::hasParamAttribute(unsigned ArgNo,743                                 Attribute::AttrKind Kind) const {744  return AttributeSets.hasParamAttr(ArgNo, Kind);745}746 747bool Function::hasParamAttribute(unsigned ArgNo, StringRef Kind) const {748  return AttributeSets.hasParamAttr(ArgNo, Kind);749}750 751Attribute Function::getAttributeAtIndex(unsigned i,752                                        Attribute::AttrKind Kind) const {753  return AttributeSets.getAttributeAtIndex(i, Kind);754}755 756Attribute Function::getAttributeAtIndex(unsigned i, StringRef Kind) const {757  return AttributeSets.getAttributeAtIndex(i, Kind);758}759 760bool Function::hasAttributeAtIndex(unsigned Idx,761                                   Attribute::AttrKind Kind) const {762  return AttributeSets.hasAttributeAtIndex(Idx, Kind);763}764 765Attribute Function::getFnAttribute(Attribute::AttrKind Kind) const {766  return AttributeSets.getFnAttr(Kind);767}768 769Attribute Function::getFnAttribute(StringRef Kind) const {770  return AttributeSets.getFnAttr(Kind);771}772 773Attribute Function::getRetAttribute(Attribute::AttrKind Kind) const {774  return AttributeSets.getRetAttr(Kind);775}776 777uint64_t Function::getFnAttributeAsParsedInteger(StringRef Name,778                                                 uint64_t Default) const {779  Attribute A = getFnAttribute(Name);780  uint64_t Result = Default;781  if (A.isStringAttribute()) {782    StringRef Str = A.getValueAsString();783    if (Str.getAsInteger(0, Result))784      getContext().emitError("cannot parse integer attribute " + Name);785  }786 787  return Result;788}789 790/// gets the specified attribute from the list of attributes.791Attribute Function::getParamAttribute(unsigned ArgNo,792                                      Attribute::AttrKind Kind) const {793  return AttributeSets.getParamAttr(ArgNo, Kind);794}795 796void Function::addDereferenceableOrNullParamAttr(unsigned ArgNo,797                                                 uint64_t Bytes) {798  AttributeSets = AttributeSets.addDereferenceableOrNullParamAttr(getContext(),799                                                                  ArgNo, Bytes);800}801 802void Function::addRangeRetAttr(const ConstantRange &CR) {803  AttributeSets = AttributeSets.addRangeRetAttr(getContext(), CR);804}805 806DenormalMode Function::getDenormalMode(const fltSemantics &FPType) const {807  if (&FPType == &APFloat::IEEEsingle()) {808    DenormalMode Mode = getDenormalModeF32Raw();809    // If the f32 variant of the attribute isn't specified, try to use the810    // generic one.811    if (Mode.isValid())812      return Mode;813  }814 815  return getDenormalModeRaw();816}817 818DenormalMode Function::getDenormalModeRaw() const {819  Attribute Attr = getFnAttribute("denormal-fp-math");820  StringRef Val = Attr.getValueAsString();821  return parseDenormalFPAttribute(Val);822}823 824DenormalMode Function::getDenormalModeF32Raw() const {825  Attribute Attr = getFnAttribute("denormal-fp-math-f32");826  if (Attr.isValid()) {827    StringRef Val = Attr.getValueAsString();828    return parseDenormalFPAttribute(Val);829  }830 831  return DenormalMode::getInvalid();832}833 834const std::string &Function::getGC() const {835  assert(hasGC() && "Function has no collector");836  return getContext().getGC(*this);837}838 839void Function::setGC(std::string Str) {840  setValueSubclassDataBit(14, !Str.empty());841  getContext().setGC(*this, std::move(Str));842}843 844void Function::clearGC() {845  if (!hasGC())846    return;847  getContext().deleteGC(*this);848  setValueSubclassDataBit(14, false);849}850 851bool Function::hasStackProtectorFnAttr() const {852  return hasFnAttribute(Attribute::StackProtect) ||853         hasFnAttribute(Attribute::StackProtectStrong) ||854         hasFnAttribute(Attribute::StackProtectReq);855}856 857/// Copy all additional attributes (those not needed to create a Function) from858/// the Function Src to this one.859void Function::copyAttributesFrom(const Function *Src) {860  GlobalObject::copyAttributesFrom(Src);861  setCallingConv(Src->getCallingConv());862  setAttributes(Src->getAttributes());863  if (Src->hasGC())864    setGC(Src->getGC());865  else866    clearGC();867  if (Src->hasPersonalityFn())868    setPersonalityFn(Src->getPersonalityFn());869  if (Src->hasPrefixData())870    setPrefixData(Src->getPrefixData());871  if (Src->hasPrologueData())872    setPrologueData(Src->getPrologueData());873}874 875MemoryEffects Function::getMemoryEffects() const {876  return getAttributes().getMemoryEffects();877}878void Function::setMemoryEffects(MemoryEffects ME) {879  addFnAttr(Attribute::getWithMemoryEffects(getContext(), ME));880}881 882/// Determine if the function does not access memory.883bool Function::doesNotAccessMemory() const {884  return getMemoryEffects().doesNotAccessMemory();885}886void Function::setDoesNotAccessMemory() {887  setMemoryEffects(MemoryEffects::none());888}889 890/// Determine if the function does not access or only reads memory.891bool Function::onlyReadsMemory() const {892  return getMemoryEffects().onlyReadsMemory();893}894void Function::setOnlyReadsMemory() {895  setMemoryEffects(getMemoryEffects() & MemoryEffects::readOnly());896}897 898/// Determine if the function does not access or only writes memory.899bool Function::onlyWritesMemory() const {900  return getMemoryEffects().onlyWritesMemory();901}902void Function::setOnlyWritesMemory() {903  setMemoryEffects(getMemoryEffects() & MemoryEffects::writeOnly());904}905 906/// Determine if the call can access memory only using pointers based907/// on its arguments.908bool Function::onlyAccessesArgMemory() const {909  return getMemoryEffects().onlyAccessesArgPointees();910}911void Function::setOnlyAccessesArgMemory() {912  setMemoryEffects(getMemoryEffects() & MemoryEffects::argMemOnly());913}914 915/// Determine if the function may only access memory that is916///  inaccessible from the IR.917bool Function::onlyAccessesInaccessibleMemory() const {918  return getMemoryEffects().onlyAccessesInaccessibleMem();919}920void Function::setOnlyAccessesInaccessibleMemory() {921  setMemoryEffects(getMemoryEffects() & MemoryEffects::inaccessibleMemOnly());922}923 924/// Determine if the function may only access memory that is925///  either inaccessible from the IR or pointed to by its arguments.926bool Function::onlyAccessesInaccessibleMemOrArgMem() const {927  return getMemoryEffects().onlyAccessesInaccessibleOrArgMem();928}929void Function::setOnlyAccessesInaccessibleMemOrArgMem() {930  setMemoryEffects(getMemoryEffects() &931                   MemoryEffects::inaccessibleOrArgMemOnly());932}933 934bool Function::isTargetIntrinsic() const {935  return Intrinsic::isTargetIntrinsic(IntID);936}937 938void Function::updateAfterNameChange() {939  LibFuncCache = UnknownLibFunc;940  StringRef Name = getName();941  if (!Name.starts_with("llvm.")) {942    HasLLVMReservedName = false;943    IntID = Intrinsic::not_intrinsic;944    return;945  }946  HasLLVMReservedName = true;947  IntID = Intrinsic::lookupIntrinsicID(Name);948}949 950/// hasAddressTaken - returns true if there are any uses of this function951/// other than direct calls or invokes to it. Optionally ignores callback952/// uses, assume like pointer annotation calls, and references in llvm.used953/// and llvm.compiler.used variables.954bool Function::hasAddressTaken(const User **PutOffender,955                               bool IgnoreCallbackUses,956                               bool IgnoreAssumeLikeCalls, bool IgnoreLLVMUsed,957                               bool IgnoreARCAttachedCall,958                               bool IgnoreCastedDirectCall) const {959  for (const Use &U : uses()) {960    const User *FU = U.getUser();961    if (IgnoreCallbackUses) {962      AbstractCallSite ACS(&U);963      if (ACS && ACS.isCallbackCall())964        continue;965    }966 967    const auto *Call = dyn_cast<CallBase>(FU);968    if (!Call) {969      if (IgnoreAssumeLikeCalls &&970          isa<BitCastOperator, AddrSpaceCastOperator>(FU) &&971          all_of(FU->users(), [](const User *U) {972            if (const auto *I = dyn_cast<IntrinsicInst>(U))973              return I->isAssumeLikeIntrinsic();974            return false;975          })) {976        continue;977      }978 979      if (IgnoreLLVMUsed && !FU->user_empty()) {980        const User *FUU = FU;981        if (isa<BitCastOperator, AddrSpaceCastOperator>(FU) &&982            FU->hasOneUse() && !FU->user_begin()->user_empty())983          FUU = *FU->user_begin();984        if (llvm::all_of(FUU->users(), [](const User *U) {985              if (const auto *GV = dyn_cast<GlobalVariable>(U))986                return GV->hasName() &&987                       (GV->getName() == "llvm.compiler.used" ||988                        GV->getName() == "llvm.used");989              return false;990            }))991          continue;992      }993      if (PutOffender)994        *PutOffender = FU;995      return true;996    }997 998    if (IgnoreAssumeLikeCalls) {999      if (const auto *I = dyn_cast<IntrinsicInst>(Call))1000        if (I->isAssumeLikeIntrinsic())1001          continue;1002    }1003 1004    if (!Call->isCallee(&U) || (!IgnoreCastedDirectCall &&1005                                Call->getFunctionType() != getFunctionType())) {1006      if (IgnoreARCAttachedCall &&1007          Call->isOperandBundleOfType(LLVMContext::OB_clang_arc_attachedcall,1008                                      U.getOperandNo()))1009        continue;1010 1011      if (PutOffender)1012        *PutOffender = FU;1013      return true;1014    }1015  }1016  return false;1017}1018 1019bool Function::isDefTriviallyDead() const {1020  // Check the linkage1021  if (!hasLinkOnceLinkage() && !hasLocalLinkage() &&1022      !hasAvailableExternallyLinkage())1023    return false;1024 1025  return use_empty();1026}1027 1028/// callsFunctionThatReturnsTwice - Return true if the function has a call to1029/// setjmp or other function that gcc recognizes as "returning twice".1030bool Function::callsFunctionThatReturnsTwice() const {1031  for (const Instruction &I : instructions(this))1032    if (const auto *Call = dyn_cast<CallBase>(&I))1033      if (Call->hasFnAttr(Attribute::ReturnsTwice))1034        return true;1035 1036  return false;1037}1038 1039Constant *Function::getPersonalityFn() const {1040  assert(hasPersonalityFn() && getNumOperands());1041  return cast<Constant>(Op<0>());1042}1043 1044void Function::setPersonalityFn(Constant *Fn) {1045  setHungoffOperand<0>(Fn);1046  setValueSubclassDataBit(3, Fn != nullptr);1047}1048 1049Constant *Function::getPrefixData() const {1050  assert(hasPrefixData() && getNumOperands());1051  return cast<Constant>(Op<1>());1052}1053 1054void Function::setPrefixData(Constant *PrefixData) {1055  setHungoffOperand<1>(PrefixData);1056  setValueSubclassDataBit(1, PrefixData != nullptr);1057}1058 1059Constant *Function::getPrologueData() const {1060  assert(hasPrologueData() && getNumOperands());1061  return cast<Constant>(Op<2>());1062}1063 1064void Function::setPrologueData(Constant *PrologueData) {1065  setHungoffOperand<2>(PrologueData);1066  setValueSubclassDataBit(2, PrologueData != nullptr);1067}1068 1069void Function::allocHungoffUselist() {1070  // If we've already allocated a uselist, stop here.1071  if (getNumOperands())1072    return;1073 1074  allocHungoffUses(3, /*IsPhi=*/ false);1075  setNumHungOffUseOperands(3);1076 1077  // Initialize the uselist with placeholder operands to allow traversal.1078  auto *CPN = ConstantPointerNull::get(PointerType::get(getContext(), 0));1079  Op<0>().set(CPN);1080  Op<1>().set(CPN);1081  Op<2>().set(CPN);1082}1083 1084template <int Idx>1085void Function::setHungoffOperand(Constant *C) {1086  if (C) {1087    allocHungoffUselist();1088    Op<Idx>().set(C);1089  } else if (getNumOperands()) {1090    Op<Idx>().set(ConstantPointerNull::get(PointerType::get(getContext(), 0)));1091  }1092}1093 1094void Function::setValueSubclassDataBit(unsigned Bit, bool On) {1095  assert(Bit < 16 && "SubclassData contains only 16 bits");1096  if (On)1097    setValueSubclassData(getSubclassDataFromValue() | (1 << Bit));1098  else1099    setValueSubclassData(getSubclassDataFromValue() & ~(1 << Bit));1100}1101 1102void Function::setEntryCount(ProfileCount Count,1103                             const DenseSet<GlobalValue::GUID> *S) {1104#if !defined(NDEBUG)1105  auto PrevCount = getEntryCount();1106  assert(!PrevCount || PrevCount->getType() == Count.getType());1107#endif1108 1109  auto ImportGUIDs = getImportGUIDs();1110  if (S == nullptr && ImportGUIDs.size())1111    S = &ImportGUIDs;1112 1113  MDBuilder MDB(getContext());1114  setMetadata(1115      LLVMContext::MD_prof,1116      MDB.createFunctionEntryCount(Count.getCount(), Count.isSynthetic(), S));1117}1118 1119void Function::setEntryCount(uint64_t Count, Function::ProfileCountType Type,1120                             const DenseSet<GlobalValue::GUID> *Imports) {1121  setEntryCount(ProfileCount(Count, Type), Imports);1122}1123 1124std::optional<ProfileCount> Function::getEntryCount(bool AllowSynthetic) const {1125  MDNode *MD = getMetadata(LLVMContext::MD_prof);1126  if (MD && MD->getOperand(0))1127    if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) {1128      if (MDS->getString() == MDProfLabels::FunctionEntryCount) {1129        ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));1130        uint64_t Count = CI->getValue().getZExtValue();1131        // A value of -1 is used for SamplePGO when there were no samples.1132        // Treat this the same as unknown.1133        if (Count == (uint64_t)-1)1134          return std::nullopt;1135        return ProfileCount(Count, PCT_Real);1136      } else if (AllowSynthetic &&1137                 MDS->getString() ==1138                     MDProfLabels::SyntheticFunctionEntryCount) {1139        ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));1140        uint64_t Count = CI->getValue().getZExtValue();1141        return ProfileCount(Count, PCT_Synthetic);1142      }1143    }1144  return std::nullopt;1145}1146 1147DenseSet<GlobalValue::GUID> Function::getImportGUIDs() const {1148  DenseSet<GlobalValue::GUID> R;1149  if (MDNode *MD = getMetadata(LLVMContext::MD_prof))1150    if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0)))1151      if (MDS->getString() == MDProfLabels::FunctionEntryCount)1152        for (unsigned i = 2; i < MD->getNumOperands(); i++)1153          R.insert(mdconst::extract<ConstantInt>(MD->getOperand(i))1154                       ->getValue()1155                       .getZExtValue());1156  return R;1157}1158 1159bool Function::nullPointerIsDefined() const {1160  return hasFnAttribute(Attribute::NullPointerIsValid);1161}1162 1163unsigned Function::getVScaleValue() const {1164  Attribute Attr = getFnAttribute(Attribute::VScaleRange);1165  if (!Attr.isValid())1166    return 0;1167 1168  unsigned VScale = Attr.getVScaleRangeMin();1169  if (VScale && VScale == Attr.getVScaleRangeMax())1170    return VScale;1171 1172  return 0;1173}1174 1175bool llvm::NullPointerIsDefined(const Function *F, unsigned AS) {1176  if (F && F->nullPointerIsDefined())1177    return true;1178 1179  if (AS != 0)1180    return true;1181 1182  return false;1183}1184 1185bool llvm::CallingConv::supportsNonVoidReturnType(CallingConv::ID CC) {1186  switch (CC) {1187  case CallingConv::C:1188  case CallingConv::Fast:1189  case CallingConv::Cold:1190  case CallingConv::GHC:1191  case CallingConv::HiPE:1192  case CallingConv::AnyReg:1193  case CallingConv::PreserveMost:1194  case CallingConv::PreserveAll:1195  case CallingConv::Swift:1196  case CallingConv::CXX_FAST_TLS:1197  case CallingConv::Tail:1198  case CallingConv::CFGuard_Check:1199  case CallingConv::SwiftTail:1200  case CallingConv::PreserveNone:1201  case CallingConv::X86_StdCall:1202  case CallingConv::X86_FastCall:1203  case CallingConv::ARM_APCS:1204  case CallingConv::ARM_AAPCS:1205  case CallingConv::ARM_AAPCS_VFP:1206  case CallingConv::MSP430_INTR:1207  case CallingConv::X86_ThisCall:1208  case CallingConv::PTX_Device:1209  case CallingConv::SPIR_FUNC:1210  case CallingConv::Intel_OCL_BI:1211  case CallingConv::X86_64_SysV:1212  case CallingConv::Win64:1213  case CallingConv::X86_VectorCall:1214  case CallingConv::DUMMY_HHVM:1215  case CallingConv::DUMMY_HHVM_C:1216  case CallingConv::X86_INTR:1217  case CallingConv::AVR_INTR:1218  case CallingConv::AVR_SIGNAL:1219  case CallingConv::AVR_BUILTIN:1220    return true;1221  case CallingConv::AMDGPU_KERNEL:1222  case CallingConv::SPIR_KERNEL:1223  case CallingConv::AMDGPU_CS_Chain:1224  case CallingConv::AMDGPU_CS_ChainPreserve:1225    return false;1226  case CallingConv::AMDGPU_VS:1227  case CallingConv::AMDGPU_HS:1228  case CallingConv::AMDGPU_GS:1229  case CallingConv::AMDGPU_PS:1230  case CallingConv::AMDGPU_CS:1231  case CallingConv::AMDGPU_LS:1232  case CallingConv::AMDGPU_ES:1233  case CallingConv::MSP430_BUILTIN:1234  case CallingConv::AArch64_VectorCall:1235  case CallingConv::AArch64_SVE_VectorCall:1236  case CallingConv::WASM_EmscriptenInvoke:1237  case CallingConv::AMDGPU_Gfx:1238  case CallingConv::AMDGPU_Gfx_WholeWave:1239  case CallingConv::M68k_INTR:1240  case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0:1241  case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2:1242  case CallingConv::M68k_RTD:1243  case CallingConv::GRAAL:1244  case CallingConv::ARM64EC_Thunk_X64:1245  case CallingConv::ARM64EC_Thunk_Native:1246  case CallingConv::RISCV_VectorCall:1247  case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1:1248  case CallingConv::RISCV_VLSCall_32:1249  case CallingConv::RISCV_VLSCall_64:1250  case CallingConv::RISCV_VLSCall_128:1251  case CallingConv::RISCV_VLSCall_256:1252  case CallingConv::RISCV_VLSCall_512:1253  case CallingConv::RISCV_VLSCall_1024:1254  case CallingConv::RISCV_VLSCall_2048:1255  case CallingConv::RISCV_VLSCall_4096:1256  case CallingConv::RISCV_VLSCall_8192:1257  case CallingConv::RISCV_VLSCall_16384:1258  case CallingConv::RISCV_VLSCall_32768:1259  case CallingConv::RISCV_VLSCall_65536:1260    return true;1261  default:1262    return false;1263  }1264 1265  llvm_unreachable("covered callingconv switch");1266}1267