@@ -542,6 +542,54 @@ fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
542542 return 1 ;
543543}
544544
545+ static int
546+ fold_unaryops_on_constants (unsigned char * codestr , PyObject * consts )
547+ {
548+ PyObject * newconst , * v ;
549+ int len_consts , opcode ;
550+
551+ /* Pre-conditions */
552+ assert (PyList_CheckExact (consts ));
553+ assert (codestr [0 ] == LOAD_CONST );
554+
555+ /* Create new constant */
556+ v = PyList_GET_ITEM (consts , GETARG (codestr , 0 ));
557+ opcode = codestr [3 ];
558+ switch (opcode ) {
559+ case UNARY_NEGATIVE :
560+ newconst = PyNumber_Negative (v );
561+ break ;
562+ case UNARY_CONVERT :
563+ newconst = PyObject_Repr (v );
564+ break ;
565+ case UNARY_INVERT :
566+ newconst = PyNumber_Invert (v );
567+ break ;
568+ default :
569+ /* Called with an unknown opcode */
570+ assert (0 );
571+ return 0 ;
572+ }
573+ if (newconst == NULL ) {
574+ PyErr_Clear ();
575+ return 0 ;
576+ }
577+
578+ /* Append folded constant into consts table */
579+ len_consts = PyList_GET_SIZE (consts );
580+ if (PyList_Append (consts , newconst )) {
581+ Py_DECREF (newconst );
582+ return 0 ;
583+ }
584+ Py_DECREF (newconst );
585+
586+ /* Write NOP LOAD_CONST newconst */
587+ codestr [0 ] = NOP ;
588+ codestr [1 ] = LOAD_CONST ;
589+ SETARG (codestr , 1 , len_consts );
590+ return 1 ;
591+ }
592+
545593static unsigned int *
546594markblocks (unsigned char * code , int len )
547595{
@@ -771,6 +819,20 @@ optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *linen
771819 }
772820 break ;
773821
822+ /* Fold unary ops on constants.
823+ LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */
824+ case UNARY_NEGATIVE :
825+ case UNARY_CONVERT :
826+ case UNARY_INVERT :
827+ if (lastlc >= 1 &&
828+ ISBASICBLOCK (blocks , i - 3 , 4 ) &&
829+ fold_unaryops_on_constants (& codestr [i - 3 ], consts )) {
830+ i -= 2 ;
831+ assert (codestr [i ] == LOAD_CONST );
832+ cumlc = 1 ;
833+ }
834+ break ;
835+
774836 /* Simplify conditional jump to conditional jump where the
775837 result of the first test implies the success of a similar
776838 test or the failure of the opposite test.
0 commit comments