Skip to content

Commit b1be41a

Browse files
rjmccallbob-wilson
authored andcommitted
Implement some more LLVM intrinsic type-decoding rules.
1 parent b45ca04 commit b1be41a

File tree

1 file changed

+114
-22
lines changed

1 file changed

+114
-22
lines changed

lib/AST/Builtins.cpp

Lines changed: 114 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,46 +1272,138 @@ swift::getLLVMIntrinsicIDForBuiltinWithOverflow(BuiltinValueKind ID) {
12721272
llvm_unreachable("Cannot convert the overflow builtin to llvm intrinsic.");
12731273
}
12741274

1275-
static Type DecodeIntrinsicType(ArrayRef<llvm::Intrinsic::IITDescriptor> &Table,
1276-
ArrayRef<Type> Tys, ASTContext &Context) {
1275+
namespace {
1276+
1277+
class IntrinsicTypeDecoder {
1278+
ArrayRef<llvm::Intrinsic::IITDescriptor> &Table;
1279+
ArrayRef<Type> TypeArguments;
1280+
ASTContext &Context;
1281+
public:
1282+
IntrinsicTypeDecoder(ArrayRef<llvm::Intrinsic::IITDescriptor> &table,
1283+
ArrayRef<Type> typeArguments, ASTContext &ctx)
1284+
: Table(table), TypeArguments(typeArguments), Context(ctx) {}
1285+
1286+
Type decodeImmediate();
1287+
1288+
/// Return the type argument at the given index.
1289+
Type getTypeArgument(unsigned index) {
1290+
if (index >= TypeArguments.size())
1291+
return Type();
1292+
return TypeArguments[index];
1293+
}
1294+
1295+
/// Create a pointer type.
1296+
Type makePointer(Type eltType, unsigned addrspace) {
1297+
// Reject non-default address space pointers.
1298+
if (addrspace)
1299+
return Type();
1300+
1301+
// For now, always ignore the element type and use RawPointer.
1302+
return Context.TheRawPointerType;
1303+
}
1304+
1305+
/// Create a vector type.
1306+
Type makeVector(Type eltType, unsigned width) {
1307+
return BuiltinVectorType::get(Context, eltType, width);
1308+
}
1309+
1310+
/// Return the first type or, if the second type is a vector type, a vector
1311+
/// of the first type of the same length as the second type.
1312+
Type maybeMakeVectorized(Type eltType, Type maybeVectorType) {
1313+
if (auto vectorType = maybeVectorType->getAs<BuiltinVectorType>()) {
1314+
return makeVector(eltType, vectorType->getNumElements());
1315+
}
1316+
return eltType;
1317+
}
1318+
};
1319+
1320+
} // end anonymous namespace
1321+
1322+
static Type DecodeIntrinsicType(ArrayRef<llvm::Intrinsic::IITDescriptor> &table,
1323+
ArrayRef<Type> typeArguments, ASTContext &ctx) {
1324+
return IntrinsicTypeDecoder(table, typeArguments, ctx).decodeImmediate();
1325+
}
1326+
1327+
Type IntrinsicTypeDecoder::decodeImmediate() {
12771328
typedef llvm::Intrinsic::IITDescriptor IITDescriptor;
12781329
IITDescriptor D = Table.front();
12791330
Table = Table.slice(1);
12801331
switch (D.Kind) {
1281-
default:
1282-
llvm_unreachable("Unhandled case");
1283-
case IITDescriptor::Half:
12841332
case IITDescriptor::MMX:
12851333
case IITDescriptor::Metadata:
1286-
case IITDescriptor::Vector:
12871334
case IITDescriptor::ExtendArgument:
12881335
case IITDescriptor::TruncArgument:
1336+
case IITDescriptor::HalfVecArgument:
12891337
case IITDescriptor::VarArg:
1338+
case IITDescriptor::Token:
1339+
case IITDescriptor::VecOfAnyPtrsToElt:
12901340
// These types cannot be expressed in swift yet.
12911341
return Type();
12921342

1293-
case IITDescriptor::Void: return TupleType::getEmpty(Context);
1294-
case IITDescriptor::Float: return Context.TheIEEE32Type;
1295-
case IITDescriptor::Double: return Context.TheIEEE64Type;
1296-
1343+
// Fundamental types.
1344+
case IITDescriptor::Void:
1345+
return TupleType::getEmpty(Context);
1346+
case IITDescriptor::Half:
1347+
return Context.TheIEEE16Type;
1348+
case IITDescriptor::Float:
1349+
return Context.TheIEEE32Type;
1350+
case IITDescriptor::Double:
1351+
return Context.TheIEEE64Type;
1352+
case IITDescriptor::Quad:
1353+
return Context.TheIEEE128Type;
12971354
case IITDescriptor::Integer:
12981355
return BuiltinIntegerType::get(D.Integer_Width, Context);
1299-
case IITDescriptor::Pointer:
1300-
if (D.Pointer_AddressSpace)
1301-
return Type(); // Reject non-default address space pointers.
1302-
1303-
// Decode but ignore the pointee. Just decode all IR pointers to unsafe
1304-
// pointer type.
1305-
(void)DecodeIntrinsicType(Table, Tys, Context);
1306-
return Context.TheRawPointerType;
1356+
1357+
// A vector of an immediate type.
1358+
case IITDescriptor::Vector: {
1359+
Type eltType = decodeImmediate();
1360+
if (!eltType) return Type();
1361+
return makeVector(eltType, D.Vector_Width);
1362+
}
1363+
1364+
// A pointer to an immediate type.
1365+
case IITDescriptor::Pointer: {
1366+
Type pointeeType = decodeImmediate();
1367+
if (!pointeeType) return Type();
1368+
return makePointer(pointeeType, D.Pointer_AddressSpace);
1369+
}
1370+
1371+
// A type argument.
13071372
case IITDescriptor::Argument:
1308-
if (D.getArgumentNumber() >= Tys.size())
1309-
return Type();
1310-
return Tys[D.getArgumentNumber()];
1373+
return getTypeArgument(D.getArgumentNumber());
1374+
1375+
// A pointer to a type argument.
1376+
case IITDescriptor::PtrToArgument: {
1377+
Type argType = getTypeArgument(D.getArgumentNumber());
1378+
if (!argType) return Type();
1379+
unsigned addrspace = 0; // An apparent limitation of LLVM.
1380+
return makePointer(argType, addrspace);
1381+
}
1382+
1383+
// A vector of the same width as a type argument.
1384+
case IITDescriptor::SameVecWidthArgument: {
1385+
Type maybeVectorType = getTypeArgument(D.getArgumentNumber());
1386+
if (!maybeVectorType) return Type();
1387+
Type eltType = decodeImmediate();
1388+
if (!eltType) return Type();
1389+
return maybeMakeVectorized(eltType, maybeVectorType);
1390+
}
1391+
1392+
// A pointer to the element type of a type argument, which must be a vector.
1393+
case IITDescriptor::PtrToElt: {
1394+
Type argType = getTypeArgument(D.getArgumentNumber());
1395+
if (!argType) return Type();
1396+
auto vecType = argType->getAs<BuiltinVectorType>();
1397+
if (!vecType) return Type();
1398+
unsigned addrspace = 0; // An apparent limitation of LLVM.
1399+
return makePointer(vecType->getElementType(), addrspace);
1400+
}
1401+
1402+
// A struct, which we translate as a tuple.
13111403
case IITDescriptor::Struct: {
13121404
SmallVector<TupleTypeElt, 5> Elts;
13131405
for (unsigned i = 0; i != D.Struct_NumElements; ++i) {
1314-
Type T = DecodeIntrinsicType(Table, Tys, Context);
1406+
Type T = decodeImmediate();
13151407
if (!T) return Type();
13161408

13171409
Elts.push_back(T);

0 commit comments

Comments
 (0)