@@ -26,24 +26,60 @@ namespace Slang
26
26
// / Note: this currently does not include PtrTypeBase.
27
27
Type* getPointedToTypeIfCanImplicitDeref (Type* type);
28
28
29
+ inline int getIntValueBitSize (IntegerLiteralValue val)
30
+ {
31
+ uint64_t v = val > 0 ? (uint64_t )val : (uint64_t )-val;
32
+ int result = 1 ;
33
+ while (v >>= 1 )
34
+ {
35
+ result++;
36
+ }
37
+ return result;
38
+ }
39
+
29
40
// A flat representation of basic types (scalars, vectors and matrices)
30
41
// that can be used as lookup key in caches
31
- enum class BasicTypeKey : uint16_t
42
+ struct BasicTypeKey
32
43
{
33
- Invalid = 0xffff , // /< Value that can never be a valid type
44
+ uint32_t baseType : 8 ;
45
+ uint32_t dim1 : 4 ;
46
+ uint32_t dim2 : 4 ;
47
+ uint32_t knownConstantBitCount : 8 ;
48
+ uint32_t knownNegative : 1 ;
49
+ uint32_t reserved : 7 ;
50
+ uint32_t getRaw () const
51
+ {
52
+ uint32_t val;
53
+ memcpy (&val, this , sizeof (uint32_t ));
54
+ return val;
55
+ }
56
+ bool operator ==(BasicTypeKey other) const
57
+ {
58
+ return getRaw () == other.getRaw ();
59
+ }
60
+ static BasicTypeKey invalid () { return BasicTypeKey{ 0xff , 0 , 0 }; }
34
61
};
35
62
36
63
SLANG_FORCE_INLINE BasicTypeKey makeBasicTypeKey (BaseType baseType, IntegerLiteralValue dim1 = 0 , IntegerLiteralValue dim2 = 0 )
37
64
{
38
65
SLANG_ASSERT (dim1 >= 0 && dim2 >= 0 );
39
- return BasicTypeKey (( uint8_t (baseType) << 8 ) | ( uint8_t (dim1) << 4 ) | uint8_t (dim2)) ;
66
+ return BasicTypeKey{ uint8_t (baseType), uint8_t (dim1), uint8_t (dim2) } ;
40
67
}
41
68
42
- inline BasicTypeKey makeBasicTypeKey (Type* typeIn)
69
+ inline BasicTypeKey makeBasicTypeKey (Type* typeIn, Expr* exprIn = nullptr )
43
70
{
44
71
if (auto basicType = as<BasicExpressionType>(typeIn))
45
72
{
46
- return makeBasicTypeKey (basicType->baseType );
73
+ auto rs = makeBasicTypeKey (basicType->baseType );
74
+ if (auto constInt = as<IntegerLiteralExpr>(exprIn))
75
+ {
76
+ if (constInt->value < 0 )
77
+ {
78
+ rs.knownNegative = 1 ;
79
+ }
80
+ rs.knownConstantBitCount = getIntValueBitSize (constInt->value );
81
+ }
82
+ return rs;
47
83
}
48
84
else if (auto vectorType = as<VectorExpressionType>(typeIn))
49
85
{
@@ -68,7 +104,7 @@ namespace Slang
68
104
}
69
105
}
70
106
}
71
- return BasicTypeKey::Invalid ;
107
+ return BasicTypeKey::invalid () ;
72
108
}
73
109
74
110
struct BasicTypeKeyPair
@@ -77,11 +113,11 @@ namespace Slang
77
113
bool operator ==(const BasicTypeKeyPair& rhs) const { return type1 == rhs.type1 && type2 == rhs.type2 ; }
78
114
bool operator !=(const BasicTypeKeyPair& rhs) const { return !(*this == rhs); }
79
115
80
- bool isValid () const { return type1 != BasicTypeKey::Invalid && type2 != BasicTypeKey::Invalid ; }
116
+ bool isValid () const { return type1. getRaw () != BasicTypeKey::invalid (). getRaw () && type2. getRaw () != BasicTypeKey::invalid (). getRaw () ; }
81
117
82
118
HashCode getHashCode ()
83
119
{
84
- return HashCode ( int ( type1) << 16 | int ( type2));
120
+ return combineHash ( type1. getRaw (), type2. getRaw ( ));
85
121
}
86
122
};
87
123
@@ -95,25 +131,25 @@ namespace Slang
95
131
}
96
132
HashCode getHashCode ()
97
133
{
98
- return HashCode ((( int )(UInt64 )(void *)(operatorName) << 16 ) ^ ( int ( args[0 ]) << 8 ) ^ ( int ( args[1 ]) ));
134
+ return combineHash (( int )(UInt64 )(void *)(operatorName), args[0 ]. getRaw (), args[1 ]. getRaw ( ));
99
135
}
100
136
bool fromOperatorExpr (OperatorExpr* opExpr)
101
137
{
102
138
// First, lets see if the argument types are ones
103
139
// that we can encode in our space of keys.
104
- args[0 ] = BasicTypeKey::Invalid ;
105
- args[1 ] = BasicTypeKey::Invalid ;
140
+ args[0 ] = BasicTypeKey::invalid () ;
141
+ args[1 ] = BasicTypeKey::invalid () ;
106
142
if (opExpr->arguments .getCount () > 2 )
107
143
return false ;
108
144
109
145
for (Index i = 0 ; i < opExpr->arguments .getCount (); i++)
110
146
{
111
- auto key = makeBasicTypeKey (opExpr->arguments [i]->type .Ptr ());
112
- if (key == BasicTypeKey::Invalid )
147
+ auto key = makeBasicTypeKey (opExpr->arguments [i]->type .Ptr (), opExpr-> arguments [i] );
148
+ if (key. getRaw () == BasicTypeKey::invalid (). getRaw () )
113
149
{
114
150
return false ;
115
151
}
116
- args[i]= key;
152
+ args[i] = key;
117
153
}
118
154
119
155
// Next, lets see if we can find an intrinsic opcode
@@ -136,7 +172,7 @@ namespace Slang
136
172
// Look at a candidate definition to be called and
137
173
// see if it gives us a key to work with.
138
174
//
139
- Decl* funcDecl = overloadedBase-> lookupResult2 . item .declRef .decl ;
175
+ Decl* funcDecl = item.declRef .decl ;
140
176
if (auto genDecl = as<GenericDecl>(funcDecl))
141
177
funcDecl = genDecl->inner ;
142
178
@@ -783,6 +819,9 @@ namespace Slang
783
819
ConversionCost getImplicitConversionCost (
784
820
Decl* decl);
785
821
822
+ ConversionCost getImplicitConversionCostWithKnownArg (Decl* decl, Type* toType, Expr* arg);
823
+
824
+
786
825
BuiltinConversionKind getImplicitConversionBuiltinKind (
787
826
Decl* decl);
788
827
0 commit comments