Skip to content

Commit d719b5d

Browse files
committed
wip
1 parent 312fe80 commit d719b5d

File tree

4 files changed

+26633
-121
lines changed

4 files changed

+26633
-121
lines changed

source/slang/core.meta.slang

+122-113
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ interface IArithmetic : IComparable
161161

162162
__init(int val);
163163

164-
/// Initialize from the same type.
164+
/// Initialize from the same type.
165165
__init(This value);
166166
}
167167

@@ -2484,47 +2484,52 @@ ${{{{
24842484

24852485
for (auto op : intrinsicUnaryOps)
24862486
{
2487-
for (auto type : kBaseTypes)
2487+
if (!op.interface)
24882488
{
2489-
if ((type.flags & op.flags) == 0)
2490-
continue;
2489+
for (auto type : kBaseTypes)
2490+
{
2491+
if ((type.flags & op.flags) == 0)
2492+
continue;
24912493

2492-
char const* resultType = type.name;
2493-
if (op.flags & BOOL_RESULT) resultType = "bool";
2494+
char const* resultType = type.name;
2495+
if (op.flags & BOOL_RESULT) resultType = "bool";
24942496

2495-
// scalar version
2496-
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << type.name << " value);\n";
2497-
sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " __" << op.funcName << "(" << type.name << " value);\n";
2497+
// scalar version
2498+
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << type.name << " value);\n";
2499+
sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " __" << op.funcName << "(" << type.name << " value);\n";
24982500

2499-
// vector version
2500-
sb << "__generic<let N : int> ";
2501-
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << "vector<" << type.name << ",N> value);\n";
2501+
// vector version
2502+
sb << "__generic<let N : int> ";
2503+
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << "vector<" << type.name << ",N> value);\n";
25022504

2503-
// matrix version
2504-
sb << "__generic<let N : int, let M : int> ";
2505-
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << "matrix<" << type.name << ",N,M> value);\n";
2505+
// matrix version
2506+
sb << "__generic<let N : int, let M : int, let L : int> ";
2507+
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M,L> operator" << op.opName << "(" << "matrix<" << type.name << ",N,M,L> value);\n";
2508+
}
25062509
}
2507-
2508-
// Synthesize generic versions
2509-
if(op.interface)
2510+
else
25102511
{
2512+
// Synthesize generic versions
25112513
char const* resultType = "T";
25122514
if (op.flags & BOOL_RESULT) resultType = "bool";
25132515

25142516
// scalar version
25152517
sb << "__generic<T : " << op.interface << ">\n";
25162518
sb << "[OverloadRank(10)]";
2517-
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << "T value);\n";
2519+
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(T value);\n";
2520+
2521+
sb << "__generic<T : " << op.interface << ">\n";
2522+
sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " __" << op.funcName << "(T value);\n";
25182523

25192524
// vector version
25202525
sb << "__generic<T : " << op.interface << ", let N : int> ";
25212526
sb << "[OverloadRank(10)]";
25222527
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(vector<T,N> value);\n";
25232528

25242529
// matrix version
2525-
sb << "__generic<T : " << op.interface << ", let N : int, let M : int> ";
2530+
sb << "__generic<T : " << op.interface << ", let N : int, let M : int, let L : int> ";
25262531
sb << "[OverloadRank(10)]";
2527-
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(matrix<T,N,M> value);\n";
2532+
sb << "__prefix __intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M,L> operator" << op.opName << "(matrix<T,N,M,L> value);\n";
25282533
}
25292534
}
25302535

@@ -2612,7 +2617,7 @@ vector<T,N> operator$(op.name)(in out vector<T,N> value)
26122617
$(fixity.qual)
26132618
__generic<T : __BuiltinArithmeticType, let R : int, let C : int, let L : int>
26142619
[__unsafeForceInlineEarly]
2615-
matrix<T,R,C> operator$(op.name)(in out matrix<T,R,C,L> value)
2620+
matrix<T,R,C,L> operator$(op.name)(in out matrix<T,R,C,L> value)
26162621
{$(fixity.bodyPrefix) value = value $(op.binOp) T(1); return $(fixity.returnVal); }
26172622

26182623
$(fixity.qual)
@@ -2626,90 +2631,91 @@ ${{{{
26262631

26272632
for (auto op : intrinsicBinaryOps)
26282633
{
2629-
for (auto type : kBaseTypes)
2634+
if(!op.interface)
26302635
{
2631-
if ((type.flags & op.flags) == 0)
2632-
continue;
2633-
2634-
char const* leftType = type.name;
2635-
char const* rightType = leftType;
2636-
char const* resultType = leftType;
2637-
2638-
if (op.flags & BOOL_RESULT) resultType = "bool";
2639-
2640-
// TODO: We should handle a `SHIFT` flag on the op
2641-
// by changing `rightType` to `int` in order to
2642-
// account for the fact that the shift amount should
2643-
// always have a fixed type independent of the LHS.
2644-
//
2645-
// (It is unclear why this change hadn't been made
2646-
// already, so it is possible that such a change
2647-
// breaks overload resolution or other parts of
2648-
// the compiler)
2649-
2650-
// scalar version
2651-
sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << leftType << " left, " << rightType << " right);\n";
2652-
sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " __" << op.funcName << "(" << leftType << " left, " << rightType << " right);\n";
2653-
2654-
// vector version
2655-
sb << "__generic<let N : int> ";
2656-
sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(vector<" << leftType << ",N> left, vector<" << rightType << ",N> right);\n";
2657-
2658-
// matrix version
2659-
sb << "__generic<let N : int, let M : int> ";
2660-
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(matrix<" << leftType << ",N,M> left, matrix<" << rightType << ",N,M> right);\n";
2661-
2662-
// We currently synthesize addiitonal overloads
2663-
// for the case where one or the other operand
2664-
// is a scalar. This choice serves a few purposes:
2665-
//
2666-
// 1. It avoids introducing scalar-to-vector or
2667-
// scalar-to-matrix promotions before the operator,
2668-
// which might allow some back ends to produce
2669-
// more optimal code.
2670-
//
2671-
// 2. It avoids concerns about making overload resolution
2672-
// and the inference rules for `N` and `M` able to
2673-
// handle the mixed vector/scalar or matrix/scalar case.
2674-
//
2675-
// 3. Having explicit overloads for the matrix/scalar cases
2676-
// here means that we do *not* need to support a general
2677-
// implicit conversion from scalars to matrices, unless
2678-
// we decide we want to.
2679-
//
2680-
// Note: Case (2) of the motivation shouldn't really apply
2681-
// any more, because we end up having to support similar
2682-
// inteference for built-in binary math functions where
2683-
// vectors and scalars might be combined (and where defining
2684-
// additional overloads to cover all the combinations doesn't
2685-
// seem practical or desirable).
2686-
//
2687-
// TODO: We should consider whether dropping these extra
2688-
// overloads is possible and worth it. The optimization
2689-
// concern (1) could possibly be addressed in specific
2690-
// back-ends. The issue (3) about not wanting to support
2691-
// implicit scalar-to-matrix conversion may be moot if
2692-
// we end up needing to support mixed scalar/matrix input
2693-
// for builtin in non-operator functions anyway.
2694-
2695-
// scalar-vector and scalar-matrix
2696-
sb << "__generic<let N : int> ";
2697-
sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << leftType << " left, vector<" << rightType << ",N> right);\n";
2698-
2699-
sb << "__generic<let N : int, let M : int> ";
2700-
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << leftType << " left, matrix<" << rightType << ",N,M> right);\n";
2701-
2702-
// vector-scalar and matrix-scalar
2703-
sb << "__generic<let N : int> ";
2704-
sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(vector<" << leftType << ",N> left, " << rightType << " right);\n";
2705-
2706-
sb << "__generic<let N : int, let M : int> ";
2707-
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(matrix<" << leftType << ",N,M> left, " << rightType << " right);\n";
2636+
for (auto type : kBaseTypes)
2637+
{
2638+
if ((type.flags & op.flags) == 0)
2639+
continue;
2640+
2641+
char const* leftType = type.name;
2642+
char const* rightType = leftType;
2643+
char const* resultType = leftType;
2644+
2645+
if (op.flags & BOOL_RESULT) resultType = "bool";
2646+
2647+
// TODO: We should handle a `SHIFT` flag on the op
2648+
// by changing `rightType` to `int` in order to
2649+
// account for the fact that the shift amount should
2650+
// always have a fixed type independent of the LHS.
2651+
//
2652+
// (It is unclear why this change hadn't been made
2653+
// already, so it is possible that such a change
2654+
// breaks overload resolution or other parts of
2655+
// the compiler)
2656+
2657+
// scalar version
2658+
sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << leftType << " left, " << rightType << " right);\n";
2659+
2660+
// vector version
2661+
sb << "__generic<let N : int> ";
2662+
sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(vector<" << leftType << ",N> left, vector<" << rightType << ",N> right);\n";
2663+
2664+
// matrix version
2665+
sb << "__generic<let N : int, let M : int, let L : int> ";
2666+
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M,L> operator" << op.opName << "(matrix<" << leftType << ",N,M,L> left, matrix<" << rightType << ",N,M,L> right);\n";
2667+
2668+
// We currently synthesize addiitonal overloads
2669+
// for the case where one or the other operand
2670+
// is a scalar. This choice serves a few purposes:
2671+
//
2672+
// 1. It avoids introducing scalar-to-vector or
2673+
// scalar-to-matrix promotions before the operator,
2674+
// which might allow some back ends to produce
2675+
// more optimal code.
2676+
//
2677+
// 2. It avoids concerns about making overload resolution
2678+
// and the inference rules for `N` and `M` able to
2679+
// handle the mixed vector/scalar or matrix/scalar case.
2680+
//
2681+
// 3. Having explicit overloads for the matrix/scalar cases
2682+
// here means that we do *not* need to support a general
2683+
// implicit conversion from scalars to matrices, unless
2684+
// we decide we want to.
2685+
//
2686+
// Note: Case (2) of the motivation shouldn't really apply
2687+
// any more, because we end up having to support similar
2688+
// inteference for built-in binary math functions where
2689+
// vectors and scalars might be combined (and where defining
2690+
// additional overloads to cover all the combinations doesn't
2691+
// seem practical or desirable).
2692+
//
2693+
// TODO: We should consider whether dropping these extra
2694+
// overloads is possible and worth it. The optimization
2695+
// concern (1) could possibly be addressed in specific
2696+
// back-ends. The issue (3) about not wanting to support
2697+
// implicit scalar-to-matrix conversion may be moot if
2698+
// we end up needing to support mixed scalar/matrix input
2699+
// for builtin in non-operator functions anyway.
2700+
2701+
// scalar-vector and scalar-matrix
2702+
sb << "__generic<let N : int> ";
2703+
sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << leftType << " left, vector<" << rightType << ",N> right);\n";
2704+
2705+
sb << "__generic<let N : int, let M : int, let L : int> ";
2706+
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M,L> operator" << op.opName << "(" << leftType << " left, matrix<" << rightType << ",N,M,L> right);\n";
2707+
2708+
// vector-scalar and matrix-scalar
2709+
sb << "__generic<let N : int> ";
2710+
sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(vector<" << leftType << ",N> left, " << rightType << " right);\n";
2711+
2712+
sb << "__generic<let N : int, let M : int, let L : int> ";
2713+
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M,L> operator" << op.opName << "(matrix<" << leftType << ",N,M,L> left, " << rightType << " right);\n";
2714+
}
27082715
}
2709-
2710-
// Synthesize generic versions
2711-
if(op.interface)
2716+
else
27122717
{
2718+
// Synthesize generic versions
27132719
char const* leftType = "T";
27142720
char const* rightType = leftType;
27152721
char const* resultType = leftType;
@@ -2721,34 +2727,37 @@ for (auto op : intrinsicBinaryOps)
27212727
sb << "__generic<T : " << op.interface << ">\n";
27222728
sb << "[OverloadRank(10)]";
27232729
sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << leftType << " left, " << rightType << " right);\n";
2730+
2731+
sb << "__generic<T : " << op.interface << ">\n";
2732+
sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " __" << op.funcName << "(" << leftType << " left, " << rightType << " right);\n";
27242733

27252734
// vector version
27262735
sb << "__generic<T : " << op.interface << ", let N : int> ";
27272736
sb << "[OverloadRank(10)]";
27282737
sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(vector<" << leftType << ",N> left, vector<" << rightType << ",N> right);\n";
27292738

27302739
// matrix version
2731-
sb << "__generic<T : " << op.interface << ", let N : int, let M : int> ";
2740+
sb << "__generic<T : " << op.interface << ", let N : int, let M : int, let L : int> ";
27322741
sb << "[OverloadRank(10)]";
2733-
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(matrix<" << leftType << ",N,M> left, matrix<" << rightType << ",N,M> right);\n";
2742+
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M,L> operator" << op.opName << "(matrix<" << leftType << ",N,M,L> left, matrix<" << rightType << ",N,M,L> right);\n";
27342743

27352744
// scalar-vector and scalar-matrix
27362745
sb << "__generic<T : " << op.interface << ", let N : int> ";
27372746
sb << "[OverloadRank(10)]";
27382747
sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << leftType << " left, vector<" << rightType << ",N> right);\n";
27392748

2740-
sb << "__generic<T : " << op.interface << ", let N : int, let M : int> ";
2749+
sb << "__generic<T : " << op.interface << ", let N : int, let M : int, let L: int> ";
27412750
sb << "[OverloadRank(10)]";
2742-
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << leftType << " left, matrix<" << rightType << ",N,M> right);\n";
2751+
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M,L> operator" << op.opName << "(" << leftType << " left, matrix<" << rightType << ",N,M,L> right);\n";
27432752

27442753
// vector-scalar and matrix-scalar
27452754
sb << "__generic<T : " << op.interface << ", let N : int> ";
27462755
sb << "[OverloadRank(10)]";
27472756
sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(vector<" << leftType << ",N> left, " << rightType << " right);\n";
27482757

2749-
sb << "__generic<T : " << op.interface << ", let N : int, let M : int> ";
2758+
sb << "__generic<T : " << op.interface << ", let N : int, let M : int, let L : int> ";
27502759
sb << "[OverloadRank(10)]";
2751-
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(matrix<" << leftType << ",N,M> left, " << rightType << " right);\n";
2760+
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M,L> operator" << op.opName << "(matrix<" << leftType << ",N,M,L> left, " << rightType << " right);\n";
27522761
}
27532762
}
27542763

@@ -2888,17 +2897,17 @@ ${{{{
28882897
return left;
28892898
}
28902899

2891-
__generic<T : $(op.interface), let R : int, let C : int, let Layout : int>
2900+
__generic<T : $(op.interface), let R : int, let C : int, let L : int>
28922901
[__unsafeForceInlineEarly]
2893-
matrix<T,R,C> operator$(op.name)=(in out matrix<T,R,C,Layout> left, matrix<T,R,C> right)
2902+
matrix<T,R,C,L> operator$(op.name)=(in out matrix<T,R,C,L> left, matrix<T,R,C,L> right)
28942903
{
28952904
left = left $(op.name) right;
28962905
return left;
28972906
}
28982907

2899-
__generic<T : $(op.interface), let R : int, let C : int, let Layout : int>
2908+
__generic<T : $(op.interface), let R : int, let C : int, let L : int>
29002909
[__unsafeForceInlineEarly]
2901-
matrix<T,R,C> operator$(op.name)=(in out matrix<T,R,C, Layout> left, T right)
2910+
matrix<T,R,C,L> operator$(op.name)=(in out matrix<T,R,C,L> left, T right)
29022911
{
29032912
left = left $(op.name) right;
29042913
return left;

0 commit comments

Comments
 (0)