aboutsummaryrefslogtreecommitdiff
path: root/lib/IR/Function.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/Function.cpp')
-rw-r--r--lib/IR/Function.cpp218
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);