summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-check-conversion.cpp13
-rw-r--r--source/slang/slang-check-impl.h96
2 files changed, 50 insertions, 59 deletions
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp
index 412bdca38..f313c7913 100644
--- a/source/slang/slang-check-conversion.cpp
+++ b/source/slang/slang-check-conversion.cpp
@@ -750,16 +750,17 @@ namespace Slang
// As an optimization, we will maintain a cache of conversion results
// for basic types such as scalars and vectors.
//
- BasicTypeKey key1, key2;
- BasicTypeKeyPair cacheKey;
+
bool shouldAddToCache = false;
ConversionCost cost;
TypeCheckingCache* typeCheckingCache = getSession()->getTypeCheckingCache();
- if( key1.fromType(toType.Ptr()) && key2.fromType(fromType.Ptr()) )
- {
- cacheKey.type1 = key1;
- cacheKey.type2 = key2;
+ BasicTypeKeyPair cacheKey;
+ cacheKey.type1 = makeBasicTypeKey(toType.Ptr());
+ cacheKey.type2 = makeBasicTypeKey(fromType.Ptr());
+
+ if( cacheKey.isValid())
+ {
if (typeCheckingCache->conversionCostCache.TryGetValue(cacheKey, cost))
{
if (outCost)
diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h
index 78425b9ae..0cc9eb628 100644
--- a/source/slang/slang-check-impl.h
+++ b/source/slang/slang-check-impl.h
@@ -25,69 +25,56 @@ namespace Slang
// A flat representation of basic types (scalars, vectors and matrices)
// that can be used as lookup key in caches
- struct BasicTypeKey
+ enum class BasicTypeKey : uint8_t
{
- union
+ Invalid = 0xff, ///< Value that can never be a valid type
+ };
+
+ SLANG_FORCE_INLINE BasicTypeKey makeBasicTypeKey(BaseType baseType, IntegerLiteralValue dim1 = 1, IntegerLiteralValue dim2 = 1)
+ {
+ SLANG_ASSERT(dim1 > 0 && dim2 > 0);
+ return BasicTypeKey((uint8_t(baseType) << 4) | ((uint8_t(dim1) - 1) << 2) | (uint8_t(dim2) - 1));
+ }
+
+ inline BasicTypeKey makeBasicTypeKey(Type* typeIn)
+ {
+ if (auto basicType = as<BasicExpressionType>(typeIn))
{
- struct
- {
- unsigned char type : 4;
- unsigned char dim1 : 2;
- unsigned char dim2 : 2;
- } data;
- unsigned char aggVal;
- };
- bool fromType(Type* typeIn)
+ return makeBasicTypeKey(basicType->baseType);
+ }
+ else if (auto vectorType = as<VectorExpressionType>(typeIn))
{
- aggVal = 0;
- if (auto basicType = as<BasicExpressionType>(typeIn))
+ if (auto elemCount = as<ConstantIntVal>(vectorType->elementCount))
{
- data.type = (unsigned char)basicType->baseType;
- data.dim1 = data.dim2 = 0;
+ auto elemBasicType = as<BasicExpressionType>(vectorType->elementType);
+ return makeBasicTypeKey(elemBasicType->baseType, elemCount->value);
}
- else if (auto vectorType = as<VectorExpressionType>(typeIn))
- {
- if (auto elemCount = as<ConstantIntVal>(vectorType->elementCount))
- {
- data.dim1 = elemCount->value - 1;
- auto elementBasicType = as<BasicExpressionType>(vectorType->elementType);
- data.type = (unsigned char)elementBasicType->baseType;
- data.dim2 = 0;
- }
- else
- return false;
- }
- else if (auto matrixType = as<MatrixExpressionType>(typeIn))
+ }
+ else if (auto matrixType = as<MatrixExpressionType>(typeIn))
+ {
+ if (auto elemCount1 = as<ConstantIntVal>(matrixType->getRowCount()))
{
- if (auto elemCount1 = as<ConstantIntVal>(matrixType->getRowCount()))
+ if (auto elemCount2 = as<ConstantIntVal>(matrixType->getColumnCount()))
{
- if (auto elemCount2 = as<ConstantIntVal>(matrixType->getColumnCount()))
- {
- auto elemBasicType = as<BasicExpressionType>(matrixType->getElementType());
- data.type = (unsigned char)elemBasicType->baseType;
- data.dim1 = elemCount1->value - 1;
- data.dim2 = elemCount2->value - 1;
- }
+ auto elemBasicType = as<BasicExpressionType>(matrixType->getElementType());
+ return makeBasicTypeKey(elemBasicType->baseType, elemCount1->value, elemCount2->value);
}
- else
- return false;
}
- else
- return false;
- return true;
}
- };
+ return BasicTypeKey::Invalid;
+ }
struct BasicTypeKeyPair
{
BasicTypeKey type1, type2;
- bool operator == (BasicTypeKeyPair p)
- {
- return type1.aggVal == p.type1.aggVal && type2.aggVal == p.type2.aggVal;
- }
+ bool operator==(const BasicTypeKeyPair& rhs) const { return type1 == rhs.type1 && type2 == rhs.type2; }
+ bool operator!=(const BasicTypeKeyPair& rhs) const { return !(*this == rhs); }
+
+ bool isValid() const { return type1 != BasicTypeKey::Invalid && type2 != BasicTypeKey::Invalid; }
+
int GetHashCode()
{
- return combineHash(type1.aggVal, type2.aggVal);
+ return int(type1) << 16 | int(type2);
}
};
@@ -97,26 +84,29 @@ namespace Slang
BasicTypeKey args[2];
bool operator == (OperatorOverloadCacheKey key)
{
- return operatorName == key.operatorName && args[0].aggVal == key.args[0].aggVal
- && args[1].aggVal == key.args[1].aggVal;
+ return operatorName == key.operatorName && args[0] == key.args[0] && args[1] == key.args[1];
}
int GetHashCode()
{
- return ((int)(UInt64)(void*)(operatorName) << 16) ^ (args[0].aggVal << 8) ^ (args[1].aggVal);
+ return ((int)(UInt64)(void*)(operatorName) << 16) ^ (int(args[0]) << 8) ^ (int(args[1]));
}
bool fromOperatorExpr(OperatorExpr* opExpr)
{
// First, lets see if the argument types are ones
// that we can encode in our space of keys.
- args[0].aggVal = 0;
- args[1].aggVal = 0;
+ args[0] = BasicTypeKey::Invalid;
+ args[1] = BasicTypeKey::Invalid;
if (opExpr->Arguments.getCount() > 2)
return false;
for (Index i = 0; i < opExpr->Arguments.getCount(); i++)
{
- if (!args[i].fromType(opExpr->Arguments[i]->type.Ptr()))
+ auto key = makeBasicTypeKey(opExpr->Arguments[i]->type.Ptr());
+ if (key == BasicTypeKey::Invalid)
+ {
return false;
+ }
+ args[i]= key;
}
// Next, lets see if we can find an intrinsic opcode