@@ -51,30 +51,97 @@ BUILTIN_CAST_OR_BITCAST_OPERATION(SExtOrBitCast, "sextOrBitCast", "n")
51
51
#undef BUILTIN_CAST_OR_BITCAST_OPERATION
52
52
53
53
// / Binary operations have type (T,T) -> T.
54
+ // /
55
+ // / We define two different sorts of operations varying when T is static,
56
+ // / specifically:
57
+ // /
58
+ // / 1. Overloaded statically typed operations. E.x:
59
+ // /
60
+ // / builtin "add_Vec4xInt32"(Vec4xInt32, Vec4xInt32) : Vec4xInt32.
61
+ // /
62
+ // / 2. Polymorphic typed operations that are valid only in raw SIL. By the time
63
+ // / diagnostic constant propagation runs, these must have as its operand a
64
+ // / fully specialized type. If the builtin has a type that is not one of its
65
+ // / overloaded types, diagnostic constant propagation will emit a diagnostic
66
+ // / saying the builtin's type has not been fully resolved. Otherwise,
67
+ // / diagnostic constant propagation will transform the builtin to the
68
+ // / relevant static overloaded builtin form. E.x.:
69
+ // /
70
+ // / builtin "add"(Self, Self) : Self // *error*
71
+ // /
72
+ // / OR
73
+ // /
74
+ // / builtin "generic_add"(Vec4xInt32, Vec4xInt32) : Vec4xInt32
75
+ // / ->
76
+ // / builtin "add_Vec4xInt32"(Vec4xInt32, Vec4xInt32) : Vec4xInt32
77
+ // /
78
+ // / NOTE: If a polymorphic typed operation is not static by the time guaranteed
79
+ // / constant propagation runs, we emit a diagnostic to inform the user (who is
80
+ // / assumed to be an expert user) to tell them the value was unspecialized. The
81
+ // / typical way this specialization occurs today is via transparent inlining
82
+ // / since the transparent inliner devirtualizes and specializes as it goes. Of
83
+ // / course this means mandatory inlining must /always/ occur before diagnostic
84
+ // / constant propagation.
85
+ // /
86
+ // / NOTE: Often times the builtin infrastructure wants to treat all
87
+ // / binary operation builtins generic or not the same way. To ensure
88
+ // / we support all use cases in the compiler, we do not declare the
89
+ // / operations as part of this builtin since often times this macro is
90
+ // / used to generic code. Instead, we stamp this out using the
91
+ // / overloaded_static, polymorphic, and all suffixed operations.
54
92
#ifndef BUILTIN_BINARY_OPERATION
55
- #define BUILTIN_BINARY_OPERATION (Id, Name, Attrs, Overload ) \
56
- BUILTIN (Id, Name, Attrs)
93
+ #define BUILTIN_BINARY_OPERATION (Id, Name, Attrs ) BUILTIN(Id, Name, Attrs)
57
94
#endif
58
- BUILTIN_BINARY_OPERATION (Add, " add" , " n" , IntegerOrVector)
59
- BUILTIN_BINARY_OPERATION(FAdd, " fadd" , " n" , FloatOrVector)
60
- BUILTIN_BINARY_OPERATION(And, " and" , " n" , IntegerOrVector)
61
- BUILTIN_BINARY_OPERATION(AShr, " ashr" , " n" , IntegerOrVector)
62
- BUILTIN_BINARY_OPERATION(LShr, " lshr" , " n" , IntegerOrVector)
63
- BUILTIN_BINARY_OPERATION(Or, " or" , " n" , IntegerOrVector)
64
- BUILTIN_BINARY_OPERATION(FDiv, " fdiv" , " n" , FloatOrVector)
65
- BUILTIN_BINARY_OPERATION(Mul, " mul" , " n" , IntegerOrVector)
66
- BUILTIN_BINARY_OPERATION(FMul, " fmul" , " n" , FloatOrVector)
67
- BUILTIN_BINARY_OPERATION(SDiv, " sdiv" , " n" , IntegerOrVector)
68
- BUILTIN_BINARY_OPERATION(ExactSDiv, " sdiv_exact" , " n" , IntegerOrVector)
69
- BUILTIN_BINARY_OPERATION(Shl, " shl" , " n" , IntegerOrVector)
70
- BUILTIN_BINARY_OPERATION(SRem, " srem" , " n" , IntegerOrVector)
71
- BUILTIN_BINARY_OPERATION(Sub, " sub" , " n" , IntegerOrVector)
72
- BUILTIN_BINARY_OPERATION(FSub, " fsub" , " n" , FloatOrVector)
73
- BUILTIN_BINARY_OPERATION(UDiv, " udiv" , " n" , IntegerOrVector)
74
- BUILTIN_BINARY_OPERATION(ExactUDiv, " udiv_exact" , " n" , IntegerOrVector)
75
- BUILTIN_BINARY_OPERATION(URem, " urem" , " n" , Integer)
76
- BUILTIN_BINARY_OPERATION(FRem, " frem" , " n" , FloatOrVector)
77
- BUILTIN_BINARY_OPERATION(Xor, " xor" , " n" , IntegerOrVector)
95
+
96
+ #ifdef BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR
97
+ #error "Do not define BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR before including this .def file"
98
+ #endif
99
+
100
+ #define BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR (NAME ) #NAME
101
+
102
+ #ifndef BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC
103
+ #define BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC (Id, Name, Attrs, Overload ) \
104
+ BUILTIN_BINARY_OPERATION (Id, Name, Attrs)
105
+ #endif
106
+
107
+ #ifndef BUILTIN_BINARY_OPERATION_POLYMORPHIC
108
+ #define BUILTIN_BINARY_OPERATION_POLYMORPHIC (Id, Name, Attrs ) \
109
+ BUILTIN_BINARY_OPERATION (Id, Name, Attrs)
110
+ #endif
111
+
112
+ // TODO: This needs a better name. We stringify generic_ in *_{OVERLOADED_STATIC,POLYMORPHIC}
113
+ #ifndef BUILTIN_BINARY_OPERATION_ALL
114
+ #define BUILTIN_BINARY_OPERATION_ALL (Id, Name, Attrs, Overload ) \
115
+ BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC (Id, BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR(Name), Attrs, Overload) \
116
+ BUILTIN_BINARY_OPERATION_POLYMORPHIC(Generic##Id, BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR(generic_##Name), Attrs)
117
+ #endif
118
+
119
+ // NOTE: Here we need our name field to be bare. We stringify them as
120
+ // appropriately in BUILTIN_BINARY_OPERATION_{OVERLOADED_STATIC,POLYMORPHIC}.
121
+ BUILTIN_BINARY_OPERATION_ALL (Add, add, " n" , IntegerOrVector)
122
+ BUILTIN_BINARY_OPERATION_ALL(FAdd, fadd, " n" , FloatOrVector)
123
+ BUILTIN_BINARY_OPERATION_ALL(And, and , " n" , IntegerOrVector)
124
+ BUILTIN_BINARY_OPERATION_ALL(AShr, ashr, " n" , IntegerOrVector)
125
+ BUILTIN_BINARY_OPERATION_ALL(LShr, lshr, " n" , IntegerOrVector)
126
+ BUILTIN_BINARY_OPERATION_ALL(Or, or , " n" , IntegerOrVector)
127
+ BUILTIN_BINARY_OPERATION_ALL(FDiv, fdiv, " n" , FloatOrVector)
128
+ BUILTIN_BINARY_OPERATION_ALL(Mul, mul, " n" , IntegerOrVector)
129
+ BUILTIN_BINARY_OPERATION_ALL(FMul, fmul, " n" , FloatOrVector)
130
+ BUILTIN_BINARY_OPERATION_ALL(SDiv, sdiv, " n" , IntegerOrVector)
131
+ BUILTIN_BINARY_OPERATION_ALL(ExactSDiv, sdiv_exact, " n" , IntegerOrVector)
132
+ BUILTIN_BINARY_OPERATION_ALL(Shl, shl, " n" , IntegerOrVector)
133
+ BUILTIN_BINARY_OPERATION_ALL(SRem, srem, " n" , IntegerOrVector)
134
+ BUILTIN_BINARY_OPERATION_ALL(Sub, sub, " n" , IntegerOrVector)
135
+ BUILTIN_BINARY_OPERATION_ALL(FSub, fsub, " n" , FloatOrVector)
136
+ BUILTIN_BINARY_OPERATION_ALL(UDiv, udiv, " n" , IntegerOrVector)
137
+ BUILTIN_BINARY_OPERATION_ALL(ExactUDiv, udiv_exact, " n" , IntegerOrVector)
138
+ BUILTIN_BINARY_OPERATION_ALL(URem, urem, " n" , Integer)
139
+ BUILTIN_BINARY_OPERATION_ALL(FRem, frem, " n" , FloatOrVector)
140
+ BUILTIN_BINARY_OPERATION_ALL(Xor, xor , " n" , IntegerOrVector)
141
+ #undef BUILTIN_BINARY_OPERATION_ALL
142
+ #undef BUILTIN_BINARY_OPERATION_POLYMORPHIC
143
+ #undef BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC
144
+ #undef BUILTIN_BINARY_OPERATION_GENERIC_HELPER_STR
78
145
#undef BUILTIN_BINARY_OPERATION
79
146
80
147
// / These builtins are analogous the similarly named llvm intrinsics. The
0 commit comments