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