diff options
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 203 |
1 files changed, 130 insertions, 73 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 54612250b0d6..10d535e3ab11 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/IR/AbstractCallSite.h" #include "llvm/IR/Argument.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" @@ -114,11 +115,39 @@ bool Argument::hasInAllocaAttr() const { return hasAttribute(Attribute::InAlloca); } -bool Argument::hasByValOrInAllocaAttr() const { +bool Argument::hasPreallocatedAttr() const { + if (!getType()->isPointerTy()) + return false; + return hasAttribute(Attribute::Preallocated); +} + +bool Argument::hasPassPointeeByValueAttr() const { if (!getType()->isPointerTy()) return false; AttributeList Attrs = getParent()->getAttributes(); return Attrs.hasParamAttribute(getArgNo(), Attribute::ByVal) || - Attrs.hasParamAttribute(getArgNo(), Attribute::InAlloca); + Attrs.hasParamAttribute(getArgNo(), Attribute::InAlloca) || + Attrs.hasParamAttribute(getArgNo(), Attribute::Preallocated); +} + +uint64_t Argument::getPassPointeeByValueCopySize(const DataLayout &DL) const { + AttributeSet ParamAttrs + = getParent()->getAttributes().getParamAttributes(getArgNo()); + + // 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); + if (Type *PreAllocTy = ParamAttrs.getPreallocatedType()) + return DL.getTypeAllocSize(PreAllocTy); + + // FIXME: 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::Preallocated)) + return DL.getTypeAllocSize(cast<PointerType>(getType())->getElementType()); + + return 0; } unsigned Argument::getParamAlignment() const { @@ -320,6 +349,18 @@ static MutableArrayRef<Argument> makeArgArray(Argument *Args, size_t Count) { return MutableArrayRef<Argument>(Args, Count); } +bool Function::isConstrainedFPIntrinsic() const { + switch (getIntrinsicID()) { +#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \ + case Intrinsic::INTRINSIC: +#include "llvm/IR/ConstrainedOps.def" + return true; +#undef INSTRUCTION + default: + return false; + } +} + void Function::clearArguments() { for (Argument &A : makeArgArray(Arguments, NumArgs)) { A.setName(""); @@ -632,16 +673,17 @@ static std::string getMangledTypeStr(Type* Ty) { // Ensure nested function types are distinguishable. Result += "f"; } else if (VectorType* VTy = dyn_cast<VectorType>(Ty)) { - if (VTy->isScalable()) + ElementCount EC = VTy->getElementCount(); + if (EC.Scalable) Result += "nx"; - Result += "v" + utostr(VTy->getVectorNumElements()) + - getMangledTypeStr(VTy->getVectorElementType()); + Result += "v" + utostr(EC.Min) + getMangledTypeStr(VTy->getElementType()); } else if (Ty) { switch (Ty->getTypeID()) { default: llvm_unreachable("Unhandled type"); case Type::VoidTyID: Result += "isVoid"; break; case Type::MetadataTyID: Result += "Metadata"; break; case Type::HalfTyID: Result += "f16"; break; + case Type::BFloatTyID: Result += "bf16"; break; case Type::FloatTyID: Result += "f32"; break; case Type::DoubleTyID: Result += "f64"; break; case Type::X86_FP80TyID: Result += "f80"; break; @@ -726,13 +768,18 @@ enum IIT_Info { IIT_SCALABLE_VEC = 43, IIT_SUBDIVIDE2_ARG = 44, IIT_SUBDIVIDE4_ARG = 45, - IIT_VEC_OF_BITCASTS_TO_INT = 46 + IIT_VEC_OF_BITCASTS_TO_INT = 46, + IIT_V128 = 47, + IIT_BF16 = 48 }; static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, + IIT_Info LastInfo, SmallVectorImpl<Intrinsic::IITDescriptor> &OutputTable) { using namespace Intrinsic; + bool IsScalableVector = (LastInfo == IIT_SCALABLE_VEC); + IIT_Info Info = IIT_Info(Infos[NextElt++]); unsigned StructElts = 2; @@ -755,6 +802,9 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, case IIT_F16: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Half, 0)); return; + case IIT_BF16: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::BFloat, 0)); + return; case IIT_F32: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Float, 0)); return; @@ -783,49 +833,53 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 128)); return; case IIT_V1: - OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 1)); - DecodeIITType(NextElt, Infos, OutputTable); + OutputTable.push_back(IITDescriptor::getVector(1, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; case IIT_V2: - OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 2)); - DecodeIITType(NextElt, Infos, OutputTable); + OutputTable.push_back(IITDescriptor::getVector(2, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; case IIT_V4: - OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 4)); - DecodeIITType(NextElt, Infos, OutputTable); + OutputTable.push_back(IITDescriptor::getVector(4, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; case IIT_V8: - OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 8)); - DecodeIITType(NextElt, Infos, OutputTable); + OutputTable.push_back(IITDescriptor::getVector(8, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; case IIT_V16: - OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 16)); - DecodeIITType(NextElt, Infos, OutputTable); + OutputTable.push_back(IITDescriptor::getVector(16, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; case IIT_V32: - OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 32)); - DecodeIITType(NextElt, Infos, OutputTable); + OutputTable.push_back(IITDescriptor::getVector(32, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; case IIT_V64: - OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 64)); - DecodeIITType(NextElt, Infos, OutputTable); + OutputTable.push_back(IITDescriptor::getVector(64, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V128: + OutputTable.push_back(IITDescriptor::getVector(128, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; case IIT_V512: - OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 512)); - DecodeIITType(NextElt, Infos, OutputTable); + OutputTable.push_back(IITDescriptor::getVector(512, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; case IIT_V1024: - OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 1024)); - DecodeIITType(NextElt, Infos, OutputTable); + OutputTable.push_back(IITDescriptor::getVector(1024, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; case IIT_PTR: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0)); - DecodeIITType(NextElt, Infos, OutputTable); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; case IIT_ANYPTR: { // [ANYPTR addrspace, subtype] OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, Infos[NextElt++])); - DecodeIITType(NextElt, Infos, OutputTable); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; } case IIT_ARG: { @@ -888,7 +942,7 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct,StructElts)); for (unsigned i = 0; i != StructElts; ++i) - DecodeIITType(NextElt, Infos, OutputTable); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; } case IIT_SUBDIVIDE2_ARG: { @@ -910,9 +964,7 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, return; } case IIT_SCALABLE_VEC: { - OutputTable.push_back(IITDescriptor::get(IITDescriptor::ScalableVecArgument, - 0)); - DecodeIITType(NextElt, Infos, OutputTable); + DecodeIITType(NextElt, Infos, Info, OutputTable); return; } case IIT_VEC_OF_BITCASTS_TO_INT: { @@ -957,9 +1009,9 @@ void Intrinsic::getIntrinsicInfoTableEntries(ID id, } // Okay, decode the table into the output vector of IITDescriptors. - DecodeIITType(NextElt, IITEntries, T); + DecodeIITType(NextElt, IITEntries, IIT_Done, T); while (NextElt != IITEntries.size() && IITEntries[NextElt] != 0) - DecodeIITType(NextElt, IITEntries, T); + DecodeIITType(NextElt, IITEntries, IIT_Done, T); } static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, @@ -976,6 +1028,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, case IITDescriptor::Token: return Type::getTokenTy(Context); case IITDescriptor::Metadata: return Type::getMetadataTy(Context); case IITDescriptor::Half: return Type::getHalfTy(Context); + case IITDescriptor::BFloat: return Type::getBFloatTy(Context); case IITDescriptor::Float: return Type::getFloatTy(Context); case IITDescriptor::Double: return Type::getDoubleTy(Context); case IITDescriptor::Quad: return Type::getFP128Ty(Context); @@ -983,7 +1036,8 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, case IITDescriptor::Integer: return IntegerType::get(Context, D.Integer_Width); case IITDescriptor::Vector: - return VectorType::get(DecodeFixedType(Infos, Tys, Context),D.Vector_Width); + return VectorType::get(DecodeFixedType(Infos, Tys, Context), + D.Vector_Width); case IITDescriptor::Pointer: return PointerType::get(DecodeFixedType(Infos, Tys, Context), D.Pointer_AddressSpace); @@ -1038,7 +1092,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, VectorType *VTy = dyn_cast<VectorType>(Ty); if (!VTy) llvm_unreachable("Expected an argument of Vector Type"); - Type *EltTy = VTy->getVectorElementType(); + Type *EltTy = VTy->getElementType(); return PointerType::getUnqual(EltTy); } case IITDescriptor::VecElementArgument: { @@ -1056,11 +1110,6 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, case IITDescriptor::VecOfAnyPtrsToElt: // Return the overloaded type (which determines the pointers address space) return Tys[D.getOverloadArgNumber()]; - case IITDescriptor::ScalableVecArgument: { - Type *Ty = DecodeFixedType(Infos, Tys, Context); - return VectorType::get(Ty->getVectorElementType(), - { Ty->getVectorNumElements(), true }); - } } llvm_unreachable("unhandled"); } @@ -1158,13 +1207,14 @@ static bool matchIntrinsicType( case IITDescriptor::Token: return !Ty->isTokenTy(); case IITDescriptor::Metadata: return !Ty->isMetadataTy(); case IITDescriptor::Half: return !Ty->isHalfTy(); + case IITDescriptor::BFloat: return !Ty->isBFloatTy(); case IITDescriptor::Float: return !Ty->isFloatTy(); case IITDescriptor::Double: return !Ty->isDoubleTy(); case IITDescriptor::Quad: return !Ty->isFP128Ty(); case IITDescriptor::Integer: return !Ty->isIntegerTy(D.Integer_Width); case IITDescriptor::Vector: { VectorType *VT = dyn_cast<VectorType>(Ty); - return !VT || VT->getNumElements() != D.Vector_Width || + return !VT || VT->getElementCount() != D.Vector_Width || matchIntrinsicType(VT->getElementType(), Infos, ArgTys, DeferredChecks, IsDeferredCheck); } @@ -1264,7 +1314,7 @@ static bool matchIntrinsicType( if (ReferenceType->getElementCount() != ThisArgType->getElementCount()) return true; - EltTy = ThisArgType->getVectorElementType(); + EltTy = ThisArgType->getElementType(); } return matchIntrinsicType(EltTy, Infos, ArgTys, DeferredChecks, IsDeferredCheck); @@ -1309,15 +1359,13 @@ static bool matchIntrinsicType( VectorType *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]); VectorType *ThisArgVecTy = dyn_cast<VectorType>(Ty); if (!ThisArgVecTy || !ReferenceType || - (ReferenceType->getVectorNumElements() != - ThisArgVecTy->getVectorNumElements())) + (ReferenceType->getNumElements() != ThisArgVecTy->getNumElements())) return true; PointerType *ThisArgEltTy = - dyn_cast<PointerType>(ThisArgVecTy->getVectorElementType()); + dyn_cast<PointerType>(ThisArgVecTy->getElementType()); if (!ThisArgEltTy) return true; - return ThisArgEltTy->getElementType() != - ReferenceType->getVectorElementType(); + return ThisArgEltTy->getElementType() != ReferenceType->getElementType(); } case IITDescriptor::VecElementArgument: { if (D.getArgumentNumber() >= ArgTys.size()) @@ -1339,13 +1387,6 @@ static bool matchIntrinsicType( } return true; } - case IITDescriptor::ScalableVecArgument: { - VectorType *VTy = dyn_cast<VectorType>(Ty); - if (!VTy || !VTy->isScalable()) - return true; - return matchIntrinsicType(VTy, Infos, ArgTys, DeferredChecks, - IsDeferredCheck); - } case IITDescriptor::VecOfBitcastsToInt: { if (D.getArgumentNumber() >= ArgTys.size()) return IsDeferredCheck || DeferCheck(Ty); @@ -1405,42 +1446,60 @@ Intrinsic::matchIntrinsicVarArg(bool isVarArg, return true; } -Optional<Function*> Intrinsic::remangleIntrinsicFunction(Function *F) { +bool Intrinsic::getIntrinsicSignature(Function *F, + SmallVectorImpl<Type *> &ArgTys) { Intrinsic::ID ID = F->getIntrinsicID(); if (!ID) - return None; + return false; - FunctionType *FTy = F->getFunctionType(); - // Accumulate an array of overloaded types for the given intrinsic - SmallVector<Type *, 4> ArgTys; - { - SmallVector<Intrinsic::IITDescriptor, 8> Table; - getIntrinsicInfoTableEntries(ID, Table); - ArrayRef<Intrinsic::IITDescriptor> TableRef = Table; - - if (Intrinsic::matchIntrinsicSignature(FTy, TableRef, ArgTys)) - return None; - if (Intrinsic::matchIntrinsicVarArg(FTy->isVarArg(), TableRef)) - return None; + SmallVector<Intrinsic::IITDescriptor, 8> Table; + getIntrinsicInfoTableEntries(ID, Table); + ArrayRef<Intrinsic::IITDescriptor> TableRef = Table; + + if (Intrinsic::matchIntrinsicSignature(F->getFunctionType(), TableRef, + ArgTys) != + Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) { + return false; } + if (Intrinsic::matchIntrinsicVarArg(F->getFunctionType()->isVarArg(), + TableRef)) + return false; + return true; +} + +Optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) { + SmallVector<Type *, 4> ArgTys; + if (!getIntrinsicSignature(F, ArgTys)) + return None; + Intrinsic::ID ID = F->getIntrinsicID(); StringRef Name = F->getName(); if (Name == Intrinsic::getName(ID, ArgTys)) return None; auto NewDecl = Intrinsic::getDeclaration(F->getParent(), ID, ArgTys); NewDecl->setCallingConv(F->getCallingConv()); - assert(NewDecl->getFunctionType() == FTy && "Shouldn't change the signature"); + assert(NewDecl->getFunctionType() == F->getFunctionType() && + "Shouldn't change the signature"); return NewDecl; } /// hasAddressTaken - returns true if there are any uses of this function -/// other than direct calls or invokes to it. -bool Function::hasAddressTaken(const User* *PutOffender) const { +/// other than direct calls or invokes to it. Optionally ignores callback +/// uses. +bool Function::hasAddressTaken(const User **PutOffender, + bool IgnoreCallbackUses) const { for (const Use &U : uses()) { const User *FU = U.getUser(); if (isa<BlockAddress>(FU)) continue; + + if (IgnoreCallbackUses) { + AbstractCallSite ACS(&U); + if (ACS && ACS.isCallbackCall()) + continue; + } + const auto *Call = dyn_cast<CallBase>(FU); if (!Call) { if (PutOffender) @@ -1620,9 +1679,7 @@ Optional<StringRef> Function::getSectionPrefix() const { } bool Function::nullPointerIsDefined() const { - return getFnAttribute("null-pointer-is-valid") - .getValueAsString() - .equals("true"); + return hasFnAttribute(Attribute::NullPointerIsValid); } bool llvm::NullPointerIsDefined(const Function *F, unsigned AS) { |