aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/IR/Function.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR/Function.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Function.cpp128
1 files changed, 110 insertions, 18 deletions
diff --git a/contrib/llvm-project/llvm/lib/IR/Function.cpp b/contrib/llvm-project/llvm/lib/IR/Function.cpp
index 10d535e3ab11..17247123f87f 100644
--- a/contrib/llvm-project/llvm/lib/IR/Function.cpp
+++ b/contrib/llvm-project/llvm/lib/IR/Function.cpp
@@ -43,6 +43,7 @@
#include "llvm/IR/IntrinsicsR600.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/IntrinsicsS390.h"
+#include "llvm/IR/IntrinsicsVE.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/IntrinsicsXCore.h"
@@ -86,9 +87,11 @@ void Argument::setParent(Function *parent) {
Parent = parent;
}
-bool Argument::hasNonNullAttr() const {
+bool Argument::hasNonNullAttr(bool AllowUndefOrPoison) const {
if (!getType()->isPointerTy()) return false;
- if (getParent()->hasParamAttribute(getArgNo(), Attribute::NonNull))
+ if (getParent()->hasParamAttribute(getArgNo(), Attribute::NonNull) &&
+ (AllowUndefOrPoison ||
+ getParent()->hasParamAttribute(getArgNo(), Attribute::NoUndef)))
return true;
else if (getDereferenceableBytes() > 0 &&
!NullPointerIsDefined(getParent(),
@@ -102,6 +105,12 @@ bool Argument::hasByValAttr() const {
return hasAttribute(Attribute::ByVal);
}
+bool Argument::hasByRefAttr() const {
+ if (!getType()->isPointerTy())
+ return false;
+ return hasAttribute(Attribute::ByRef);
+}
+
bool Argument::hasSwiftSelfAttr() const {
return getParent()->hasParamAttribute(getArgNo(), Attribute::SwiftSelf);
}
@@ -121,7 +130,7 @@ bool Argument::hasPreallocatedAttr() const {
return hasAttribute(Attribute::Preallocated);
}
-bool Argument::hasPassPointeeByValueAttr() const {
+bool Argument::hasPassPointeeByValueCopyAttr() const {
if (!getType()->isPointerTy()) return false;
AttributeList Attrs = getParent()->getAttributes();
return Attrs.hasParamAttribute(getArgNo(), Attribute::ByVal) ||
@@ -129,27 +138,54 @@ bool Argument::hasPassPointeeByValueAttr() const {
Attrs.hasParamAttribute(getArgNo(), Attribute::Preallocated);
}
-uint64_t Argument::getPassPointeeByValueCopySize(const DataLayout &DL) const {
- AttributeSet ParamAttrs
- = getParent()->getAttributes().getParamAttributes(getArgNo());
+bool Argument::hasPointeeInMemoryValueAttr() const {
+ if (!getType()->isPointerTy())
+ return false;
+ AttributeList Attrs = getParent()->getAttributes();
+ return Attrs.hasParamAttribute(getArgNo(), Attribute::ByVal) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::StructRet) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::InAlloca) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::Preallocated) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::ByRef);
+}
+/// For a byval, sret, inalloca, or preallocated parameter, get the in-memory
+/// parameter type.
+static Type *getMemoryParamAllocType(AttributeSet ParamAttrs, Type *ArgTy) {
// FIXME: All the type carrying attributes are mutually exclusive, so there
// should be a single query to get the stored type that handles any of them.
if (Type *ByValTy = ParamAttrs.getByValType())
- return DL.getTypeAllocSize(ByValTy);
+ return ByValTy;
+ if (Type *ByRefTy = ParamAttrs.getByRefType())
+ return ByRefTy;
if (Type *PreAllocTy = ParamAttrs.getPreallocatedType())
- return DL.getTypeAllocSize(PreAllocTy);
+ return PreAllocTy;
- // FIXME: inalloca always depends on pointee element type. It's also possible
- // for byval to miss it.
+ // FIXME: sret and inalloca always depends on pointee element type. It's also
+ // possible for byval to miss it.
if (ParamAttrs.hasAttribute(Attribute::InAlloca) ||
ParamAttrs.hasAttribute(Attribute::ByVal) ||
+ ParamAttrs.hasAttribute(Attribute::StructRet) ||
ParamAttrs.hasAttribute(Attribute::Preallocated))
- return DL.getTypeAllocSize(cast<PointerType>(getType())->getElementType());
+ return cast<PointerType>(ArgTy)->getElementType();
+ return nullptr;
+}
+
+uint64_t Argument::getPassPointeeByValueCopySize(const DataLayout &DL) const {
+ AttributeSet ParamAttrs =
+ getParent()->getAttributes().getParamAttributes(getArgNo());
+ if (Type *MemTy = getMemoryParamAllocType(ParamAttrs, getType()))
+ return DL.getTypeAllocSize(MemTy);
return 0;
}
+Type *Argument::getPointeeInMemoryValueType() const {
+ AttributeSet ParamAttrs =
+ getParent()->getAttributes().getParamAttributes(getArgNo());
+ return getMemoryParamAllocType(ParamAttrs, getType());
+}
+
unsigned Argument::getParamAlignment() const {
assert(getType()->isPointerTy() && "Only pointers have alignments");
return getParent()->getParamAlignment(getArgNo());
@@ -165,6 +201,16 @@ Type *Argument::getParamByValType() const {
return getParent()->getParamByValType(getArgNo());
}
+Type *Argument::getParamStructRetType() const {
+ assert(getType()->isPointerTy() && "Only pointers have sret types");
+ return getParent()->getParamStructRetType(getArgNo());
+}
+
+Type *Argument::getParamByRefType() const {
+ assert(getType()->isPointerTy() && "Only pointers have byval types");
+ return getParent()->getParamByRefType(getArgNo());
+}
+
uint64_t Argument::getDereferenceableBytes() const {
assert(getType()->isPointerTy() &&
"Only pointers have dereferenceable bytes");
@@ -534,6 +580,21 @@ void Function::addDereferenceableOrNullParamAttr(unsigned ArgNo,
setAttributes(PAL);
}
+DenormalMode Function::getDenormalMode(const fltSemantics &FPType) const {
+ if (&FPType == &APFloat::IEEEsingle()) {
+ Attribute Attr = getFnAttribute("denormal-fp-math-f32");
+ StringRef Val = Attr.getValueAsString();
+ if (!Val.empty())
+ return parseDenormalFPAttribute(Val);
+
+ // If the f32 variant of the attribute isn't specified, try to use the
+ // generic one.
+ }
+
+ Attribute Attr = getFnAttribute("denormal-fp-math");
+ return parseDenormalFPAttribute(Attr.getValueAsString());
+}
+
const std::string &Function::getGC() const {
assert(hasGC() && "Function has no collector");
return getContext().getGC(*this);
@@ -551,6 +612,12 @@ void Function::clearGC() {
setValueSubclassDataBit(14, false);
}
+bool Function::hasStackProtectorFnAttr() const {
+ return hasFnAttribute(Attribute::StackProtect) ||
+ hasFnAttribute(Attribute::StackProtectStrong) ||
+ hasFnAttribute(Attribute::StackProtectReq);
+}
+
/// Copy all additional attributes (those not needed to create a Function) from
/// the Function Src to this one.
void Function::copyAttributesFrom(const Function *Src) {
@@ -582,6 +649,14 @@ static const char * const IntrinsicNameTable[] = {
#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_TARGET_DATA
+bool Function::isTargetIntrinsic(Intrinsic::ID IID) {
+ return IID > TargetInfos[0].Count;
+}
+
+bool Function::isTargetIntrinsic() const {
+ return isTargetIntrinsic(IntID);
+}
+
/// Find the segment of \c IntrinsicNameTable for intrinsics with the same
/// target as \c Name, or the generic table if \c Name is not target specific.
///
@@ -674,9 +749,10 @@ static std::string getMangledTypeStr(Type* Ty) {
Result += "f";
} else if (VectorType* VTy = dyn_cast<VectorType>(Ty)) {
ElementCount EC = VTy->getElementCount();
- if (EC.Scalable)
+ if (EC.isScalable())
Result += "nx";
- Result += "v" + utostr(EC.Min) + getMangledTypeStr(VTy->getElementType());
+ Result += "v" + utostr(EC.getKnownMinValue()) +
+ getMangledTypeStr(VTy->getElementType());
} else if (Ty) {
switch (Ty->getTypeID()) {
default: llvm_unreachable("Unhandled type");
@@ -690,6 +766,7 @@ static std::string getMangledTypeStr(Type* Ty) {
case Type::FP128TyID: Result += "f128"; break;
case Type::PPC_FP128TyID: Result += "ppcf128"; break;
case Type::X86_MMXTyID: Result += "x86mmx"; break;
+ case Type::X86_AMXTyID: Result += "x86amx"; break;
case Type::IntegerTyID:
Result += "i" + utostr(cast<IntegerType>(Ty)->getBitWidth());
break;
@@ -707,6 +784,8 @@ StringRef Intrinsic::getName(ID id) {
std::string Intrinsic::getName(ID id, ArrayRef<Type*> Tys) {
assert(id < num_intrinsics && "Invalid intrinsic ID!");
+ assert((Tys.empty() || Intrinsic::isOverloaded(id)) &&
+ "This version of getName is for overloaded intrinsics only");
std::string Result(IntrinsicNameTable[id]);
for (Type *Ty : Tys) {
Result += "." + getMangledTypeStr(Ty);
@@ -770,7 +849,10 @@ enum IIT_Info {
IIT_SUBDIVIDE4_ARG = 45,
IIT_VEC_OF_BITCASTS_TO_INT = 46,
IIT_V128 = 47,
- IIT_BF16 = 48
+ IIT_BF16 = 48,
+ IIT_STRUCT9 = 49,
+ IIT_V256 = 50,
+ IIT_AMX = 51
};
static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
@@ -793,6 +875,9 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
case IIT_MMX:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0));
return;
+ case IIT_AMX:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::AMX, 0));
+ return;
case IIT_TOKEN:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Token, 0));
return;
@@ -864,6 +949,10 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
OutputTable.push_back(IITDescriptor::getVector(128, IsScalableVector));
DecodeIITType(NextElt, Infos, Info, OutputTable);
return;
+ case IIT_V256:
+ OutputTable.push_back(IITDescriptor::getVector(256, IsScalableVector));
+ DecodeIITType(NextElt, Infos, Info, OutputTable);
+ return;
case IIT_V512:
OutputTable.push_back(IITDescriptor::getVector(512, IsScalableVector));
DecodeIITType(NextElt, Infos, Info, OutputTable);
@@ -932,6 +1021,7 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
case IIT_EMPTYSTRUCT:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
return;
+ case IIT_STRUCT9: ++StructElts; LLVM_FALLTHROUGH;
case IIT_STRUCT8: ++StructElts; LLVM_FALLTHROUGH;
case IIT_STRUCT7: ++StructElts; LLVM_FALLTHROUGH;
case IIT_STRUCT6: ++StructElts; LLVM_FALLTHROUGH;
@@ -1025,6 +1115,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::Void: return Type::getVoidTy(Context);
case IITDescriptor::VarArg: return Type::getVoidTy(Context);
case IITDescriptor::MMX: return Type::getX86_MMXTy(Context);
+ case IITDescriptor::AMX: return Type::getX86_AMXTy(Context);
case IITDescriptor::Token: return Type::getTokenTy(Context);
case IITDescriptor::Metadata: return Type::getMetadataTy(Context);
case IITDescriptor::Half: return Type::getHalfTy(Context);
@@ -1162,7 +1253,7 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
// There can never be multiple globals with the same name of different types,
// because intrinsics must be a specific type.
return cast<Function>(
- M->getOrInsertFunction(getName(id, Tys),
+ M->getOrInsertFunction(Tys.empty() ? getName(id) : getName(id, Tys),
getType(M->getContext(), id, Tys))
.getCallee());
}
@@ -1204,6 +1295,7 @@ static bool matchIntrinsicType(
case IITDescriptor::Void: return !Ty->isVoidTy();
case IITDescriptor::VarArg: return true;
case IITDescriptor::MMX: return !Ty->isX86_MMXTy();
+ case IITDescriptor::AMX: return !Ty->isX86_AMXTy();
case IITDescriptor::Token: return !Ty->isTokenTy();
case IITDescriptor::Metadata: return !Ty->isMetadataTy();
case IITDescriptor::Half: return !Ty->isHalfTy();
@@ -1356,10 +1448,10 @@ static bool matchIntrinsicType(
// Verify the overloaded type "matches" the Ref type.
// i.e. Ty is a vector with the same width as Ref.
// Composed of pointers to the same element type as Ref.
- VectorType *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]);
- VectorType *ThisArgVecTy = dyn_cast<VectorType>(Ty);
+ auto *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]);
+ auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
if (!ThisArgVecTy || !ReferenceType ||
- (ReferenceType->getNumElements() != ThisArgVecTy->getNumElements()))
+ (ReferenceType->getElementCount() != ThisArgVecTy->getElementCount()))
return true;
PointerType *ThisArgEltTy =
dyn_cast<PointerType>(ThisArgVecTy->getElementType());