@@ -7573,6 +7573,9 @@ normalize_basic_block(basicblock *bb);
75737573static int
75747574optimize_cfg (struct compiler * c , struct assembler * a , PyObject * consts );
75757575
7576+ static int
7577+ trim_unused_consts (struct compiler * c , struct assembler * a , PyObject * consts );
7578+
75767579/* Duplicates exit BBs, so that line numbers can be propagated to them */
75777580static int
75787581duplicate_exits_without_lineno (struct compiler * c );
@@ -7870,6 +7873,9 @@ assemble(struct compiler *c, int addNone)
78707873 if (duplicate_exits_without_lineno (c )) {
78717874 return NULL ;
78727875 }
7876+ if (trim_unused_consts (c , & a , consts )) {
7877+ goto error ;
7878+ }
78737879 propagate_line_numbers (& a );
78747880 guarantee_lineno_for_exits (& a , c -> u -> u_firstlineno );
78757881 int maxdepth = stackdepth (c );
@@ -8599,6 +8605,33 @@ optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts)
85998605 return 0 ;
86008606}
86018607
8608+ // Remove trailing unused constants.
8609+ static int
8610+ trim_unused_consts (struct compiler * c , struct assembler * a , PyObject * consts )
8611+ {
8612+ assert (PyList_CheckExact (consts ));
8613+
8614+ // The first constant may be docstring; keep it always.
8615+ int max_const_index = 0 ;
8616+ for (basicblock * b = a -> a_entry ; b != NULL ; b = b -> b_next ) {
8617+ for (int i = 0 ; i < b -> b_iused ; i ++ ) {
8618+ if (b -> b_instr [i ].i_opcode == LOAD_CONST &&
8619+ b -> b_instr [i ].i_oparg > max_const_index ) {
8620+ max_const_index = b -> b_instr [i ].i_oparg ;
8621+ }
8622+ }
8623+ }
8624+ if (max_const_index + 1 < PyList_GET_SIZE (consts )) {
8625+ //fprintf(stderr, "removing trailing consts: max=%d, size=%d\n",
8626+ // max_const_index, (int)PyList_GET_SIZE(consts));
8627+ if (PyList_SetSlice (consts , max_const_index + 1 ,
8628+ PyList_GET_SIZE (consts ), NULL ) < 0 ) {
8629+ return 1 ;
8630+ }
8631+ }
8632+ return 0 ;
8633+ }
8634+
86028635static inline int
86038636is_exit_without_lineno (basicblock * b ) {
86048637 return b -> b_exit && b -> b_instr [0 ].i_lineno < 0 ;
0 commit comments