Skip to content

Commit

Permalink
NFC. Move Verifier::verifyIntrinsicType to Intrinsics.h
Browse files Browse the repository at this point in the history
    
Move Verifier::verifyIntrinsicType to Intrinsics::matchIntrinsicsType. Will be used to accumulate overloaded types of a given intrinsic by the upcoming patch to fix intrinsics names when overloaded types are renamed.
    
Reviewed By: reames
    
Differential Revision: http://reviews.llvm.org/D19372


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273424 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
arpilipe committed Jun 22, 2016
1 parent 0993083 commit 5e371d9
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 148 deletions.
9 changes: 9 additions & 0 deletions include/llvm/IR/Intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ namespace Intrinsic {
/// of IITDescriptors.
void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);

/// Match the specified type (which comes from an intrinsic argument or return
/// value) with the type constraints specified by the .td file. If the given
/// type is an overloaded type it is pushed to the ArgTys vector.
///
/// Returns false if the given type matches with the constraints, true
/// otherwise.
bool matchIntrinsicType(Type *Ty, ArrayRef<IITDescriptor> &Infos,
SmallVectorImpl<Type*> &ArgTys);

} // End Intrinsic namespace

} // End llvm namespace
Expand Down
138 changes: 138 additions & 0 deletions lib/IR/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,144 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
#include "llvm/IR/Intrinsics.gen"
#undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN

bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
SmallVectorImpl<Type*> &ArgTys) {
using namespace Intrinsic;

// If we ran out of descriptors, there are too many arguments.
if (Infos.empty()) return true;
IITDescriptor D = Infos.front();
Infos = Infos.slice(1);

switch (D.Kind) {
case IITDescriptor::Void: return !Ty->isVoidTy();
case IITDescriptor::VarArg: return true;
case IITDescriptor::MMX: return !Ty->isX86_MMXTy();
case IITDescriptor::Token: return !Ty->isTokenTy();
case IITDescriptor::Metadata: return !Ty->isMetadataTy();
case IITDescriptor::Half: return !Ty->isHalfTy();
case IITDescriptor::Float: return !Ty->isFloatTy();
case IITDescriptor::Double: return !Ty->isDoubleTy();
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 ||
matchIntrinsicType(VT->getElementType(), Infos, ArgTys);
}
case IITDescriptor::Pointer: {
PointerType *PT = dyn_cast<PointerType>(Ty);
return !PT || PT->getAddressSpace() != D.Pointer_AddressSpace ||
matchIntrinsicType(PT->getElementType(), Infos, ArgTys);
}

case IITDescriptor::Struct: {
StructType *ST = dyn_cast<StructType>(Ty);
if (!ST || ST->getNumElements() != D.Struct_NumElements)
return true;

for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
if (matchIntrinsicType(ST->getElementType(i), Infos, ArgTys))
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 (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);

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");

case IITDescriptor::ExtendArgument: {
// This may only be used when referring to a previous vector argument.
if (D.getArgumentNumber() >= ArgTys.size())
return true;

Type *NewTy = ArgTys[D.getArgumentNumber()];
if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
NewTy = VectorType::getExtendedElementVectorType(VTy);
else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth());
else
return true;

return Ty != NewTy;
}
case IITDescriptor::TruncArgument: {
// This may only be used when referring to a previous vector argument.
if (D.getArgumentNumber() >= ArgTys.size())
return true;

Type *NewTy = ArgTys[D.getArgumentNumber()];
if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
NewTy = VectorType::getTruncatedElementVectorType(VTy);
else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2);
else
return true;

return Ty != NewTy;
}
case IITDescriptor::HalfVecArgument:
// This may only be used when referring to a previous vector argument.
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()))
return true;
return matchIntrinsicType(ThisArgType->getVectorElementType(),
Infos, ArgTys);
}
case IITDescriptor::PtrToArgument: {
if (D.getArgumentNumber() >= ArgTys.size())
return true;
Type * ReferenceType = ArgTys[D.getArgumentNumber()];
PointerType *ThisArgType = dyn_cast<PointerType>(Ty);
return (!ThisArgType || ThisArgType->getElementType() != ReferenceType);
}
case IITDescriptor::VecOfPtrsToElt: {
if (D.getArgumentNumber() >= ArgTys.size())
return true;
VectorType * ReferenceType =
dyn_cast<VectorType> (ArgTys[D.getArgumentNumber()]);
VectorType *ThisArgVecTy = dyn_cast<VectorType>(Ty);
if (!ThisArgVecTy || !ReferenceType ||
(ReferenceType->getVectorNumElements() !=
ThisArgVecTy->getVectorNumElements()))
return true;
PointerType *ThisArgEltTy =
dyn_cast<PointerType>(ThisArgVecTy->getVectorElementType());
if (!ThisArgEltTy)
return true;
return ThisArgEltTy->getElementType() !=
ReferenceType->getVectorElementType();
}
}
llvm_unreachable("unhandled");
}

/// 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 {
Expand Down
152 changes: 4 additions & 148 deletions lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,6 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
void verifyMustTailCall(CallInst &CI);
bool performTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty, int VT,
unsigned ArgNo, std::string &Suffix);
bool verifyIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
SmallVectorImpl<Type *> &ArgTys);
bool verifyIntrinsicIsVarArg(bool isVarArg,
ArrayRef<Intrinsic::IITDescriptor> &Infos);
bool verifyAttributeCount(AttributeSet Attrs, unsigned Params);
Expand Down Expand Up @@ -3727,150 +3725,6 @@ void Verifier::visitInstruction(Instruction &I) {
InstsInThisBlock.insert(&I);
}

/// Verify that the specified type (which comes from an intrinsic argument or
/// return value) matches the type constraints specified by the .td file (e.g.
/// an "any integer" argument really is an integer).
///
/// This returns true on error but does not print a message.
bool Verifier::verifyIntrinsicType(Type *Ty,
ArrayRef<Intrinsic::IITDescriptor> &Infos,
SmallVectorImpl<Type*> &ArgTys) {
using namespace Intrinsic;

// If we ran out of descriptors, there are too many arguments.
if (Infos.empty()) return true;
IITDescriptor D = Infos.front();
Infos = Infos.slice(1);

switch (D.Kind) {
case IITDescriptor::Void: return !Ty->isVoidTy();
case IITDescriptor::VarArg: return true;
case IITDescriptor::MMX: return !Ty->isX86_MMXTy();
case IITDescriptor::Token: return !Ty->isTokenTy();
case IITDescriptor::Metadata: return !Ty->isMetadataTy();
case IITDescriptor::Half: return !Ty->isHalfTy();
case IITDescriptor::Float: return !Ty->isFloatTy();
case IITDescriptor::Double: return !Ty->isDoubleTy();
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 ||
verifyIntrinsicType(VT->getElementType(), Infos, ArgTys);
}
case IITDescriptor::Pointer: {
PointerType *PT = dyn_cast<PointerType>(Ty);
return !PT || PT->getAddressSpace() != D.Pointer_AddressSpace ||
verifyIntrinsicType(PT->getElementType(), Infos, ArgTys);
}

case IITDescriptor::Struct: {
StructType *ST = dyn_cast<StructType>(Ty);
if (!ST || ST->getNumElements() != D.Struct_NumElements)
return true;

for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
if (verifyIntrinsicType(ST->getElementType(i), Infos, ArgTys))
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 (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);

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");

case IITDescriptor::ExtendArgument: {
// This may only be used when referring to a previous vector argument.
if (D.getArgumentNumber() >= ArgTys.size())
return true;

Type *NewTy = ArgTys[D.getArgumentNumber()];
if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
NewTy = VectorType::getExtendedElementVectorType(VTy);
else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth());
else
return true;

return Ty != NewTy;
}
case IITDescriptor::TruncArgument: {
// This may only be used when referring to a previous vector argument.
if (D.getArgumentNumber() >= ArgTys.size())
return true;

Type *NewTy = ArgTys[D.getArgumentNumber()];
if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
NewTy = VectorType::getTruncatedElementVectorType(VTy);
else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2);
else
return true;

return Ty != NewTy;
}
case IITDescriptor::HalfVecArgument:
// This may only be used when referring to a previous vector argument.
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()))
return true;
return verifyIntrinsicType(ThisArgType->getVectorElementType(),
Infos, ArgTys);
}
case IITDescriptor::PtrToArgument: {
if (D.getArgumentNumber() >= ArgTys.size())
return true;
Type * ReferenceType = ArgTys[D.getArgumentNumber()];
PointerType *ThisArgType = dyn_cast<PointerType>(Ty);
return (!ThisArgType || ThisArgType->getElementType() != ReferenceType);
}
case IITDescriptor::VecOfPtrsToElt: {
if (D.getArgumentNumber() >= ArgTys.size())
return true;
VectorType * ReferenceType =
dyn_cast<VectorType> (ArgTys[D.getArgumentNumber()]);
VectorType *ThisArgVecTy = dyn_cast<VectorType>(Ty);
if (!ThisArgVecTy || !ReferenceType ||
(ReferenceType->getVectorNumElements() !=
ThisArgVecTy->getVectorNumElements()))
return true;
PointerType *ThisArgEltTy =
dyn_cast<PointerType>(ThisArgVecTy->getVectorElementType());
if (!ThisArgEltTy)
return true;
return ThisArgEltTy->getElementType() !=
ReferenceType->getVectorElementType();
}
}
llvm_unreachable("unhandled");
}

/// Verify if the intrinsic has variable arguments. This method is intended to
/// be called after all the fixed arguments have been verified first.
///
Expand Down Expand Up @@ -3913,10 +3767,12 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;

SmallVector<Type *, 4> ArgTys;
Assert(!verifyIntrinsicType(IFTy->getReturnType(), TableRef, ArgTys),
Assert(!Intrinsic::matchIntrinsicType(IFTy->getReturnType(),
TableRef, ArgTys),
"Intrinsic has incorrect return type!", IF);
for (unsigned i = 0, e = IFTy->getNumParams(); i != e; ++i)
Assert(!verifyIntrinsicType(IFTy->getParamType(i), TableRef, ArgTys),
Assert(!Intrinsic::matchIntrinsicType(IFTy->getParamType(i),
TableRef, ArgTys),
"Intrinsic has incorrect argument type!", IF);

// Verify if the intrinsic call matches the vararg property.
Expand Down

0 comments on commit 5e371d9

Please sign in to comment.