diff options
Diffstat (limited to 'lib/IR/Function.cpp')
-rw-r--r-- | lib/IR/Function.cpp | 218 |
1 files changed, 152 insertions, 66 deletions
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index a88478b89bfc..dc28d22548dd 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -1,9 +1,8 @@ //===- Function.cpp - Implement the Global object classes -----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -114,6 +113,11 @@ unsigned Argument::getParamAlignment() const { return getParent()->getParamAlignment(getArgNo()); } +Type *Argument::getParamByValType() const { + assert(getType()->isPointerTy() && "Only pointers have byval types"); + return getParent()->getParamByValType(getArgNo()); +} + uint64_t Argument::getDereferenceableBytes() const { assert(getType()->isPointerTy() && "Only pointers have dereferenceable bytes"); @@ -146,6 +150,10 @@ bool Argument::hasStructRetAttr() const { return hasAttribute(Attribute::StructRet); } +bool Argument::hasInRegAttr() const { + return hasAttribute(Attribute::InReg); +} + bool Argument::hasReturnedAttr() const { return hasAttribute(Attribute::Returned); } @@ -186,6 +194,10 @@ bool Argument::hasAttribute(Attribute::AttrKind Kind) const { return getParent()->hasParamAttribute(getArgNo(), Kind); } +Attribute Argument::getAttribute(Attribute::AttrKind Kind) const { + return getParent()->getParamAttribute(getArgNo(), Kind); +} + //===----------------------------------------------------------------------===// // Helper Methods in Function //===----------------------------------------------------------------------===// @@ -521,9 +533,8 @@ static ArrayRef<const char *> findTargetSubtable(StringRef Name) { // Drop "llvm." and take the first dotted component. That will be the target // if this is target specific. StringRef Target = Name.drop_front(5).split('.').first; - auto It = std::lower_bound(Targets.begin(), Targets.end(), Target, - [](const IntrinsicTargetInfo &TI, - StringRef Target) { return TI.Name < Target; }); + auto It = partition_point( + Targets, [=](const IntrinsicTargetInfo &TI) { return TI.Name < Target; }); // We've either found the target or just fall back to the generic set, which // is always first. const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0]; @@ -688,7 +699,8 @@ enum IIT_Info { IIT_STRUCT6 = 38, IIT_STRUCT7 = 39, IIT_STRUCT8 = 40, - IIT_F128 = 41 + IIT_F128 = 41, + IIT_VEC_ELEMENT = 42 }; static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, @@ -853,6 +865,12 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, DecodeIITType(NextElt, Infos, OutputTable); return; } + case IIT_VEC_ELEMENT: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecElementArgument, + ArgInfo)); + return; + } } llvm_unreachable("unhandled"); } @@ -949,10 +967,9 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, case IITDescriptor::SameVecWidthArgument: { Type *EltTy = DecodeFixedType(Infos, Tys, Context); Type *Ty = Tys[D.getArgumentNumber()]; - if (VectorType *VTy = dyn_cast<VectorType>(Ty)) { + if (auto *VTy = dyn_cast<VectorType>(Ty)) return VectorType::get(EltTy, VTy->getNumElements()); - } - llvm_unreachable("unhandled"); + return EltTy; } case IITDescriptor::PtrToArgument: { Type *Ty = Tys[D.getArgumentNumber()]; @@ -966,6 +983,12 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, Type *EltTy = VTy->getVectorElementType(); return PointerType::getUnqual(EltTy); } + case IITDescriptor::VecElementArgument: { + Type *Ty = Tys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast<VectorType>(Ty)) + return VTy->getElementType(); + llvm_unreachable("Expected an argument of Vector Type"); + } case IITDescriptor::VecOfAnyPtrsToElt: // Return the overloaded type (which determines the pointers address space) return Tys[D.getOverloadArgNumber()]; @@ -1020,9 +1043,10 @@ bool Intrinsic::isLeaf(ID id) { 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), - getType(M->getContext(), id, Tys))); + return cast<Function>( + M->getOrInsertFunction(getName(id, Tys), + getType(M->getContext(), id, Tys)) + .getCallee()); } // This defines the "Intrinsic::getIntrinsicForGCCBuiltin()" method. @@ -1035,12 +1059,26 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) { #include "llvm/IR/IntrinsicImpl.inc" #undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN -bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos, - SmallVectorImpl<Type*> &ArgTys) { +using DeferredIntrinsicMatchPair = + std::pair<Type *, ArrayRef<Intrinsic::IITDescriptor>>; + +static bool matchIntrinsicType( + Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos, + SmallVectorImpl<Type *> &ArgTys, + SmallVectorImpl<DeferredIntrinsicMatchPair> &DeferredChecks, + bool IsDeferredCheck) { using namespace Intrinsic; // If we ran out of descriptors, there are too many arguments. if (Infos.empty()) return true; + + // Do this before slicing off the 'front' part + auto InfosRef = Infos; + auto DeferCheck = [&DeferredChecks, &InfosRef](Type *T) { + DeferredChecks.emplace_back(T, InfosRef); + return false; + }; + IITDescriptor D = Infos.front(); Infos = Infos.slice(1); @@ -1058,12 +1096,14 @@ bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> case IITDescriptor::Vector: { VectorType *VT = dyn_cast<VectorType>(Ty); return !VT || VT->getNumElements() != D.Vector_Width || - matchIntrinsicType(VT->getElementType(), Infos, ArgTys); + matchIntrinsicType(VT->getElementType(), Infos, ArgTys, + DeferredChecks, IsDeferredCheck); } case IITDescriptor::Pointer: { PointerType *PT = dyn_cast<PointerType>(Ty); return !PT || PT->getAddressSpace() != D.Pointer_AddressSpace || - matchIntrinsicType(PT->getElementType(), Infos, ArgTys); + matchIntrinsicType(PT->getElementType(), Infos, ArgTys, + DeferredChecks, IsDeferredCheck); } case IITDescriptor::Struct: { @@ -1072,35 +1112,40 @@ bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> return true; for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i) - if (matchIntrinsicType(ST->getElementType(i), Infos, ArgTys)) + if (matchIntrinsicType(ST->getElementType(i), Infos, ArgTys, + DeferredChecks, IsDeferredCheck)) return true; return false; } case IITDescriptor::Argument: - // Two cases here - If this is the second occurrence of an argument, verify - // that the later instance matches the previous instance. + // If this is the second occurrence of an argument, + // verify that the later instance matches the previous instance. if (D.getArgumentNumber() < ArgTys.size()) return Ty != ArgTys[D.getArgumentNumber()]; - // Otherwise, if this is the first instance of an argument, record it and - // verify the "Any" kind. - assert(D.getArgumentNumber() == ArgTys.size() && "Table consistency error"); - ArgTys.push_back(Ty); + if (D.getArgumentNumber() > ArgTys.size() || + D.getArgumentKind() == IITDescriptor::AK_MatchType) + return IsDeferredCheck || DeferCheck(Ty); - switch (D.getArgumentKind()) { - case IITDescriptor::AK_Any: return false; // Success - case IITDescriptor::AK_AnyInteger: return !Ty->isIntOrIntVectorTy(); - case IITDescriptor::AK_AnyFloat: return !Ty->isFPOrFPVectorTy(); - case IITDescriptor::AK_AnyVector: return !isa<VectorType>(Ty); - case IITDescriptor::AK_AnyPointer: return !isa<PointerType>(Ty); - } - llvm_unreachable("all argument kinds not covered"); + assert(D.getArgumentNumber() == ArgTys.size() && !IsDeferredCheck && + "Table consistency error"); + ArgTys.push_back(Ty); + + switch (D.getArgumentKind()) { + case IITDescriptor::AK_Any: return false; // Success + case IITDescriptor::AK_AnyInteger: return !Ty->isIntOrIntVectorTy(); + case IITDescriptor::AK_AnyFloat: return !Ty->isFPOrFPVectorTy(); + case IITDescriptor::AK_AnyVector: return !isa<VectorType>(Ty); + case IITDescriptor::AK_AnyPointer: return !isa<PointerType>(Ty); + default: break; + } + llvm_unreachable("all argument kinds not covered"); case IITDescriptor::ExtendArgument: { - // This may only be used when referring to a previous vector argument. + // If this is a forward reference, defer the check for later. if (D.getArgumentNumber() >= ArgTys.size()) - return true; + return IsDeferredCheck || DeferCheck(Ty); Type *NewTy = ArgTys[D.getArgumentNumber()]; if (VectorType *VTy = dyn_cast<VectorType>(NewTy)) @@ -1113,9 +1158,9 @@ bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> return Ty != NewTy; } case IITDescriptor::TruncArgument: { - // This may only be used when referring to a previous vector argument. + // If this is a forward reference, defer the check for later. if (D.getArgumentNumber() >= ArgTys.size()) - return true; + return IsDeferredCheck || DeferCheck(Ty); Type *NewTy = ArgTys[D.getArgumentNumber()]; if (VectorType *VTy = dyn_cast<VectorType>(NewTy)) @@ -1128,34 +1173,42 @@ bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> return Ty != NewTy; } case IITDescriptor::HalfVecArgument: - // This may only be used when referring to a previous vector argument. + // If this is a forward reference, defer the check for later. return D.getArgumentNumber() >= ArgTys.size() || !isa<VectorType>(ArgTys[D.getArgumentNumber()]) || VectorType::getHalfElementsVectorType( cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty; case IITDescriptor::SameVecWidthArgument: { - if (D.getArgumentNumber() >= ArgTys.size()) - return true; - VectorType * ReferenceType = - dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]); - VectorType *ThisArgType = dyn_cast<VectorType>(Ty); - if (!ThisArgType || !ReferenceType || - (ReferenceType->getVectorNumElements() != - ThisArgType->getVectorNumElements())) + if (D.getArgumentNumber() >= ArgTys.size()) { + // Defer check and subsequent check for the vector element type. + Infos = Infos.slice(1); + return IsDeferredCheck || DeferCheck(Ty); + } + auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]); + auto *ThisArgType = dyn_cast<VectorType>(Ty); + // Both must be vectors of the same number of elements or neither. + if ((ReferenceType != nullptr) != (ThisArgType != nullptr)) return true; - return matchIntrinsicType(ThisArgType->getVectorElementType(), - Infos, ArgTys); + Type *EltTy = Ty; + if (ThisArgType) { + if (ReferenceType->getVectorNumElements() != + ThisArgType->getVectorNumElements()) + return true; + EltTy = ThisArgType->getVectorElementType(); + } + return matchIntrinsicType(EltTy, Infos, ArgTys, DeferredChecks, + IsDeferredCheck); } case IITDescriptor::PtrToArgument: { if (D.getArgumentNumber() >= ArgTys.size()) - return true; + return IsDeferredCheck || DeferCheck(Ty); Type * ReferenceType = ArgTys[D.getArgumentNumber()]; PointerType *ThisArgType = dyn_cast<PointerType>(Ty); return (!ThisArgType || ThisArgType->getElementType() != ReferenceType); } case IITDescriptor::PtrToElt: { if (D.getArgumentNumber() >= ArgTys.size()) - return true; + return IsDeferredCheck || DeferCheck(Ty); VectorType * ReferenceType = dyn_cast<VectorType> (ArgTys[D.getArgumentNumber()]); PointerType *ThisArgType = dyn_cast<PointerType>(Ty); @@ -1165,15 +1218,20 @@ bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> } case IITDescriptor::VecOfAnyPtrsToElt: { unsigned RefArgNumber = D.getRefArgNumber(); + if (RefArgNumber >= ArgTys.size()) { + if (IsDeferredCheck) + return true; + // If forward referencing, already add the pointer-vector type and + // defer the checks for later. + ArgTys.push_back(Ty); + return DeferCheck(Ty); + } - // This may only be used when referring to a previous argument. - if (RefArgNumber >= ArgTys.size()) - return true; - - // Record the overloaded type - assert(D.getOverloadArgNumber() == ArgTys.size() && - "Table consistency error"); - ArgTys.push_back(Ty); + if (!IsDeferredCheck){ + assert(D.getOverloadArgNumber() == ArgTys.size() && + "Table consistency error"); + ArgTys.push_back(Ty); + } // Verify the overloaded type "matches" the Ref type. // i.e. Ty is a vector with the same width as Ref. @@ -1191,10 +1249,42 @@ bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> return ThisArgEltTy->getElementType() != ReferenceType->getVectorElementType(); } + case IITDescriptor::VecElementArgument: { + if (D.getArgumentNumber() >= ArgTys.size()) + return IsDeferredCheck ? true : DeferCheck(Ty); + auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]); + return !ReferenceType || Ty != ReferenceType->getElementType(); + } } llvm_unreachable("unhandled"); } +Intrinsic::MatchIntrinsicTypesResult +Intrinsic::matchIntrinsicSignature(FunctionType *FTy, + ArrayRef<Intrinsic::IITDescriptor> &Infos, + SmallVectorImpl<Type *> &ArgTys) { + SmallVector<DeferredIntrinsicMatchPair, 2> DeferredChecks; + if (matchIntrinsicType(FTy->getReturnType(), Infos, ArgTys, DeferredChecks, + false)) + return MatchIntrinsicTypes_NoMatchRet; + + unsigned NumDeferredReturnChecks = DeferredChecks.size(); + + for (auto Ty : FTy->params()) + if (matchIntrinsicType(Ty, Infos, ArgTys, DeferredChecks, false)) + return MatchIntrinsicTypes_NoMatchArg; + + for (unsigned I = 0, E = DeferredChecks.size(); I != E; ++I) { + DeferredIntrinsicMatchPair &Check = DeferredChecks[I]; + if (matchIntrinsicType(Check.first, Check.second, ArgTys, DeferredChecks, + true)) + return I < NumDeferredReturnChecks ? MatchIntrinsicTypes_NoMatchRet + : MatchIntrinsicTypes_NoMatchArg; + } + + return MatchIntrinsicTypes_Match; +} + bool Intrinsic::matchIntrinsicVarArg(bool isVarArg, ArrayRef<Intrinsic::IITDescriptor> &Infos) { @@ -1228,13 +1318,8 @@ Optional<Function*> Intrinsic::remangleIntrinsicFunction(Function *F) { getIntrinsicInfoTableEntries(ID, Table); ArrayRef<Intrinsic::IITDescriptor> TableRef = Table; - // If we encounter any problems matching the signature with the descriptor - // just give up remangling. It's up to verifier to report the discrepancy. - if (Intrinsic::matchIntrinsicType(FTy->getReturnType(), TableRef, ArgTys)) + if (Intrinsic::matchIntrinsicSignature(FTy, TableRef, ArgTys)) return None; - for (auto Ty : FTy->params()) - if (Intrinsic::matchIntrinsicType(Ty, TableRef, ArgTys)) - return None; if (Intrinsic::matchIntrinsicVarArg(FTy->isVarArg(), TableRef)) return None; } @@ -1378,7 +1463,7 @@ void Function::setEntryCount(uint64_t Count, Function::ProfileCountType Type, setEntryCount(ProfileCount(Count, Type), Imports); } -ProfileCount Function::getEntryCount() const { +ProfileCount Function::getEntryCount(bool AllowSynthetic) const { MDNode *MD = getMetadata(LLVMContext::MD_prof); if (MD && MD->getOperand(0)) if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) { @@ -1390,7 +1475,8 @@ ProfileCount Function::getEntryCount() const { if (Count == (uint64_t)-1) return ProfileCount::getInvalid(); return ProfileCount(Count, PCT_Real); - } else if (MDS->getString().equals("synthetic_function_entry_count")) { + } else if (AllowSynthetic && + MDS->getString().equals("synthetic_function_entry_count")) { ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(1)); uint64_t Count = CI->getValue().getZExtValue(); return ProfileCount(Count, PCT_Synthetic); |