xref: /src/contrib/llvm-project/llvm/lib/IR/Function.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
16b3f41edSDimitry Andric //===- Function.cpp - Implement the Global object classes -----------------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
94a16efa3SDimitry Andric // This file implements the Function class for the IR library.
10009b1c42SEd Schouten //
11009b1c42SEd Schouten //===----------------------------------------------------------------------===//
12009b1c42SEd Schouten 
137ab83427SDimitry Andric #include "llvm/IR/Function.h"
14009b1c42SEd Schouten #include "SymbolTableListTraitsImpl.h"
156b3f41edSDimitry Andric #include "llvm/ADT/ArrayRef.h"
166b3f41edSDimitry Andric #include "llvm/ADT/DenseSet.h"
177ab83427SDimitry Andric #include "llvm/ADT/STLExtras.h"
186b3f41edSDimitry Andric #include "llvm/ADT/SmallString.h"
196b3f41edSDimitry Andric #include "llvm/ADT/SmallVector.h"
20009b1c42SEd Schouten #include "llvm/ADT/StringExtras.h"
216b3f41edSDimitry Andric #include "llvm/ADT/StringRef.h"
22cfca06d7SDimitry Andric #include "llvm/IR/AbstractCallSite.h"
236b3f41edSDimitry Andric #include "llvm/IR/Argument.h"
246b3f41edSDimitry Andric #include "llvm/IR/Attributes.h"
256b3f41edSDimitry Andric #include "llvm/IR/BasicBlock.h"
266b3f41edSDimitry Andric #include "llvm/IR/Constant.h"
27ac9a064cSDimitry Andric #include "llvm/IR/ConstantRange.h"
285a5ac124SDimitry Andric #include "llvm/IR/Constants.h"
294a16efa3SDimitry Andric #include "llvm/IR/DerivedTypes.h"
306b3f41edSDimitry Andric #include "llvm/IR/GlobalValue.h"
315ca98fd9SDimitry Andric #include "llvm/IR/InstIterator.h"
326b3f41edSDimitry Andric #include "llvm/IR/Instruction.h"
33344a3780SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
346b3f41edSDimitry Andric #include "llvm/IR/Intrinsics.h"
35706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsAArch64.h"
36706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsAMDGPU.h"
37706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsARM.h"
38706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsBPF.h"
39145449b1SDimitry Andric #include "llvm/IR/IntrinsicsDirectX.h"
40706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsHexagon.h"
41b1c73532SDimitry Andric #include "llvm/IR/IntrinsicsLoongArch.h"
42706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsMips.h"
43706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsNVPTX.h"
44706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsPowerPC.h"
45706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsR600.h"
46706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsRISCV.h"
47706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsS390.h"
48ac9a064cSDimitry Andric #include "llvm/IR/IntrinsicsSPIRV.h"
49b60736ecSDimitry Andric #include "llvm/IR/IntrinsicsVE.h"
50706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsWebAssembly.h"
51706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsX86.h"
52706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsXCore.h"
534a16efa3SDimitry Andric #include "llvm/IR/LLVMContext.h"
545a5ac124SDimitry Andric #include "llvm/IR/MDBuilder.h"
555a5ac124SDimitry Andric #include "llvm/IR/Metadata.h"
564a16efa3SDimitry Andric #include "llvm/IR/Module.h"
57344a3780SDimitry Andric #include "llvm/IR/Operator.h"
586b3f41edSDimitry Andric #include "llvm/IR/SymbolTableListTraits.h"
596b3f41edSDimitry Andric #include "llvm/IR/Type.h"
606b3f41edSDimitry Andric #include "llvm/IR/Use.h"
616b3f41edSDimitry Andric #include "llvm/IR/User.h"
626b3f41edSDimitry Andric #include "llvm/IR/Value.h"
636b3f41edSDimitry Andric #include "llvm/IR/ValueSymbolTable.h"
646b3f41edSDimitry Andric #include "llvm/Support/Casting.h"
65344a3780SDimitry Andric #include "llvm/Support/CommandLine.h"
666b3f41edSDimitry Andric #include "llvm/Support/Compiler.h"
676b3f41edSDimitry Andric #include "llvm/Support/ErrorHandling.h"
68e3b55780SDimitry Andric #include "llvm/Support/ModRef.h"
696b3f41edSDimitry Andric #include <cassert>
706b3f41edSDimitry Andric #include <cstddef>
716b3f41edSDimitry Andric #include <cstdint>
726b3f41edSDimitry Andric #include <cstring>
736b3f41edSDimitry Andric #include <string>
746b3f41edSDimitry Andric 
75009b1c42SEd Schouten using namespace llvm;
76eb11fae6SDimitry Andric using ProfileCount = Function::ProfileCount;
77009b1c42SEd Schouten 
78009b1c42SEd Schouten // Explicit instantiations of SymbolTableListTraits since some of the methods
79009b1c42SEd Schouten // are not in the public header file...
80dd58ef01SDimitry Andric template class llvm::SymbolTableListTraits<BasicBlock>;
81009b1c42SEd Schouten 
82ac9a064cSDimitry Andric static cl::opt<int> NonGlobalValueMaxNameSize(
83344a3780SDimitry Andric     "non-global-value-max-name-size", cl::Hidden, cl::init(1024),
84344a3780SDimitry Andric     cl::desc("Maximum size for the name of non-global values."));
85344a3780SDimitry Andric 
86ac9a064cSDimitry Andric extern cl::opt<bool> UseNewDbgInfoFormat;
87ac9a064cSDimitry Andric 
convertToNewDbgValues()88b1c73532SDimitry Andric void Function::convertToNewDbgValues() {
89b1c73532SDimitry Andric   IsNewDbgInfoFormat = true;
90b1c73532SDimitry Andric   for (auto &BB : *this) {
91b1c73532SDimitry Andric     BB.convertToNewDbgValues();
92b1c73532SDimitry Andric   }
93b1c73532SDimitry Andric }
94b1c73532SDimitry Andric 
convertFromNewDbgValues()95b1c73532SDimitry Andric void Function::convertFromNewDbgValues() {
96b1c73532SDimitry Andric   IsNewDbgInfoFormat = false;
97b1c73532SDimitry Andric   for (auto &BB : *this) {
98b1c73532SDimitry Andric     BB.convertFromNewDbgValues();
99b1c73532SDimitry Andric   }
100b1c73532SDimitry Andric }
101b1c73532SDimitry Andric 
setIsNewDbgInfoFormat(bool NewFlag)102b1c73532SDimitry Andric void Function::setIsNewDbgInfoFormat(bool NewFlag) {
103b1c73532SDimitry Andric   if (NewFlag && !IsNewDbgInfoFormat)
104b1c73532SDimitry Andric     convertToNewDbgValues();
105b1c73532SDimitry Andric   else if (!NewFlag && IsNewDbgInfoFormat)
106b1c73532SDimitry Andric     convertFromNewDbgValues();
107b1c73532SDimitry Andric }
setNewDbgInfoFormatFlag(bool NewFlag)108ac9a064cSDimitry Andric void Function::setNewDbgInfoFormatFlag(bool NewFlag) {
109ac9a064cSDimitry Andric   for (auto &BB : *this) {
110ac9a064cSDimitry Andric     BB.setNewDbgInfoFormatFlag(NewFlag);
111ac9a064cSDimitry Andric   }
112ac9a064cSDimitry Andric   IsNewDbgInfoFormat = NewFlag;
113ac9a064cSDimitry Andric }
114b1c73532SDimitry Andric 
115009b1c42SEd Schouten //===----------------------------------------------------------------------===//
116009b1c42SEd Schouten // Argument Implementation
117009b1c42SEd Schouten //===----------------------------------------------------------------------===//
118009b1c42SEd Schouten 
Argument(Type * Ty,const Twine & Name,Function * Par,unsigned ArgNo)11971d5a254SDimitry Andric Argument::Argument(Type *Ty, const Twine &Name, Function *Par, unsigned ArgNo)
12071d5a254SDimitry Andric     : Value(Ty, Value::ArgumentVal), Parent(Par), ArgNo(ArgNo) {
121009b1c42SEd Schouten   setName(Name);
122009b1c42SEd Schouten }
123009b1c42SEd Schouten 
setParent(Function * parent)124009b1c42SEd Schouten void Argument::setParent(Function *parent) {
125009b1c42SEd Schouten   Parent = parent;
126009b1c42SEd Schouten }
127009b1c42SEd Schouten 
hasNonNullAttr(bool AllowUndefOrPoison) const128b60736ecSDimitry Andric bool Argument::hasNonNullAttr(bool AllowUndefOrPoison) const {
1295ca98fd9SDimitry Andric   if (!getType()->isPointerTy()) return false;
130b60736ecSDimitry Andric   if (getParent()->hasParamAttribute(getArgNo(), Attribute::NonNull) &&
131b60736ecSDimitry Andric       (AllowUndefOrPoison ||
132b60736ecSDimitry Andric        getParent()->hasParamAttribute(getArgNo(), Attribute::NoUndef)))
1335ca98fd9SDimitry Andric     return true;
1345ca98fd9SDimitry Andric   else if (getDereferenceableBytes() > 0 &&
135eb11fae6SDimitry Andric            !NullPointerIsDefined(getParent(),
136eb11fae6SDimitry Andric                                  getType()->getPointerAddressSpace()))
1375ca98fd9SDimitry Andric     return true;
1385ca98fd9SDimitry Andric   return false;
1395ca98fd9SDimitry Andric }
1405ca98fd9SDimitry Andric 
hasByValAttr() const141009b1c42SEd Schouten bool Argument::hasByValAttr() const {
14267a71b31SRoman Divacky   if (!getType()->isPointerTy()) return false;
14301095a5dSDimitry Andric   return hasAttribute(Attribute::ByVal);
14401095a5dSDimitry Andric }
14501095a5dSDimitry Andric 
hasByRefAttr() const146b60736ecSDimitry Andric bool Argument::hasByRefAttr() const {
147b60736ecSDimitry Andric   if (!getType()->isPointerTy())
148b60736ecSDimitry Andric     return false;
149b60736ecSDimitry Andric   return hasAttribute(Attribute::ByRef);
150b60736ecSDimitry Andric }
151b60736ecSDimitry Andric 
hasSwiftSelfAttr() const15201095a5dSDimitry Andric bool Argument::hasSwiftSelfAttr() const {
15371d5a254SDimitry Andric   return getParent()->hasParamAttribute(getArgNo(), Attribute::SwiftSelf);
15401095a5dSDimitry Andric }
15501095a5dSDimitry Andric 
hasSwiftErrorAttr() const15601095a5dSDimitry Andric bool Argument::hasSwiftErrorAttr() const {
15771d5a254SDimitry Andric   return getParent()->hasParamAttribute(getArgNo(), Attribute::SwiftError);
158009b1c42SEd Schouten }
159009b1c42SEd Schouten 
hasInAllocaAttr() const1605ca98fd9SDimitry Andric bool Argument::hasInAllocaAttr() const {
1615ca98fd9SDimitry Andric   if (!getType()->isPointerTy()) return false;
16201095a5dSDimitry Andric   return hasAttribute(Attribute::InAlloca);
1635ca98fd9SDimitry Andric }
1645ca98fd9SDimitry Andric 
hasPreallocatedAttr() const165cfca06d7SDimitry Andric bool Argument::hasPreallocatedAttr() const {
166cfca06d7SDimitry Andric   if (!getType()->isPointerTy())
167cfca06d7SDimitry Andric     return false;
168cfca06d7SDimitry Andric   return hasAttribute(Attribute::Preallocated);
169cfca06d7SDimitry Andric }
170cfca06d7SDimitry Andric 
hasPassPointeeByValueCopyAttr() const171b60736ecSDimitry Andric bool Argument::hasPassPointeeByValueCopyAttr() const {
1725ca98fd9SDimitry Andric   if (!getType()->isPointerTy()) return false;
17371d5a254SDimitry Andric   AttributeList Attrs = getParent()->getAttributes();
174c0981da4SDimitry Andric   return Attrs.hasParamAttr(getArgNo(), Attribute::ByVal) ||
175c0981da4SDimitry Andric          Attrs.hasParamAttr(getArgNo(), Attribute::InAlloca) ||
176c0981da4SDimitry Andric          Attrs.hasParamAttr(getArgNo(), Attribute::Preallocated);
177cfca06d7SDimitry Andric }
178cfca06d7SDimitry Andric 
hasPointeeInMemoryValueAttr() const179b60736ecSDimitry Andric bool Argument::hasPointeeInMemoryValueAttr() const {
180b60736ecSDimitry Andric   if (!getType()->isPointerTy())
181b60736ecSDimitry Andric     return false;
182b60736ecSDimitry Andric   AttributeList Attrs = getParent()->getAttributes();
183c0981da4SDimitry Andric   return Attrs.hasParamAttr(getArgNo(), Attribute::ByVal) ||
184c0981da4SDimitry Andric          Attrs.hasParamAttr(getArgNo(), Attribute::StructRet) ||
185c0981da4SDimitry Andric          Attrs.hasParamAttr(getArgNo(), Attribute::InAlloca) ||
186c0981da4SDimitry Andric          Attrs.hasParamAttr(getArgNo(), Attribute::Preallocated) ||
187c0981da4SDimitry Andric          Attrs.hasParamAttr(getArgNo(), Attribute::ByRef);
188b60736ecSDimitry Andric }
189cfca06d7SDimitry Andric 
190b60736ecSDimitry Andric /// For a byval, sret, inalloca, or preallocated parameter, get the in-memory
191b60736ecSDimitry Andric /// parameter type.
getMemoryParamAllocType(AttributeSet ParamAttrs)192c0981da4SDimitry Andric static Type *getMemoryParamAllocType(AttributeSet ParamAttrs) {
193cfca06d7SDimitry Andric   // FIXME: All the type carrying attributes are mutually exclusive, so there
194cfca06d7SDimitry Andric   // should be a single query to get the stored type that handles any of them.
195cfca06d7SDimitry Andric   if (Type *ByValTy = ParamAttrs.getByValType())
196b60736ecSDimitry Andric     return ByValTy;
197b60736ecSDimitry Andric   if (Type *ByRefTy = ParamAttrs.getByRefType())
198b60736ecSDimitry Andric     return ByRefTy;
199cfca06d7SDimitry Andric   if (Type *PreAllocTy = ParamAttrs.getPreallocatedType())
200b60736ecSDimitry Andric     return PreAllocTy;
201344a3780SDimitry Andric   if (Type *InAllocaTy = ParamAttrs.getInAllocaType())
202344a3780SDimitry Andric     return InAllocaTy;
203344a3780SDimitry Andric   if (Type *SRetTy = ParamAttrs.getStructRetType())
204344a3780SDimitry Andric     return SRetTy;
205cfca06d7SDimitry Andric 
206b60736ecSDimitry Andric   return nullptr;
207b60736ecSDimitry Andric }
208b60736ecSDimitry Andric 
getPassPointeeByValueCopySize(const DataLayout & DL) const209b60736ecSDimitry Andric uint64_t Argument::getPassPointeeByValueCopySize(const DataLayout &DL) const {
210b60736ecSDimitry Andric   AttributeSet ParamAttrs =
211c0981da4SDimitry Andric       getParent()->getAttributes().getParamAttrs(getArgNo());
212c0981da4SDimitry Andric   if (Type *MemTy = getMemoryParamAllocType(ParamAttrs))
213b60736ecSDimitry Andric     return DL.getTypeAllocSize(MemTy);
214cfca06d7SDimitry Andric   return 0;
2155ca98fd9SDimitry Andric }
2165ca98fd9SDimitry Andric 
getPointeeInMemoryValueType() const217b60736ecSDimitry Andric Type *Argument::getPointeeInMemoryValueType() const {
218b60736ecSDimitry Andric   AttributeSet ParamAttrs =
219c0981da4SDimitry Andric       getParent()->getAttributes().getParamAttrs(getArgNo());
220c0981da4SDimitry Andric   return getMemoryParamAllocType(ParamAttrs);
221b60736ecSDimitry Andric }
222b60736ecSDimitry Andric 
getParamAlign() const223706b4fc4SDimitry Andric MaybeAlign Argument::getParamAlign() const {
224706b4fc4SDimitry Andric   assert(getType()->isPointerTy() && "Only pointers have alignments");
225706b4fc4SDimitry Andric   return getParent()->getParamAlign(getArgNo());
226706b4fc4SDimitry Andric }
227706b4fc4SDimitry Andric 
getParamStackAlign() const228344a3780SDimitry Andric MaybeAlign Argument::getParamStackAlign() const {
229344a3780SDimitry Andric   return getParent()->getParamStackAlign(getArgNo());
230344a3780SDimitry Andric }
231344a3780SDimitry Andric 
getParamByValType() const232e6d15924SDimitry Andric Type *Argument::getParamByValType() const {
233e6d15924SDimitry Andric   assert(getType()->isPointerTy() && "Only pointers have byval types");
234e6d15924SDimitry Andric   return getParent()->getParamByValType(getArgNo());
235e6d15924SDimitry Andric }
236e6d15924SDimitry Andric 
getParamStructRetType() const237b60736ecSDimitry Andric Type *Argument::getParamStructRetType() const {
238b60736ecSDimitry Andric   assert(getType()->isPointerTy() && "Only pointers have sret types");
239b60736ecSDimitry Andric   return getParent()->getParamStructRetType(getArgNo());
240b60736ecSDimitry Andric }
241b60736ecSDimitry Andric 
getParamByRefType() const242b60736ecSDimitry Andric Type *Argument::getParamByRefType() const {
243344a3780SDimitry Andric   assert(getType()->isPointerTy() && "Only pointers have byref types");
244b60736ecSDimitry Andric   return getParent()->getParamByRefType(getArgNo());
245b60736ecSDimitry Andric }
246b60736ecSDimitry Andric 
getParamInAllocaType() const247344a3780SDimitry Andric Type *Argument::getParamInAllocaType() const {
248344a3780SDimitry Andric   assert(getType()->isPointerTy() && "Only pointers have inalloca types");
249344a3780SDimitry Andric   return getParent()->getParamInAllocaType(getArgNo());
250344a3780SDimitry Andric }
251344a3780SDimitry Andric 
getDereferenceableBytes() const2525ca98fd9SDimitry Andric uint64_t Argument::getDereferenceableBytes() const {
2535ca98fd9SDimitry Andric   assert(getType()->isPointerTy() &&
2545ca98fd9SDimitry Andric          "Only pointers have dereferenceable bytes");
255f382538dSDimitry Andric   return getParent()->getParamDereferenceableBytes(getArgNo());
2565ca98fd9SDimitry Andric }
2575ca98fd9SDimitry Andric 
getDereferenceableOrNullBytes() const2585a5ac124SDimitry Andric uint64_t Argument::getDereferenceableOrNullBytes() const {
2595a5ac124SDimitry Andric   assert(getType()->isPointerTy() &&
2605a5ac124SDimitry Andric          "Only pointers have dereferenceable bytes");
261f382538dSDimitry Andric   return getParent()->getParamDereferenceableOrNullBytes(getArgNo());
2625a5ac124SDimitry Andric }
2635a5ac124SDimitry Andric 
getNoFPClass() const2647fa27ce4SDimitry Andric FPClassTest Argument::getNoFPClass() const {
2657fa27ce4SDimitry Andric   return getParent()->getParamNoFPClass(getArgNo());
2667fa27ce4SDimitry Andric }
2677fa27ce4SDimitry Andric 
getRange() const268ac9a064cSDimitry Andric std::optional<ConstantRange> Argument::getRange() const {
269ac9a064cSDimitry Andric   const Attribute RangeAttr = getAttribute(llvm::Attribute::Range);
270ac9a064cSDimitry Andric   if (RangeAttr.isValid())
271ac9a064cSDimitry Andric     return RangeAttr.getRange();
272ac9a064cSDimitry Andric   return std::nullopt;
273ac9a064cSDimitry Andric }
274ac9a064cSDimitry Andric 
hasNestAttr() const275571945e6SRoman Divacky bool Argument::hasNestAttr() const {
27667a71b31SRoman Divacky   if (!getType()->isPointerTy()) return false;
27701095a5dSDimitry Andric   return hasAttribute(Attribute::Nest);
278571945e6SRoman Divacky }
279571945e6SRoman Divacky 
hasNoAliasAttr() const280009b1c42SEd Schouten bool Argument::hasNoAliasAttr() const {
28167a71b31SRoman Divacky   if (!getType()->isPointerTy()) return false;
28201095a5dSDimitry Andric   return hasAttribute(Attribute::NoAlias);
283009b1c42SEd Schouten }
284009b1c42SEd Schouten 
hasNoCaptureAttr() const285009b1c42SEd Schouten bool Argument::hasNoCaptureAttr() const {
28667a71b31SRoman Divacky   if (!getType()->isPointerTy()) return false;
28701095a5dSDimitry Andric   return hasAttribute(Attribute::NoCapture);
288009b1c42SEd Schouten }
289009b1c42SEd Schouten 
hasNoFreeAttr() const290344a3780SDimitry Andric bool Argument::hasNoFreeAttr() const {
291344a3780SDimitry Andric   if (!getType()->isPointerTy()) return false;
292344a3780SDimitry Andric   return hasAttribute(Attribute::NoFree);
293344a3780SDimitry Andric }
294344a3780SDimitry Andric 
hasStructRetAttr() const295009b1c42SEd Schouten bool Argument::hasStructRetAttr() const {
29667a71b31SRoman Divacky   if (!getType()->isPointerTy()) return false;
29701095a5dSDimitry Andric   return hasAttribute(Attribute::StructRet);
298009b1c42SEd Schouten }
299009b1c42SEd Schouten 
hasInRegAttr() const300e6d15924SDimitry Andric bool Argument::hasInRegAttr() const {
301e6d15924SDimitry Andric   return hasAttribute(Attribute::InReg);
302e6d15924SDimitry Andric }
303e6d15924SDimitry Andric 
hasReturnedAttr() const30459d6cff9SDimitry Andric bool Argument::hasReturnedAttr() const {
30501095a5dSDimitry Andric   return hasAttribute(Attribute::Returned);
30659d6cff9SDimitry Andric }
30759d6cff9SDimitry Andric 
hasZExtAttr() const30867c32a98SDimitry Andric bool Argument::hasZExtAttr() const {
30901095a5dSDimitry Andric   return hasAttribute(Attribute::ZExt);
31067c32a98SDimitry Andric }
31167c32a98SDimitry Andric 
hasSExtAttr() const31267c32a98SDimitry Andric bool Argument::hasSExtAttr() const {
31301095a5dSDimitry Andric   return hasAttribute(Attribute::SExt);
31467c32a98SDimitry Andric }
31567c32a98SDimitry Andric 
onlyReadsMemory() const316f8af5cf6SDimitry Andric bool Argument::onlyReadsMemory() const {
31771d5a254SDimitry Andric   AttributeList Attrs = getParent()->getAttributes();
318c0981da4SDimitry Andric   return Attrs.hasParamAttr(getArgNo(), Attribute::ReadOnly) ||
319c0981da4SDimitry Andric          Attrs.hasParamAttr(getArgNo(), Attribute::ReadNone);
320f8af5cf6SDimitry Andric }
321f8af5cf6SDimitry Andric 
addAttrs(AttrBuilder & B)322d99dafe2SDimitry Andric void Argument::addAttrs(AttrBuilder &B) {
323d99dafe2SDimitry Andric   AttributeList AL = getParent()->getAttributes();
324f382538dSDimitry Andric   AL = AL.addParamAttributes(Parent->getContext(), getArgNo(), B);
325d99dafe2SDimitry Andric   getParent()->setAttributes(AL);
326d99dafe2SDimitry Andric }
327d99dafe2SDimitry Andric 
addAttr(Attribute::AttrKind Kind)328d99dafe2SDimitry Andric void Argument::addAttr(Attribute::AttrKind Kind) {
329f382538dSDimitry Andric   getParent()->addParamAttr(getArgNo(), Kind);
330d99dafe2SDimitry Andric }
331d99dafe2SDimitry Andric 
addAttr(Attribute Attr)332d99dafe2SDimitry Andric void Argument::addAttr(Attribute Attr) {
333f382538dSDimitry Andric   getParent()->addParamAttr(getArgNo(), Attr);
334009b1c42SEd Schouten }
335009b1c42SEd Schouten 
removeAttr(Attribute::AttrKind Kind)336d99dafe2SDimitry Andric void Argument::removeAttr(Attribute::AttrKind Kind) {
337f382538dSDimitry Andric   getParent()->removeParamAttr(getArgNo(), Kind);
338d99dafe2SDimitry Andric }
339d99dafe2SDimitry Andric 
removeAttrs(const AttributeMask & AM)3406f8fc217SDimitry Andric void Argument::removeAttrs(const AttributeMask &AM) {
341344a3780SDimitry Andric   AttributeList AL = getParent()->getAttributes();
3426f8fc217SDimitry Andric   AL = AL.removeParamAttributes(Parent->getContext(), getArgNo(), AM);
343344a3780SDimitry Andric   getParent()->setAttributes(AL);
344344a3780SDimitry Andric }
345344a3780SDimitry Andric 
hasAttribute(Attribute::AttrKind Kind) const34601095a5dSDimitry Andric bool Argument::hasAttribute(Attribute::AttrKind Kind) const {
34771d5a254SDimitry Andric   return getParent()->hasParamAttribute(getArgNo(), Kind);
34801095a5dSDimitry Andric }
34901095a5dSDimitry Andric 
getAttribute(Attribute::AttrKind Kind) const350e6d15924SDimitry Andric Attribute Argument::getAttribute(Attribute::AttrKind Kind) const {
351e6d15924SDimitry Andric   return getParent()->getParamAttribute(getArgNo(), Kind);
352e6d15924SDimitry Andric }
353e6d15924SDimitry Andric 
354009b1c42SEd Schouten //===----------------------------------------------------------------------===//
355009b1c42SEd Schouten // Helper Methods in Function
356009b1c42SEd Schouten //===----------------------------------------------------------------------===//
357009b1c42SEd Schouten 
getContext() const35859850d08SRoman Divacky LLVMContext &Function::getContext() const {
35959850d08SRoman Divacky   return getType()->getContext();
36018f153bdSEd Schouten }
36118f153bdSEd Schouten 
getDataLayout() const362ac9a064cSDimitry Andric const DataLayout &Function::getDataLayout() const {
363ac9a064cSDimitry Andric   return getParent()->getDataLayout();
364ac9a064cSDimitry Andric }
365ac9a064cSDimitry Andric 
getInstructionCount() const366d8e91e46SDimitry Andric unsigned Function::getInstructionCount() const {
367eb11fae6SDimitry Andric   unsigned NumInstrs = 0;
368d8e91e46SDimitry Andric   for (const BasicBlock &BB : BasicBlocks)
369eb11fae6SDimitry Andric     NumInstrs += std::distance(BB.instructionsWithoutDebug().begin(),
370eb11fae6SDimitry Andric                                BB.instructionsWithoutDebug().end());
371eb11fae6SDimitry Andric   return NumInstrs;
372eb11fae6SDimitry Andric }
373eb11fae6SDimitry Andric 
Create(FunctionType * Ty,LinkageTypes Linkage,const Twine & N,Module & M)374d8e91e46SDimitry Andric Function *Function::Create(FunctionType *Ty, LinkageTypes Linkage,
375d8e91e46SDimitry Andric                            const Twine &N, Module &M) {
376d8e91e46SDimitry Andric   return Create(Ty, Linkage, M.getDataLayout().getProgramAddressSpace(), N, &M);
377d8e91e46SDimitry Andric }
378d8e91e46SDimitry Andric 
createWithDefaultAttr(FunctionType * Ty,LinkageTypes Linkage,unsigned AddrSpace,const Twine & N,Module * M)379344a3780SDimitry Andric Function *Function::createWithDefaultAttr(FunctionType *Ty,
380344a3780SDimitry Andric                                           LinkageTypes Linkage,
381344a3780SDimitry Andric                                           unsigned AddrSpace, const Twine &N,
382344a3780SDimitry Andric                                           Module *M) {
383344a3780SDimitry Andric   auto *F = new Function(Ty, Linkage, AddrSpace, N, M);
3846f8fc217SDimitry Andric   AttrBuilder B(F->getContext());
385145449b1SDimitry Andric   UWTableKind UWTable = M->getUwtable();
386145449b1SDimitry Andric   if (UWTable != UWTableKind::None)
387145449b1SDimitry Andric     B.addUWTableAttr(UWTable);
388344a3780SDimitry Andric   switch (M->getFramePointer()) {
389344a3780SDimitry Andric   case FramePointerKind::None:
390344a3780SDimitry Andric     // 0 ("none") is the default.
391344a3780SDimitry Andric     break;
392ac9a064cSDimitry Andric   case FramePointerKind::Reserved:
393ac9a064cSDimitry Andric     B.addAttribute("frame-pointer", "reserved");
394ac9a064cSDimitry Andric     break;
395344a3780SDimitry Andric   case FramePointerKind::NonLeaf:
396344a3780SDimitry Andric     B.addAttribute("frame-pointer", "non-leaf");
397344a3780SDimitry Andric     break;
398344a3780SDimitry Andric   case FramePointerKind::All:
399344a3780SDimitry Andric     B.addAttribute("frame-pointer", "all");
400344a3780SDimitry Andric     break;
401344a3780SDimitry Andric   }
4024b4fe385SDimitry Andric   if (M->getModuleFlag("function_return_thunk_extern"))
4034b4fe385SDimitry Andric     B.addAttribute(Attribute::FnRetThunkExtern);
404ac9a064cSDimitry Andric   StringRef DefaultCPU = F->getContext().getDefaultTargetCPU();
405ac9a064cSDimitry Andric   if (!DefaultCPU.empty())
406ac9a064cSDimitry Andric     B.addAttribute("target-cpu", DefaultCPU);
407ac9a064cSDimitry Andric   StringRef DefaultFeatures = F->getContext().getDefaultTargetFeatures();
408ac9a064cSDimitry Andric   if (!DefaultFeatures.empty())
409ac9a064cSDimitry Andric     B.addAttribute("target-features", DefaultFeatures);
410ac9a064cSDimitry Andric 
411ac9a064cSDimitry Andric   // Check if the module attribute is present and not zero.
412ac9a064cSDimitry Andric   auto isModuleAttributeSet = [&](const StringRef &ModAttr) -> bool {
413ac9a064cSDimitry Andric     const auto *Attr =
414ac9a064cSDimitry Andric         mdconst::extract_or_null<ConstantInt>(M->getModuleFlag(ModAttr));
415ac9a064cSDimitry Andric     return Attr && !Attr->isZero();
416ac9a064cSDimitry Andric   };
417ac9a064cSDimitry Andric 
418ac9a064cSDimitry Andric   auto AddAttributeIfSet = [&](const StringRef &ModAttr) {
419ac9a064cSDimitry Andric     if (isModuleAttributeSet(ModAttr))
420ac9a064cSDimitry Andric       B.addAttribute(ModAttr);
421ac9a064cSDimitry Andric   };
422ac9a064cSDimitry Andric 
423ac9a064cSDimitry Andric   StringRef SignType = "none";
424ac9a064cSDimitry Andric   if (isModuleAttributeSet("sign-return-address"))
425ac9a064cSDimitry Andric     SignType = "non-leaf";
426ac9a064cSDimitry Andric   if (isModuleAttributeSet("sign-return-address-all"))
427ac9a064cSDimitry Andric     SignType = "all";
428ac9a064cSDimitry Andric   if (SignType != "none") {
429ac9a064cSDimitry Andric     B.addAttribute("sign-return-address", SignType);
430ac9a064cSDimitry Andric     B.addAttribute("sign-return-address-key",
431ac9a064cSDimitry Andric                    isModuleAttributeSet("sign-return-address-with-bkey")
432ac9a064cSDimitry Andric                        ? "b_key"
433ac9a064cSDimitry Andric                        : "a_key");
434ac9a064cSDimitry Andric   }
435ac9a064cSDimitry Andric   AddAttributeIfSet("branch-target-enforcement");
436ac9a064cSDimitry Andric   AddAttributeIfSet("branch-protection-pauth-lr");
437ac9a064cSDimitry Andric   AddAttributeIfSet("guarded-control-stack");
438ac9a064cSDimitry Andric 
439c0981da4SDimitry Andric   F->addFnAttrs(B);
440344a3780SDimitry Andric   return F;
441344a3780SDimitry Andric }
442344a3780SDimitry Andric 
removeFromParent()443009b1c42SEd Schouten void Function::removeFromParent() {
444dd58ef01SDimitry Andric   getParent()->getFunctionList().remove(getIterator());
445009b1c42SEd Schouten }
446009b1c42SEd Schouten 
eraseFromParent()447009b1c42SEd Schouten void Function::eraseFromParent() {
448dd58ef01SDimitry Andric   getParent()->getFunctionList().erase(getIterator());
449009b1c42SEd Schouten }
450009b1c42SEd Schouten 
splice(Function::iterator ToIt,Function * FromF,Function::iterator FromBeginIt,Function::iterator FromEndIt)451e3b55780SDimitry Andric void Function::splice(Function::iterator ToIt, Function *FromF,
452e3b55780SDimitry Andric                       Function::iterator FromBeginIt,
453e3b55780SDimitry Andric                       Function::iterator FromEndIt) {
454e3b55780SDimitry Andric #ifdef EXPENSIVE_CHECKS
455e3b55780SDimitry Andric   // Check that FromBeginIt is before FromEndIt.
456e3b55780SDimitry Andric   auto FromFEnd = FromF->end();
457e3b55780SDimitry Andric   for (auto It = FromBeginIt; It != FromEndIt; ++It)
458e3b55780SDimitry Andric     assert(It != FromFEnd && "FromBeginIt not before FromEndIt!");
459e3b55780SDimitry Andric #endif // EXPENSIVE_CHECKS
460e3b55780SDimitry Andric   BasicBlocks.splice(ToIt, FromF->BasicBlocks, FromBeginIt, FromEndIt);
461e3b55780SDimitry Andric }
462e3b55780SDimitry Andric 
erase(Function::iterator FromIt,Function::iterator ToIt)463e3b55780SDimitry Andric Function::iterator Function::erase(Function::iterator FromIt,
464e3b55780SDimitry Andric                                    Function::iterator ToIt) {
465e3b55780SDimitry Andric   return BasicBlocks.erase(FromIt, ToIt);
466e3b55780SDimitry Andric }
467e3b55780SDimitry Andric 
468009b1c42SEd Schouten //===----------------------------------------------------------------------===//
469009b1c42SEd Schouten // Function Implementation
470009b1c42SEd Schouten //===----------------------------------------------------------------------===//
471009b1c42SEd Schouten 
computeAddrSpace(unsigned AddrSpace,Module * M)472d8e91e46SDimitry Andric static unsigned computeAddrSpace(unsigned AddrSpace, Module *M) {
473d8e91e46SDimitry Andric   // If AS == -1 and we are passed a valid module pointer we place the function
474d8e91e46SDimitry Andric   // in the program address space. Otherwise we default to AS0.
475d8e91e46SDimitry Andric   if (AddrSpace == static_cast<unsigned>(-1))
476d8e91e46SDimitry Andric     return M ? M->getDataLayout().getProgramAddressSpace() : 0;
477d8e91e46SDimitry Andric   return AddrSpace;
478d8e91e46SDimitry Andric }
479d8e91e46SDimitry Andric 
Function(FunctionType * Ty,LinkageTypes Linkage,unsigned AddrSpace,const Twine & name,Module * ParentModule)480d8e91e46SDimitry Andric Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace,
481d8e91e46SDimitry Andric                    const Twine &name, Module *ParentModule)
482dd58ef01SDimitry Andric     : GlobalObject(Ty, Value::FunctionVal,
483d8e91e46SDimitry Andric                    OperandTraits<Function>::op_begin(this), 0, Linkage, name,
484d8e91e46SDimitry Andric                    computeAddrSpace(AddrSpace, ParentModule)),
485ac9a064cSDimitry Andric       NumArgs(Ty->getNumParams()), IsNewDbgInfoFormat(UseNewDbgInfoFormat) {
486009b1c42SEd Schouten   assert(FunctionType::isValidReturnType(getReturnType()) &&
487411bd29eSDimitry Andric          "invalid return type");
4885a5ac124SDimitry Andric   setGlobalObjectSubClassData(0);
489b915e9e0SDimitry Andric 
490b915e9e0SDimitry Andric   // We only need a symbol table for a function if the context keeps value names
491b915e9e0SDimitry Andric   if (!getContext().shouldDiscardValueNames())
492344a3780SDimitry Andric     SymTab = std::make_unique<ValueSymbolTable>(NonGlobalValueMaxNameSize);
493009b1c42SEd Schouten 
494009b1c42SEd Schouten   // If the function has arguments, mark them as lazily built.
495009b1c42SEd Schouten   if (Ty->getNumParams())
4961e7804dbSRoman Divacky     setValueSubclassData(1);   // Set the "has lazy arguments" bit.
497009b1c42SEd Schouten 
498ac9a064cSDimitry Andric   if (ParentModule) {
499009b1c42SEd Schouten     ParentModule->getFunctionList().push_back(this);
500ac9a064cSDimitry Andric     IsNewDbgInfoFormat = ParentModule->IsNewDbgInfoFormat;
501ac9a064cSDimitry Andric   }
502009b1c42SEd Schouten 
503312c0ed1SDimitry Andric   HasLLVMReservedName = getName().starts_with("llvm.");
504009b1c42SEd Schouten   // Ensure intrinsics have the right parameter attributes.
5055a5ac124SDimitry Andric   // Note, the IntID field will have been set in Value::setName if this function
5065a5ac124SDimitry Andric   // name is a valid intrinsic ID.
5075a5ac124SDimitry Andric   if (IntID)
5085a5ac124SDimitry Andric     setAttributes(Intrinsic::getAttributes(getContext(), IntID));
509009b1c42SEd Schouten }
510009b1c42SEd Schouten 
~Function()511009b1c42SEd Schouten Function::~Function() {
512009b1c42SEd Schouten   dropAllReferences();    // After this it is safe to delete instructions.
513009b1c42SEd Schouten 
514009b1c42SEd Schouten   // Delete all of the method arguments and unlink from symbol table...
51571d5a254SDimitry Andric   if (Arguments)
51671d5a254SDimitry Andric     clearArguments();
517009b1c42SEd Schouten 
518009b1c42SEd Schouten   // Remove the function from the on-the-side GC table.
519009b1c42SEd Schouten   clearGC();
520009b1c42SEd Schouten }
521009b1c42SEd Schouten 
BuildLazyArguments() const522009b1c42SEd Schouten void Function::BuildLazyArguments() const {
523009b1c42SEd Schouten   // Create the arguments vector, all arguments start out unnamed.
52471d5a254SDimitry Andric   auto *FT = getFunctionType();
52571d5a254SDimitry Andric   if (NumArgs > 0) {
52671d5a254SDimitry Andric     Arguments = std::allocator<Argument>().allocate(NumArgs);
52771d5a254SDimitry Andric     for (unsigned i = 0, e = NumArgs; i != e; ++i) {
52871d5a254SDimitry Andric       Type *ArgTy = FT->getParamType(i);
52971d5a254SDimitry Andric       assert(!ArgTy->isVoidTy() && "Cannot have void typed arguments!");
53071d5a254SDimitry Andric       new (Arguments + i) Argument(ArgTy, "", const_cast<Function *>(this), i);
53171d5a254SDimitry Andric     }
532009b1c42SEd Schouten   }
533009b1c42SEd Schouten 
534009b1c42SEd Schouten   // Clear the lazy arguments bit.
5351e7804dbSRoman Divacky   unsigned SDC = getSubclassDataFromValue();
5361d5ae102SDimitry Andric   SDC &= ~(1 << 0);
5371d5ae102SDimitry Andric   const_cast<Function*>(this)->setValueSubclassData(SDC);
53871d5a254SDimitry Andric   assert(!hasLazyArguments());
53971d5a254SDimitry Andric }
54071d5a254SDimitry Andric 
makeArgArray(Argument * Args,size_t Count)54171d5a254SDimitry Andric static MutableArrayRef<Argument> makeArgArray(Argument *Args, size_t Count) {
54271d5a254SDimitry Andric   return MutableArrayRef<Argument>(Args, Count);
54371d5a254SDimitry Andric }
54471d5a254SDimitry Andric 
isConstrainedFPIntrinsic() const545cfca06d7SDimitry Andric bool Function::isConstrainedFPIntrinsic() const {
546ac9a064cSDimitry Andric   return Intrinsic::isConstrainedFPIntrinsic(getIntrinsicID());
547cfca06d7SDimitry Andric }
548cfca06d7SDimitry Andric 
clearArguments()54971d5a254SDimitry Andric void Function::clearArguments() {
55071d5a254SDimitry Andric   for (Argument &A : makeArgArray(Arguments, NumArgs)) {
55171d5a254SDimitry Andric     A.setName("");
55271d5a254SDimitry Andric     A.~Argument();
55371d5a254SDimitry Andric   }
55471d5a254SDimitry Andric   std::allocator<Argument>().deallocate(Arguments, NumArgs);
55571d5a254SDimitry Andric   Arguments = nullptr;
556009b1c42SEd Schouten }
557009b1c42SEd Schouten 
stealArgumentListFrom(Function & Src)55801095a5dSDimitry Andric void Function::stealArgumentListFrom(Function &Src) {
55901095a5dSDimitry Andric   assert(isDeclaration() && "Expected no references to current arguments");
56001095a5dSDimitry Andric 
56101095a5dSDimitry Andric   // Drop the current arguments, if any, and set the lazy argument bit.
56201095a5dSDimitry Andric   if (!hasLazyArguments()) {
56371d5a254SDimitry Andric     assert(llvm::all_of(makeArgArray(Arguments, NumArgs),
56401095a5dSDimitry Andric                         [](const Argument &A) { return A.use_empty(); }) &&
56501095a5dSDimitry Andric            "Expected arguments to be unused in declaration");
56671d5a254SDimitry Andric     clearArguments();
56701095a5dSDimitry Andric     setValueSubclassData(getSubclassDataFromValue() | (1 << 0));
56801095a5dSDimitry Andric   }
56901095a5dSDimitry Andric 
57001095a5dSDimitry Andric   // Nothing to steal if Src has lazy arguments.
57101095a5dSDimitry Andric   if (Src.hasLazyArguments())
57201095a5dSDimitry Andric     return;
57301095a5dSDimitry Andric 
57401095a5dSDimitry Andric   // Steal arguments from Src, and fix the lazy argument bits.
57571d5a254SDimitry Andric   assert(arg_size() == Src.arg_size());
57671d5a254SDimitry Andric   Arguments = Src.Arguments;
57771d5a254SDimitry Andric   Src.Arguments = nullptr;
57871d5a254SDimitry Andric   for (Argument &A : makeArgArray(Arguments, NumArgs)) {
57971d5a254SDimitry Andric     // FIXME: This does the work of transferNodesFromList inefficiently.
58071d5a254SDimitry Andric     SmallString<128> Name;
58171d5a254SDimitry Andric     if (A.hasName())
58271d5a254SDimitry Andric       Name = A.getName();
58371d5a254SDimitry Andric     if (!Name.empty())
58471d5a254SDimitry Andric       A.setName("");
58571d5a254SDimitry Andric     A.setParent(this);
58671d5a254SDimitry Andric     if (!Name.empty())
58771d5a254SDimitry Andric       A.setName(Name);
58801095a5dSDimitry Andric   }
58901095a5dSDimitry Andric 
59071d5a254SDimitry Andric   setValueSubclassData(getSubclassDataFromValue() & ~(1 << 0));
59171d5a254SDimitry Andric   assert(!hasLazyArguments());
59271d5a254SDimitry Andric   Src.setValueSubclassData(Src.getSubclassDataFromValue() | (1 << 0));
593009b1c42SEd Schouten }
594009b1c42SEd Schouten 
deleteBodyImpl(bool ShouldDrop)595b1c73532SDimitry Andric void Function::deleteBodyImpl(bool ShouldDrop) {
59667c32a98SDimitry Andric   setIsMaterializable(false);
59767c32a98SDimitry Andric 
59801095a5dSDimitry Andric   for (BasicBlock &BB : *this)
59901095a5dSDimitry Andric     BB.dropAllReferences();
60036bf506aSRoman Divacky 
601cf099d11SDimitry Andric   // Delete all basic blocks. They are now unused, except possibly by
602cf099d11SDimitry Andric   // blockaddresses, but BasicBlock's destructor takes care of those.
603cf099d11SDimitry Andric   while (!BasicBlocks.empty())
604cf099d11SDimitry Andric     BasicBlocks.begin()->eraseFromParent();
605f8af5cf6SDimitry Andric 
606dd58ef01SDimitry Andric   if (getNumOperands()) {
607b1c73532SDimitry Andric     if (ShouldDrop) {
608b1c73532SDimitry Andric       // Drop uses of any optional data (real or placeholder).
609dd58ef01SDimitry Andric       User::dropAllReferences();
610dd58ef01SDimitry Andric       setNumHungOffUseOperands(0);
611b1c73532SDimitry Andric     } else {
612b1c73532SDimitry Andric       // The code needs to match Function::allocHungoffUselist().
613b1c73532SDimitry Andric       auto *CPN = ConstantPointerNull::get(PointerType::get(getContext(), 0));
614b1c73532SDimitry Andric       Op<0>().set(CPN);
615b1c73532SDimitry Andric       Op<1>().set(CPN);
616b1c73532SDimitry Andric       Op<2>().set(CPN);
617b1c73532SDimitry Andric     }
618dd58ef01SDimitry Andric     setValueSubclassData(getSubclassDataFromValue() & ~0xe);
619dd58ef01SDimitry Andric   }
6205a5ac124SDimitry Andric 
6215a5ac124SDimitry Andric   // Metadata is stored in a side-table.
6225a5ac124SDimitry Andric   clearMetadata();
623009b1c42SEd Schouten }
624009b1c42SEd Schouten 
addAttributeAtIndex(unsigned i,Attribute Attr)625c0981da4SDimitry Andric void Function::addAttributeAtIndex(unsigned i, Attribute Attr) {
626c0981da4SDimitry Andric   AttributeSets = AttributeSets.addAttributeAtIndex(getContext(), i, Attr);
627009b1c42SEd Schouten }
628009b1c42SEd Schouten 
addFnAttr(Attribute::AttrKind Kind)629c0981da4SDimitry Andric void Function::addFnAttr(Attribute::AttrKind Kind) {
630c0981da4SDimitry Andric   AttributeSets = AttributeSets.addFnAttribute(getContext(), Kind);
6314a16efa3SDimitry Andric }
6324a16efa3SDimitry Andric 
addFnAttr(StringRef Kind,StringRef Val)633c0981da4SDimitry Andric void Function::addFnAttr(StringRef Kind, StringRef Val) {
634c0981da4SDimitry Andric   AttributeSets = AttributeSets.addFnAttribute(getContext(), Kind, Val);
635c0981da4SDimitry Andric }
636c0981da4SDimitry Andric 
addFnAttr(Attribute Attr)637c0981da4SDimitry Andric void Function::addFnAttr(Attribute Attr) {
638c0981da4SDimitry Andric   AttributeSets = AttributeSets.addFnAttribute(getContext(), Attr);
639c0981da4SDimitry Andric }
640c0981da4SDimitry Andric 
addFnAttrs(const AttrBuilder & Attrs)641c0981da4SDimitry Andric void Function::addFnAttrs(const AttrBuilder &Attrs) {
642c0981da4SDimitry Andric   AttributeSets = AttributeSets.addFnAttributes(getContext(), Attrs);
643c0981da4SDimitry Andric }
644c0981da4SDimitry Andric 
addRetAttr(Attribute::AttrKind Kind)645c0981da4SDimitry Andric void Function::addRetAttr(Attribute::AttrKind Kind) {
646c0981da4SDimitry Andric   AttributeSets = AttributeSets.addRetAttribute(getContext(), Kind);
647c0981da4SDimitry Andric }
648c0981da4SDimitry Andric 
addRetAttr(Attribute Attr)649c0981da4SDimitry Andric void Function::addRetAttr(Attribute Attr) {
650c0981da4SDimitry Andric   AttributeSets = AttributeSets.addRetAttribute(getContext(), Attr);
651c0981da4SDimitry Andric }
652c0981da4SDimitry Andric 
addRetAttrs(const AttrBuilder & Attrs)653c0981da4SDimitry Andric void Function::addRetAttrs(const AttrBuilder &Attrs) {
654c0981da4SDimitry Andric   AttributeSets = AttributeSets.addRetAttributes(getContext(), Attrs);
65501095a5dSDimitry Andric }
65601095a5dSDimitry Andric 
addParamAttr(unsigned ArgNo,Attribute::AttrKind Kind)657f382538dSDimitry Andric void Function::addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
658c0981da4SDimitry Andric   AttributeSets = AttributeSets.addParamAttribute(getContext(), ArgNo, Kind);
659f382538dSDimitry Andric }
660f382538dSDimitry Andric 
addParamAttr(unsigned ArgNo,Attribute Attr)661f382538dSDimitry Andric void Function::addParamAttr(unsigned ArgNo, Attribute Attr) {
662c0981da4SDimitry Andric   AttributeSets = AttributeSets.addParamAttribute(getContext(), ArgNo, Attr);
663f382538dSDimitry Andric }
664f382538dSDimitry Andric 
addParamAttrs(unsigned ArgNo,const AttrBuilder & Attrs)665f382538dSDimitry Andric void Function::addParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) {
666c0981da4SDimitry Andric   AttributeSets = AttributeSets.addParamAttributes(getContext(), ArgNo, Attrs);
667f382538dSDimitry Andric }
668f382538dSDimitry Andric 
removeAttributeAtIndex(unsigned i,Attribute::AttrKind Kind)669c0981da4SDimitry Andric void Function::removeAttributeAtIndex(unsigned i, Attribute::AttrKind Kind) {
670c0981da4SDimitry Andric   AttributeSets = AttributeSets.removeAttributeAtIndex(getContext(), i, Kind);
67101095a5dSDimitry Andric }
67201095a5dSDimitry Andric 
removeAttributeAtIndex(unsigned i,StringRef Kind)673c0981da4SDimitry Andric void Function::removeAttributeAtIndex(unsigned i, StringRef Kind) {
674c0981da4SDimitry Andric   AttributeSets = AttributeSets.removeAttributeAtIndex(getContext(), i, Kind);
67501095a5dSDimitry Andric }
67601095a5dSDimitry Andric 
removeFnAttr(Attribute::AttrKind Kind)677c0981da4SDimitry Andric void Function::removeFnAttr(Attribute::AttrKind Kind) {
678c0981da4SDimitry Andric   AttributeSets = AttributeSets.removeFnAttribute(getContext(), Kind);
679c0981da4SDimitry Andric }
680c0981da4SDimitry Andric 
removeFnAttr(StringRef Kind)681c0981da4SDimitry Andric void Function::removeFnAttr(StringRef Kind) {
682c0981da4SDimitry Andric   AttributeSets = AttributeSets.removeFnAttribute(getContext(), Kind);
683c0981da4SDimitry Andric }
684c0981da4SDimitry Andric 
removeFnAttrs(const AttributeMask & AM)6856f8fc217SDimitry Andric void Function::removeFnAttrs(const AttributeMask &AM) {
6866f8fc217SDimitry Andric   AttributeSets = AttributeSets.removeFnAttributes(getContext(), AM);
687c0981da4SDimitry Andric }
688c0981da4SDimitry Andric 
removeRetAttr(Attribute::AttrKind Kind)689c0981da4SDimitry Andric void Function::removeRetAttr(Attribute::AttrKind Kind) {
690c0981da4SDimitry Andric   AttributeSets = AttributeSets.removeRetAttribute(getContext(), Kind);
691c0981da4SDimitry Andric }
692c0981da4SDimitry Andric 
removeRetAttr(StringRef Kind)693c0981da4SDimitry Andric void Function::removeRetAttr(StringRef Kind) {
694c0981da4SDimitry Andric   AttributeSets = AttributeSets.removeRetAttribute(getContext(), Kind);
695c0981da4SDimitry Andric }
696c0981da4SDimitry Andric 
removeRetAttrs(const AttributeMask & Attrs)6976f8fc217SDimitry Andric void Function::removeRetAttrs(const AttributeMask &Attrs) {
698c0981da4SDimitry Andric   AttributeSets = AttributeSets.removeRetAttributes(getContext(), Attrs);
699009b1c42SEd Schouten }
700009b1c42SEd Schouten 
removeParamAttr(unsigned ArgNo,Attribute::AttrKind Kind)701f382538dSDimitry Andric void Function::removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
702c0981da4SDimitry Andric   AttributeSets = AttributeSets.removeParamAttribute(getContext(), ArgNo, Kind);
703f382538dSDimitry Andric }
704f382538dSDimitry Andric 
removeParamAttr(unsigned ArgNo,StringRef Kind)705f382538dSDimitry Andric void Function::removeParamAttr(unsigned ArgNo, StringRef Kind) {
706c0981da4SDimitry Andric   AttributeSets = AttributeSets.removeParamAttribute(getContext(), ArgNo, Kind);
707f382538dSDimitry Andric }
708f382538dSDimitry Andric 
removeParamAttrs(unsigned ArgNo,const AttributeMask & Attrs)7096f8fc217SDimitry Andric void Function::removeParamAttrs(unsigned ArgNo, const AttributeMask &Attrs) {
710c0981da4SDimitry Andric   AttributeSets =
711c0981da4SDimitry Andric       AttributeSets.removeParamAttributes(getContext(), ArgNo, Attrs);
7125a5ac124SDimitry Andric }
7135a5ac124SDimitry Andric 
addDereferenceableParamAttr(unsigned ArgNo,uint64_t Bytes)714f382538dSDimitry Andric void Function::addDereferenceableParamAttr(unsigned ArgNo, uint64_t Bytes) {
715c0981da4SDimitry Andric   AttributeSets =
716c0981da4SDimitry Andric       AttributeSets.addDereferenceableParamAttr(getContext(), ArgNo, Bytes);
717f382538dSDimitry Andric }
718f382538dSDimitry Andric 
hasFnAttribute(Attribute::AttrKind Kind) const719c0981da4SDimitry Andric bool Function::hasFnAttribute(Attribute::AttrKind Kind) const {
720c0981da4SDimitry Andric   return AttributeSets.hasFnAttr(Kind);
721c0981da4SDimitry Andric }
722c0981da4SDimitry Andric 
hasFnAttribute(StringRef Kind) const723c0981da4SDimitry Andric bool Function::hasFnAttribute(StringRef Kind) const {
724c0981da4SDimitry Andric   return AttributeSets.hasFnAttr(Kind);
725c0981da4SDimitry Andric }
726c0981da4SDimitry Andric 
hasRetAttribute(Attribute::AttrKind Kind) const727c0981da4SDimitry Andric bool Function::hasRetAttribute(Attribute::AttrKind Kind) const {
728c0981da4SDimitry Andric   return AttributeSets.hasRetAttr(Kind);
729c0981da4SDimitry Andric }
730c0981da4SDimitry Andric 
hasParamAttribute(unsigned ArgNo,Attribute::AttrKind Kind) const731c0981da4SDimitry Andric bool Function::hasParamAttribute(unsigned ArgNo,
732c0981da4SDimitry Andric                                  Attribute::AttrKind Kind) const {
733c0981da4SDimitry Andric   return AttributeSets.hasParamAttr(ArgNo, Kind);
734c0981da4SDimitry Andric }
735c0981da4SDimitry Andric 
getAttributeAtIndex(unsigned i,Attribute::AttrKind Kind) const736c0981da4SDimitry Andric Attribute Function::getAttributeAtIndex(unsigned i,
737c0981da4SDimitry Andric                                         Attribute::AttrKind Kind) const {
738c0981da4SDimitry Andric   return AttributeSets.getAttributeAtIndex(i, Kind);
739c0981da4SDimitry Andric }
740c0981da4SDimitry Andric 
getAttributeAtIndex(unsigned i,StringRef Kind) const741c0981da4SDimitry Andric Attribute Function::getAttributeAtIndex(unsigned i, StringRef Kind) const {
742c0981da4SDimitry Andric   return AttributeSets.getAttributeAtIndex(i, Kind);
743c0981da4SDimitry Andric }
744c0981da4SDimitry Andric 
getFnAttribute(Attribute::AttrKind Kind) const745c0981da4SDimitry Andric Attribute Function::getFnAttribute(Attribute::AttrKind Kind) const {
746c0981da4SDimitry Andric   return AttributeSets.getFnAttr(Kind);
747c0981da4SDimitry Andric }
748c0981da4SDimitry Andric 
getFnAttribute(StringRef Kind) const749c0981da4SDimitry Andric Attribute Function::getFnAttribute(StringRef Kind) const {
750c0981da4SDimitry Andric   return AttributeSets.getFnAttr(Kind);
751c0981da4SDimitry Andric }
752c0981da4SDimitry Andric 
getRetAttribute(Attribute::AttrKind Kind) const753ac9a064cSDimitry Andric Attribute Function::getRetAttribute(Attribute::AttrKind Kind) const {
754ac9a064cSDimitry Andric   return AttributeSets.getRetAttr(Kind);
755ac9a064cSDimitry Andric }
756ac9a064cSDimitry Andric 
getFnAttributeAsParsedInteger(StringRef Name,uint64_t Default) const757e3b55780SDimitry Andric uint64_t Function::getFnAttributeAsParsedInteger(StringRef Name,
758e3b55780SDimitry Andric                                                  uint64_t Default) const {
759e3b55780SDimitry Andric   Attribute A = getFnAttribute(Name);
760e3b55780SDimitry Andric   uint64_t Result = Default;
761e3b55780SDimitry Andric   if (A.isStringAttribute()) {
762e3b55780SDimitry Andric     StringRef Str = A.getValueAsString();
763e3b55780SDimitry Andric     if (Str.getAsInteger(0, Result))
764e3b55780SDimitry Andric       getContext().emitError("cannot parse integer attribute " + Name);
765e3b55780SDimitry Andric   }
766e3b55780SDimitry Andric 
767e3b55780SDimitry Andric   return Result;
768e3b55780SDimitry Andric }
769e3b55780SDimitry Andric 
770c0981da4SDimitry Andric /// gets the specified attribute from the list of attributes.
getParamAttribute(unsigned ArgNo,Attribute::AttrKind Kind) const771c0981da4SDimitry Andric Attribute Function::getParamAttribute(unsigned ArgNo,
772c0981da4SDimitry Andric                                       Attribute::AttrKind Kind) const {
773c0981da4SDimitry Andric   return AttributeSets.getParamAttr(ArgNo, Kind);
7745a5ac124SDimitry Andric }
7755a5ac124SDimitry Andric 
addDereferenceableOrNullParamAttr(unsigned ArgNo,uint64_t Bytes)776f382538dSDimitry Andric void Function::addDereferenceableOrNullParamAttr(unsigned ArgNo,
777f382538dSDimitry Andric                                                  uint64_t Bytes) {
778c0981da4SDimitry Andric   AttributeSets = AttributeSets.addDereferenceableOrNullParamAttr(getContext(),
779c0981da4SDimitry Andric                                                                   ArgNo, Bytes);
780f382538dSDimitry Andric }
781f382538dSDimitry Andric 
addRangeRetAttr(const ConstantRange & CR)782ac9a064cSDimitry Andric void Function::addRangeRetAttr(const ConstantRange &CR) {
783ac9a064cSDimitry Andric   AttributeSets = AttributeSets.addRangeRetAttr(getContext(), CR);
784ac9a064cSDimitry Andric }
785ac9a064cSDimitry Andric 
getDenormalMode(const fltSemantics & FPType) const786b60736ecSDimitry Andric DenormalMode Function::getDenormalMode(const fltSemantics &FPType) const {
787b60736ecSDimitry Andric   if (&FPType == &APFloat::IEEEsingle()) {
7887fa27ce4SDimitry Andric     DenormalMode Mode = getDenormalModeF32Raw();
789b60736ecSDimitry Andric     // If the f32 variant of the attribute isn't specified, try to use the
790b60736ecSDimitry Andric     // generic one.
7917fa27ce4SDimitry Andric     if (Mode.isValid())
7927fa27ce4SDimitry Andric       return Mode;
793b60736ecSDimitry Andric   }
794b60736ecSDimitry Andric 
7957fa27ce4SDimitry Andric   return getDenormalModeRaw();
7967fa27ce4SDimitry Andric }
7977fa27ce4SDimitry Andric 
getDenormalModeRaw() const7987fa27ce4SDimitry Andric DenormalMode Function::getDenormalModeRaw() const {
799b60736ecSDimitry Andric   Attribute Attr = getFnAttribute("denormal-fp-math");
8007fa27ce4SDimitry Andric   StringRef Val = Attr.getValueAsString();
8017fa27ce4SDimitry Andric   return parseDenormalFPAttribute(Val);
8027fa27ce4SDimitry Andric }
8037fa27ce4SDimitry Andric 
getDenormalModeF32Raw() const8047fa27ce4SDimitry Andric DenormalMode Function::getDenormalModeF32Raw() const {
8057fa27ce4SDimitry Andric   Attribute Attr = getFnAttribute("denormal-fp-math-f32");
8067fa27ce4SDimitry Andric   if (Attr.isValid()) {
8077fa27ce4SDimitry Andric     StringRef Val = Attr.getValueAsString();
8087fa27ce4SDimitry Andric     return parseDenormalFPAttribute(Val);
8097fa27ce4SDimitry Andric   }
8107fa27ce4SDimitry Andric 
8117fa27ce4SDimitry Andric   return DenormalMode::getInvalid();
812b60736ecSDimitry Andric }
813b60736ecSDimitry Andric 
getGC() const814050e163aSDimitry Andric const std::string &Function::getGC() const {
815009b1c42SEd Schouten   assert(hasGC() && "Function has no collector");
816050e163aSDimitry Andric   return getContext().getGC(*this);
817009b1c42SEd Schouten }
818009b1c42SEd Schouten 
setGC(std::string Str)81901095a5dSDimitry Andric void Function::setGC(std::string Str) {
820050e163aSDimitry Andric   setValueSubclassDataBit(14, !Str.empty());
821050e163aSDimitry Andric   getContext().setGC(*this, std::move(Str));
822009b1c42SEd Schouten }
823009b1c42SEd Schouten 
clearGC()824009b1c42SEd Schouten void Function::clearGC() {
825050e163aSDimitry Andric   if (!hasGC())
826050e163aSDimitry Andric     return;
827050e163aSDimitry Andric   getContext().deleteGC(*this);
828050e163aSDimitry Andric   setValueSubclassDataBit(14, false);
829009b1c42SEd Schouten }
830009b1c42SEd Schouten 
hasStackProtectorFnAttr() const831b60736ecSDimitry Andric bool Function::hasStackProtectorFnAttr() const {
832b60736ecSDimitry Andric   return hasFnAttribute(Attribute::StackProtect) ||
833b60736ecSDimitry Andric          hasFnAttribute(Attribute::StackProtectStrong) ||
834b60736ecSDimitry Andric          hasFnAttribute(Attribute::StackProtectReq);
835b60736ecSDimitry Andric }
836b60736ecSDimitry Andric 
837dd58ef01SDimitry Andric /// Copy all additional attributes (those not needed to create a Function) from
838dd58ef01SDimitry Andric /// the Function Src to this one.
copyAttributesFrom(const Function * Src)8396b3f41edSDimitry Andric void Function::copyAttributesFrom(const Function *Src) {
8405ca98fd9SDimitry Andric   GlobalObject::copyAttributesFrom(Src);
8416b3f41edSDimitry Andric   setCallingConv(Src->getCallingConv());
8426b3f41edSDimitry Andric   setAttributes(Src->getAttributes());
8436b3f41edSDimitry Andric   if (Src->hasGC())
8446b3f41edSDimitry Andric     setGC(Src->getGC());
845009b1c42SEd Schouten   else
846009b1c42SEd Schouten     clearGC();
8476b3f41edSDimitry Andric   if (Src->hasPersonalityFn())
8486b3f41edSDimitry Andric     setPersonalityFn(Src->getPersonalityFn());
8496b3f41edSDimitry Andric   if (Src->hasPrefixData())
8506b3f41edSDimitry Andric     setPrefixData(Src->getPrefixData());
8516b3f41edSDimitry Andric   if (Src->hasPrologueData())
8526b3f41edSDimitry Andric     setPrologueData(Src->getPrologueData());
853009b1c42SEd Schouten }
854009b1c42SEd Schouten 
getMemoryEffects() const855e3b55780SDimitry Andric MemoryEffects Function::getMemoryEffects() const {
856e3b55780SDimitry Andric   return getAttributes().getMemoryEffects();
857e3b55780SDimitry Andric }
setMemoryEffects(MemoryEffects ME)858e3b55780SDimitry Andric void Function::setMemoryEffects(MemoryEffects ME) {
859e3b55780SDimitry Andric   addFnAttr(Attribute::getWithMemoryEffects(getContext(), ME));
860e3b55780SDimitry Andric }
861e3b55780SDimitry Andric 
862e3b55780SDimitry Andric /// Determine if the function does not access memory.
doesNotAccessMemory() const863e3b55780SDimitry Andric bool Function::doesNotAccessMemory() const {
864e3b55780SDimitry Andric   return getMemoryEffects().doesNotAccessMemory();
865e3b55780SDimitry Andric }
setDoesNotAccessMemory()866e3b55780SDimitry Andric void Function::setDoesNotAccessMemory() {
867e3b55780SDimitry Andric   setMemoryEffects(MemoryEffects::none());
868e3b55780SDimitry Andric }
869e3b55780SDimitry Andric 
870e3b55780SDimitry Andric /// Determine if the function does not access or only reads memory.
onlyReadsMemory() const871e3b55780SDimitry Andric bool Function::onlyReadsMemory() const {
872e3b55780SDimitry Andric   return getMemoryEffects().onlyReadsMemory();
873e3b55780SDimitry Andric }
setOnlyReadsMemory()874e3b55780SDimitry Andric void Function::setOnlyReadsMemory() {
875e3b55780SDimitry Andric   setMemoryEffects(getMemoryEffects() & MemoryEffects::readOnly());
876e3b55780SDimitry Andric }
877e3b55780SDimitry Andric 
878e3b55780SDimitry Andric /// Determine if the function does not access or only writes memory.
onlyWritesMemory() const879e3b55780SDimitry Andric bool Function::onlyWritesMemory() const {
880e3b55780SDimitry Andric   return getMemoryEffects().onlyWritesMemory();
881e3b55780SDimitry Andric }
setOnlyWritesMemory()882e3b55780SDimitry Andric void Function::setOnlyWritesMemory() {
883e3b55780SDimitry Andric   setMemoryEffects(getMemoryEffects() & MemoryEffects::writeOnly());
884e3b55780SDimitry Andric }
885e3b55780SDimitry Andric 
886e3b55780SDimitry Andric /// Determine if the call can access memmory only using pointers based
887e3b55780SDimitry Andric /// on its arguments.
onlyAccessesArgMemory() const888e3b55780SDimitry Andric bool Function::onlyAccessesArgMemory() const {
889e3b55780SDimitry Andric   return getMemoryEffects().onlyAccessesArgPointees();
890e3b55780SDimitry Andric }
setOnlyAccessesArgMemory()891e3b55780SDimitry Andric void Function::setOnlyAccessesArgMemory() {
892e3b55780SDimitry Andric   setMemoryEffects(getMemoryEffects() & MemoryEffects::argMemOnly());
893e3b55780SDimitry Andric }
894e3b55780SDimitry Andric 
895e3b55780SDimitry Andric /// Determine if the function may only access memory that is
896e3b55780SDimitry Andric ///  inaccessible from the IR.
onlyAccessesInaccessibleMemory() const897e3b55780SDimitry Andric bool Function::onlyAccessesInaccessibleMemory() const {
898e3b55780SDimitry Andric   return getMemoryEffects().onlyAccessesInaccessibleMem();
899e3b55780SDimitry Andric }
setOnlyAccessesInaccessibleMemory()900e3b55780SDimitry Andric void Function::setOnlyAccessesInaccessibleMemory() {
901e3b55780SDimitry Andric   setMemoryEffects(getMemoryEffects() & MemoryEffects::inaccessibleMemOnly());
902e3b55780SDimitry Andric }
903e3b55780SDimitry Andric 
904e3b55780SDimitry Andric /// Determine if the function may only access memory that is
905e3b55780SDimitry Andric ///  either inaccessible from the IR or pointed to by its arguments.
onlyAccessesInaccessibleMemOrArgMem() const906e3b55780SDimitry Andric bool Function::onlyAccessesInaccessibleMemOrArgMem() const {
907e3b55780SDimitry Andric   return getMemoryEffects().onlyAccessesInaccessibleOrArgMem();
908e3b55780SDimitry Andric }
setOnlyAccessesInaccessibleMemOrArgMem()909e3b55780SDimitry Andric void Function::setOnlyAccessesInaccessibleMemOrArgMem() {
910e3b55780SDimitry Andric   setMemoryEffects(getMemoryEffects() &
911e3b55780SDimitry Andric                    MemoryEffects::inaccessibleOrArgMemOnly());
912e3b55780SDimitry Andric }
913e3b55780SDimitry Andric 
91401095a5dSDimitry Andric /// Table of string intrinsic names indexed by enum value.
91501095a5dSDimitry Andric static const char * const IntrinsicNameTable[] = {
91601095a5dSDimitry Andric   "not_intrinsic",
91701095a5dSDimitry Andric #define GET_INTRINSIC_NAME_TABLE
918eb11fae6SDimitry Andric #include "llvm/IR/IntrinsicImpl.inc"
91901095a5dSDimitry Andric #undef GET_INTRINSIC_NAME_TABLE
92001095a5dSDimitry Andric };
92101095a5dSDimitry Andric 
92201095a5dSDimitry Andric /// Table of per-target intrinsic name tables.
92301095a5dSDimitry Andric #define GET_INTRINSIC_TARGET_DATA
924eb11fae6SDimitry Andric #include "llvm/IR/IntrinsicImpl.inc"
92501095a5dSDimitry Andric #undef GET_INTRINSIC_TARGET_DATA
92601095a5dSDimitry Andric 
isTargetIntrinsic(Intrinsic::ID IID)927b60736ecSDimitry Andric bool Function::isTargetIntrinsic(Intrinsic::ID IID) {
928b60736ecSDimitry Andric   return IID > TargetInfos[0].Count;
929b60736ecSDimitry Andric }
930b60736ecSDimitry Andric 
isTargetIntrinsic() const931b60736ecSDimitry Andric bool Function::isTargetIntrinsic() const {
932b60736ecSDimitry Andric   return isTargetIntrinsic(IntID);
933b60736ecSDimitry Andric }
934b60736ecSDimitry Andric 
93501095a5dSDimitry Andric /// Find the segment of \c IntrinsicNameTable for intrinsics with the same
93601095a5dSDimitry Andric /// target as \c Name, or the generic table if \c Name is not target specific.
93701095a5dSDimitry Andric ///
93801095a5dSDimitry Andric /// Returns the relevant slice of \c IntrinsicNameTable
findTargetSubtable(StringRef Name)93901095a5dSDimitry Andric static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
940312c0ed1SDimitry Andric   assert(Name.starts_with("llvm."));
94101095a5dSDimitry Andric 
94201095a5dSDimitry Andric   ArrayRef<IntrinsicTargetInfo> Targets(TargetInfos);
94301095a5dSDimitry Andric   // Drop "llvm." and take the first dotted component. That will be the target
94401095a5dSDimitry Andric   // if this is target specific.
94501095a5dSDimitry Andric   StringRef Target = Name.drop_front(5).split('.').first;
946e6d15924SDimitry Andric   auto It = partition_point(
947e6d15924SDimitry Andric       Targets, [=](const IntrinsicTargetInfo &TI) { return TI.Name < Target; });
94801095a5dSDimitry Andric   // We've either found the target or just fall back to the generic set, which
94901095a5dSDimitry Andric   // is always first.
95001095a5dSDimitry Andric   const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0];
951e3b55780SDimitry Andric   return ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count);
95201095a5dSDimitry Andric }
95301095a5dSDimitry Andric 
954eb11fae6SDimitry Andric /// This does the actual lookup of an intrinsic ID which
9555a5ac124SDimitry Andric /// matches the given function name.
lookupIntrinsicID(StringRef Name)956b915e9e0SDimitry Andric Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
95701095a5dSDimitry Andric   ArrayRef<const char *> NameTable = findTargetSubtable(Name);
95801095a5dSDimitry Andric   int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name);
95901095a5dSDimitry Andric   if (Idx == -1)
9605a5ac124SDimitry Andric     return Intrinsic::not_intrinsic;
96101095a5dSDimitry Andric 
96201095a5dSDimitry Andric   // Intrinsic IDs correspond to the location in IntrinsicNameTable, but we have
96301095a5dSDimitry Andric   // an index into a sub-table.
96401095a5dSDimitry Andric   int Adjust = NameTable.data() - IntrinsicNameTable;
96501095a5dSDimitry Andric   Intrinsic::ID ID = static_cast<Intrinsic::ID>(Idx + Adjust);
96601095a5dSDimitry Andric 
96701095a5dSDimitry Andric   // If the intrinsic is not overloaded, require an exact match. If it is
968eb11fae6SDimitry Andric   // overloaded, require either exact or prefix match.
969eb11fae6SDimitry Andric   const auto MatchSize = strlen(NameTable[Idx]);
970eb11fae6SDimitry Andric   assert(Name.size() >= MatchSize && "Expected either exact or prefix match");
971eb11fae6SDimitry Andric   bool IsExactMatch = Name.size() == MatchSize;
972706b4fc4SDimitry Andric   return IsExactMatch || Intrinsic::isOverloaded(ID) ? ID
973706b4fc4SDimitry Andric                                                      : Intrinsic::not_intrinsic;
9745a5ac124SDimitry Andric }
9755a5ac124SDimitry Andric 
updateAfterNameChange()976b1c73532SDimitry Andric void Function::updateAfterNameChange() {
977b1c73532SDimitry Andric   LibFuncCache = UnknownLibFunc;
978b915e9e0SDimitry Andric   StringRef Name = getName();
979312c0ed1SDimitry Andric   if (!Name.starts_with("llvm.")) {
980b915e9e0SDimitry Andric     HasLLVMReservedName = false;
9815a5ac124SDimitry Andric     IntID = Intrinsic::not_intrinsic;
9825a5ac124SDimitry Andric     return;
9835a5ac124SDimitry Andric   }
984b915e9e0SDimitry Andric   HasLLVMReservedName = true;
985b915e9e0SDimitry Andric   IntID = lookupIntrinsicID(Name);
986009b1c42SEd Schouten }
987009b1c42SEd Schouten 
98867c32a98SDimitry Andric /// Returns a stable mangling for the type specified for use in the name
98967c32a98SDimitry Andric /// mangling scheme used by 'any' types in intrinsic signatures.  The mangling
99067c32a98SDimitry Andric /// of named types is simply their name.  Manglings for unnamed types consist
99167c32a98SDimitry Andric /// of a prefix ('p' for pointers, 'a' for arrays, 'f_' for functions)
99267c32a98SDimitry Andric /// combined with the mangling of their component types.  A vararg function
99367c32a98SDimitry Andric /// type will have a suffix of 'vararg'.  Since function types can contain
99467c32a98SDimitry Andric /// other function types, we close a function type mangling with suffix 'f'
99567c32a98SDimitry Andric /// which can't be confused with it's prefix.  This ensures we don't have
99667c32a98SDimitry Andric /// collisions between two unrelated function types. Otherwise, you might
99767c32a98SDimitry Andric /// parse ffXX as f(fXX) or f(fX)X.  (X is a placeholder for any other type.)
998344a3780SDimitry Andric /// The HasUnnamedType boolean is set if an unnamed type was encountered,
999344a3780SDimitry Andric /// indicating that extra care must be taken to ensure a unique name.
getMangledTypeStr(Type * Ty,bool & HasUnnamedType)1000344a3780SDimitry Andric static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType) {
100167c32a98SDimitry Andric   std::string Result;
100267c32a98SDimitry Andric   if (PointerType *PTyp = dyn_cast<PointerType>(Ty)) {
1003344a3780SDimitry Andric     Result += "p" + utostr(PTyp->getAddressSpace());
100467c32a98SDimitry Andric   } else if (ArrayType *ATyp = dyn_cast<ArrayType>(Ty)) {
10056b3f41edSDimitry Andric     Result += "a" + utostr(ATyp->getNumElements()) +
1006344a3780SDimitry Andric               getMangledTypeStr(ATyp->getElementType(), HasUnnamedType);
100767c32a98SDimitry Andric   } else if (StructType *STyp = dyn_cast<StructType>(Ty)) {
100871d5a254SDimitry Andric     if (!STyp->isLiteral()) {
100971d5a254SDimitry Andric       Result += "s_";
1010344a3780SDimitry Andric       if (STyp->hasName())
101167c32a98SDimitry Andric         Result += STyp->getName();
1012344a3780SDimitry Andric       else
1013344a3780SDimitry Andric         HasUnnamedType = true;
101471d5a254SDimitry Andric     } else {
101571d5a254SDimitry Andric       Result += "sl_";
1016e3b55780SDimitry Andric       for (auto *Elem : STyp->elements())
1017344a3780SDimitry Andric         Result += getMangledTypeStr(Elem, HasUnnamedType);
101871d5a254SDimitry Andric     }
101971d5a254SDimitry Andric     // Ensure nested structs are distinguishable.
102071d5a254SDimitry Andric     Result += "s";
102167c32a98SDimitry Andric   } else if (FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
1022344a3780SDimitry Andric     Result += "f_" + getMangledTypeStr(FT->getReturnType(), HasUnnamedType);
102367c32a98SDimitry Andric     for (size_t i = 0; i < FT->getNumParams(); i++)
1024344a3780SDimitry Andric       Result += getMangledTypeStr(FT->getParamType(i), HasUnnamedType);
102567c32a98SDimitry Andric     if (FT->isVarArg())
102667c32a98SDimitry Andric       Result += "vararg";
102767c32a98SDimitry Andric     // Ensure nested function types are distinguishable.
102867c32a98SDimitry Andric     Result += "f";
10291d5ae102SDimitry Andric   } else if (VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1030cfca06d7SDimitry Andric     ElementCount EC = VTy->getElementCount();
1031b60736ecSDimitry Andric     if (EC.isScalable())
10321d5ae102SDimitry Andric       Result += "nx";
1033b60736ecSDimitry Andric     Result += "v" + utostr(EC.getKnownMinValue()) +
1034344a3780SDimitry Andric               getMangledTypeStr(VTy->getElementType(), HasUnnamedType);
1035e3b55780SDimitry Andric   } else if (TargetExtType *TETy = dyn_cast<TargetExtType>(Ty)) {
1036e3b55780SDimitry Andric     Result += "t";
1037e3b55780SDimitry Andric     Result += TETy->getName();
1038e3b55780SDimitry Andric     for (Type *ParamTy : TETy->type_params())
1039e3b55780SDimitry Andric       Result += "_" + getMangledTypeStr(ParamTy, HasUnnamedType);
1040e3b55780SDimitry Andric     for (unsigned IntParam : TETy->int_params())
1041e3b55780SDimitry Andric       Result += "_" + utostr(IntParam);
1042e3b55780SDimitry Andric     // Ensure nested target extension types are distinguishable.
1043e3b55780SDimitry Andric     Result += "t";
1044eb11fae6SDimitry Andric   } else if (Ty) {
1045eb11fae6SDimitry Andric     switch (Ty->getTypeID()) {
1046eb11fae6SDimitry Andric     default: llvm_unreachable("Unhandled type");
1047eb11fae6SDimitry Andric     case Type::VoidTyID:      Result += "isVoid";   break;
1048eb11fae6SDimitry Andric     case Type::MetadataTyID:  Result += "Metadata"; break;
1049eb11fae6SDimitry Andric     case Type::HalfTyID:      Result += "f16";      break;
1050cfca06d7SDimitry Andric     case Type::BFloatTyID:    Result += "bf16";     break;
1051eb11fae6SDimitry Andric     case Type::FloatTyID:     Result += "f32";      break;
1052eb11fae6SDimitry Andric     case Type::DoubleTyID:    Result += "f64";      break;
1053eb11fae6SDimitry Andric     case Type::X86_FP80TyID:  Result += "f80";      break;
1054eb11fae6SDimitry Andric     case Type::FP128TyID:     Result += "f128";     break;
1055eb11fae6SDimitry Andric     case Type::PPC_FP128TyID: Result += "ppcf128";  break;
1056eb11fae6SDimitry Andric     case Type::X86_MMXTyID:   Result += "x86mmx";   break;
1057b60736ecSDimitry Andric     case Type::X86_AMXTyID:   Result += "x86amx";   break;
1058eb11fae6SDimitry Andric     case Type::IntegerTyID:
1059eb11fae6SDimitry Andric       Result += "i" + utostr(cast<IntegerType>(Ty)->getBitWidth());
1060eb11fae6SDimitry Andric       break;
1061eb11fae6SDimitry Andric     }
1062eb11fae6SDimitry Andric   }
106367c32a98SDimitry Andric   return Result;
106467c32a98SDimitry Andric }
106567c32a98SDimitry Andric 
getBaseName(ID id)1066344a3780SDimitry Andric StringRef Intrinsic::getBaseName(ID id) {
1067344a3780SDimitry Andric   assert(id < num_intrinsics && "Invalid intrinsic ID!");
1068344a3780SDimitry Andric   return IntrinsicNameTable[id];
1069344a3780SDimitry Andric }
1070344a3780SDimitry Andric 
getName(ID id)1071b915e9e0SDimitry Andric StringRef Intrinsic::getName(ID id) {
1072b915e9e0SDimitry Andric   assert(id < num_intrinsics && "Invalid intrinsic ID!");
1073706b4fc4SDimitry Andric   assert(!Intrinsic::isOverloaded(id) &&
1074b915e9e0SDimitry Andric          "This version of getName does not support overloading");
1075344a3780SDimitry Andric   return getBaseName(id);
1076b915e9e0SDimitry Andric }
1077b915e9e0SDimitry Andric 
getIntrinsicNameImpl(Intrinsic::ID Id,ArrayRef<Type * > Tys,Module * M,FunctionType * FT,bool EarlyModuleCheck)1078344a3780SDimitry Andric static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef<Type *> Tys,
1079344a3780SDimitry Andric                                         Module *M, FunctionType *FT,
1080344a3780SDimitry Andric                                         bool EarlyModuleCheck) {
1081344a3780SDimitry Andric 
1082344a3780SDimitry Andric   assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!");
1083344a3780SDimitry Andric   assert((Tys.empty() || Intrinsic::isOverloaded(Id)) &&
1084b60736ecSDimitry Andric          "This version of getName is for overloaded intrinsics only");
1085344a3780SDimitry Andric   (void)EarlyModuleCheck;
1086344a3780SDimitry Andric   assert((!EarlyModuleCheck || M ||
1087344a3780SDimitry Andric           !any_of(Tys, [](Type *T) { return isa<PointerType>(T); })) &&
1088344a3780SDimitry Andric          "Intrinsic overloading on pointer types need to provide a Module");
1089344a3780SDimitry Andric   bool HasUnnamedType = false;
1090344a3780SDimitry Andric   std::string Result(Intrinsic::getBaseName(Id));
1091344a3780SDimitry Andric   for (Type *Ty : Tys)
1092344a3780SDimitry Andric     Result += "." + getMangledTypeStr(Ty, HasUnnamedType);
1093344a3780SDimitry Andric   if (HasUnnamedType) {
1094344a3780SDimitry Andric     assert(M && "unnamed types need a module");
1095344a3780SDimitry Andric     if (!FT)
1096344a3780SDimitry Andric       FT = Intrinsic::getType(M->getContext(), Id, Tys);
1097344a3780SDimitry Andric     else
1098344a3780SDimitry Andric       assert((FT == Intrinsic::getType(M->getContext(), Id, Tys)) &&
1099344a3780SDimitry Andric              "Provided FunctionType must match arguments");
1100344a3780SDimitry Andric     return M->getUniqueIntrinsicName(Result, Id, FT);
1101009b1c42SEd Schouten   }
1102009b1c42SEd Schouten   return Result;
1103009b1c42SEd Schouten }
1104009b1c42SEd Schouten 
getName(ID Id,ArrayRef<Type * > Tys,Module * M,FunctionType * FT)1105344a3780SDimitry Andric std::string Intrinsic::getName(ID Id, ArrayRef<Type *> Tys, Module *M,
1106344a3780SDimitry Andric                                FunctionType *FT) {
1107344a3780SDimitry Andric   assert(M && "We need to have a Module");
1108344a3780SDimitry Andric   return getIntrinsicNameImpl(Id, Tys, M, FT, true);
1109344a3780SDimitry Andric }
1110344a3780SDimitry Andric 
getNameNoUnnamedTypes(ID Id,ArrayRef<Type * > Tys)1111344a3780SDimitry Andric std::string Intrinsic::getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys) {
1112344a3780SDimitry Andric   return getIntrinsicNameImpl(Id, Tys, nullptr, nullptr, false);
1113344a3780SDimitry Andric }
1114344a3780SDimitry Andric 
111558b69754SDimitry Andric /// IIT_Info - These are enumerators that describe the entries returned by the
111658b69754SDimitry Andric /// getIntrinsicInfoTableEntries function.
111758b69754SDimitry Andric ///
11187fa27ce4SDimitry Andric /// Defined in Intrinsics.td.
111958b69754SDimitry Andric enum IIT_Info {
11207fa27ce4SDimitry Andric #define GET_INTRINSIC_IITINFO
11217fa27ce4SDimitry Andric #include "llvm/IR/IntrinsicImpl.inc"
11227fa27ce4SDimitry Andric #undef GET_INTRINSIC_IITINFO
112358b69754SDimitry Andric };
112458b69754SDimitry Andric 
DecodeIITType(unsigned & NextElt,ArrayRef<unsigned char> Infos,IIT_Info LastInfo,SmallVectorImpl<Intrinsic::IITDescriptor> & OutputTable)112558b69754SDimitry Andric static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
1126cfca06d7SDimitry Andric                       IIT_Info LastInfo,
112758b69754SDimitry Andric                       SmallVectorImpl<Intrinsic::IITDescriptor> &OutputTable) {
11286b3f41edSDimitry Andric   using namespace Intrinsic;
11296b3f41edSDimitry Andric 
1130cfca06d7SDimitry Andric   bool IsScalableVector = (LastInfo == IIT_SCALABLE_VEC);
1131cfca06d7SDimitry Andric 
113258b69754SDimitry Andric   IIT_Info Info = IIT_Info(Infos[NextElt++]);
113358b69754SDimitry Andric   unsigned StructElts = 2;
113458b69754SDimitry Andric 
113558b69754SDimitry Andric   switch (Info) {
113658b69754SDimitry Andric   case IIT_Done:
113758b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0));
113858b69754SDimitry Andric     return;
1139f8af5cf6SDimitry Andric   case IIT_VARARG:
1140f8af5cf6SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0));
1141f8af5cf6SDimitry Andric     return;
114258b69754SDimitry Andric   case IIT_MMX:
114358b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0));
114458b69754SDimitry Andric     return;
1145b60736ecSDimitry Andric   case IIT_AMX:
1146b60736ecSDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::AMX, 0));
1147b60736ecSDimitry Andric     return;
1148dd58ef01SDimitry Andric   case IIT_TOKEN:
1149dd58ef01SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Token, 0));
1150dd58ef01SDimitry Andric     return;
115158b69754SDimitry Andric   case IIT_METADATA:
115258b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Metadata, 0));
115358b69754SDimitry Andric     return;
11544a16efa3SDimitry Andric   case IIT_F16:
11554a16efa3SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Half, 0));
11564a16efa3SDimitry Andric     return;
1157cfca06d7SDimitry Andric   case IIT_BF16:
1158cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::BFloat, 0));
1159cfca06d7SDimitry Andric     return;
116058b69754SDimitry Andric   case IIT_F32:
116158b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Float, 0));
116258b69754SDimitry Andric     return;
116358b69754SDimitry Andric   case IIT_F64:
116458b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Double, 0));
116558b69754SDimitry Andric     return;
1166eb11fae6SDimitry Andric   case IIT_F128:
1167eb11fae6SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Quad, 0));
1168eb11fae6SDimitry Andric     return;
1169c0981da4SDimitry Andric   case IIT_PPCF128:
1170c0981da4SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::PPCQuad, 0));
1171c0981da4SDimitry Andric     return;
117258b69754SDimitry Andric   case IIT_I1:
117358b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 1));
117458b69754SDimitry Andric     return;
1175145449b1SDimitry Andric   case IIT_I2:
1176145449b1SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 2));
1177145449b1SDimitry Andric     return;
1178145449b1SDimitry Andric   case IIT_I4:
1179145449b1SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 4));
1180145449b1SDimitry Andric     return;
11817fa27ce4SDimitry Andric   case IIT_AARCH64_SVCOUNT:
11827fa27ce4SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::AArch64Svcount, 0));
11837fa27ce4SDimitry Andric     return;
118458b69754SDimitry Andric   case IIT_I8:
118558b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 8));
118658b69754SDimitry Andric     return;
118758b69754SDimitry Andric   case IIT_I16:
118858b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer,16));
118958b69754SDimitry Andric     return;
119058b69754SDimitry Andric   case IIT_I32:
119158b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 32));
119258b69754SDimitry Andric     return;
119358b69754SDimitry Andric   case IIT_I64:
119458b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 64));
119558b69754SDimitry Andric     return;
11965a5ac124SDimitry Andric   case IIT_I128:
11975a5ac124SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 128));
11985a5ac124SDimitry Andric     return;
1199f8af5cf6SDimitry Andric   case IIT_V1:
1200cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(1, IsScalableVector));
1201cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
1202f8af5cf6SDimitry Andric     return;
120358b69754SDimitry Andric   case IIT_V2:
1204cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(2, IsScalableVector));
1205cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
120658b69754SDimitry Andric     return;
120777fc4c14SDimitry Andric   case IIT_V3:
120877fc4c14SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(3, IsScalableVector));
120977fc4c14SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
121077fc4c14SDimitry Andric     return;
121158b69754SDimitry Andric   case IIT_V4:
1212cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(4, IsScalableVector));
1213cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
121458b69754SDimitry Andric     return;
1215ac9a064cSDimitry Andric   case IIT_V6:
1216ac9a064cSDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(6, IsScalableVector));
1217ac9a064cSDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
1218ac9a064cSDimitry Andric     return;
121958b69754SDimitry Andric   case IIT_V8:
1220cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(8, IsScalableVector));
1221cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
122258b69754SDimitry Andric     return;
1223ac9a064cSDimitry Andric   case IIT_V10:
1224ac9a064cSDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(10, IsScalableVector));
1225ac9a064cSDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
1226ac9a064cSDimitry Andric     return;
122758b69754SDimitry Andric   case IIT_V16:
1228cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(16, IsScalableVector));
1229cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
123058b69754SDimitry Andric     return;
123158b69754SDimitry Andric   case IIT_V32:
1232cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(32, IsScalableVector));
1233cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
123458b69754SDimitry Andric     return;
123567c32a98SDimitry Andric   case IIT_V64:
1236cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(64, IsScalableVector));
1237cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
1238cfca06d7SDimitry Andric     return;
1239cfca06d7SDimitry Andric   case IIT_V128:
1240cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(128, IsScalableVector));
1241cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
124267c32a98SDimitry Andric     return;
1243b60736ecSDimitry Andric   case IIT_V256:
1244b60736ecSDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(256, IsScalableVector));
1245b60736ecSDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
1246b60736ecSDimitry Andric     return;
1247dd58ef01SDimitry Andric   case IIT_V512:
1248cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(512, IsScalableVector));
1249cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
1250dd58ef01SDimitry Andric     return;
1251dd58ef01SDimitry Andric   case IIT_V1024:
1252cfca06d7SDimitry Andric     OutputTable.push_back(IITDescriptor::getVector(1024, IsScalableVector));
1253cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
1254dd58ef01SDimitry Andric     return;
125577fc4c14SDimitry Andric   case IIT_EXTERNREF:
125677fc4c14SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 10));
125777fc4c14SDimitry Andric     return;
125877fc4c14SDimitry Andric   case IIT_FUNCREF:
125977fc4c14SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 20));
126077fc4c14SDimitry Andric     return;
126158b69754SDimitry Andric   case IIT_PTR:
126258b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
126358b69754SDimitry Andric     return;
12647fa27ce4SDimitry Andric   case IIT_ANYPTR: // [ANYPTR addrspace]
126558b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer,
126658b69754SDimitry Andric                                              Infos[NextElt++]));
126758b69754SDimitry Andric     return;
126858b69754SDimitry Andric   case IIT_ARG: {
126958b69754SDimitry Andric     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
127058b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo));
127158b69754SDimitry Andric     return;
127258b69754SDimitry Andric   }
12735ca98fd9SDimitry Andric   case IIT_EXTEND_ARG: {
127458b69754SDimitry Andric     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
12755ca98fd9SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::ExtendArgument,
127658b69754SDimitry Andric                                              ArgInfo));
127758b69754SDimitry Andric     return;
127858b69754SDimitry Andric   }
12795ca98fd9SDimitry Andric   case IIT_TRUNC_ARG: {
128058b69754SDimitry Andric     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
12815ca98fd9SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncArgument,
12825ca98fd9SDimitry Andric                                              ArgInfo));
12835ca98fd9SDimitry Andric     return;
12845ca98fd9SDimitry Andric   }
12855ca98fd9SDimitry Andric   case IIT_HALF_VEC_ARG: {
12865ca98fd9SDimitry Andric     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
12875ca98fd9SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::HalfVecArgument,
128858b69754SDimitry Andric                                              ArgInfo));
128958b69754SDimitry Andric     return;
129058b69754SDimitry Andric   }
129167c32a98SDimitry Andric   case IIT_SAME_VEC_WIDTH_ARG: {
129267c32a98SDimitry Andric     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
129367c32a98SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::SameVecWidthArgument,
129467c32a98SDimitry Andric                                              ArgInfo));
129567c32a98SDimitry Andric     return;
129667c32a98SDimitry Andric   }
1297148779dfSDimitry Andric   case IIT_VEC_OF_ANYPTRS_TO_ELT: {
1298148779dfSDimitry Andric     unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
1299148779dfSDimitry Andric     unsigned short RefNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
1300148779dfSDimitry Andric     OutputTable.push_back(
1301148779dfSDimitry Andric         IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt, ArgNo, RefNo));
13025a5ac124SDimitry Andric     return;
13035a5ac124SDimitry Andric   }
130458b69754SDimitry Andric   case IIT_EMPTYSTRUCT:
130558b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
130658b69754SDimitry Andric     return;
1307e3b55780SDimitry Andric   case IIT_STRUCT9: ++StructElts; [[fallthrough]];
1308e3b55780SDimitry Andric   case IIT_STRUCT8: ++StructElts; [[fallthrough]];
1309e3b55780SDimitry Andric   case IIT_STRUCT7: ++StructElts; [[fallthrough]];
1310e3b55780SDimitry Andric   case IIT_STRUCT6: ++StructElts; [[fallthrough]];
1311e3b55780SDimitry Andric   case IIT_STRUCT5: ++StructElts; [[fallthrough]];
1312e3b55780SDimitry Andric   case IIT_STRUCT4: ++StructElts; [[fallthrough]];
1313e3b55780SDimitry Andric   case IIT_STRUCT3: ++StructElts; [[fallthrough]];
131458b69754SDimitry Andric   case IIT_STRUCT2: {
131558b69754SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct,StructElts));
131658b69754SDimitry Andric 
131758b69754SDimitry Andric     for (unsigned i = 0; i != StructElts; ++i)
1318cfca06d7SDimitry Andric       DecodeIITType(NextElt, Infos, Info, OutputTable);
131958b69754SDimitry Andric     return;
132058b69754SDimitry Andric   }
13211d5ae102SDimitry Andric   case IIT_SUBDIVIDE2_ARG: {
13221d5ae102SDimitry Andric     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
13231d5ae102SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Subdivide2Argument,
13241d5ae102SDimitry Andric                                              ArgInfo));
13251d5ae102SDimitry Andric     return;
13261d5ae102SDimitry Andric   }
13271d5ae102SDimitry Andric   case IIT_SUBDIVIDE4_ARG: {
13281d5ae102SDimitry Andric     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
13291d5ae102SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Subdivide4Argument,
13301d5ae102SDimitry Andric                                              ArgInfo));
13311d5ae102SDimitry Andric     return;
13321d5ae102SDimitry Andric   }
1333e6d15924SDimitry Andric   case IIT_VEC_ELEMENT: {
1334e6d15924SDimitry Andric     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
1335e6d15924SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecElementArgument,
1336e6d15924SDimitry Andric                                              ArgInfo));
1337e6d15924SDimitry Andric     return;
1338e6d15924SDimitry Andric   }
13391d5ae102SDimitry Andric   case IIT_SCALABLE_VEC: {
1340cfca06d7SDimitry Andric     DecodeIITType(NextElt, Infos, Info, OutputTable);
13411d5ae102SDimitry Andric     return;
13421d5ae102SDimitry Andric   }
13431d5ae102SDimitry Andric   case IIT_VEC_OF_BITCASTS_TO_INT: {
13441d5ae102SDimitry Andric     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
13451d5ae102SDimitry Andric     OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt,
13461d5ae102SDimitry Andric                                              ArgInfo));
13471d5ae102SDimitry Andric     return;
13481d5ae102SDimitry Andric   }
134958b69754SDimitry Andric   }
135058b69754SDimitry Andric   llvm_unreachable("unhandled");
135158b69754SDimitry Andric }
135258b69754SDimitry Andric 
135358b69754SDimitry Andric #define GET_INTRINSIC_GENERATOR_GLOBAL
1354eb11fae6SDimitry Andric #include "llvm/IR/IntrinsicImpl.inc"
135558b69754SDimitry Andric #undef GET_INTRINSIC_GENERATOR_GLOBAL
135658b69754SDimitry Andric 
getIntrinsicInfoTableEntries(ID id,SmallVectorImpl<IITDescriptor> & T)135758b69754SDimitry Andric void Intrinsic::getIntrinsicInfoTableEntries(ID id,
135858b69754SDimitry Andric                                              SmallVectorImpl<IITDescriptor> &T){
135958b69754SDimitry Andric   // Check to see if the intrinsic's type was expressible by the table.
136058b69754SDimitry Andric   unsigned TableVal = IIT_Table[id-1];
136158b69754SDimitry Andric 
136258b69754SDimitry Andric   // Decode the TableVal into an array of IITValues.
136358b69754SDimitry Andric   SmallVector<unsigned char, 8> IITValues;
136458b69754SDimitry Andric   ArrayRef<unsigned char> IITEntries;
136558b69754SDimitry Andric   unsigned NextElt = 0;
136658b69754SDimitry Andric   if ((TableVal >> 31) != 0) {
136758b69754SDimitry Andric     // This is an offset into the IIT_LongEncodingTable.
136858b69754SDimitry Andric     IITEntries = IIT_LongEncodingTable;
136958b69754SDimitry Andric 
137058b69754SDimitry Andric     // Strip sentinel bit.
137158b69754SDimitry Andric     NextElt = (TableVal << 1) >> 1;
137258b69754SDimitry Andric   } else {
137358b69754SDimitry Andric     // Decode the TableVal into an array of IITValues.  If the entry was encoded
137458b69754SDimitry Andric     // into a single word in the table itself, decode it now.
137558b69754SDimitry Andric     do {
137658b69754SDimitry Andric       IITValues.push_back(TableVal & 0xF);
137758b69754SDimitry Andric       TableVal >>= 4;
137858b69754SDimitry Andric     } while (TableVal);
137958b69754SDimitry Andric 
138058b69754SDimitry Andric     IITEntries = IITValues;
138158b69754SDimitry Andric     NextElt = 0;
138258b69754SDimitry Andric   }
138358b69754SDimitry Andric 
138458b69754SDimitry Andric   // Okay, decode the table into the output vector of IITDescriptors.
1385cfca06d7SDimitry Andric   DecodeIITType(NextElt, IITEntries, IIT_Done, T);
138658b69754SDimitry Andric   while (NextElt != IITEntries.size() && IITEntries[NextElt] != 0)
1387cfca06d7SDimitry Andric     DecodeIITType(NextElt, IITEntries, IIT_Done, T);
138858b69754SDimitry Andric }
138958b69754SDimitry Andric 
DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> & Infos,ArrayRef<Type * > Tys,LLVMContext & Context)139058b69754SDimitry Andric static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
139158b69754SDimitry Andric                              ArrayRef<Type*> Tys, LLVMContext &Context) {
139258b69754SDimitry Andric   using namespace Intrinsic;
13936b3f41edSDimitry Andric 
139458b69754SDimitry Andric   IITDescriptor D = Infos.front();
139558b69754SDimitry Andric   Infos = Infos.slice(1);
139658b69754SDimitry Andric 
139758b69754SDimitry Andric   switch (D.Kind) {
139858b69754SDimitry Andric   case IITDescriptor::Void: return Type::getVoidTy(Context);
1399f8af5cf6SDimitry Andric   case IITDescriptor::VarArg: return Type::getVoidTy(Context);
140058b69754SDimitry Andric   case IITDescriptor::MMX: return Type::getX86_MMXTy(Context);
1401b60736ecSDimitry Andric   case IITDescriptor::AMX: return Type::getX86_AMXTy(Context);
1402dd58ef01SDimitry Andric   case IITDescriptor::Token: return Type::getTokenTy(Context);
140358b69754SDimitry Andric   case IITDescriptor::Metadata: return Type::getMetadataTy(Context);
14044a16efa3SDimitry Andric   case IITDescriptor::Half: return Type::getHalfTy(Context);
1405cfca06d7SDimitry Andric   case IITDescriptor::BFloat: return Type::getBFloatTy(Context);
140658b69754SDimitry Andric   case IITDescriptor::Float: return Type::getFloatTy(Context);
140758b69754SDimitry Andric   case IITDescriptor::Double: return Type::getDoubleTy(Context);
1408eb11fae6SDimitry Andric   case IITDescriptor::Quad: return Type::getFP128Ty(Context);
1409c0981da4SDimitry Andric   case IITDescriptor::PPCQuad: return Type::getPPC_FP128Ty(Context);
14107fa27ce4SDimitry Andric   case IITDescriptor::AArch64Svcount:
14117fa27ce4SDimitry Andric     return TargetExtType::get(Context, "aarch64.svcount");
141258b69754SDimitry Andric 
141358b69754SDimitry Andric   case IITDescriptor::Integer:
141458b69754SDimitry Andric     return IntegerType::get(Context, D.Integer_Width);
141558b69754SDimitry Andric   case IITDescriptor::Vector:
1416cfca06d7SDimitry Andric     return VectorType::get(DecodeFixedType(Infos, Tys, Context),
1417cfca06d7SDimitry Andric                            D.Vector_Width);
141858b69754SDimitry Andric   case IITDescriptor::Pointer:
14197fa27ce4SDimitry Andric     return PointerType::get(Context, D.Pointer_AddressSpace);
142058b69754SDimitry Andric   case IITDescriptor::Struct: {
1421044eb2f6SDimitry Andric     SmallVector<Type *, 8> Elts;
142258b69754SDimitry Andric     for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
1423044eb2f6SDimitry Andric       Elts.push_back(DecodeFixedType(Infos, Tys, Context));
1424044eb2f6SDimitry Andric     return StructType::get(Context, Elts);
142558b69754SDimitry Andric   }
142658b69754SDimitry Andric   case IITDescriptor::Argument:
142758b69754SDimitry Andric     return Tys[D.getArgumentNumber()];
14285ca98fd9SDimitry Andric   case IITDescriptor::ExtendArgument: {
14295ca98fd9SDimitry Andric     Type *Ty = Tys[D.getArgumentNumber()];
14305ca98fd9SDimitry Andric     if (VectorType *VTy = dyn_cast<VectorType>(Ty))
14315ca98fd9SDimitry Andric       return VectorType::getExtendedElementVectorType(VTy);
143258b69754SDimitry Andric 
14335ca98fd9SDimitry Andric     return IntegerType::get(Context, 2 * cast<IntegerType>(Ty)->getBitWidth());
14345ca98fd9SDimitry Andric   }
14355ca98fd9SDimitry Andric   case IITDescriptor::TruncArgument: {
14365ca98fd9SDimitry Andric     Type *Ty = Tys[D.getArgumentNumber()];
14375ca98fd9SDimitry Andric     if (VectorType *VTy = dyn_cast<VectorType>(Ty))
14385ca98fd9SDimitry Andric       return VectorType::getTruncatedElementVectorType(VTy);
14395ca98fd9SDimitry Andric 
14405ca98fd9SDimitry Andric     IntegerType *ITy = cast<IntegerType>(Ty);
14415ca98fd9SDimitry Andric     assert(ITy->getBitWidth() % 2 == 0);
14425ca98fd9SDimitry Andric     return IntegerType::get(Context, ITy->getBitWidth() / 2);
14435ca98fd9SDimitry Andric   }
14441d5ae102SDimitry Andric   case IITDescriptor::Subdivide2Argument:
14451d5ae102SDimitry Andric   case IITDescriptor::Subdivide4Argument: {
14461d5ae102SDimitry Andric     Type *Ty = Tys[D.getArgumentNumber()];
14471d5ae102SDimitry Andric     VectorType *VTy = dyn_cast<VectorType>(Ty);
14481d5ae102SDimitry Andric     assert(VTy && "Expected an argument of Vector Type");
14491d5ae102SDimitry Andric     int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
14501d5ae102SDimitry Andric     return VectorType::getSubdividedVectorType(VTy, SubDivs);
14511d5ae102SDimitry Andric   }
14525ca98fd9SDimitry Andric   case IITDescriptor::HalfVecArgument:
14535ca98fd9SDimitry Andric     return VectorType::getHalfElementsVectorType(cast<VectorType>(
145458b69754SDimitry Andric                                                   Tys[D.getArgumentNumber()]));
145567c32a98SDimitry Andric   case IITDescriptor::SameVecWidthArgument: {
145667c32a98SDimitry Andric     Type *EltTy = DecodeFixedType(Infos, Tys, Context);
145767c32a98SDimitry Andric     Type *Ty = Tys[D.getArgumentNumber()];
1458e6d15924SDimitry Andric     if (auto *VTy = dyn_cast<VectorType>(Ty))
14591d5ae102SDimitry Andric       return VectorType::get(EltTy, VTy->getElementCount());
1460e6d15924SDimitry Andric     return EltTy;
146167c32a98SDimitry Andric   }
1462e6d15924SDimitry Andric   case IITDescriptor::VecElementArgument: {
1463e6d15924SDimitry Andric     Type *Ty = Tys[D.getArgumentNumber()];
1464e6d15924SDimitry Andric     if (VectorType *VTy = dyn_cast<VectorType>(Ty))
1465e6d15924SDimitry Andric       return VTy->getElementType();
1466e6d15924SDimitry Andric     llvm_unreachable("Expected an argument of Vector Type");
1467e6d15924SDimitry Andric   }
14681d5ae102SDimitry Andric   case IITDescriptor::VecOfBitcastsToInt: {
14691d5ae102SDimitry Andric     Type *Ty = Tys[D.getArgumentNumber()];
14701d5ae102SDimitry Andric     VectorType *VTy = dyn_cast<VectorType>(Ty);
14711d5ae102SDimitry Andric     assert(VTy && "Expected an argument of Vector Type");
14721d5ae102SDimitry Andric     return VectorType::getInteger(VTy);
14731d5ae102SDimitry Andric   }
1474148779dfSDimitry Andric   case IITDescriptor::VecOfAnyPtrsToElt:
1475148779dfSDimitry Andric     // Return the overloaded type (which determines the pointers address space)
1476148779dfSDimitry Andric     return Tys[D.getOverloadArgNumber()];
147758b69754SDimitry Andric   }
147858b69754SDimitry Andric   llvm_unreachable("unhandled");
147958b69754SDimitry Andric }
148058b69754SDimitry Andric 
getType(LLVMContext & Context,ID id,ArrayRef<Type * > Tys)148130815c53SDimitry Andric FunctionType *Intrinsic::getType(LLVMContext &Context,
1482411bd29eSDimitry Andric                                  ID id, ArrayRef<Type*> Tys) {
148358b69754SDimitry Andric   SmallVector<IITDescriptor, 8> Table;
148458b69754SDimitry Andric   getIntrinsicInfoTableEntries(id, Table);
148558b69754SDimitry Andric 
148658b69754SDimitry Andric   ArrayRef<IITDescriptor> TableRef = Table;
148758b69754SDimitry Andric   Type *ResultTy = DecodeFixedType(TableRef, Tys, Context);
148858b69754SDimitry Andric 
148963faed5bSDimitry Andric   SmallVector<Type*, 8> ArgTys;
149058b69754SDimitry Andric   while (!TableRef.empty())
149158b69754SDimitry Andric     ArgTys.push_back(DecodeFixedType(TableRef, Tys, Context));
1492009b1c42SEd Schouten 
149367c32a98SDimitry Andric   // DecodeFixedType returns Void for IITDescriptor::Void and IITDescriptor::VarArg
149467c32a98SDimitry Andric   // If we see void type as the type of the last argument, it is vararg intrinsic
149567c32a98SDimitry Andric   if (!ArgTys.empty() && ArgTys.back()->isVoidTy()) {
149667c32a98SDimitry Andric     ArgTys.pop_back();
149767c32a98SDimitry Andric     return FunctionType::get(ResultTy, ArgTys, true);
149867c32a98SDimitry Andric   }
149958b69754SDimitry Andric   return FunctionType::get(ResultTy, ArgTys, false);
1500009b1c42SEd Schouten }
1501009b1c42SEd Schouten 
isOverloaded(ID id)1502009b1c42SEd Schouten bool Intrinsic::isOverloaded(ID id) {
1503009b1c42SEd Schouten #define GET_INTRINSIC_OVERLOAD_TABLE
1504eb11fae6SDimitry Andric #include "llvm/IR/IntrinsicImpl.inc"
1505009b1c42SEd Schouten #undef GET_INTRINSIC_OVERLOAD_TABLE
1506009b1c42SEd Schouten }
1507009b1c42SEd Schouten 
1508009b1c42SEd Schouten /// This defines the "Intrinsic::getAttributes(ID id)" method.
1509009b1c42SEd Schouten #define GET_INTRINSIC_ATTRIBUTES
1510eb11fae6SDimitry Andric #include "llvm/IR/IntrinsicImpl.inc"
1511009b1c42SEd Schouten #undef GET_INTRINSIC_ATTRIBUTES
1512009b1c42SEd Schouten 
getDeclaration(Module * M,ID id,ArrayRef<Type * > Tys)1513411bd29eSDimitry Andric Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
1514009b1c42SEd Schouten   // There can never be multiple globals with the same name of different types,
1515009b1c42SEd Schouten   // because intrinsics must be a specific type.
1516344a3780SDimitry Andric   auto *FT = getType(M->getContext(), id, Tys);
1517e6d15924SDimitry Andric   return cast<Function>(
1518e3b55780SDimitry Andric       M->getOrInsertFunction(
1519e3b55780SDimitry Andric            Tys.empty() ? getName(id) : getName(id, Tys, M, FT), FT)
1520e6d15924SDimitry Andric           .getCallee());
1521009b1c42SEd Schouten }
1522009b1c42SEd Schouten 
1523145449b1SDimitry Andric // This defines the "Intrinsic::getIntrinsicForClangBuiltin()" method.
1524145449b1SDimitry Andric #define GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN
1525eb11fae6SDimitry Andric #include "llvm/IR/IntrinsicImpl.inc"
1526145449b1SDimitry Andric #undef GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN
1527009b1c42SEd Schouten 
15285ca98fd9SDimitry Andric // This defines the "Intrinsic::getIntrinsicForMSBuiltin()" method.
15295ca98fd9SDimitry Andric #define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
1530eb11fae6SDimitry Andric #include "llvm/IR/IntrinsicImpl.inc"
15315ca98fd9SDimitry Andric #undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
15325ca98fd9SDimitry Andric 
isConstrainedFPIntrinsic(ID QID)1533ac9a064cSDimitry Andric bool Intrinsic::isConstrainedFPIntrinsic(ID QID) {
1534ac9a064cSDimitry Andric   switch (QID) {
1535ac9a064cSDimitry Andric #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC)                         \
1536ac9a064cSDimitry Andric   case Intrinsic::INTRINSIC:
1537ac9a064cSDimitry Andric #include "llvm/IR/ConstrainedOps.def"
1538ac9a064cSDimitry Andric #undef INSTRUCTION
1539ac9a064cSDimitry Andric     return true;
1540ac9a064cSDimitry Andric   default:
1541ac9a064cSDimitry Andric     return false;
1542ac9a064cSDimitry Andric   }
1543ac9a064cSDimitry Andric }
1544ac9a064cSDimitry Andric 
hasConstrainedFPRoundingModeOperand(Intrinsic::ID QID)1545ac9a064cSDimitry Andric bool Intrinsic::hasConstrainedFPRoundingModeOperand(Intrinsic::ID QID) {
1546ac9a064cSDimitry Andric   switch (QID) {
1547ac9a064cSDimitry Andric #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC)                         \
1548ac9a064cSDimitry Andric   case Intrinsic::INTRINSIC:                                                   \
1549ac9a064cSDimitry Andric     return ROUND_MODE == 1;
1550ac9a064cSDimitry Andric #include "llvm/IR/ConstrainedOps.def"
1551ac9a064cSDimitry Andric #undef INSTRUCTION
1552ac9a064cSDimitry Andric   default:
1553ac9a064cSDimitry Andric     return false;
1554ac9a064cSDimitry Andric   }
1555ac9a064cSDimitry Andric }
1556ac9a064cSDimitry Andric 
1557e6d15924SDimitry Andric using DeferredIntrinsicMatchPair =
1558e6d15924SDimitry Andric     std::pair<Type *, ArrayRef<Intrinsic::IITDescriptor>>;
1559e6d15924SDimitry Andric 
matchIntrinsicType(Type * Ty,ArrayRef<Intrinsic::IITDescriptor> & Infos,SmallVectorImpl<Type * > & ArgTys,SmallVectorImpl<DeferredIntrinsicMatchPair> & DeferredChecks,bool IsDeferredCheck)1560e6d15924SDimitry Andric static bool matchIntrinsicType(
1561e6d15924SDimitry Andric     Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
1562e6d15924SDimitry Andric     SmallVectorImpl<Type *> &ArgTys,
1563e6d15924SDimitry Andric     SmallVectorImpl<DeferredIntrinsicMatchPair> &DeferredChecks,
1564e6d15924SDimitry Andric     bool IsDeferredCheck) {
156501095a5dSDimitry Andric   using namespace Intrinsic;
156601095a5dSDimitry Andric 
156701095a5dSDimitry Andric   // If we ran out of descriptors, there are too many arguments.
156801095a5dSDimitry Andric   if (Infos.empty()) return true;
1569e6d15924SDimitry Andric 
1570e6d15924SDimitry Andric   // Do this before slicing off the 'front' part
1571e6d15924SDimitry Andric   auto InfosRef = Infos;
1572e6d15924SDimitry Andric   auto DeferCheck = [&DeferredChecks, &InfosRef](Type *T) {
1573e6d15924SDimitry Andric     DeferredChecks.emplace_back(T, InfosRef);
1574e6d15924SDimitry Andric     return false;
1575e6d15924SDimitry Andric   };
1576e6d15924SDimitry Andric 
157701095a5dSDimitry Andric   IITDescriptor D = Infos.front();
157801095a5dSDimitry Andric   Infos = Infos.slice(1);
157901095a5dSDimitry Andric 
158001095a5dSDimitry Andric   switch (D.Kind) {
158101095a5dSDimitry Andric     case IITDescriptor::Void: return !Ty->isVoidTy();
158201095a5dSDimitry Andric     case IITDescriptor::VarArg: return true;
158301095a5dSDimitry Andric     case IITDescriptor::MMX:  return !Ty->isX86_MMXTy();
1584b60736ecSDimitry Andric     case IITDescriptor::AMX:  return !Ty->isX86_AMXTy();
158501095a5dSDimitry Andric     case IITDescriptor::Token: return !Ty->isTokenTy();
158601095a5dSDimitry Andric     case IITDescriptor::Metadata: return !Ty->isMetadataTy();
158701095a5dSDimitry Andric     case IITDescriptor::Half: return !Ty->isHalfTy();
1588cfca06d7SDimitry Andric     case IITDescriptor::BFloat: return !Ty->isBFloatTy();
158901095a5dSDimitry Andric     case IITDescriptor::Float: return !Ty->isFloatTy();
159001095a5dSDimitry Andric     case IITDescriptor::Double: return !Ty->isDoubleTy();
1591eb11fae6SDimitry Andric     case IITDescriptor::Quad: return !Ty->isFP128Ty();
1592c0981da4SDimitry Andric     case IITDescriptor::PPCQuad: return !Ty->isPPC_FP128Ty();
159301095a5dSDimitry Andric     case IITDescriptor::Integer: return !Ty->isIntegerTy(D.Integer_Width);
15947fa27ce4SDimitry Andric     case IITDescriptor::AArch64Svcount:
15957fa27ce4SDimitry Andric       return !isa<TargetExtType>(Ty) ||
15967fa27ce4SDimitry Andric              cast<TargetExtType>(Ty)->getName() != "aarch64.svcount";
159701095a5dSDimitry Andric     case IITDescriptor::Vector: {
159801095a5dSDimitry Andric       VectorType *VT = dyn_cast<VectorType>(Ty);
1599cfca06d7SDimitry Andric       return !VT || VT->getElementCount() != D.Vector_Width ||
1600e6d15924SDimitry Andric              matchIntrinsicType(VT->getElementType(), Infos, ArgTys,
1601e6d15924SDimitry Andric                                 DeferredChecks, IsDeferredCheck);
160201095a5dSDimitry Andric     }
160301095a5dSDimitry Andric     case IITDescriptor::Pointer: {
160401095a5dSDimitry Andric       PointerType *PT = dyn_cast<PointerType>(Ty);
16057fa27ce4SDimitry Andric       return !PT || PT->getAddressSpace() != D.Pointer_AddressSpace;
160601095a5dSDimitry Andric     }
160701095a5dSDimitry Andric 
160801095a5dSDimitry Andric     case IITDescriptor::Struct: {
160901095a5dSDimitry Andric       StructType *ST = dyn_cast<StructType>(Ty);
1610145449b1SDimitry Andric       if (!ST || !ST->isLiteral() || ST->isPacked() ||
1611145449b1SDimitry Andric           ST->getNumElements() != D.Struct_NumElements)
161201095a5dSDimitry Andric         return true;
161301095a5dSDimitry Andric 
161401095a5dSDimitry Andric       for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
1615e6d15924SDimitry Andric         if (matchIntrinsicType(ST->getElementType(i), Infos, ArgTys,
1616e6d15924SDimitry Andric                                DeferredChecks, IsDeferredCheck))
161701095a5dSDimitry Andric           return true;
161801095a5dSDimitry Andric       return false;
161901095a5dSDimitry Andric     }
162001095a5dSDimitry Andric 
162101095a5dSDimitry Andric     case IITDescriptor::Argument:
1622e6d15924SDimitry Andric       // If this is the second occurrence of an argument,
1623e6d15924SDimitry Andric       // verify that the later instance matches the previous instance.
162401095a5dSDimitry Andric       if (D.getArgumentNumber() < ArgTys.size())
162501095a5dSDimitry Andric         return Ty != ArgTys[D.getArgumentNumber()];
162601095a5dSDimitry Andric 
1627e6d15924SDimitry Andric       if (D.getArgumentNumber() > ArgTys.size() ||
1628e6d15924SDimitry Andric           D.getArgumentKind() == IITDescriptor::AK_MatchType)
1629e6d15924SDimitry Andric         return IsDeferredCheck || DeferCheck(Ty);
1630e6d15924SDimitry Andric 
1631e6d15924SDimitry Andric       assert(D.getArgumentNumber() == ArgTys.size() && !IsDeferredCheck &&
1632e6d15924SDimitry Andric              "Table consistency error");
163301095a5dSDimitry Andric       ArgTys.push_back(Ty);
163401095a5dSDimitry Andric 
163501095a5dSDimitry Andric       switch (D.getArgumentKind()) {
163601095a5dSDimitry Andric         case IITDescriptor::AK_Any:        return false; // Success
163701095a5dSDimitry Andric         case IITDescriptor::AK_AnyInteger: return !Ty->isIntOrIntVectorTy();
163801095a5dSDimitry Andric         case IITDescriptor::AK_AnyFloat:   return !Ty->isFPOrFPVectorTy();
163901095a5dSDimitry Andric         case IITDescriptor::AK_AnyVector:  return !isa<VectorType>(Ty);
164001095a5dSDimitry Andric         case IITDescriptor::AK_AnyPointer: return !isa<PointerType>(Ty);
1641e6d15924SDimitry Andric         default:                           break;
164201095a5dSDimitry Andric       }
164301095a5dSDimitry Andric       llvm_unreachable("all argument kinds not covered");
164401095a5dSDimitry Andric 
164501095a5dSDimitry Andric     case IITDescriptor::ExtendArgument: {
1646e6d15924SDimitry Andric       // If this is a forward reference, defer the check for later.
164701095a5dSDimitry Andric       if (D.getArgumentNumber() >= ArgTys.size())
1648e6d15924SDimitry Andric         return IsDeferredCheck || DeferCheck(Ty);
164901095a5dSDimitry Andric 
165001095a5dSDimitry Andric       Type *NewTy = ArgTys[D.getArgumentNumber()];
165101095a5dSDimitry Andric       if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
165201095a5dSDimitry Andric         NewTy = VectorType::getExtendedElementVectorType(VTy);
165301095a5dSDimitry Andric       else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
165401095a5dSDimitry Andric         NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth());
165501095a5dSDimitry Andric       else
165601095a5dSDimitry Andric         return true;
165701095a5dSDimitry Andric 
165801095a5dSDimitry Andric       return Ty != NewTy;
165901095a5dSDimitry Andric     }
166001095a5dSDimitry Andric     case IITDescriptor::TruncArgument: {
1661e6d15924SDimitry Andric       // If this is a forward reference, defer the check for later.
166201095a5dSDimitry Andric       if (D.getArgumentNumber() >= ArgTys.size())
1663e6d15924SDimitry Andric         return IsDeferredCheck || DeferCheck(Ty);
166401095a5dSDimitry Andric 
166501095a5dSDimitry Andric       Type *NewTy = ArgTys[D.getArgumentNumber()];
166601095a5dSDimitry Andric       if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
166701095a5dSDimitry Andric         NewTy = VectorType::getTruncatedElementVectorType(VTy);
166801095a5dSDimitry Andric       else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
166901095a5dSDimitry Andric         NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2);
167001095a5dSDimitry Andric       else
167101095a5dSDimitry Andric         return true;
167201095a5dSDimitry Andric 
167301095a5dSDimitry Andric       return Ty != NewTy;
167401095a5dSDimitry Andric     }
167501095a5dSDimitry Andric     case IITDescriptor::HalfVecArgument:
1676e6d15924SDimitry Andric       // If this is a forward reference, defer the check for later.
16771d5ae102SDimitry Andric       if (D.getArgumentNumber() >= ArgTys.size())
16781d5ae102SDimitry Andric         return IsDeferredCheck || DeferCheck(Ty);
16791d5ae102SDimitry Andric       return !isa<VectorType>(ArgTys[D.getArgumentNumber()]) ||
168001095a5dSDimitry Andric              VectorType::getHalfElementsVectorType(
168101095a5dSDimitry Andric                      cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty;
168201095a5dSDimitry Andric     case IITDescriptor::SameVecWidthArgument: {
1683e6d15924SDimitry Andric       if (D.getArgumentNumber() >= ArgTys.size()) {
1684e6d15924SDimitry Andric         // Defer check and subsequent check for the vector element type.
1685e6d15924SDimitry Andric         Infos = Infos.slice(1);
1686e6d15924SDimitry Andric         return IsDeferredCheck || DeferCheck(Ty);
1687e6d15924SDimitry Andric       }
1688e6d15924SDimitry Andric       auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
1689e6d15924SDimitry Andric       auto *ThisArgType = dyn_cast<VectorType>(Ty);
1690e6d15924SDimitry Andric       // Both must be vectors of the same number of elements or neither.
1691e6d15924SDimitry Andric       if ((ReferenceType != nullptr) != (ThisArgType != nullptr))
169201095a5dSDimitry Andric         return true;
1693e6d15924SDimitry Andric       Type *EltTy = Ty;
1694e6d15924SDimitry Andric       if (ThisArgType) {
16951d5ae102SDimitry Andric         if (ReferenceType->getElementCount() !=
16961d5ae102SDimitry Andric             ThisArgType->getElementCount())
169701095a5dSDimitry Andric           return true;
1698cfca06d7SDimitry Andric         EltTy = ThisArgType->getElementType();
1699e6d15924SDimitry Andric       }
1700e6d15924SDimitry Andric       return matchIntrinsicType(EltTy, Infos, ArgTys, DeferredChecks,
1701e6d15924SDimitry Andric                                 IsDeferredCheck);
170201095a5dSDimitry Andric     }
1703148779dfSDimitry Andric     case IITDescriptor::VecOfAnyPtrsToElt: {
1704148779dfSDimitry Andric       unsigned RefArgNumber = D.getRefArgNumber();
1705e6d15924SDimitry Andric       if (RefArgNumber >= ArgTys.size()) {
1706e6d15924SDimitry Andric         if (IsDeferredCheck)
170701095a5dSDimitry Andric           return true;
1708e6d15924SDimitry Andric         // If forward referencing, already add the pointer-vector type and
1709e6d15924SDimitry Andric         // defer the checks for later.
1710e6d15924SDimitry Andric         ArgTys.push_back(Ty);
1711e6d15924SDimitry Andric         return DeferCheck(Ty);
1712e6d15924SDimitry Andric       }
1713148779dfSDimitry Andric 
1714e6d15924SDimitry Andric       if (!IsDeferredCheck){
1715148779dfSDimitry Andric         assert(D.getOverloadArgNumber() == ArgTys.size() &&
1716148779dfSDimitry Andric                "Table consistency error");
1717148779dfSDimitry Andric         ArgTys.push_back(Ty);
1718e6d15924SDimitry Andric       }
1719148779dfSDimitry Andric 
1720148779dfSDimitry Andric       // Verify the overloaded type "matches" the Ref type.
1721148779dfSDimitry Andric       // i.e. Ty is a vector with the same width as Ref.
1722148779dfSDimitry Andric       // Composed of pointers to the same element type as Ref.
1723b60736ecSDimitry Andric       auto *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]);
1724b60736ecSDimitry Andric       auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
172501095a5dSDimitry Andric       if (!ThisArgVecTy || !ReferenceType ||
1726b60736ecSDimitry Andric           (ReferenceType->getElementCount() != ThisArgVecTy->getElementCount()))
172701095a5dSDimitry Andric         return true;
17287fa27ce4SDimitry Andric       return !ThisArgVecTy->getElementType()->isPointerTy();
172901095a5dSDimitry Andric     }
1730e6d15924SDimitry Andric     case IITDescriptor::VecElementArgument: {
1731e6d15924SDimitry Andric       if (D.getArgumentNumber() >= ArgTys.size())
1732e6d15924SDimitry Andric         return IsDeferredCheck ? true : DeferCheck(Ty);
1733e6d15924SDimitry Andric       auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
1734e6d15924SDimitry Andric       return !ReferenceType || Ty != ReferenceType->getElementType();
1735e6d15924SDimitry Andric     }
17361d5ae102SDimitry Andric     case IITDescriptor::Subdivide2Argument:
17371d5ae102SDimitry Andric     case IITDescriptor::Subdivide4Argument: {
17381d5ae102SDimitry Andric       // If this is a forward reference, defer the check for later.
17391d5ae102SDimitry Andric       if (D.getArgumentNumber() >= ArgTys.size())
17401d5ae102SDimitry Andric         return IsDeferredCheck || DeferCheck(Ty);
17411d5ae102SDimitry Andric 
17421d5ae102SDimitry Andric       Type *NewTy = ArgTys[D.getArgumentNumber()];
17431d5ae102SDimitry Andric       if (auto *VTy = dyn_cast<VectorType>(NewTy)) {
17441d5ae102SDimitry Andric         int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
17451d5ae102SDimitry Andric         NewTy = VectorType::getSubdividedVectorType(VTy, SubDivs);
17461d5ae102SDimitry Andric         return Ty != NewTy;
17471d5ae102SDimitry Andric       }
17481d5ae102SDimitry Andric       return true;
17491d5ae102SDimitry Andric     }
17501d5ae102SDimitry Andric     case IITDescriptor::VecOfBitcastsToInt: {
17511d5ae102SDimitry Andric       if (D.getArgumentNumber() >= ArgTys.size())
17521d5ae102SDimitry Andric         return IsDeferredCheck || DeferCheck(Ty);
17531d5ae102SDimitry Andric       auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
17541d5ae102SDimitry Andric       auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
17551d5ae102SDimitry Andric       if (!ThisArgVecTy || !ReferenceType)
17561d5ae102SDimitry Andric         return true;
17571d5ae102SDimitry Andric       return ThisArgVecTy != VectorType::getInteger(ReferenceType);
17581d5ae102SDimitry Andric     }
175901095a5dSDimitry Andric   }
176001095a5dSDimitry Andric   llvm_unreachable("unhandled");
176101095a5dSDimitry Andric }
176201095a5dSDimitry Andric 
1763e6d15924SDimitry Andric Intrinsic::MatchIntrinsicTypesResult
matchIntrinsicSignature(FunctionType * FTy,ArrayRef<Intrinsic::IITDescriptor> & Infos,SmallVectorImpl<Type * > & ArgTys)1764e6d15924SDimitry Andric Intrinsic::matchIntrinsicSignature(FunctionType *FTy,
1765e6d15924SDimitry Andric                                    ArrayRef<Intrinsic::IITDescriptor> &Infos,
1766e6d15924SDimitry Andric                                    SmallVectorImpl<Type *> &ArgTys) {
1767e6d15924SDimitry Andric   SmallVector<DeferredIntrinsicMatchPair, 2> DeferredChecks;
1768e6d15924SDimitry Andric   if (matchIntrinsicType(FTy->getReturnType(), Infos, ArgTys, DeferredChecks,
1769e6d15924SDimitry Andric                          false))
1770e6d15924SDimitry Andric     return MatchIntrinsicTypes_NoMatchRet;
1771e6d15924SDimitry Andric 
1772e6d15924SDimitry Andric   unsigned NumDeferredReturnChecks = DeferredChecks.size();
1773e6d15924SDimitry Andric 
1774e3b55780SDimitry Andric   for (auto *Ty : FTy->params())
1775e6d15924SDimitry Andric     if (matchIntrinsicType(Ty, Infos, ArgTys, DeferredChecks, false))
1776e6d15924SDimitry Andric       return MatchIntrinsicTypes_NoMatchArg;
1777e6d15924SDimitry Andric 
1778e6d15924SDimitry Andric   for (unsigned I = 0, E = DeferredChecks.size(); I != E; ++I) {
1779e6d15924SDimitry Andric     DeferredIntrinsicMatchPair &Check = DeferredChecks[I];
1780e6d15924SDimitry Andric     if (matchIntrinsicType(Check.first, Check.second, ArgTys, DeferredChecks,
1781e6d15924SDimitry Andric                            true))
1782e6d15924SDimitry Andric       return I < NumDeferredReturnChecks ? MatchIntrinsicTypes_NoMatchRet
1783e6d15924SDimitry Andric                                          : MatchIntrinsicTypes_NoMatchArg;
1784e6d15924SDimitry Andric   }
1785e6d15924SDimitry Andric 
1786e6d15924SDimitry Andric   return MatchIntrinsicTypes_Match;
1787e6d15924SDimitry Andric }
1788e6d15924SDimitry Andric 
178901095a5dSDimitry Andric bool
matchIntrinsicVarArg(bool isVarArg,ArrayRef<Intrinsic::IITDescriptor> & Infos)179001095a5dSDimitry Andric Intrinsic::matchIntrinsicVarArg(bool isVarArg,
179101095a5dSDimitry Andric                                 ArrayRef<Intrinsic::IITDescriptor> &Infos) {
179201095a5dSDimitry Andric   // If there are no descriptors left, then it can't be a vararg.
179301095a5dSDimitry Andric   if (Infos.empty())
179401095a5dSDimitry Andric     return isVarArg;
179501095a5dSDimitry Andric 
179601095a5dSDimitry Andric   // There should be only one descriptor remaining at this point.
179701095a5dSDimitry Andric   if (Infos.size() != 1)
179801095a5dSDimitry Andric     return true;
179901095a5dSDimitry Andric 
180001095a5dSDimitry Andric   // Check and verify the descriptor.
180101095a5dSDimitry Andric   IITDescriptor D = Infos.front();
180201095a5dSDimitry Andric   Infos = Infos.slice(1);
180301095a5dSDimitry Andric   if (D.Kind == IITDescriptor::VarArg)
180401095a5dSDimitry Andric     return !isVarArg;
180501095a5dSDimitry Andric 
180601095a5dSDimitry Andric   return true;
180701095a5dSDimitry Andric }
180801095a5dSDimitry Andric 
getIntrinsicSignature(Intrinsic::ID ID,FunctionType * FT,SmallVectorImpl<Type * > & ArgTys)1809ac9a064cSDimitry Andric bool Intrinsic::getIntrinsicSignature(Intrinsic::ID ID, FunctionType *FT,
1810cfca06d7SDimitry Andric                                       SmallVectorImpl<Type *> &ArgTys) {
181101095a5dSDimitry Andric   if (!ID)
1812cfca06d7SDimitry Andric     return false;
181301095a5dSDimitry Andric 
181401095a5dSDimitry Andric   SmallVector<Intrinsic::IITDescriptor, 8> Table;
181501095a5dSDimitry Andric   getIntrinsicInfoTableEntries(ID, Table);
181601095a5dSDimitry Andric   ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;
181701095a5dSDimitry Andric 
1818ac9a064cSDimitry Andric   if (Intrinsic::matchIntrinsicSignature(FT, TableRef, ArgTys) !=
1819cfca06d7SDimitry Andric       Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) {
1820cfca06d7SDimitry Andric     return false;
1821cfca06d7SDimitry Andric   }
1822ac9a064cSDimitry Andric   if (Intrinsic::matchIntrinsicVarArg(FT->isVarArg(), TableRef))
1823cfca06d7SDimitry Andric     return false;
1824cfca06d7SDimitry Andric   return true;
182501095a5dSDimitry Andric }
182601095a5dSDimitry Andric 
getIntrinsicSignature(Function * F,SmallVectorImpl<Type * > & ArgTys)1827ac9a064cSDimitry Andric bool Intrinsic::getIntrinsicSignature(Function *F,
1828ac9a064cSDimitry Andric                                       SmallVectorImpl<Type *> &ArgTys) {
1829ac9a064cSDimitry Andric   return getIntrinsicSignature(F->getIntrinsicID(), F->getFunctionType(),
1830ac9a064cSDimitry Andric                                ArgTys);
1831ac9a064cSDimitry Andric }
1832ac9a064cSDimitry Andric 
remangleIntrinsicFunction(Function * F)1833e3b55780SDimitry Andric std::optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) {
1834cfca06d7SDimitry Andric   SmallVector<Type *, 4> ArgTys;
1835cfca06d7SDimitry Andric   if (!getIntrinsicSignature(F, ArgTys))
1836e3b55780SDimitry Andric     return std::nullopt;
1837cfca06d7SDimitry Andric 
1838cfca06d7SDimitry Andric   Intrinsic::ID ID = F->getIntrinsicID();
183901095a5dSDimitry Andric   StringRef Name = F->getName();
1840344a3780SDimitry Andric   std::string WantedName =
1841344a3780SDimitry Andric       Intrinsic::getName(ID, ArgTys, F->getParent(), F->getFunctionType());
1842344a3780SDimitry Andric   if (Name == WantedName)
1843e3b55780SDimitry Andric     return std::nullopt;
184401095a5dSDimitry Andric 
1845344a3780SDimitry Andric   Function *NewDecl = [&] {
1846344a3780SDimitry Andric     if (auto *ExistingGV = F->getParent()->getNamedValue(WantedName)) {
1847344a3780SDimitry Andric       if (auto *ExistingF = dyn_cast<Function>(ExistingGV))
1848344a3780SDimitry Andric         if (ExistingF->getFunctionType() == F->getFunctionType())
1849344a3780SDimitry Andric           return ExistingF;
1850344a3780SDimitry Andric 
1851344a3780SDimitry Andric       // The name already exists, but is not a function or has the wrong
1852344a3780SDimitry Andric       // prototype. Make place for the new one by renaming the old version.
1853344a3780SDimitry Andric       // Either this old version will be removed later on or the module is
1854344a3780SDimitry Andric       // invalid and we'll get an error.
1855344a3780SDimitry Andric       ExistingGV->setName(WantedName + ".renamed");
1856344a3780SDimitry Andric     }
1857344a3780SDimitry Andric     return Intrinsic::getDeclaration(F->getParent(), ID, ArgTys);
1858344a3780SDimitry Andric   }();
1859344a3780SDimitry Andric 
186001095a5dSDimitry Andric   NewDecl->setCallingConv(F->getCallingConv());
1861cfca06d7SDimitry Andric   assert(NewDecl->getFunctionType() == F->getFunctionType() &&
1862cfca06d7SDimitry Andric          "Shouldn't change the signature");
186301095a5dSDimitry Andric   return NewDecl;
186401095a5dSDimitry Andric }
186501095a5dSDimitry Andric 
1866600c6fa1SEd Schouten /// hasAddressTaken - returns true if there are any uses of this function
1867cfca06d7SDimitry Andric /// other than direct calls or invokes to it. Optionally ignores callback
1868344a3780SDimitry Andric /// uses, assume like pointer annotation calls, and references in llvm.used
1869344a3780SDimitry Andric /// and llvm.compiler.used variables.
hasAddressTaken(const User ** PutOffender,bool IgnoreCallbackUses,bool IgnoreAssumeLikeCalls,bool IgnoreLLVMUsed,bool IgnoreARCAttachedCall,bool IgnoreCastedDirectCall) const1870cfca06d7SDimitry Andric bool Function::hasAddressTaken(const User **PutOffender,
1871344a3780SDimitry Andric                                bool IgnoreCallbackUses,
1872c0981da4SDimitry Andric                                bool IgnoreAssumeLikeCalls, bool IgnoreLLVMUsed,
1873b1c73532SDimitry Andric                                bool IgnoreARCAttachedCall,
1874b1c73532SDimitry Andric                                bool IgnoreCastedDirectCall) const {
18755ca98fd9SDimitry Andric   for (const Use &U : uses()) {
18765ca98fd9SDimitry Andric     const User *FU = U.getUser();
18775ca98fd9SDimitry Andric     if (isa<BlockAddress>(FU))
187858b69754SDimitry Andric       continue;
1879cfca06d7SDimitry Andric 
1880cfca06d7SDimitry Andric     if (IgnoreCallbackUses) {
1881cfca06d7SDimitry Andric       AbstractCallSite ACS(&U);
1882cfca06d7SDimitry Andric       if (ACS && ACS.isCallbackCall())
1883cfca06d7SDimitry Andric         continue;
1884cfca06d7SDimitry Andric     }
1885cfca06d7SDimitry Andric 
1886d8e91e46SDimitry Andric     const auto *Call = dyn_cast<CallBase>(FU);
1887d8e91e46SDimitry Andric     if (!Call) {
1888e3b55780SDimitry Andric       if (IgnoreAssumeLikeCalls &&
1889e3b55780SDimitry Andric           isa<BitCastOperator, AddrSpaceCastOperator>(FU) &&
1890e3b55780SDimitry Andric           all_of(FU->users(), [](const User *U) {
1891344a3780SDimitry Andric             if (const auto *I = dyn_cast<IntrinsicInst>(U))
1892344a3780SDimitry Andric               return I->isAssumeLikeIntrinsic();
1893344a3780SDimitry Andric             return false;
1894e3b55780SDimitry Andric           })) {
1895344a3780SDimitry Andric         continue;
1896344a3780SDimitry Andric       }
1897e3b55780SDimitry Andric 
1898344a3780SDimitry Andric       if (IgnoreLLVMUsed && !FU->user_empty()) {
1899344a3780SDimitry Andric         const User *FUU = FU;
1900e3b55780SDimitry Andric         if (isa<BitCastOperator, AddrSpaceCastOperator>(FU) &&
1901e3b55780SDimitry Andric             FU->hasOneUse() && !FU->user_begin()->user_empty())
1902344a3780SDimitry Andric           FUU = *FU->user_begin();
1903344a3780SDimitry Andric         if (llvm::all_of(FUU->users(), [](const User *U) {
1904344a3780SDimitry Andric               if (const auto *GV = dyn_cast<GlobalVariable>(U))
1905344a3780SDimitry Andric                 return GV->hasName() &&
1906ac9a064cSDimitry Andric                        (GV->getName() == "llvm.compiler.used" ||
1907ac9a064cSDimitry Andric                         GV->getName() == "llvm.used");
1908344a3780SDimitry Andric               return false;
1909344a3780SDimitry Andric             }))
1910344a3780SDimitry Andric           continue;
1911344a3780SDimitry Andric       }
191201095a5dSDimitry Andric       if (PutOffender)
191301095a5dSDimitry Andric         *PutOffender = FU;
191401095a5dSDimitry Andric       return true;
191501095a5dSDimitry Andric     }
1916e3b55780SDimitry Andric 
1917e3b55780SDimitry Andric     if (IgnoreAssumeLikeCalls) {
1918e3b55780SDimitry Andric       if (const auto *I = dyn_cast<IntrinsicInst>(Call))
1919e3b55780SDimitry Andric         if (I->isAssumeLikeIntrinsic())
1920e3b55780SDimitry Andric           continue;
1921e3b55780SDimitry Andric     }
1922e3b55780SDimitry Andric 
1923b1c73532SDimitry Andric     if (!Call->isCallee(&U) || (!IgnoreCastedDirectCall &&
1924b1c73532SDimitry Andric                                 Call->getFunctionType() != getFunctionType())) {
1925c0981da4SDimitry Andric       if (IgnoreARCAttachedCall &&
1926c0981da4SDimitry Andric           Call->isOperandBundleOfType(LLVMContext::OB_clang_arc_attachedcall,
1927c0981da4SDimitry Andric                                       U.getOperandNo()))
1928c0981da4SDimitry Andric         continue;
1929c0981da4SDimitry Andric 
193001095a5dSDimitry Andric       if (PutOffender)
193101095a5dSDimitry Andric         *PutOffender = FU;
193201095a5dSDimitry Andric       return true;
193301095a5dSDimitry Andric     }
1934600c6fa1SEd Schouten   }
1935600c6fa1SEd Schouten   return false;
1936600c6fa1SEd Schouten }
1937600c6fa1SEd Schouten 
isDefTriviallyDead() const193863faed5bSDimitry Andric bool Function::isDefTriviallyDead() const {
193963faed5bSDimitry Andric   // Check the linkage
194063faed5bSDimitry Andric   if (!hasLinkOnceLinkage() && !hasLocalLinkage() &&
194163faed5bSDimitry Andric       !hasAvailableExternallyLinkage())
194263faed5bSDimitry Andric     return false;
194363faed5bSDimitry Andric 
194463faed5bSDimitry Andric   // Check if the function is used by anything other than a blockaddress.
19455ca98fd9SDimitry Andric   for (const User *U : users())
19465ca98fd9SDimitry Andric     if (!isa<BlockAddress>(U))
194763faed5bSDimitry Andric       return false;
194863faed5bSDimitry Andric 
194963faed5bSDimitry Andric   return true;
195063faed5bSDimitry Andric }
195163faed5bSDimitry Andric 
195256fe8f14SDimitry Andric /// callsFunctionThatReturnsTwice - Return true if the function has a call to
195356fe8f14SDimitry Andric /// setjmp or other function that gcc recognizes as "returning twice".
callsFunctionThatReturnsTwice() const195456fe8f14SDimitry Andric bool Function::callsFunctionThatReturnsTwice() const {
1955d8e91e46SDimitry Andric   for (const Instruction &I : instructions(this))
1956d8e91e46SDimitry Andric     if (const auto *Call = dyn_cast<CallBase>(&I))
1957d8e91e46SDimitry Andric       if (Call->hasFnAttr(Attribute::ReturnsTwice))
195856fe8f14SDimitry Andric         return true;
195956fe8f14SDimitry Andric 
196056fe8f14SDimitry Andric   return false;
196156fe8f14SDimitry Andric }
196256fe8f14SDimitry Andric 
getPersonalityFn() const1963dd58ef01SDimitry Andric Constant *Function::getPersonalityFn() const {
1964dd58ef01SDimitry Andric   assert(hasPersonalityFn() && getNumOperands());
1965dd58ef01SDimitry Andric   return cast<Constant>(Op<0>());
1966dd58ef01SDimitry Andric }
1967dd58ef01SDimitry Andric 
setPersonalityFn(Constant * Fn)1968dd58ef01SDimitry Andric void Function::setPersonalityFn(Constant *Fn) {
1969dd58ef01SDimitry Andric   setHungoffOperand<0>(Fn);
1970dd58ef01SDimitry Andric   setValueSubclassDataBit(3, Fn != nullptr);
1971dd58ef01SDimitry Andric }
1972dd58ef01SDimitry Andric 
getPrefixData() const1973f8af5cf6SDimitry Andric Constant *Function::getPrefixData() const {
1974dd58ef01SDimitry Andric   assert(hasPrefixData() && getNumOperands());
1975dd58ef01SDimitry Andric   return cast<Constant>(Op<1>());
1976f8af5cf6SDimitry Andric }
1977f8af5cf6SDimitry Andric 
setPrefixData(Constant * PrefixData)1978f8af5cf6SDimitry Andric void Function::setPrefixData(Constant *PrefixData) {
1979dd58ef01SDimitry Andric   setHungoffOperand<1>(PrefixData);
1980dd58ef01SDimitry Andric   setValueSubclassDataBit(1, PrefixData != nullptr);
1981f8af5cf6SDimitry Andric }
198267c32a98SDimitry Andric 
getPrologueData() const198367c32a98SDimitry Andric Constant *Function::getPrologueData() const {
1984dd58ef01SDimitry Andric   assert(hasPrologueData() && getNumOperands());
1985dd58ef01SDimitry Andric   return cast<Constant>(Op<2>());
198667c32a98SDimitry Andric }
198767c32a98SDimitry Andric 
setPrologueData(Constant * PrologueData)198867c32a98SDimitry Andric void Function::setPrologueData(Constant *PrologueData) {
1989dd58ef01SDimitry Andric   setHungoffOperand<2>(PrologueData);
1990dd58ef01SDimitry Andric   setValueSubclassDataBit(2, PrologueData != nullptr);
1991dd58ef01SDimitry Andric }
1992dd58ef01SDimitry Andric 
allocHungoffUselist()1993dd58ef01SDimitry Andric void Function::allocHungoffUselist() {
1994dd58ef01SDimitry Andric   // If we've already allocated a uselist, stop here.
1995dd58ef01SDimitry Andric   if (getNumOperands())
199667c32a98SDimitry Andric     return;
199767c32a98SDimitry Andric 
1998dd58ef01SDimitry Andric   allocHungoffUses(3, /*IsPhi=*/ false);
1999dd58ef01SDimitry Andric   setNumHungOffUseOperands(3);
2000dd58ef01SDimitry Andric 
2001dd58ef01SDimitry Andric   // Initialize the uselist with placeholder operands to allow traversal.
2002b1c73532SDimitry Andric   auto *CPN = ConstantPointerNull::get(PointerType::get(getContext(), 0));
2003dd58ef01SDimitry Andric   Op<0>().set(CPN);
2004dd58ef01SDimitry Andric   Op<1>().set(CPN);
2005dd58ef01SDimitry Andric   Op<2>().set(CPN);
200667c32a98SDimitry Andric }
2007dd58ef01SDimitry Andric 
2008dd58ef01SDimitry Andric template <int Idx>
setHungoffOperand(Constant * C)2009dd58ef01SDimitry Andric void Function::setHungoffOperand(Constant *C) {
2010dd58ef01SDimitry Andric   if (C) {
2011dd58ef01SDimitry Andric     allocHungoffUselist();
2012dd58ef01SDimitry Andric     Op<Idx>().set(C);
2013dd58ef01SDimitry Andric   } else if (getNumOperands()) {
2014b1c73532SDimitry Andric     Op<Idx>().set(ConstantPointerNull::get(PointerType::get(getContext(), 0)));
2015dd58ef01SDimitry Andric   }
2016dd58ef01SDimitry Andric }
2017dd58ef01SDimitry Andric 
setValueSubclassDataBit(unsigned Bit,bool On)2018dd58ef01SDimitry Andric void Function::setValueSubclassDataBit(unsigned Bit, bool On) {
2019dd58ef01SDimitry Andric   assert(Bit < 16 && "SubclassData contains only 16 bits");
2020dd58ef01SDimitry Andric   if (On)
2021dd58ef01SDimitry Andric     setValueSubclassData(getSubclassDataFromValue() | (1 << Bit));
2022dd58ef01SDimitry Andric   else
2023dd58ef01SDimitry Andric     setValueSubclassData(getSubclassDataFromValue() & ~(1 << Bit));
202467c32a98SDimitry Andric }
20255a5ac124SDimitry Andric 
setEntryCount(ProfileCount Count,const DenseSet<GlobalValue::GUID> * S)2026eb11fae6SDimitry Andric void Function::setEntryCount(ProfileCount Count,
202771d5a254SDimitry Andric                              const DenseSet<GlobalValue::GUID> *S) {
2028eb11fae6SDimitry Andric #if !defined(NDEBUG)
2029eb11fae6SDimitry Andric   auto PrevCount = getEntryCount();
2030145449b1SDimitry Andric   assert(!PrevCount || PrevCount->getType() == Count.getType());
2031eb11fae6SDimitry Andric #endif
2032706b4fc4SDimitry Andric 
2033706b4fc4SDimitry Andric   auto ImportGUIDs = getImportGUIDs();
2034706b4fc4SDimitry Andric   if (S == nullptr && ImportGUIDs.size())
2035706b4fc4SDimitry Andric     S = &ImportGUIDs;
2036706b4fc4SDimitry Andric 
20375a5ac124SDimitry Andric   MDBuilder MDB(getContext());
2038eb11fae6SDimitry Andric   setMetadata(
2039eb11fae6SDimitry Andric       LLVMContext::MD_prof,
2040eb11fae6SDimitry Andric       MDB.createFunctionEntryCount(Count.getCount(), Count.isSynthetic(), S));
20415a5ac124SDimitry Andric }
20425a5ac124SDimitry Andric 
setEntryCount(uint64_t Count,Function::ProfileCountType Type,const DenseSet<GlobalValue::GUID> * Imports)2043eb11fae6SDimitry Andric void Function::setEntryCount(uint64_t Count, Function::ProfileCountType Type,
2044eb11fae6SDimitry Andric                              const DenseSet<GlobalValue::GUID> *Imports) {
2045eb11fae6SDimitry Andric   setEntryCount(ProfileCount(Count, Type), Imports);
2046eb11fae6SDimitry Andric }
2047eb11fae6SDimitry Andric 
getEntryCount(bool AllowSynthetic) const2048e3b55780SDimitry Andric std::optional<ProfileCount> Function::getEntryCount(bool AllowSynthetic) const {
20495a5ac124SDimitry Andric   MDNode *MD = getMetadata(LLVMContext::MD_prof);
20505a5ac124SDimitry Andric   if (MD && MD->getOperand(0))
2051eb11fae6SDimitry Andric     if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) {
2052ac9a064cSDimitry Andric       if (MDS->getString() == "function_entry_count") {
20535a5ac124SDimitry Andric         ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));
2054b915e9e0SDimitry Andric         uint64_t Count = CI->getValue().getZExtValue();
2055c7dac04cSDimitry Andric         // A value of -1 is used for SamplePGO when there were no samples.
2056c7dac04cSDimitry Andric         // Treat this the same as unknown.
2057c7dac04cSDimitry Andric         if (Count == (uint64_t)-1)
2058e3b55780SDimitry Andric           return std::nullopt;
2059eb11fae6SDimitry Andric         return ProfileCount(Count, PCT_Real);
2060e6d15924SDimitry Andric       } else if (AllowSynthetic &&
2061ac9a064cSDimitry Andric                  MDS->getString() == "synthetic_function_entry_count") {
2062eb11fae6SDimitry Andric         ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1));
2063eb11fae6SDimitry Andric         uint64_t Count = CI->getValue().getZExtValue();
2064eb11fae6SDimitry Andric         return ProfileCount(Count, PCT_Synthetic);
2065b915e9e0SDimitry Andric       }
2066eb11fae6SDimitry Andric     }
2067e3b55780SDimitry Andric   return std::nullopt;
2068b915e9e0SDimitry Andric }
2069b915e9e0SDimitry Andric 
getImportGUIDs() const207071d5a254SDimitry Andric DenseSet<GlobalValue::GUID> Function::getImportGUIDs() const {
207171d5a254SDimitry Andric   DenseSet<GlobalValue::GUID> R;
207271d5a254SDimitry Andric   if (MDNode *MD = getMetadata(LLVMContext::MD_prof))
207371d5a254SDimitry Andric     if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0)))
2074ac9a064cSDimitry Andric       if (MDS->getString() == "function_entry_count")
207571d5a254SDimitry Andric         for (unsigned i = 2; i < MD->getNumOperands(); i++)
207671d5a254SDimitry Andric           R.insert(mdconst::extract<ConstantInt>(MD->getOperand(i))
207771d5a254SDimitry Andric                        ->getValue()
207871d5a254SDimitry Andric                        .getZExtValue());
207971d5a254SDimitry Andric   return R;
208071d5a254SDimitry Andric }
208171d5a254SDimitry Andric 
setSectionPrefix(StringRef Prefix)2082b915e9e0SDimitry Andric void Function::setSectionPrefix(StringRef Prefix) {
2083b915e9e0SDimitry Andric   MDBuilder MDB(getContext());
2084b915e9e0SDimitry Andric   setMetadata(LLVMContext::MD_section_prefix,
2085b915e9e0SDimitry Andric               MDB.createFunctionSectionPrefix(Prefix));
2086b915e9e0SDimitry Andric }
2087b915e9e0SDimitry Andric 
getSectionPrefix() const2088e3b55780SDimitry Andric std::optional<StringRef> Function::getSectionPrefix() const {
2089b915e9e0SDimitry Andric   if (MDNode *MD = getMetadata(LLVMContext::MD_section_prefix)) {
2090ac9a064cSDimitry Andric     assert(cast<MDString>(MD->getOperand(0))->getString() ==
2091ac9a064cSDimitry Andric                "function_section_prefix" &&
2092b915e9e0SDimitry Andric            "Metadata not match");
2093eb11fae6SDimitry Andric     return cast<MDString>(MD->getOperand(1))->getString();
20945a5ac124SDimitry Andric   }
2095e3b55780SDimitry Andric   return std::nullopt;
20965a5ac124SDimitry Andric }
2097eb11fae6SDimitry Andric 
nullPointerIsDefined() const2098eb11fae6SDimitry Andric bool Function::nullPointerIsDefined() const {
2099cfca06d7SDimitry Andric   return hasFnAttribute(Attribute::NullPointerIsValid);
2100eb11fae6SDimitry Andric }
2101eb11fae6SDimitry Andric 
NullPointerIsDefined(const Function * F,unsigned AS)2102eb11fae6SDimitry Andric bool llvm::NullPointerIsDefined(const Function *F, unsigned AS) {
2103eb11fae6SDimitry Andric   if (F && F->nullPointerIsDefined())
2104eb11fae6SDimitry Andric     return true;
2105eb11fae6SDimitry Andric 
2106eb11fae6SDimitry Andric   if (AS != 0)
2107eb11fae6SDimitry Andric     return true;
2108eb11fae6SDimitry Andric 
2109eb11fae6SDimitry Andric   return false;
2110eb11fae6SDimitry Andric }
2111