Skip to content

Commit 7215a58

Browse files
committed
simplify: fully port IsTruthy to C + add emitGetLengthInt64 helper
IsTruthy now covers ALL 4 paths in C (no fallback): 1. Known immutable object → PyObject_IsTrue constant fold 2. TBool → PrimitiveCompare with Py_True 3. Collection (Tuple/List/Dict/Set/Unicode) → GetLength + CIntToCBool 4. TLongExact → PrimitiveCompare with _PyLong_GetZero() New helpers: emit_get_length_int64_c (loads ob_size/ma_used/used/length), simplify_env_emit_load_field, simplify_env_emit_cint_to_cbool.
1 parent f02c5d8 commit 7215a58

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

Python/jit/hir/simplify.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2786,8 +2786,7 @@ Register* simplifyInstr(Env& env, const Instr* instr) {
27862786
SimplifyEnv cenv = make_c_env();
27872787
auto *r = static_cast<Register*>(simplify_is_truthy_c(&cenv, instr));
27882788
sync_c_env(cenv);
2789-
if (r) return r;
2790-
return simplifyIsTruthy(env, instr);
2789+
return r;
27912790
}
27922791

27932792
// TODO(T255262756) - Enable this again. See P2169675076 and P2184559031 (same

Python/jit/hir/simplify_c.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,68 @@ void *simplify_env_emit_call_static_instr(SimplifyEnv *env, size_t n_operands,
131131
return instr;
132132
}
133133

134+
void *simplify_env_emit_load_field(SimplifyEnv *env, void *receiver,
135+
const char *name, intptr_t offset,
136+
HirType type, int borrowed) {
137+
extern void *hir_c_create_load_field(void *func, void *recv, const char *name,
138+
intptr_t offset, HirType type, int borrowed);
139+
void *instr = hir_c_create_load_field(env->func, receiver, name, offset, type, borrowed);
140+
return simplify_env_emit(env, instr);
141+
}
142+
143+
void *simplify_env_emit_cint_to_cbool(SimplifyEnv *env, void *src) {
144+
void *reg = hir_func_alloc_register(env->func);
145+
extern void *hir_c_create_cint_to_cbool(void *dst, void *src);
146+
void *instr = hir_c_create_cint_to_cbool(reg, src);
147+
return simplify_env_emit(env, instr);
148+
}
149+
150+
/* ---- emitGetLengthInt64 C helper ----
151+
* Returns ob_size/ma_used/used/length field as CInt64, or NULL. */
152+
static void *emit_get_length_int64_c(SimplifyEnv *env, void *obj) {
153+
HirType obj_type = hir_register_type(obj);
154+
HirType t_tuple_exact = HIR_TYPE_TUPLEEXACT;
155+
HirType t_cint64 = HIR_TYPE_CINT64;
156+
157+
#ifndef Py_GIL_DISABLED
158+
HirType t_list_exact = HIR_TYPE_SIMPLE(0x00000010000ULL, HIR_TYPE_LIFETIME_TOP);
159+
if (hir_type_is_subtype(obj_type, t_list_exact) ||
160+
hir_type_is_subtype(obj_type, t_tuple_exact)) {
161+
#else
162+
if (hir_type_is_subtype(obj_type, t_tuple_exact)) {
163+
#endif
164+
HirType unspec = hir_type_unspecialized(&obj_type);
165+
simplify_env_emit_use_type(env, obj, unspec);
166+
return simplify_env_emit_load_field(env, obj, "ob_size",
167+
(intptr_t)offsetof(PyVarObject, ob_size), t_cint64, 0);
168+
}
169+
170+
HirType t_unicode_exact = HIR_TYPE_UNICODEEXACT;
171+
#ifndef Py_GIL_DISABLED
172+
HirType t_dict_exact = HIR_TYPE_DICTEXACT;
173+
HirType t_set_exact = HIR_TYPE_SIMPLE(0x00000020000ULL, HIR_TYPE_LIFETIME_TOP);
174+
if (hir_type_is_subtype(obj_type, t_dict_exact)) {
175+
HirType unspec = hir_type_unspecialized(&obj_type);
176+
simplify_env_emit_use_type(env, obj, unspec);
177+
return simplify_env_emit_load_field(env, obj, "ma_used",
178+
(intptr_t)offsetof(PyDictObject, ma_used), t_cint64, 0);
179+
}
180+
if (hir_type_is_subtype(obj_type, t_set_exact)) {
181+
HirType unspec = hir_type_unspecialized(&obj_type);
182+
simplify_env_emit_use_type(env, obj, unspec);
183+
return simplify_env_emit_load_field(env, obj, "used",
184+
(intptr_t)offsetof(PySetObject, used), t_cint64, 0);
185+
}
186+
#endif
187+
if (hir_type_is_subtype(obj_type, t_unicode_exact)) {
188+
HirType unspec = hir_type_unspecialized(&obj_type);
189+
simplify_env_emit_use_type(env, obj, unspec);
190+
return simplify_env_emit_load_field(env, obj, "length",
191+
(intptr_t)offsetof(PyASCIIObject, length), t_cint64, 0);
192+
}
193+
return NULL;
194+
}
195+
134196
void *simplify_env_emit_check_neg(SimplifyEnv *env, void *src, void *frame_state) {
135197
extern void *hir_c_create_check_neg(void *func, void *src, void *fs);
136198
void *instr = hir_c_create_check_neg(env->func, src, frame_state);
@@ -286,6 +348,12 @@ void *simplify_is_truthy_c(SimplifyEnv *env, const void *instr) {
286348
return simplify_env_emit_primitive_compare(env, HIR_PCMP_Equal, input, right);
287349
}
288350

351+
/* Collection length path: emit GetLengthInt64 + CIntToCBool */
352+
void *size = emit_get_length_int64_c(env, input);
353+
if (size != NULL) {
354+
return simplify_env_emit_cint_to_cbool(env, size);
355+
}
356+
289357
/* TLongExact: compare with _PyLong_GetZero() */
290358
HirType t_long_exact = HIR_TYPE_LONGEXACT;
291359
if (hir_type_is_subtype(input_type, t_long_exact)) {

0 commit comments

Comments
 (0)