@@ -1127,6 +1127,22 @@ def emit_specialized_int_is_true(self):
11271127 self ._emit_jump (lines )
11281128 return lines
11291129
1130+ def emit_specialized_int_is_zero (self ):
1131+ arg , = self ._get_args ()
1132+ result = self .insn [self .resindex ]
1133+ # Constant folding: if arg is a constant, evaluate at compile time
1134+ val = self ._get_constant_int_value (arg )
1135+ if val is not None :
1136+ lines = ["i%s = %d" % (result .index , int (val == 0 ))]
1137+ self ._emit_jump (lines )
1138+ return lines
1139+ lines = ["i%s = int(%s == 0)" % (
1140+ result .index ,
1141+ self ._get_as_unboxed (arg )
1142+ )]
1143+ self ._emit_jump (lines )
1144+ return lines
1145+
11301146 def emit_specialized_guard_class (self ):
11311147 lines = ['# guard_class, argument is already constant' ]
11321148 arg , = self ._get_args ()
@@ -1146,6 +1162,8 @@ def emit_specialized_getfield_raw_i(self):
11461162 self ._emit_jump (lines , constant_registers = self .constant_registers .union ({res }))
11471163 return lines
11481164 raise Unsupported
1165+ emit_specialized_getfield_raw_r = emit_specialized_getfield_raw_i
1166+ emit_specialized_getfield_raw_f = emit_specialized_getfield_raw_i
11491167
11501168 def emit_specialized_getfield_gc_i_pure (self ):
11511169 if self .insn [2 ].is_always_pure ():
@@ -1175,6 +1193,19 @@ def emit_specialized_getarrayitem_gc_i_pure(self):
11751193 emit_specialized_getarrayitem_gc_r_pure = emit_specialized_getarrayitem_gc_i_pure
11761194 emit_specialized_getarrayitem_gc_f_pure = emit_specialized_getarrayitem_gc_i_pure
11771195
1196+ def emit_specialized_getarrayitem_raw_i_pure (self ):
1197+ lines = []
1198+ arg , index , descr , res = self ._get_args_and_res ()
1199+ TYPE , ITEM = _get_ptrtype_itemtype_from_arraydescr (descr )
1200+ resultcast = _find_result_cast (ITEM )
1201+ lines .append ('%s = %sllmemory.cast_adr_to_ptr(support.int2adr(i%s), %s)[%s])' % (
1202+ self ._get_as_unboxed (res ), resultcast , arg .index , self ._add_global (TYPE ),
1203+ self ._get_as_unboxed (index )))
1204+ self ._emit_jump (lines , constant_registers = self .constant_registers .union ({res }))
1205+ return lines
1206+ emit_specialized_getarrayitem_raw_r_pure = emit_specialized_getarrayitem_raw_i_pure
1207+ emit_specialized_getarrayitem_raw_f_pure = emit_specialized_getarrayitem_raw_i_pure
1208+
11781209 def emit_specialized_getfield_gc_i (self ):
11791210 arg , descr = self ._get_args ()
11801211 res = self .insn [self .resindex ]
@@ -1430,6 +1461,14 @@ def emit_specialized_unicodelen(self):
14301461 self ._emit_jump (lines )
14311462 return lines
14321463
1464+ def emit_specialized_unicodegetitem (self ):
1465+ arg0 , arg1 = self ._get_args ()
1466+ result = self .insn [self .resindex ]
1467+ lines = ["i%s = ord(lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), r%d).chars[%s])" % (
1468+ result .index , arg0 .index , self ._get_as_unboxed (arg1 ))]
1469+ self ._emit_jump (lines )
1470+ return lines
1471+
14331472 def _get_type_prefix (self , arg ):
14341473 if isinstance (arg , Constant ) or isinstance (arg , Register ):
14351474 # TODO: this logic also works for the 'else' case. probably.
@@ -2039,23 +2078,64 @@ def emit_unspecialized_goto_if_not_comparison(self, name, symbol):
20392078 lines .append ("continue" )
20402079 return lines
20412080
2081+ def _emit_goto_if_not_int_comparison_fast (self , rop_name , py_op ):
2082+ """Generate fast-path code for goto_if_not_int_* that skips heapcache."""
2083+ lines = []
2084+ _ , arg0 , arg1 , arg2 = self .insn # left, right, label
2085+
2086+ target_pc = self .get_target_pc (arg2 )
2087+
2088+ # Handle constant folding case
2089+ self ._emit_n_ary_if ([arg0 , arg1 ], lines )
2090+ specializer = self .work_list .specialize_insn (
2091+ self .insn , self .constant_registers .union ({arg0 , arg1 }), self .orig_pc )
2092+ lines .append (" pc = %d" % (specializer .get_pc (),))
2093+ lines .append (" continue" )
2094+
2095+ # Fast-path: compute comparison and record directly, skip heapcache
2096+ self ._emit_sync_registers (lines )
2097+ box0 = self ._get_as_box_after_sync (arg0 )
2098+ box1 = self ._get_as_box_after_sync (arg1 )
2099+ lines .append ("_v0 = %s" % self ._get_as_unboxed_after_sync (arg0 ))
2100+ lines .append ("_v1 = %s" % self ._get_as_unboxed_after_sync (arg1 ))
2101+ lines .append ("_cond = int(_v0 %s _v1)" % py_op )
2102+ lines .append ("# fast-path: record comparison directly, skip heapcache" )
2103+ lines .append ("condbox = self.metainterp.history.record2_int(rop.%s, %s, %s, _cond)" % (
2104+ rop_name , box0 , box1 ))
2105+
2106+ # Call opimpl_goto_if_not for guard generation
2107+ lines .append ("self.opimpl_goto_if_not(condbox, %d, %d, replace=False)" % (target_pc , self .orig_pc ))
2108+ lines .append ("pc = self.pc" )
2109+ lines .append ("if pc == %s:" % (target_pc ,))
2110+ specializer = self .work_list .specialize_pc (
2111+ self .constant_registers , target_pc )
2112+ lines .append (" pc = %s" % (specializer .spec_pc ,))
2113+ lines .append ("else:" )
2114+ next_pc = self .work_list .pc_to_nextpc [self .orig_pc ]
2115+ specializer = self .work_list .specialize_pc (
2116+ self .constant_registers , next_pc )
2117+ lines .append (" assert self.pc == %s" % (specializer .orig_pc ,))
2118+ lines .append (" pc = %s" % (specializer .spec_pc ,))
2119+ lines .append ("continue" )
2120+ return lines
2121+
20422122 def emit_unspecialized_goto_if_not_int_lt (self ):
2043- return self .emit_unspecialized_goto_if_not_comparison ( "int_lt " , "<" )
2123+ return self ._emit_goto_if_not_int_comparison_fast ( "INT_LT " , "<" )
20442124
20452125 def emit_unspecialized_goto_if_not_int_gt (self ):
2046- return self .emit_unspecialized_goto_if_not_comparison ( "int_gt " , ">" )
2126+ return self ._emit_goto_if_not_int_comparison_fast ( "INT_GT " , ">" )
20472127
20482128 def emit_unspecialized_goto_if_not_int_le (self ):
2049- return self .emit_unspecialized_goto_if_not_comparison ( "int_le " , "<=" )
2129+ return self ._emit_goto_if_not_int_comparison_fast ( "INT_LE " , "<=" )
20502130
20512131 def emit_unspecialized_goto_if_not_int_ge (self ):
2052- return self .emit_unspecialized_goto_if_not_comparison ( "int_ge " , ">=" )
2132+ return self ._emit_goto_if_not_int_comparison_fast ( "INT_GE " , ">=" )
20532133
20542134 def emit_unspecialized_goto_if_not_int_ne (self ):
2055- return self .emit_unspecialized_goto_if_not_comparison ( "int_ne " , "!=" )
2135+ return self ._emit_goto_if_not_int_comparison_fast ( "INT_NE " , "!=" )
20562136
20572137 def emit_unspecialized_goto_if_not_int_eq (self ):
2058- return self .emit_unspecialized_goto_if_not_comparison ( "int_eq " , "==" )
2138+ return self ._emit_goto_if_not_int_comparison_fast ( "INT_EQ " , "==" )
20592139
20602140 def emit_unspecialized_switch (self ):
20612141 lines = []
0 commit comments