@@ -864,12 +864,12 @@ dummy_func(void) {
864864 }
865865
866866 op (_CHECK_FUNCTION_VERSION , (func_version /2 , callable , self_or_null , unused [oparg ] -- callable , self_or_null , unused [oparg ])) {
867- if (sym_is_const (ctx , callable ) && sym_matches_type (callable , & PyFunction_Type )) {
868- assert (PyFunction_Check (sym_get_const (ctx , callable )));
869- ADD_OP (_CHECK_FUNCTION_VERSION_INLINE , 0 , func_version );
870- uop_buffer_last (& ctx -> out_buffer )-> operand1 = (uintptr_t )sym_get_const (ctx , callable );
867+ if (sym_get_func_version (callable ) == func_version ) {
868+ REPLACE_OP (this_instr , _NOP , 0 , 0 );
869+ }
870+ else {
871+ sym_set_func_version (ctx , callable , func_version );
871872 }
872- sym_set_type (callable , & PyFunction_Type );
873873 }
874874
875875 op (_CHECK_METHOD_VERSION , (func_version /2 , callable , null , unused [oparg ] -- callable , null , unused [oparg ])) {
@@ -1779,12 +1779,47 @@ dummy_func(void) {
17791779 sym_set_recorded_gen_func (nos , func );
17801780 }
17811781
1782+ op (_GUARD_CODE_VERSION__PUSH_FRAME , (version /2 -- )) {
1783+ PyCodeObject * co = get_current_code_object (ctx );
1784+ if (co -> co_version == version ) {
1785+ _Py_BloomFilter_Add (dependencies , co );
1786+ // Functions derive their version from code objects.
1787+ if (sym_get_func_version (ctx -> frame -> callable ) == version ) {
1788+ REPLACE_OP (this_instr , _NOP , 0 , 0 );
1789+ }
1790+ }
1791+ else {
1792+ ctx -> done = true;
1793+ }
1794+ }
1795+
1796+ op (_GUARD_CODE_VERSION_RETURN_VALUE , (version /2 -- )) {
1797+ if (ctx -> frame -> caller ) {
1798+ REPLACE_OP (this_instr , _NOP , 0 , 0 );
1799+ }
1800+ }
1801+
1802+ op (_GUARD_CODE_VERSION_YIELD_VALUE , (version /2 -- )) {
1803+ if (ctx -> frame -> caller ) {
1804+ REPLACE_OP (this_instr , _NOP , 0 , 0 );
1805+ }
1806+ }
1807+
1808+ op (_GUARD_CODE_VERSION_RETURN_GENERATOR , (version /2 -- )) {
1809+ if (ctx -> frame -> caller ) {
1810+ REPLACE_OP (this_instr , _NOP , 0 , 0 );
1811+ }
1812+ }
1813+
17821814 op (_GUARD_IP__PUSH_FRAME , (ip /4 -- )) {
17831815 (void )ip ;
17841816 stack_pointer = sym_set_stack_depth ((int )this_instr -> operand1 , stack_pointer );
1785- // TO DO
1786- // Normal function calls to known functions
1787- // do not need an IP guard.
1817+ if (sym_get_func_version (ctx -> frame -> callable ) != 0 &&
1818+ // We can remove this guard for simple function call targets.
1819+ (((PyCodeObject * )ctx -> frame -> func -> func_code )-> co_flags &
1820+ (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR )) == 0 ) {
1821+ REPLACE_OP (this_instr , _NOP , 0 , 0 );
1822+ }
17881823 }
17891824
17901825 op (_GUARD_IP_YIELD_VALUE , (ip /4 -- )) {
0 commit comments