@@ -258,6 +258,7 @@ _Py_uop_sym_set_type(JitOptContext *ctx, JitOptRef ref, PyTypeObject *typ)
258258 sym -> cls .version = 0 ;
259259 sym -> cls .type = typ ;
260260 return ;
261+ case JIT_SYM_PREDICATE_TAG :
261262 case JIT_SYM_TRUTHINESS_TAG :
262263 if (typ != & PyBool_Type ) {
263264 sym_set_bottom (ctx , sym );
@@ -319,6 +320,7 @@ _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptRef ref, unsigned int ver
319320 sym -> tag = JIT_SYM_TYPE_VERSION_TAG ;
320321 sym -> version .version = version ;
321322 return true;
323+ case JIT_SYM_PREDICATE_TAG :
322324 case JIT_SYM_TRUTHINESS_TAG :
323325 if (version != PyBool_Type .tp_version_tag ) {
324326 sym_set_bottom (ctx , sym );
@@ -385,6 +387,16 @@ _Py_uop_sym_set_const(JitOptContext *ctx, JitOptRef ref, PyObject *const_val)
385387 case JIT_SYM_UNKNOWN_TAG :
386388 make_const (sym , const_val );
387389 return ;
390+ case JIT_SYM_PREDICATE_TAG :
391+ if (!PyBool_Check (const_val ) ||
392+ (_Py_uop_sym_is_const (ctx , ref ) &&
393+ _Py_uop_sym_get_const (ctx , ref ) != const_val ))
394+ {
395+ sym_set_bottom (ctx , sym );
396+ return ;
397+ }
398+ make_const (sym , const_val );
399+ return ;
388400 case JIT_SYM_TRUTHINESS_TAG :
389401 if (!PyBool_Check (const_val ) ||
390402 (_Py_uop_sym_is_const (ctx , ref ) &&
@@ -538,6 +550,7 @@ _Py_uop_sym_get_type(JitOptRef ref)
538550 return _PyType_LookupByVersion (sym -> version .version );
539551 case JIT_SYM_TUPLE_TAG :
540552 return & PyTuple_Type ;
553+ case JIT_SYM_PREDICATE_TAG :
541554 case JIT_SYM_TRUTHINESS_TAG :
542555 return & PyBool_Type ;
543556 case JIT_SYM_COMPACT_INT :
@@ -566,6 +579,7 @@ _Py_uop_sym_get_type_version(JitOptRef ref)
566579 return Py_TYPE (sym -> value .value )-> tp_version_tag ;
567580 case JIT_SYM_TUPLE_TAG :
568581 return PyTuple_Type .tp_version_tag ;
582+ case JIT_SYM_PREDICATE_TAG :
569583 case JIT_SYM_TRUTHINESS_TAG :
570584 return PyBool_Type .tp_version_tag ;
571585 case JIT_SYM_COMPACT_INT :
@@ -759,6 +773,7 @@ _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef ref)
759773 }
760774 return ;
761775 case JIT_SYM_TUPLE_TAG :
776+ case JIT_SYM_PREDICATE_TAG :
762777 case JIT_SYM_TRUTHINESS_TAG :
763778 sym_set_bottom (ctx , sym );
764779 return ;
@@ -772,6 +787,64 @@ _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef ref)
772787 }
773788}
774789
790+ JitOptRef
791+ _Py_uop_sym_new_predicate (JitOptContext * ctx , JitOptRef subject_ref , JitOptRef constant_ref , JitOptPredicateKind kind , bool invert )
792+ {
793+ assert (_Py_uop_sym_is_const (ctx , constant_ref ));
794+
795+ JitOptSymbol * subject = PyJitRef_Unwrap (subject_ref );
796+ JitOptSymbol * constant = PyJitRef_Unwrap (constant_ref );
797+
798+ JitOptSymbol * res = sym_new (ctx );
799+ if (res == NULL ) {
800+ return out_of_space_ref (ctx );
801+ }
802+
803+ res -> tag = JIT_SYM_PREDICATE_TAG ;
804+ res -> predicate .invert = invert ;
805+ res -> predicate .kind = kind ;
806+ res -> predicate .subject = (uint16_t )(subject - allocation_base (ctx ));
807+ res -> predicate .constant = (uint16_t )(constant - allocation_base (ctx ));
808+
809+ return PyJitRef_Wrap (res );
810+ }
811+
812+ bool
813+ _Py_uop_sym_is_known_singleton (JitOptContext * ctx , JitOptRef ref )
814+ {
815+ if (_Py_uop_sym_is_safe_const (ctx , ref )) {
816+ PyObject * value = _Py_uop_sym_get_const (ctx , ref );
817+ return value == Py_None || value == Py_True || value == Py_False ;
818+ }
819+ return false;
820+ }
821+
822+ void
823+ _Py_uop_sym_apply_predicate_narrowing (JitOptContext * ctx , JitOptRef ref , bool branch_is_true )
824+ {
825+ JitOptSymbol * sym = PyJitRef_Unwrap (ref );
826+ if (sym -> tag != JIT_SYM_PREDICATE_TAG ) {
827+ return ;
828+ }
829+
830+ JitOptPredicate pred = sym -> predicate ;
831+ bool narrow = (branch_is_true && !pred .invert ) || (!branch_is_true && pred .invert );
832+ if (!narrow ) {
833+ return ;
834+ }
835+
836+ if (pred .kind == JIT_PRED_IS ) {
837+ JitOptRef subject_ref = PyJitRef_Wrap (allocation_base (ctx ) + pred .subject );
838+ JitOptRef constant_ref = PyJitRef_Wrap (allocation_base (ctx ) + pred .constant );
839+ PyObject * const_val = _Py_uop_sym_get_const (ctx , constant_ref );
840+ if (const_val == NULL ) {
841+ return ;
842+ }
843+ _Py_uop_sym_set_const (ctx , subject_ref , const_val );
844+ assert (_Py_uop_sym_is_safe_const (ctx , subject_ref ));
845+ }
846+ }
847+
775848JitOptRef
776849_Py_uop_sym_new_truthiness (JitOptContext * ctx , JitOptRef ref , bool truthy )
777850{
0 commit comments