[llvm] r363233 - [IntrinsicEmitter] Extend argument overloading with forward references.
Sander de Smalen via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 13 01:19:33 PDT 2019
Author: s.desmalen
Date: Thu Jun 13 01:19:33 2019
New Revision: 363233
URL: http://llvm.org/viewvc/llvm-project?rev=363233&view=rev
Log:
[IntrinsicEmitter] Extend argument overloading with forward references.
Extend the mechanism to overload intrinsic arguments by using either
backward or forward references to the overloadable arguments.
In for example:
def int_something : Intrinsic<[LLVMPointerToElt<0>],
[llvm_anyvector_ty], []>;
LLVMPointerToElt<0> is a forward reference to the overloadable operand
of type 'llvm_anyvector_ty' and would allow intrinsics such as:
declare i32* @llvm.something.v4i32(<4 x i32>);
declare i64* @llvm.something.v2i64(<2 x i64>);
where the result pointer type is deduced from the element type of the
first argument.
If the returned pointer is not a pointer to the element type, LLVM will
give an error:
Intrinsic has incorrect return type!
i64* (<4 x i32>)* @llvm.something.v4i32
Reviewers: RKSimon, arsenm, rnk, greened
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D62995
Modified:
llvm/trunk/include/llvm/IR/Intrinsics.h
llvm/trunk/lib/IR/Function.cpp
llvm/trunk/lib/IR/Verifier.cpp
llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
llvm/trunk/utils/TableGen/CodeGenTarget.cpp
llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
Modified: llvm/trunk/include/llvm/IR/Intrinsics.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.h?rev=363233&r1=363232&r2=363233&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.h (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.h Thu Jun 13 01:19:33 2019
@@ -116,7 +116,8 @@ namespace Intrinsic {
AK_AnyInteger,
AK_AnyFloat,
AK_AnyVector,
- AK_AnyPointer
+ AK_AnyPointer,
+ AK_MatchType = 7
};
unsigned getArgumentNumber() const {
@@ -161,14 +162,21 @@ 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.
+ enum MatchIntrinsicTypesResult {
+ MatchIntrinsicTypes_Match = 0,
+ MatchIntrinsicTypes_NoMatchRet = 1,
+ MatchIntrinsicTypes_NoMatchArg = 2,
+ };
+
+ /// Match the specified function type 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);
+ MatchIntrinsicTypesResult
+ matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos,
+ SmallVectorImpl<Type *> &ArgTys);
/// Verify if the intrinsic has variable arguments. This method is intended to
/// be called after all the fixed arguments have been matched first.
Modified: llvm/trunk/lib/IR/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Function.cpp?rev=363233&r1=363232&r2=363233&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Function.cpp (original)
+++ llvm/trunk/lib/IR/Function.cpp Thu Jun 13 01:19:33 2019
@@ -1047,12 +1047,26 @@ Function *Intrinsic::getDeclaration(Modu
#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);
@@ -1070,12 +1084,14 @@ bool Intrinsic::matchIntrinsicType(Type
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: {
@@ -1084,20 +1100,24 @@ bool Intrinsic::matchIntrinsicType(Type
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");
+ if (D.getArgumentNumber() > ArgTys.size() ||
+ D.getArgumentKind() == IITDescriptor::AK_MatchType)
+ return IsDeferredCheck || DeferCheck(Ty);
+
+ assert(D.getArgumentNumber() == ArgTys.size() && !IsDeferredCheck &&
+ "Table consistency error");
ArgTys.push_back(Ty);
switch (D.getArgumentKind()) {
@@ -1106,13 +1126,14 @@ bool Intrinsic::matchIntrinsicType(Type
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))
@@ -1125,9 +1146,9 @@ bool Intrinsic::matchIntrinsicType(Type
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))
@@ -1140,14 +1161,17 @@ bool Intrinsic::matchIntrinsicType(Type
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;
+ 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.
@@ -1160,18 +1184,19 @@ bool Intrinsic::matchIntrinsicType(Type
return true;
EltTy = ThisArgType->getVectorElementType();
}
- return matchIntrinsicType(EltTy, Infos, ArgTys);
+ 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);
@@ -1181,15 +1206,20 @@ bool Intrinsic::matchIntrinsicType(Type
}
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.
@@ -1211,6 +1241,32 @@ bool Intrinsic::matchIntrinsicType(Type
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) {
@@ -1244,13 +1300,8 @@ Optional<Function*> Intrinsic::remangleI
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;
}
Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=363233&r1=363232&r2=363233&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Thu Jun 13 01:19:33 2019
@@ -4154,14 +4154,14 @@ void Verifier::visitIntrinsicCall(Intrin
getIntrinsicInfoTableEntries(ID, Table);
ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;
+ // Walk the descriptors to extract overloaded types.
SmallVector<Type *, 4> ArgTys;
- Assert(!Intrinsic::matchIntrinsicType(IFTy->getReturnType(),
- TableRef, ArgTys),
+ Intrinsic::MatchIntrinsicTypesResult Res =
+ Intrinsic::matchIntrinsicSignature(IFTy, TableRef, ArgTys);
+ Assert(Res != Intrinsic::MatchIntrinsicTypes_NoMatchRet,
"Intrinsic has incorrect return type!", IF);
- for (unsigned i = 0, e = IFTy->getNumParams(); i != e; ++i)
- Assert(!Intrinsic::matchIntrinsicType(IFTy->getParamType(i),
- TableRef, ArgTys),
- "Intrinsic has incorrect argument type!", IF);
+ Assert(Res != Intrinsic::MatchIntrinsicTypes_NoMatchArg,
+ "Intrinsic has incorrect argument type!", IF);
// Verify if the intrinsic call matches the vararg property.
if (IsVarArg)
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp?rev=363233&r1=363232&r2=363233&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp Thu Jun 13 01:19:33 2019
@@ -1019,13 +1019,12 @@ Value *InstCombiner::simplifyAMDGCNMemor
getIntrinsicInfoTableEntries(IID, Table);
ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;
+ // Validate function argument and return types, extracting overloaded types
+ // along the way.
FunctionType *FTy = II->getCalledFunction()->getFunctionType();
SmallVector<Type *, 6> OverloadTys;
- Intrinsic::matchIntrinsicType(FTy->getReturnType(), TableRef, OverloadTys);
- for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
- Intrinsic::matchIntrinsicType(FTy->getParamType(i), TableRef, OverloadTys);
+ Intrinsic::matchIntrinsicSignature(FTy, TableRef, OverloadTys);
- // Get the new return type overload of the intrinsic.
Module *M = II->getParent()->getParent()->getParent();
Type *EltTy = II->getType()->getVectorElementType();
Type *NewTy = (NewNumElts == 1) ? EltTy : VectorType::get(EltTy, NewNumElts);
Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=363233&r1=363232&r2=363233&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Thu Jun 13 01:19:33 2019
@@ -591,9 +591,29 @@ CodeGenIntrinsic::CodeGenIntrinsic(Recor
TargetPrefix + ".'!");
}
- // Parse the list of return types.
+ ListInit *RetTypes = R->getValueAsListInit("RetTypes");
+ ListInit *ParamTypes = R->getValueAsListInit("ParamTypes");
+
+ // First collate a list of overloaded types.
std::vector<MVT::SimpleValueType> OverloadedVTs;
- ListInit *TypeList = R->getValueAsListInit("RetTypes");
+ for (ListInit *TypeList : {RetTypes, ParamTypes}) {
+ for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
+ Record *TyEl = TypeList->getElementAsRecord(i);
+ assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
+
+ if (TyEl->isSubClassOf("LLVMMatchType"))
+ continue;
+
+ MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
+ if (MVT(VT).isOverloaded()) {
+ OverloadedVTs.push_back(VT);
+ isOverloaded = true;
+ }
+ }
+ }
+
+ // Parse the list of return types.
+ ListInit *TypeList = RetTypes;
for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
Record *TyEl = TypeList->getElementAsRecord(i);
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
@@ -613,10 +633,6 @@ CodeGenIntrinsic::CodeGenIntrinsic(Recor
} else {
VT = getValueType(TyEl->getValueAsDef("VT"));
}
- if (MVT(VT).isOverloaded()) {
- OverloadedVTs.push_back(VT);
- isOverloaded = true;
- }
// Reject invalid types.
if (VT == MVT::isVoid)
@@ -628,7 +644,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Recor
}
// Parse the list of parameter types.
- TypeList = R->getValueAsListInit("ParamTypes");
+ TypeList = ParamTypes;
for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
Record *TyEl = TypeList->getElementAsRecord(i);
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
@@ -654,11 +670,6 @@ CodeGenIntrinsic::CodeGenIntrinsic(Recor
} else
VT = getValueType(TyEl->getValueAsDef("VT"));
- if (MVT(VT).isOverloaded()) {
- OverloadedVTs.push_back(VT);
- isOverloaded = true;
- }
-
// Reject invalid types.
if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
PrintFatalError(DefLoc, "Intrinsic '" + DefName +
Modified: llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp?rev=363233&r1=363232&r2=363233&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp Thu Jun 13 01:19:33 2019
@@ -258,10 +258,12 @@ static void EncodeFixedValueType(MVT::Si
#endif
static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
- std::vector<unsigned char> &Sig) {
+ unsigned &NextArgCode,
+ std::vector<unsigned char> &Sig,
+ ArrayRef<unsigned char> Mapping) {
if (R->isSubClassOf("LLVMMatchType")) {
- unsigned Number = R->getValueAsInt("Number");
+ unsigned Number = Mapping[R->getValueAsInt("Number")];
assert(Number < ArgCodes.size() && "Invalid matching number!");
if (R->isSubClassOf("LLVMExtendedType"))
Sig.push_back(IIT_EXTEND_ARG);
@@ -280,10 +282,8 @@ static void EncodeFixedType(Record *R, s
Sig.push_back(IIT_PTR_TO_ARG);
else if (R->isSubClassOf("LLVMVectorOfAnyPointersToElt")) {
Sig.push_back(IIT_VEC_OF_ANYPTRS_TO_ELT);
- unsigned ArgNo = ArgCodes.size();
- ArgCodes.push_back(3 /*vAny*/);
// Encode overloaded ArgNo
- Sig.push_back(ArgNo);
+ Sig.push_back(NextArgCode++);
// Encode LLVMMatchType<Number> ArgNo
Sig.push_back(Number);
return;
@@ -291,7 +291,7 @@ static void EncodeFixedType(Record *R, s
Sig.push_back(IIT_PTR_TO_ELT);
else
Sig.push_back(IIT_ARG);
- return Sig.push_back((Number << 3) | ArgCodes[Number]);
+ return Sig.push_back((Number << 3) | 7 /*IITDescriptor::AK_MatchType*/);
}
MVT::SimpleValueType VT = getValueType(R->getValueAsDef("VT"));
@@ -309,8 +309,9 @@ static void EncodeFixedType(Record *R, s
Sig.push_back(IIT_ARG);
// Figure out what arg # this is consuming, and remember what kind it was.
- unsigned ArgNo = ArgCodes.size();
- ArgCodes.push_back(Tmp);
+ assert(NextArgCode < ArgCodes.size() && ArgCodes[NextArgCode] == Tmp &&
+ "Invalid or no ArgCode associated with overloaded VT!");
+ unsigned ArgNo = NextArgCode++;
// Encode what sort of argument it must be in the low 3 bits of the ArgNo.
return Sig.push_back((ArgNo << 3) | Tmp);
@@ -328,7 +329,8 @@ static void EncodeFixedType(Record *R, s
} else {
Sig.push_back(IIT_PTR);
}
- return EncodeFixedType(R->getValueAsDef("ElTy"), ArgCodes, Sig);
+ return EncodeFixedType(R->getValueAsDef("ElTy"), ArgCodes, NextArgCode, Sig,
+ Mapping);
}
}
@@ -353,6 +355,42 @@ static void EncodeFixedType(Record *R, s
EncodeFixedValueType(VT, Sig);
}
+static void UpdateArgCodes(Record *R, std::vector<unsigned char> &ArgCodes,
+ unsigned int &NumInserted,
+ SmallVectorImpl<unsigned char> &Mapping) {
+ if (R->isSubClassOf("LLVMMatchType")) {
+ if (R->isSubClassOf("LLVMVectorOfAnyPointersToElt")) {
+ ArgCodes.push_back(3 /*vAny*/);
+ ++NumInserted;
+ }
+ return;
+ }
+
+ unsigned Tmp = 0;
+ switch (getValueType(R->getValueAsDef("VT"))) {
+ default: break;
+ case MVT::iPTRAny:
+ ++Tmp;
+ LLVM_FALLTHROUGH;
+ case MVT::vAny:
+ ++Tmp;
+ LLVM_FALLTHROUGH;
+ case MVT::fAny:
+ ++Tmp;
+ LLVM_FALLTHROUGH;
+ case MVT::iAny:
+ ++Tmp;
+ LLVM_FALLTHROUGH;
+ case MVT::Any:
+ unsigned OriginalIdx = ArgCodes.size() - NumInserted;
+ assert(OriginalIdx >= Mapping.size());
+ Mapping.resize(OriginalIdx+1);
+ Mapping[OriginalIdx] = ArgCodes.size();
+ ArgCodes.push_back(Tmp);
+ break;
+ }
+}
+
#if defined(_MSC_VER) && !defined(__clang__)
#pragma optimize("",on)
#endif
@@ -363,6 +401,17 @@ static void ComputeFixedEncoding(const C
std::vector<unsigned char> &TypeSig) {
std::vector<unsigned char> ArgCodes;
+ // Add codes for any overloaded result VTs.
+ unsigned int NumInserted = 0;
+ SmallVector<unsigned char, 8> ArgMapping;
+ for (unsigned i = 0, e = Int.IS.RetVTs.size(); i != e; ++i)
+ UpdateArgCodes(Int.IS.RetTypeDefs[i], ArgCodes, NumInserted, ArgMapping);
+
+ // Add codes for any overloaded operand VTs.
+ for (unsigned i = 0, e = Int.IS.ParamTypeDefs.size(); i != e; ++i)
+ UpdateArgCodes(Int.IS.ParamTypeDefs[i], ArgCodes, NumInserted, ArgMapping);
+
+ unsigned NextArgCode = 0;
if (Int.IS.RetVTs.empty())
TypeSig.push_back(IIT_Done);
else if (Int.IS.RetVTs.size() == 1 &&
@@ -382,11 +431,13 @@ static void ComputeFixedEncoding(const C
}
for (unsigned i = 0, e = Int.IS.RetVTs.size(); i != e; ++i)
- EncodeFixedType(Int.IS.RetTypeDefs[i], ArgCodes, TypeSig);
+ EncodeFixedType(Int.IS.RetTypeDefs[i], ArgCodes, NextArgCode, TypeSig,
+ ArgMapping);
}
for (unsigned i = 0, e = Int.IS.ParamTypeDefs.size(); i != e; ++i)
- EncodeFixedType(Int.IS.ParamTypeDefs[i], ArgCodes, TypeSig);
+ EncodeFixedType(Int.IS.ParamTypeDefs[i], ArgCodes, NextArgCode, TypeSig,
+ ArgMapping);
}
static void printIITEntry(raw_ostream &OS, unsigned char X) {
More information about the llvm-commits
mailing list