Coverage Report

Created: 2026-09-03 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/Python/flowgraph.c
Line
Count
Source
1
#include "Python.h"
2
#include "opcode.h"
3
#include "pycore_c_array.h"       // _Py_CArray_EnsureCapacity
4
#include "pycore_flowgraph.h"
5
#include "pycore_compile.h"
6
#include "pycore_intrinsics.h"
7
#include "pycore_pymem.h"         // _PyMem_IsPtrFreed()
8
#include "pycore_long.h"          // _PY_IS_SMALL_INT()
9
#include "pycore_hashtable.h"     // _Py_hashtable_t
10
11
#include "pycore_opcode_utils.h"
12
#include "pycore_opcode_metadata.h" // OPCODE_HAS_ARG, etc
13
#include "pycore_pystate.h"         // _PyInterpreterState_GET()
14
#include "pycore_stackref.h"        // PyStackRef_AsPyObjectBorrow()
15
16
#include <stdbool.h>
17
18
19
#undef SUCCESS
20
#undef ERROR
21
15.2M
#define SUCCESS 0
22
52.7k
#define ERROR -1
23
24
#define RETURN_IF_ERROR(X)  \
25
23.5M
    if ((X) == -1) {        \
26
0
        return ERROR;       \
27
0
    }
28
29
5.21M
#define DEFAULT_BLOCK_SIZE 16
30
31
typedef _Py_SourceLocation location;
32
typedef _PyJumpTargetLabel jump_target_label;
33
34
typedef struct _PyCfgInstruction {
35
    int i_opcode;
36
    int i_oparg;
37
    _Py_SourceLocation i_loc;
38
    struct _PyCfgBasicblock *i_target; /* target block (if jump instruction) */
39
    struct _PyCfgBasicblock *i_except; /* target block when exception is raised */
40
} cfg_instr;
41
42
typedef struct _PyCfgBasicblock {
43
    /* Each basicblock in a compilation unit is linked via b_list in the
44
       reverse order that blocks are allocated.  b_list points to the
45
       previously allocated block, not to be confused with b_next, which is
46
       next by control flow. */
47
    struct _PyCfgBasicblock *b_list;
48
    /* The label of this block if it is a jump target, -1 otherwise */
49
    _PyJumpTargetLabel b_label;
50
    /* Exception stack at start of block, used by assembler to create the exception handling table */
51
    struct _PyCfgExceptStack *b_exceptstack;
52
    /* pointer to an array of instructions, initially NULL */
53
    cfg_instr *b_instr;
54
    /* If b_next is non-NULL, it is a pointer to the next
55
       block reached by normal control flow. */
56
    struct _PyCfgBasicblock *b_next;
57
    /* number of instructions used */
58
    int b_iused;
59
    /* length of instruction array (b_instr) */
60
    int b_ialloc;
61
    /* Used by add_checks_for_loads_of_unknown_variables */
62
    uint64_t b_unsafe_locals_mask;
63
    /* Number of predecessors that a block has. */
64
    int b_predecessors;
65
    /* depth of stack upon entry of block, computed by stackdepth() */
66
    int b_startdepth;
67
    /* Basic block is an exception handler that preserves lasti */
68
    unsigned b_preserve_lasti : 1;
69
    /* Used by compiler passes to mark whether they have visited a basic block. */
70
    unsigned b_visited : 1;
71
    /* b_except_handler is used by the cold-detection algorithm to mark exception targets */
72
    unsigned b_except_handler : 1;
73
    /* b_cold is true if this block is not perf critical (like an exception handler) */
74
    unsigned b_cold : 1;
75
    /* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
76
    unsigned b_warm : 1;
77
} basicblock;
78
79
80
struct _PyCfgBuilder {
81
    /* The entryblock, at which control flow begins. All blocks of the
82
       CFG are reachable through the b_next links */
83
    struct _PyCfgBasicblock *g_entryblock;
84
    /* Pointer to the most recently allocated block.  By following
85
       b_list links, you can reach all allocated blocks. */
86
    struct _PyCfgBasicblock *g_block_list;
87
    /* pointer to the block currently being constructed */
88
    struct _PyCfgBasicblock *g_curblock;
89
    /* label for the next instruction to be placed */
90
    _PyJumpTargetLabel g_current_label;
91
};
92
93
typedef struct _PyCfgBuilder cfg_builder;
94
95
5.51M
#define SAME_LABEL(L1, L2) ((L1).id == (L2).id)
96
5.51M
#define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL)))
97
98
#define LOCATION(LNO, END_LNO, COL, END_COL) \
99
    ((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)})
100
101
static inline int
102
is_block_push(cfg_instr *i)
103
21.3M
{
104
21.3M
    assert(OPCODE_HAS_ARG(i->i_opcode) || !IS_BLOCK_PUSH_OPCODE(i->i_opcode));
105
21.3M
    return IS_BLOCK_PUSH_OPCODE(i->i_opcode);
106
21.3M
}
107
108
static inline int
109
is_jump(cfg_instr *i)
110
18.4M
{
111
18.4M
    return OPCODE_HAS_JUMP(i->i_opcode);
112
18.4M
}
113
114
/* One arg*/
115
#define INSTR_SET_OP1(I, OP, ARG) \
116
1.48M
    do { \
117
1.48M
        assert(OPCODE_HAS_ARG(OP)); \
118
1.48M
        cfg_instr *_instr__ptr_ = (I); \
119
1.48M
        _instr__ptr_->i_opcode = (OP); \
120
1.48M
        _instr__ptr_->i_oparg = (ARG); \
121
1.48M
    } while (0);
122
123
/* No args*/
124
#define INSTR_SET_OP0(I, OP) \
125
2.08M
    do { \
126
2.08M
        assert(!OPCODE_HAS_ARG(OP)); \
127
2.08M
        cfg_instr *_instr__ptr_ = (I); \
128
2.08M
        _instr__ptr_->i_opcode = (OP); \
129
2.08M
        _instr__ptr_->i_oparg = 0; \
130
2.08M
    } while (0);
131
132
#define INSTR_SET_LOC(I, LOC) \
133
1.38M
    do { \
134
1.38M
        cfg_instr *_instr__ptr_ = (I); \
135
1.38M
        _instr__ptr_->i_loc = (LOC); \
136
1.38M
    } while (0);
137
138
/***** Blocks *****/
139
140
/* Returns the offset of the next instruction in the current block's
141
   b_instr array.  Resizes the b_instr as necessary.
142
   Returns -1 on failure.
143
*/
144
static int
145
basicblock_next_instr(basicblock *b)
146
5.21M
{
147
5.21M
    assert(b != NULL);
148
5.21M
    _Py_c_array_t array = {
149
5.21M
        .array = (void*)b->b_instr,
150
5.21M
        .allocated_entries = b->b_ialloc,
151
5.21M
        .item_size = sizeof(cfg_instr),
152
5.21M
        .initial_num_entries = DEFAULT_BLOCK_SIZE,
153
5.21M
    };
154
155
5.21M
    RETURN_IF_ERROR(_Py_CArray_EnsureCapacity(&array, b->b_iused + 1));
156
5.21M
    b->b_instr = array.array;
157
5.21M
    b->b_ialloc = array.allocated_entries;
158
5.21M
    return b->b_iused++;
159
5.21M
}
160
161
static cfg_instr *
162
18.2M
basicblock_last_instr(const basicblock *b) {
163
18.2M
    assert(b->b_iused >= 0);
164
18.2M
    if (b->b_iused > 0) {
165
17.0M
        assert(b->b_instr != NULL);
166
17.0M
        return &b->b_instr[b->b_iused - 1];
167
17.0M
    }
168
1.18M
    return NULL;
169
18.2M
}
170
171
/* Allocate a new block and return a pointer to it.
172
   Returns NULL on error.
173
*/
174
175
static basicblock *
176
cfg_builder_new_block(cfg_builder *g)
177
494k
{
178
494k
    basicblock *b = (basicblock *)PyMem_Calloc(1, sizeof(basicblock));
179
494k
    if (b == NULL) {
180
0
        PyErr_NoMemory();
181
0
        return NULL;
182
0
    }
183
    /* Extend the singly linked list of blocks with new block. */
184
494k
    b->b_list = g->g_block_list;
185
494k
    g->g_block_list = b;
186
494k
    b->b_label = NO_LABEL;
187
494k
    return b;
188
494k
}
189
190
static int
191
basicblock_addop(basicblock *b, int opcode, int oparg, location loc)
192
5.15M
{
193
5.15M
    assert(IS_WITHIN_OPCODE_RANGE(opcode));
194
5.15M
    assert(!IS_ASSEMBLER_OPCODE(opcode));
195
5.15M
    assert(OPCODE_HAS_ARG(opcode) || HAS_TARGET(opcode) || oparg == 0);
196
5.15M
    assert(0 <= oparg && oparg < (1 << 30));
197
198
5.15M
    int off = basicblock_next_instr(b);
199
5.15M
    if (off < 0) {
200
0
        return ERROR;
201
0
    }
202
5.15M
    cfg_instr *i = &b->b_instr[off];
203
5.15M
    i->i_opcode = opcode;
204
5.15M
    i->i_oparg = oparg;
205
5.15M
    i->i_loc = loc;
206
    // memory is already zero initialized
207
5.15M
    assert(i->i_target == NULL);
208
5.15M
    assert(i->i_except == NULL);
209
210
5.15M
    return SUCCESS;
211
5.15M
}
212
213
static int
214
basicblock_add_jump(basicblock *b, int opcode, basicblock *target, location loc)
215
1.54k
{
216
1.54k
    cfg_instr *last = basicblock_last_instr(b);
217
1.54k
    if (last && is_jump(last)) {
218
0
        return ERROR;
219
0
    }
220
221
1.54k
    RETURN_IF_ERROR(
222
1.54k
        basicblock_addop(b, opcode, target->b_label.id, loc));
223
1.54k
    last = basicblock_last_instr(b);
224
1.54k
    assert(last && last->i_opcode == opcode);
225
1.54k
    last->i_target = target;
226
1.54k
    return SUCCESS;
227
1.54k
}
228
229
static inline int
230
basicblock_append_instructions(basicblock *to, basicblock *from)
231
15.0k
{
232
47.3k
    for (int i = 0; i < from->b_iused; i++) {
233
32.3k
        int n = basicblock_next_instr(to);
234
32.3k
        if (n < 0) {
235
0
            return ERROR;
236
0
        }
237
32.3k
        to->b_instr[n] = from->b_instr[i];
238
32.3k
    }
239
15.0k
    return SUCCESS;
240
15.0k
}
241
242
static inline int
243
4.98M
basicblock_nofallthrough(const basicblock *b) {
244
4.98M
    cfg_instr *last = basicblock_last_instr(b);
245
4.98M
    return (last &&
246
4.78M
            (IS_SCOPE_EXIT_OPCODE(last->i_opcode) ||
247
3.66M
             IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)));
248
4.98M
}
249
250
#define BB_NO_FALLTHROUGH(B) (basicblock_nofallthrough(B))
251
7.70M
#define BB_HAS_FALLTHROUGH(B) (!basicblock_nofallthrough(B))
252
253
static basicblock *
254
copy_basicblock(cfg_builder *g, basicblock *block)
255
2.09k
{
256
    /* Cannot copy a block if it has a fallthrough, since
257
     * a block can only have one fallthrough predecessor.
258
     */
259
2.09k
    assert(BB_NO_FALLTHROUGH(block));
260
2.09k
    basicblock *result = cfg_builder_new_block(g);
261
2.09k
    if (result == NULL) {
262
0
        return NULL;
263
0
    }
264
2.09k
    if (basicblock_append_instructions(result, block) < 0) {
265
0
        return NULL;
266
0
    }
267
2.09k
    return result;
268
2.09k
}
269
270
static int
271
30.8k
basicblock_insert_instruction(basicblock *block, int pos, cfg_instr *instr) {
272
30.8k
    RETURN_IF_ERROR(basicblock_next_instr(block));
273
522k
    for (int i = block->b_iused - 1; i > pos; i--) {
274
491k
        block->b_instr[i] = block->b_instr[i-1];
275
491k
    }
276
30.8k
    block->b_instr[pos] = *instr;
277
30.8k
    return SUCCESS;
278
30.8k
}
279
280
/* For debugging purposes only */
281
#if 0
282
static void
283
dump_instr(cfg_instr *i)
284
{
285
    const char *jump = is_jump(i) ? "jump " : "";
286
287
    char arg[128];
288
289
    *arg = '\0';
290
    if (OPCODE_HAS_ARG(i->i_opcode)) {
291
        sprintf(arg, "arg: %d ", i->i_oparg);
292
    }
293
    if (HAS_TARGET(i->i_opcode)) {
294
        sprintf(arg, "target: %p [%d] ", i->i_target, i->i_oparg);
295
    }
296
    fprintf(stderr, "line: %d, %s (%d)  %s%s\n",
297
                    i->i_loc.lineno, _PyOpcode_OpName[i->i_opcode], i->i_opcode, arg, jump);
298
}
299
300
static inline int
301
basicblock_returns(const basicblock *b) {
302
    cfg_instr *last = basicblock_last_instr(b);
303
    return last && IS_RETURN_OPCODE(last->i_opcode);
304
}
305
306
static void
307
dump_basicblock(const basicblock *b, bool highlight)
308
{
309
    const char *b_return = basicblock_returns(b) ? "return " : "";
310
    if (highlight) {
311
        fprintf(stderr, ">>> ");
312
    }
313
    fprintf(stderr, "%d: [EH=%d CLD=%d WRM=%d NO_FT=%d %p] used: %d, depth: %d, preds: %d %s\n",
314
        b->b_label.id, b->b_except_handler, b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused,
315
        b->b_startdepth, b->b_predecessors, b_return);
316
    int depth = b->b_startdepth;
317
    if (b->b_instr) {
318
        int i;
319
        for (i = 0; i < b->b_iused; i++) {
320
            fprintf(stderr, "  [%02d] depth: %d ", i, depth);
321
            dump_instr(b->b_instr + i);
322
323
            int popped = _PyOpcode_num_popped(b->b_instr[i].i_opcode, b->b_instr[i].i_oparg);
324
            int pushed = _PyOpcode_num_pushed(b->b_instr[i].i_opcode, b->b_instr[i].i_oparg);
325
            depth += (pushed - popped);
326
        }
327
    }
328
}
329
330
void
331
_PyCfgBuilder_DumpGraph(const basicblock *entryblock, const basicblock *mark)
332
{
333
    for (const basicblock *b = entryblock; b != NULL; b = b->b_next) {
334
        dump_basicblock(b, b == mark);
335
    }
336
}
337
338
#endif
339
340
341
/***** CFG construction and modification *****/
342
343
static basicblock *
344
cfg_builder_use_next_block(cfg_builder *g, basicblock *block)
345
419k
{
346
419k
    assert(block != NULL);
347
419k
    g->g_curblock->b_next = block;
348
419k
    g->g_curblock = block;
349
419k
    return block;
350
419k
}
351
352
static inline int
353
1.10M
basicblock_exits_scope(const basicblock *b) {
354
1.10M
    cfg_instr *last = basicblock_last_instr(b);
355
1.10M
    return last && IS_SCOPE_EXIT_OPCODE(last->i_opcode);
356
1.10M
}
357
358
static inline int
359
808k
basicblock_has_eval_break(const basicblock *b) {
360
5.27M
    for (int i = 0; i < b->b_iused; i++) {
361
4.67M
        if (OPCODE_HAS_EVAL_BREAK(b->b_instr[i].i_opcode)) {
362
207k
            return true;
363
207k
        }
364
4.67M
    }
365
601k
    return false;
366
808k
}
367
368
static bool
369
cfg_builder_current_block_is_terminated(cfg_builder *g)
370
5.28M
{
371
5.28M
    cfg_instr *last = basicblock_last_instr(g->g_curblock);
372
5.28M
    if (last && IS_TERMINATOR_OPCODE(last->i_opcode)) {
373
323k
        return true;
374
323k
    }
375
4.95M
    if (IS_LABEL(g->g_current_label)) {
376
96.6k
        if (last || IS_LABEL(g->g_curblock->b_label)) {
377
96.6k
            return true;
378
96.6k
        }
379
0
        else {
380
            /* current block is empty, label it */
381
0
            g->g_curblock->b_label = g->g_current_label;
382
0
            g->g_current_label = NO_LABEL;
383
0
        }
384
96.6k
    }
385
4.86M
    return false;
386
4.95M
}
387
388
static int
389
cfg_builder_maybe_start_new_block(cfg_builder *g)
390
5.28M
{
391
5.28M
    if (cfg_builder_current_block_is_terminated(g)) {
392
419k
        basicblock *b = cfg_builder_new_block(g);
393
419k
        if (b == NULL) {
394
0
            return ERROR;
395
0
        }
396
419k
        b->b_label = g->g_current_label;
397
419k
        g->g_current_label = NO_LABEL;
398
419k
        cfg_builder_use_next_block(g, b);
399
419k
    }
400
5.28M
    return SUCCESS;
401
5.28M
}
402
403
#ifndef NDEBUG
404
static bool
405
cfg_builder_check(cfg_builder *g)
406
105k
{
407
1.07M
    for (basicblock *block = g->g_block_list; block != NULL; block = block->b_list) {
408
967k
        assert(!_PyMem_IsPtrFreed(block));
409
967k
        if (block->b_instr != NULL) {
410
967k
            assert(block->b_ialloc > 0);
411
967k
            assert(block->b_iused >= 0);
412
967k
            assert(block->b_ialloc >= block->b_iused);
413
967k
        }
414
0
        else {
415
0
            assert (block->b_iused == 0);
416
0
            assert (block->b_ialloc == 0);
417
0
        }
418
967k
    }
419
105k
    return true;
420
105k
}
421
#endif
422
423
static int
424
init_cfg_builder(cfg_builder *g)
425
52.7k
{
426
52.7k
    g->g_block_list = NULL;
427
52.7k
    basicblock *block = cfg_builder_new_block(g);
428
52.7k
    if (block == NULL) {
429
0
        return ERROR;
430
0
    }
431
52.7k
    g->g_curblock = g->g_entryblock = block;
432
52.7k
    g->g_current_label = NO_LABEL;
433
52.7k
    return SUCCESS;
434
52.7k
}
435
436
cfg_builder *
437
_PyCfgBuilder_New(void)
438
52.7k
{
439
52.7k
    cfg_builder *g = PyMem_Malloc(sizeof(cfg_builder));
440
52.7k
    if (g == NULL) {
441
0
        PyErr_NoMemory();
442
0
        return NULL;
443
0
    }
444
52.7k
    memset(g, 0, sizeof(cfg_builder));
445
52.7k
    if (init_cfg_builder(g) < 0) {
446
0
        PyMem_Free(g);
447
0
        return NULL;
448
0
    }
449
52.7k
    return g;
450
52.7k
}
451
452
void
453
_PyCfgBuilder_Free(cfg_builder *g)
454
52.7k
{
455
52.7k
    if (g == NULL) {
456
0
        return;
457
0
    }
458
52.7k
    assert(cfg_builder_check(g));
459
52.7k
    basicblock *b = g->g_block_list;
460
547k
    while (b != NULL) {
461
494k
        if (b->b_instr) {
462
494k
            PyMem_Free((void *)b->b_instr);
463
494k
        }
464
494k
        basicblock *next = b->b_list;
465
494k
        PyMem_Free((void *)b);
466
494k
        b = next;
467
494k
    }
468
52.7k
    PyMem_Free(g);
469
52.7k
}
470
471
int
472
_PyCfgBuilder_CheckSize(cfg_builder *g)
473
52.7k
{
474
52.7k
    int nblocks = 0;
475
525k
    for (basicblock *b = g->g_block_list; b != NULL; b = b->b_list) {
476
472k
        nblocks++;
477
472k
    }
478
52.7k
    if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) {
479
0
        PyErr_NoMemory();
480
0
        return ERROR;
481
0
    }
482
52.7k
    return SUCCESS;
483
52.7k
}
484
485
int
486
_PyCfgBuilder_UseLabel(cfg_builder *g, jump_target_label lbl)
487
239k
{
488
239k
    g->g_current_label = lbl;
489
239k
    return cfg_builder_maybe_start_new_block(g);
490
239k
}
491
492
int
493
_PyCfgBuilder_Addop(cfg_builder *g, int opcode, int oparg, location loc)
494
5.04M
{
495
5.04M
    RETURN_IF_ERROR(cfg_builder_maybe_start_new_block(g));
496
5.04M
    return basicblock_addop(g->g_curblock, opcode, oparg, loc);
497
5.04M
}
498
499
500
static basicblock *
501
next_nonempty_block(basicblock *b)
502
1.75M
{
503
1.91M
    while (b && b->b_iused == 0) {
504
155k
        b = b->b_next;
505
155k
    }
506
1.75M
    return b;
507
1.75M
}
508
509
/***** debugging helpers *****/
510
511
#ifndef NDEBUG
512
static int remove_redundant_nops(cfg_builder *g);
513
514
static bool
515
52.7k
no_redundant_nops(cfg_builder *g) {
516
52.7k
    if (remove_redundant_nops(g) != 0) {
517
0
        return false;
518
0
    }
519
52.7k
    return true;
520
52.7k
}
521
522
static bool
523
105k
no_redundant_jumps(cfg_builder *g) {
524
1.07M
    for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
525
969k
        cfg_instr *last = basicblock_last_instr(b);
526
969k
        if (last != NULL) {
527
845k
            if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
528
165k
                basicblock *next = next_nonempty_block(b->b_next);
529
165k
                basicblock *jump_target = next_nonempty_block(last->i_target);
530
165k
                if (jump_target == next) {
531
0
                    assert(next);
532
0
                    if (last->i_loc.lineno == next->b_instr[0].i_loc.lineno) {
533
0
                        assert(0);
534
0
                        return false;
535
0
                    }
536
0
                }
537
165k
            }
538
845k
        }
539
969k
    }
540
105k
    return true;
541
105k
}
542
#endif
543
544
/***** CFG preprocessing (jump targets and exceptions) *****/
545
546
static int
547
494k
normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
548
494k
    cfg_instr *last = basicblock_last_instr(b);
549
494k
    if (last == NULL || !IS_CONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
550
405k
        return SUCCESS;
551
405k
    }
552
494k
    assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
553
554
89.0k
    bool is_forward = last->i_target->b_visited == 0;
555
89.0k
    if (is_forward) {
556
89.0k
        RETURN_IF_ERROR(
557
89.0k
            basicblock_addop(b, NOT_TAKEN, 0, last->i_loc));
558
89.0k
        return SUCCESS;
559
89.0k
    }
560
561
25
    int reversed_opcode = 0;
562
25
    switch(last->i_opcode) {
563
0
        case POP_JUMP_IF_NOT_NONE:
564
0
            reversed_opcode = POP_JUMP_IF_NONE;
565
0
            break;
566
0
        case POP_JUMP_IF_NONE:
567
0
            reversed_opcode = POP_JUMP_IF_NOT_NONE;
568
0
            break;
569
24
        case POP_JUMP_IF_FALSE:
570
24
            reversed_opcode = POP_JUMP_IF_TRUE;
571
24
            break;
572
1
        case POP_JUMP_IF_TRUE:
573
1
            reversed_opcode = POP_JUMP_IF_FALSE;
574
1
            break;
575
25
    }
576
    /* transform 'conditional jump T' to
577
     * 'reversed_jump b_next' followed by 'jump_backwards T'
578
     */
579
580
25
    basicblock *target = last->i_target;
581
25
    basicblock *backwards_jump = cfg_builder_new_block(g);
582
25
    if (backwards_jump == NULL) {
583
0
        return ERROR;
584
0
    }
585
25
    RETURN_IF_ERROR(
586
25
        basicblock_addop(backwards_jump, NOT_TAKEN, 0, last->i_loc));
587
25
    RETURN_IF_ERROR(
588
25
        basicblock_add_jump(backwards_jump, JUMP, target, last->i_loc));
589
25
    backwards_jump->b_startdepth = target->b_startdepth;
590
25
    last->i_opcode = reversed_opcode;
591
25
    last->i_target = b->b_next;
592
593
25
    backwards_jump->b_cold = b->b_cold;
594
25
    backwards_jump->b_next = b->b_next;
595
25
    b->b_next = backwards_jump;
596
25
    return SUCCESS;
597
25
}
598
599
600
static int
601
normalize_jumps(cfg_builder *g)
602
52.7k
{
603
52.7k
    basicblock *entryblock = g->g_entryblock;
604
547k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
605
494k
        b->b_visited = 0;
606
494k
    }
607
547k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
608
494k
        b->b_visited = 1;
609
494k
        RETURN_IF_ERROR(normalize_jumps_in_block(g, b));
610
494k
    }
611
52.7k
    return SUCCESS;
612
52.7k
}
613
614
static int
615
52.7k
check_cfg(cfg_builder *g) {
616
525k
    for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
617
        /* Raise SystemError if jump or exit is not last instruction in the block. */
618
5.51M
        for (int i = 0; i < b->b_iused; i++) {
619
5.04M
            int opcode = b->b_instr[i].i_opcode;
620
5.04M
            assert(!IS_ASSEMBLER_OPCODE(opcode));
621
5.04M
            if (IS_TERMINATOR_OPCODE(opcode)) {
622
375k
                if (i != b->b_iused - 1) {
623
0
                    PyErr_SetString(PyExc_SystemError, "malformed control flow graph.");
624
0
                    return ERROR;
625
0
                }
626
375k
            }
627
5.04M
        }
628
472k
    }
629
52.7k
    return SUCCESS;
630
52.7k
}
631
632
static int
633
get_max_label(basicblock *entryblock)
634
194k
{
635
194k
    int lbl = -1;
636
2.09M
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
637
1.89M
        if (b->b_label.id > lbl) {
638
822k
            lbl = b->b_label.id;
639
822k
        }
640
1.89M
    }
641
194k
    return lbl;
642
194k
}
643
644
/* Calculate the actual jump target from the target_label */
645
static int
646
translate_jump_labels_to_targets(basicblock *entryblock)
647
52.7k
{
648
52.7k
    int max_label = get_max_label(entryblock);
649
52.7k
    size_t mapsize = sizeof(basicblock *) * (max_label + 1);
650
52.7k
    basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize);
651
52.7k
    if (!label2block) {
652
0
        PyErr_NoMemory();
653
0
        return ERROR;
654
0
    }
655
52.7k
    memset(label2block, 0, mapsize);
656
525k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
657
472k
        if (b->b_label.id >= 0) {
658
239k
            label2block[b->b_label.id] = b;
659
239k
        }
660
472k
    }
661
525k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
662
5.51M
        for (int i = 0; i < b->b_iused; i++) {
663
5.04M
            cfg_instr *instr = &b->b_instr[i];
664
5.04M
            assert(instr->i_target == NULL);
665
5.04M
            if (HAS_TARGET(instr->i_opcode)) {
666
313k
                int lbl = instr->i_oparg;
667
313k
                assert(lbl >= 0 && lbl <= max_label);
668
313k
                instr->i_target = label2block[lbl];
669
313k
                assert(instr->i_target != NULL);
670
313k
                assert(instr->i_target->b_label.id == lbl);
671
313k
            }
672
5.04M
        }
673
472k
    }
674
52.7k
    PyMem_Free(label2block);
675
52.7k
    return SUCCESS;
676
52.7k
}
677
678
static int
679
52.7k
mark_except_handlers(basicblock *entryblock) {
680
52.7k
#ifndef NDEBUG
681
525k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
682
472k
        assert(!b->b_except_handler);
683
472k
    }
684
52.7k
#endif
685
525k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
686
5.51M
        for (int i=0; i < b->b_iused; i++) {
687
5.04M
            cfg_instr *instr = &b->b_instr[i];
688
5.04M
            if (is_block_push(instr)) {
689
75.1k
                instr->i_target->b_except_handler = 1;
690
75.1k
            }
691
5.04M
        }
692
472k
    }
693
52.7k
    return SUCCESS;
694
52.7k
}
695
696
697
struct _PyCfgExceptStack {
698
    basicblock *handlers[CO_MAXBLOCKS+2];
699
    int depth;
700
};
701
702
703
static basicblock *
704
74.9k
push_except_block(struct _PyCfgExceptStack *stack, cfg_instr *setup) {
705
74.9k
    assert(is_block_push(setup));
706
74.9k
    int opcode = setup->i_opcode;
707
74.9k
    basicblock * target = setup->i_target;
708
74.9k
    if (opcode == SETUP_WITH || opcode == SETUP_CLEANUP) {
709
31.6k
        target->b_preserve_lasti = 1;
710
31.6k
    }
711
74.9k
    assert(stack->depth <= CO_MAXBLOCKS);
712
74.9k
    stack->handlers[++stack->depth] = target;
713
74.9k
    return target;
714
74.9k
}
715
716
static basicblock *
717
73.1k
pop_except_block(struct _PyCfgExceptStack *stack) {
718
73.1k
    assert(stack->depth > 0);
719
73.1k
    return stack->handlers[--stack->depth];
720
73.1k
}
721
722
static basicblock *
723
437k
except_stack_top(struct _PyCfgExceptStack *stack) {
724
437k
    return stack->handlers[stack->depth];
725
437k
}
726
727
static struct _PyCfgExceptStack *
728
52.7k
make_except_stack(void) {
729
52.7k
    struct _PyCfgExceptStack *new = PyMem_Malloc(sizeof(struct _PyCfgExceptStack));
730
52.7k
    if (new == NULL) {
731
0
        PyErr_NoMemory();
732
0
        return NULL;
733
0
    }
734
52.7k
    new->depth = 0;
735
52.7k
    new->handlers[0] = NULL;
736
52.7k
    return new;
737
52.7k
}
738
739
static struct _PyCfgExceptStack *
740
164k
copy_except_stack(struct _PyCfgExceptStack *stack) {
741
164k
    struct _PyCfgExceptStack *copy = PyMem_Malloc(sizeof(struct _PyCfgExceptStack));
742
164k
    if (copy == NULL) {
743
0
        PyErr_NoMemory();
744
0
        return NULL;
745
0
    }
746
164k
    memcpy(copy, stack, sizeof(struct _PyCfgExceptStack));
747
164k
    return copy;
748
164k
}
749
750
static basicblock**
751
362k
make_cfg_traversal_stack(basicblock *entryblock) {
752
362k
    int nblocks = 0;
753
3.98M
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
754
3.61M
        b->b_visited = 0;
755
3.61M
        nblocks++;
756
3.61M
    }
757
362k
    basicblock **stack = (basicblock **)PyMem_Malloc(sizeof(basicblock *) * nblocks);
758
362k
    if (!stack) {
759
0
        PyErr_NoMemory();
760
0
    }
761
362k
    return stack;
762
362k
}
763
764
/* Compute the stack effects of opcode with argument oparg.
765
766
   Some opcodes have different stack effect when jump to the target and
767
   when not jump. The 'jump' parameter specifies the case:
768
769
   * 0 -- when not jump
770
   * 1 -- when jump
771
   * -1 -- maximal
772
 */
773
typedef struct {
774
    /* The stack effect of the instruction. */
775
    int net;
776
} stack_effects;
777
778
Py_LOCAL(int)
779
get_stack_effects(int opcode, int oparg, int jump, stack_effects *effects)
780
3.63M
{
781
3.63M
    if (opcode < 0) {
782
0
        return -1;
783
0
    }
784
3.63M
    if ((opcode <= MAX_REAL_OPCODE) && (_PyOpcode_Deopt[opcode] != opcode)) {
785
        // Specialized instructions are not supported.
786
0
        return -1;
787
0
    }
788
3.63M
    int popped = _PyOpcode_num_popped(opcode, oparg);
789
3.63M
    int pushed = _PyOpcode_num_pushed(opcode, oparg);
790
3.63M
    if (popped < 0 || pushed < 0) {
791
0
        return -1;
792
0
    }
793
3.63M
    if (IS_BLOCK_PUSH_OPCODE(opcode) && !jump) {
794
74.8k
        effects->net = 0;
795
74.8k
        return 0;
796
74.8k
    }
797
3.56M
    effects->net = pushed - popped;
798
3.56M
    return 0;
799
3.63M
}
800
801
Py_LOCAL_INLINE(int)
802
stackdepth_push(basicblock ***sp, basicblock *b, int depth)
803
602k
{
804
602k
    if (!(b->b_startdepth < 0 || b->b_startdepth == depth)) {
805
0
        PyErr_Format(PyExc_ValueError, "Invalid CFG, inconsistent stackdepth");
806
0
        return ERROR;
807
0
    }
808
602k
    if (b->b_startdepth < depth && b->b_startdepth < 100) {
809
457k
        assert(b->b_startdepth < 0);
810
457k
        b->b_startdepth = depth;
811
457k
        *(*sp)++ = b;
812
457k
    }
813
602k
    return SUCCESS;
814
602k
}
815
816
/* Find the flow path that needs the largest stack.  We assume that
817
 * cycles in the flow graph have no net effect on the stack depth.
818
 */
819
static int
820
calculate_stackdepth(cfg_builder *g)
821
52.7k
{
822
52.7k
    basicblock *entryblock = g->g_entryblock;
823
547k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
824
494k
        b->b_startdepth = INT_MIN;
825
494k
    }
826
52.7k
    basicblock **stack = make_cfg_traversal_stack(entryblock);
827
52.7k
    if (!stack) {
828
0
        return ERROR;
829
0
    }
830
831
832
52.7k
    int stackdepth = -1;
833
52.7k
    int maxdepth = 0;
834
52.7k
    basicblock **sp = stack;
835
52.7k
    if (stackdepth_push(&sp, entryblock, 0) < 0) {
836
0
        goto error;
837
0
    }
838
509k
    while (sp != stack) {
839
457k
        basicblock *b = *--sp;
840
457k
        int depth = b->b_startdepth;
841
457k
        assert(depth >= 0);
842
457k
        basicblock *next = b->b_next;
843
3.60M
        for (int i = 0; i < b->b_iused; i++) {
844
3.34M
            cfg_instr *instr = &b->b_instr[i];
845
3.34M
            stack_effects effects;
846
3.34M
            if (get_stack_effects(instr->i_opcode, instr->i_oparg, 0, &effects) < 0) {
847
0
                PyErr_Format(PyExc_SystemError,
848
0
                             "Invalid stack effect for opcode=%d, arg=%i",
849
0
                             instr->i_opcode, instr->i_oparg);
850
0
                goto error;
851
0
            }
852
3.34M
            int new_depth = depth + effects.net;
853
3.34M
            if (new_depth < 0) {
854
0
                PyErr_Format(PyExc_ValueError,
855
0
                             "Invalid CFG, stack underflow at line %d", instr->i_loc.lineno);
856
0
                goto error;
857
0
            }
858
3.34M
            maxdepth = Py_MAX(maxdepth, depth);
859
3.34M
            if (HAS_TARGET(instr->i_opcode) && instr->i_opcode != END_ASYNC_FOR) {
860
287k
                if (get_stack_effects(instr->i_opcode, instr->i_oparg, 1, &effects) < 0) {
861
0
                    PyErr_Format(PyExc_SystemError,
862
0
                                 "Invalid stack effect for opcode=%d, arg=%i",
863
0
                                 instr->i_opcode, instr->i_oparg);
864
0
                    goto error;
865
0
                }
866
287k
                int target_depth = depth + effects.net;
867
287k
                assert(target_depth >= 0); /* invalid code or bug in stackdepth() */
868
287k
                maxdepth = Py_MAX(maxdepth, depth);
869
287k
                if (stackdepth_push(&sp, instr->i_target, target_depth) < 0) {
870
0
                    goto error;
871
0
                }
872
287k
            }
873
3.34M
            depth = new_depth;
874
3.34M
            assert(!IS_ASSEMBLER_OPCODE(instr->i_opcode));
875
3.34M
            if (IS_UNCONDITIONAL_JUMP_OPCODE(instr->i_opcode) ||
876
3.25M
                IS_SCOPE_EXIT_OPCODE(instr->i_opcode))
877
194k
            {
878
                /* remaining code is dead */
879
194k
                next = NULL;
880
194k
                break;
881
194k
            }
882
3.34M
        }
883
457k
        if (next != NULL) {
884
262k
            assert(BB_HAS_FALLTHROUGH(b));
885
262k
            if (stackdepth_push(&sp, next, depth) < 0) {
886
0
                goto error;
887
0
            }
888
262k
        }
889
457k
    }
890
52.7k
    stackdepth = maxdepth;
891
52.7k
error:
892
52.7k
    PyMem_Free(stack);
893
52.7k
    return stackdepth;
894
52.7k
}
895
896
static int
897
52.7k
label_exception_targets(basicblock *entryblock) {
898
52.7k
    basicblock **todo_stack = make_cfg_traversal_stack(entryblock);
899
52.7k
    if (todo_stack == NULL) {
900
0
        return ERROR;
901
0
    }
902
52.7k
    struct _PyCfgExceptStack *except_stack = make_except_stack();
903
52.7k
    if (except_stack == NULL) {
904
0
        PyMem_Free(todo_stack);
905
0
        PyErr_NoMemory();
906
0
        return ERROR;
907
0
    }
908
52.7k
    except_stack->depth = 0;
909
52.7k
    todo_stack[0] = entryblock;
910
52.7k
    entryblock->b_visited = 1;
911
52.7k
    entryblock->b_exceptstack = except_stack;
912
52.7k
    basicblock **todo = &todo_stack[1];
913
52.7k
    basicblock *handler = NULL;
914
489k
    while (todo > todo_stack) {
915
437k
        todo--;
916
437k
        basicblock *b = todo[0];
917
437k
        assert(b->b_visited == 1);
918
437k
        except_stack = b->b_exceptstack;
919
437k
        assert(except_stack != NULL);
920
437k
        b->b_exceptstack = NULL;
921
437k
        handler = except_stack_top(except_stack);
922
437k
        int last_yield_except_depth = -1;
923
5.40M
        for (int i = 0; i < b->b_iused; i++) {
924
4.96M
            cfg_instr *instr = &b->b_instr[i];
925
4.96M
            if (is_block_push(instr)) {
926
74.9k
                if (!instr->i_target->b_visited) {
927
74.9k
                    struct _PyCfgExceptStack *copy = copy_except_stack(except_stack);
928
74.9k
                    if (copy == NULL) {
929
0
                        goto error;
930
0
                    }
931
74.9k
                    instr->i_target->b_exceptstack = copy;
932
74.9k
                    todo[0] = instr->i_target;
933
74.9k
                    instr->i_target->b_visited = 1;
934
74.9k
                    todo++;
935
74.9k
                }
936
74.9k
                handler = push_except_block(except_stack, instr);
937
74.9k
            }
938
4.89M
            else if (instr->i_opcode == POP_BLOCK) {
939
73.1k
                handler = pop_except_block(except_stack);
940
73.1k
                INSTR_SET_OP0(instr, NOP);
941
73.1k
            }
942
4.81M
            else if (is_jump(instr)) {
943
237k
                instr->i_except = handler;
944
237k
                assert(i == b->b_iused -1);
945
237k
                if (!instr->i_target->b_visited) {
946
122k
                    if (BB_HAS_FALLTHROUGH(b)) {
947
90.0k
                        struct _PyCfgExceptStack *copy = copy_except_stack(except_stack);
948
90.0k
                        if (copy == NULL) {
949
0
                            goto error;
950
0
                        }
951
90.0k
                        instr->i_target->b_exceptstack = copy;
952
90.0k
                    }
953
32.6k
                    else {
954
32.6k
                        instr->i_target->b_exceptstack = except_stack;
955
32.6k
                        except_stack = NULL;
956
32.6k
                    }
957
122k
                    todo[0] = instr->i_target;
958
122k
                    instr->i_target->b_visited = 1;
959
122k
                    todo++;
960
122k
                }
961
237k
            }
962
4.58M
            else if (instr->i_opcode == YIELD_VALUE) {
963
35.7k
                instr->i_except = handler;
964
35.7k
                last_yield_except_depth = except_stack->depth;
965
35.7k
            }
966
4.54M
            else if (instr->i_opcode == RESUME) {
967
88.9k
                instr->i_except = handler;
968
88.9k
                if (instr->i_oparg != RESUME_AT_FUNC_START && instr->i_oparg != RESUME_AT_GEN_EXPR_START) {
969
35.7k
                    assert(last_yield_except_depth >= 0);
970
35.7k
                    if (last_yield_except_depth == 1) {
971
810
                        instr->i_oparg |= RESUME_OPARG_DEPTH1_MASK;
972
810
                    }
973
35.7k
                    last_yield_except_depth = -1;
974
35.7k
                }
975
88.9k
            }
976
4.45M
            else if (instr->i_opcode == RETURN_GENERATOR) {
977
2.96k
                instr->i_except = NULL;
978
2.96k
            }
979
4.45M
            else {
980
4.45M
                instr->i_except = handler;
981
4.45M
            }
982
4.96M
        }
983
437k
        if (BB_HAS_FALLTHROUGH(b) && !b->b_next->b_visited) {
984
186k
            assert(except_stack != NULL);
985
186k
            b->b_next->b_exceptstack = except_stack;
986
186k
            todo[0] = b->b_next;
987
186k
            b->b_next->b_visited = 1;
988
186k
            todo++;
989
186k
        }
990
250k
        else if (except_stack != NULL) {
991
217k
           PyMem_Free(except_stack);
992
217k
        }
993
437k
    }
994
#ifdef Py_DEBUG
995
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
996
        assert(b->b_exceptstack == NULL);
997
    }
998
#endif
999
52.7k
    PyMem_Free(todo_stack);
1000
52.7k
    return SUCCESS;
1001
0
error:
1002
0
    PyMem_Free(todo_stack);
1003
0
    PyMem_Free(except_stack);
1004
0
    return ERROR;
1005
52.7k
}
1006
1007
/***** CFG optimizations *****/
1008
1009
static int
1010
105k
remove_unreachable(basicblock *entryblock) {
1011
1.05M
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
1012
947k
        b->b_predecessors = 0;
1013
947k
    }
1014
105k
    basicblock **stack = make_cfg_traversal_stack(entryblock);
1015
105k
    if (stack == NULL) {
1016
0
        return ERROR;
1017
0
    }
1018
105k
    basicblock **sp = stack;
1019
105k
    entryblock->b_predecessors = 1;
1020
105k
    *sp++ = entryblock;
1021
105k
    entryblock->b_visited = 1;
1022
953k
    while (sp > stack) {
1023
848k
        basicblock *b = *(--sp);
1024
848k
        if (b->b_next && BB_HAS_FALLTHROUGH(b)) {
1025
464k
            if (!b->b_next->b_visited) {
1026
379k
                assert(b->b_next->b_predecessors == 0);
1027
379k
                *sp++ = b->b_next;
1028
379k
                b->b_next->b_visited = 1;
1029
379k
            }
1030
464k
            b->b_next->b_predecessors++;
1031
464k
        }
1032
9.18M
        for (int i = 0; i < b->b_iused; i++) {
1033
8.33M
            basicblock *target;
1034
8.33M
            cfg_instr *instr = &b->b_instr[i];
1035
8.33M
            if (is_jump(instr) || is_block_push(instr)) {
1036
589k
                target = instr->i_target;
1037
589k
                if (!target->b_visited) {
1038
363k
                    *sp++ = target;
1039
363k
                    target->b_visited = 1;
1040
363k
                }
1041
589k
                target->b_predecessors++;
1042
589k
            }
1043
8.33M
        }
1044
848k
    }
1045
105k
    PyMem_Free(stack);
1046
1047
    /* Delete unreachable instructions */
1048
1.05M
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
1049
947k
       if (b->b_predecessors == 0) {
1050
99.0k
            b->b_iused = 0;
1051
99.0k
            b->b_except_handler = 0;
1052
99.0k
       }
1053
947k
    }
1054
105k
    return SUCCESS;
1055
105k
}
1056
1057
static int
1058
3.72M
basicblock_remove_redundant_nops(basicblock *bb) {
1059
    /* Remove NOPs when legal to do so. */
1060
3.72M
    int dest = 0;
1061
3.72M
    int prev_lineno = -1;
1062
27.7M
    for (int src = 0; src < bb->b_iused; src++) {
1063
24.0M
        int lineno = bb->b_instr[src].i_loc.lineno;
1064
24.0M
        if (bb->b_instr[src].i_opcode == NOP) {
1065
            /* Eliminate no-op if it doesn't have a line number */
1066
1.63M
            if (lineno < 0) {
1067
1.38M
                continue;
1068
1.38M
            }
1069
            /* or, if the previous instruction had the same line number. */
1070
246k
            if (prev_lineno == lineno) {
1071
146k
                continue;
1072
146k
            }
1073
            /* or, if the next instruction has same line number or no line number */
1074
100k
            if (src < bb->b_iused - 1) {
1075
91.6k
                int next_lineno = bb->b_instr[src+1].i_loc.lineno;
1076
91.6k
                if (next_lineno == lineno) {
1077
74.1k
                    continue;
1078
74.1k
                }
1079
17.5k
                if (next_lineno < 0) {
1080
1.17k
                    bb->b_instr[src+1].i_loc = bb->b_instr[src].i_loc;
1081
1.17k
                    continue;
1082
1.17k
                }
1083
17.5k
            }
1084
8.71k
            else {
1085
8.71k
                basicblock *next = next_nonempty_block(bb->b_next);
1086
                /* or if last instruction in BB and next BB has same line number */
1087
8.71k
                if (next) {
1088
8.71k
                    location next_loc = NO_LOCATION;
1089
9.17k
                    for (int next_i=0; next_i < next->b_iused; next_i++) {
1090
9.16k
                        cfg_instr *instr = &next->b_instr[next_i];
1091
9.16k
                        if (instr->i_opcode == NOP && instr->i_loc.lineno < 0) {
1092
                            /* Skip over NOPs without a location, they will be removed */
1093
462
                            continue;
1094
462
                        }
1095
8.70k
                        next_loc = instr->i_loc;
1096
8.70k
                        break;
1097
9.16k
                    }
1098
8.71k
                    if (lineno == next_loc.lineno) {
1099
1.85k
                        continue;
1100
1.85k
                    }
1101
8.71k
                }
1102
8.71k
            }
1103
1104
100k
        }
1105
22.4M
        if (dest != src) {
1106
1.98M
            bb->b_instr[dest] = bb->b_instr[src];
1107
1.98M
        }
1108
22.4M
        dest++;
1109
22.4M
        prev_lineno = lineno;
1110
22.4M
    }
1111
3.72M
    assert(dest <= bb->b_iused);
1112
3.72M
    int num_removed = bb->b_iused - dest;
1113
3.72M
    bb->b_iused = dest;
1114
3.72M
    memset(&bb->b_instr[dest], 0, sizeof(cfg_instr) * num_removed);
1115
3.72M
    return num_removed;
1116
3.72M
}
1117
1118
static int
1119
221k
remove_redundant_nops(cfg_builder *g) {
1120
221k
    int changes = 0;
1121
3.40M
    for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
1122
3.18M
        int change = basicblock_remove_redundant_nops(b);
1123
3.18M
        RETURN_IF_ERROR(change);
1124
3.18M
        changes += change;
1125
3.18M
    }
1126
221k
    return changes;
1127
221k
}
1128
1129
static int loads_const(int opcode);
1130
1131
static int
1132
remove_redundant_nops_and_pairs(basicblock *entryblock)
1133
52.7k
{
1134
52.7k
    bool done = false;
1135
1136
106k
    while (! done) {
1137
53.8k
        done = true;
1138
53.8k
        cfg_instr *prev_instr = NULL;
1139
53.8k
        cfg_instr *instr = NULL;
1140
595k
        for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
1141
541k
            RETURN_IF_ERROR(basicblock_remove_redundant_nops(b));
1142
541k
            if (IS_LABEL(b->b_label)) {
1143
                /* this block is a jump target, forget instr */
1144
286k
                instr = NULL;
1145
286k
            }
1146
4.38M
            for (int i = 0; i < b->b_iused; i++) {
1147
3.84M
                prev_instr = instr;
1148
3.84M
                instr = &b->b_instr[i];
1149
3.84M
                int prev_opcode = prev_instr ? prev_instr->i_opcode : 0;
1150
3.84M
                int prev_oparg = prev_instr ? prev_instr->i_oparg : 0;
1151
3.84M
                int opcode = instr->i_opcode;
1152
3.84M
                bool is_redundant_pair = false;
1153
3.84M
                if (opcode == POP_TOP) {
1154
293k
                   if (loads_const(prev_opcode)) {
1155
5.89k
                       is_redundant_pair = true;
1156
5.89k
                   }
1157
288k
                   else if (prev_opcode == COPY && prev_oparg == 1) {
1158
130
                       is_redundant_pair = true;
1159
130
                   }
1160
293k
                }
1161
3.84M
                if (is_redundant_pair) {
1162
6.02k
                    INSTR_SET_OP0(prev_instr, NOP);
1163
6.02k
                    INSTR_SET_OP0(instr, NOP);
1164
6.02k
                    done = false;
1165
6.02k
                }
1166
3.84M
            }
1167
541k
            if ((instr && is_jump(instr)) || !BB_HAS_FALLTHROUGH(b)) {
1168
382k
                instr = NULL;
1169
382k
            }
1170
541k
        }
1171
53.8k
    }
1172
52.7k
    return SUCCESS;
1173
52.7k
}
1174
1175
static int
1176
116k
remove_redundant_jumps(cfg_builder *g) {
1177
    /* If a non-empty block ends with a jump instruction, check if the next
1178
     * non-empty block reached through normal flow control is the target
1179
     * of that jump. If it is, then the jump instruction is redundant and
1180
     * can be deleted.
1181
     *
1182
     * Return the number of changes applied, or -1 on error.
1183
     */
1184
1185
116k
    int changes = 0;
1186
2.35M
    for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
1187
2.23M
        cfg_instr *last = basicblock_last_instr(b);
1188
2.23M
        if (last == NULL) {
1189
282k
            continue;
1190
282k
        }
1191
2.23M
        assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
1192
1.95M
        if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
1193
486k
            basicblock* jump_target = next_nonempty_block(last->i_target);
1194
486k
            if (jump_target == NULL) {
1195
0
                PyErr_SetString(PyExc_SystemError, "jump with NULL target");
1196
0
                return ERROR;
1197
0
            }
1198
486k
            basicblock *next = next_nonempty_block(b->b_next);
1199
486k
            if (jump_target == next) {
1200
16.2k
                changes++;
1201
16.2k
                INSTR_SET_OP0(last, NOP);
1202
16.2k
            }
1203
486k
        }
1204
1.95M
    }
1205
1206
116k
    return changes;
1207
116k
}
1208
1209
static inline bool
1210
499k
basicblock_has_no_lineno(basicblock *b) {
1211
606k
    for (int i = 0; i < b->b_iused; i++) {
1212
564k
        if (b->b_instr[i].i_loc.lineno >= 0) {
1213
457k
            return false;
1214
457k
        }
1215
564k
    }
1216
42.0k
    return true;
1217
499k
}
1218
1219
/* Maximum size of basic block that should be copied in optimizer */
1220
8.53k
#define MAX_COPY_SIZE 4
1221
1222
/* If this block ends with an unconditional jump to a small exit block or
1223
 * a block that has no line numbers (and no fallthrough), then
1224
 * remove the jump and extend this block with the target.
1225
 * Returns 1 if extended, 0 if no change, and -1 on error.
1226
 */
1227
static int
1228
816k
basicblock_inline_small_or_no_lineno_blocks(basicblock *bb) {
1229
816k
    cfg_instr *last = basicblock_last_instr(bb);
1230
816k
    if (last == NULL) {
1231
0
        return 0;
1232
0
    }
1233
816k
    if (!IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
1234
639k
        return 0;
1235
639k
    }
1236
177k
    basicblock *target = last->i_target;
1237
177k
    bool small_exit_block = (basicblock_exits_scope(target) &&
1238
8.53k
                             target->b_iused <= MAX_COPY_SIZE);
1239
177k
    bool no_lineno_no_fallthrough = (basicblock_has_no_lineno(target) &&
1240
21.6k
                                     !BB_HAS_FALLTHROUGH(target));
1241
177k
    if (small_exit_block || no_lineno_no_fallthrough) {
1242
12.9k
        assert(is_jump(last));
1243
12.9k
        int removed_jump_opcode = last->i_opcode;
1244
12.9k
        INSTR_SET_OP0(last, NOP);
1245
12.9k
        RETURN_IF_ERROR(basicblock_append_instructions(bb, target));
1246
12.9k
        if (no_lineno_no_fallthrough) {
1247
10.8k
            last = basicblock_last_instr(bb);
1248
10.8k
            if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode) &&
1249
6.28k
                removed_jump_opcode == JUMP)
1250
79
            {
1251
                /* Make sure we don't lose eval breaker checks */
1252
79
                last->i_opcode = JUMP;
1253
79
            }
1254
10.8k
        }
1255
12.9k
        target->b_predecessors--;
1256
12.9k
        return 1;
1257
12.9k
    }
1258
164k
    return 0;
1259
177k
}
1260
1261
static int
1262
52.7k
inline_small_or_no_lineno_blocks(basicblock *entryblock) {
1263
52.7k
    bool changes;
1264
55.6k
    do {
1265
55.6k
        changes = false;
1266
872k
        for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
1267
816k
            int res = basicblock_inline_small_or_no_lineno_blocks(b);
1268
816k
            RETURN_IF_ERROR(res);
1269
816k
            if (res) {
1270
12.9k
                changes = true;
1271
12.9k
            }
1272
816k
        }
1273
55.6k
    } while(changes); /* every change removes a jump, ensuring convergence */
1274
52.7k
    return changes;
1275
52.7k
}
1276
1277
// Attempt to eliminate jumps to jumps by updating inst to jump to
1278
// target->i_target using the provided opcode. Return whether or not the
1279
// optimization was successful.
1280
static bool
1281
jump_thread(basicblock *bb, cfg_instr *inst, cfg_instr *target, int opcode)
1282
1.51k
{
1283
1.51k
    assert(is_jump(inst));
1284
1.51k
    assert(is_jump(target));
1285
1.51k
    assert(inst == basicblock_last_instr(bb));
1286
    // bpo-45773: If inst->i_target == target->i_target, then nothing actually
1287
    // changes (and we fall into an infinite loop):
1288
1.51k
    if (inst->i_target != target->i_target) {
1289
        /* Change inst to NOP and append a jump to target->i_target. The
1290
         * NOP will be removed later if it's not needed for the lineno.
1291
         */
1292
1.51k
        INSTR_SET_OP0(inst, NOP);
1293
1294
1.51k
        RETURN_IF_ERROR(
1295
1.51k
            basicblock_add_jump(
1296
1.51k
                bb, opcode, target->i_target, target->i_loc));
1297
1298
1.51k
        return true;
1299
1.51k
    }
1300
0
    return false;
1301
1.51k
}
1302
1303
static int
1304
loads_const(int opcode)
1305
12.1M
{
1306
12.1M
    return OPCODE_HAS_CONST(opcode)
1307
6.43M
        || opcode == LOAD_SMALL_INT
1308
4.46M
        || opcode == LOAD_COMMON_CONSTANT;
1309
12.1M
}
1310
1311
/* Returns new reference */
1312
static PyObject*
1313
get_const_value(int opcode, int oparg, PyObject *co_consts)
1314
3.46M
{
1315
3.46M
    PyObject *constant = NULL;
1316
3.46M
    assert(loads_const(opcode));
1317
3.46M
    if (opcode == LOAD_CONST) {
1318
2.94M
        assert(PyList_Check(co_consts));
1319
2.94M
        Py_ssize_t n = PyList_GET_SIZE(co_consts);
1320
2.94M
        if (oparg < 0 || oparg >= n) {
1321
0
            PyErr_Format(PyExc_ValueError,
1322
0
                         "LOAD_CONST index %d is out of range for consts (len=%zd)",
1323
0
                         oparg, n);
1324
0
            return NULL;
1325
0
        }
1326
2.94M
        constant = PyList_GET_ITEM(co_consts, oparg);
1327
2.94M
    }
1328
3.46M
    if (opcode == LOAD_SMALL_INT) {
1329
472k
        return PyLong_FromLong(oparg);
1330
472k
    }
1331
2.99M
    if (opcode == LOAD_COMMON_CONSTANT) {
1332
46.3k
        assert(oparg < NUM_COMMON_CONSTANTS);
1333
46.3k
        return PyStackRef_AsPyObjectBorrow(
1334
46.3k
            _PyInterpreterState_GET()->common_consts[oparg]);
1335
46.3k
    }
1336
1337
2.94M
    if (constant == NULL) {
1338
0
        PyErr_SetString(PyExc_SystemError,
1339
0
                        "Internal error: failed to get value of a constant");
1340
0
        return NULL;
1341
0
    }
1342
2.94M
    return Py_NewRef(constant);
1343
2.94M
}
1344
1345
// Steals a reference to newconst.
1346
static int
1347
add_const(PyObject *newconst, PyObject *consts, PyObject *const_cache,
1348
          _Py_hashtable_t *consts_index)
1349
657k
{
1350
657k
    if (_PyCompile_ConstCacheMergeOne(const_cache, &newconst) < 0) {
1351
0
        Py_DECREF(newconst);
1352
0
        return -1;
1353
0
    }
1354
1355
657k
    _Py_hashtable_entry_t *entry = _Py_hashtable_get_entry(consts_index, (void *)newconst);
1356
657k
    if (entry != NULL) {
1357
492k
        Py_DECREF(newconst);
1358
492k
        return (int)(uintptr_t)entry->value;
1359
492k
    }
1360
1361
164k
    Py_ssize_t index = PyList_GET_SIZE(consts);
1362
164k
    if ((size_t)index >= (size_t)INT_MAX - 1) {
1363
0
        PyErr_SetString(PyExc_OverflowError, "too many constants");
1364
0
        Py_DECREF(newconst);
1365
0
        return -1;
1366
0
    }
1367
164k
    if (PyList_Append(consts, newconst)) {
1368
0
        Py_DECREF(newconst);
1369
0
        return -1;
1370
0
    }
1371
1372
164k
    if (_Py_hashtable_set(consts_index, (void *)newconst, (void *)(uintptr_t)index) < 0) {
1373
0
        PyList_SetSlice(consts, index, index + 1, NULL);
1374
0
        Py_DECREF(newconst);
1375
0
        PyErr_NoMemory();
1376
0
        return -1;
1377
0
    }
1378
1379
164k
    Py_DECREF(newconst);
1380
164k
    return (int)index;
1381
164k
}
1382
1383
/*
1384
  Traverse the instructions of the basic block backwards from index "start", skipping over NOPs.
1385
  Try to collect "size" number of consecutive instructions that load constants into the array "instrs".
1386
  Caller must make sure that length of "instrs" is sufficient to fit in at least "size" instructions.
1387
1388
  Return boolean indicating whether "size" such instructions were found.
1389
*/
1390
static bool
1391
get_const_loading_instrs(basicblock *bb, int start, cfg_instr **instrs, int size)
1392
1.11M
{
1393
1.11M
    assert(start < bb->b_iused);
1394
1.11M
    assert(size >= 0);
1395
1.11M
    assert(size <= _PY_STACK_USE_GUIDELINE);
1396
1397
3.82M
    for (; start >= 0 && size > 0; start--) {
1398
2.99M
        cfg_instr *instr = &bb->b_instr[start];
1399
2.99M
        if (instr->i_opcode == NOP) {
1400
1.13M
            continue;
1401
1.13M
        }
1402
1.86M
        if (!loads_const(instr->i_opcode)) {
1403
278k
            return false;
1404
278k
        }
1405
1.58M
        instrs[--size] = instr;
1406
1.58M
    }
1407
1408
833k
    return size == 0;
1409
1.11M
}
1410
1411
/*
1412
  Change every instruction in "instrs" NOP and set its location to NO_LOCATION.
1413
  Caller must make sure "instrs" has at least "size" elements.
1414
*/
1415
static void
1416
nop_out(cfg_instr **instrs, int size)
1417
798k
{
1418
2.18M
    for (int i = 0; i < size; i++) {
1419
1.38M
        cfg_instr *instr = instrs[i];
1420
1.38M
        assert(instr->i_opcode != NOP);
1421
1.38M
        INSTR_SET_OP0(instr, NOP);
1422
1.38M
        INSTR_SET_LOC(instr, NO_LOCATION);
1423
1.38M
    }
1424
798k
}
1425
1426
/* Does not steal reference to "newconst".
1427
   Return 1 if changed instruction to LOAD_SMALL_INT.
1428
   Return 0 if could not change instruction to LOAD_SMALL_INT.
1429
   Return -1 on error.
1430
*/
1431
static int
1432
maybe_instr_make_load_smallint(cfg_instr *instr, PyObject *newconst,
1433
                               PyObject *consts, PyObject *const_cache)
1434
2.02M
{
1435
2.02M
    if (PyLong_CheckExact(newconst)) {
1436
1.10M
        int overflow;
1437
1.10M
        long val = PyLong_AsLongAndOverflow(newconst, &overflow);
1438
1.10M
        if (val == -1 && PyErr_Occurred()) {
1439
0
            return -1;
1440
0
        }
1441
1.10M
        if (!overflow && _PY_IS_SMALL_INT(val) && 0 <= val && val <= 255) {
1442
594k
            assert(_Py_IsImmortal(newconst));
1443
594k
            INSTR_SET_OP1(instr, LOAD_SMALL_INT, (int)val);
1444
594k
            return 1;
1445
594k
        }
1446
1.10M
    }
1447
1.42M
    return 0;
1448
2.02M
}
1449
1450
/* Does not steal reference to "newconst".
1451
   Return 1 if changed instruction to LOAD_COMMON_CONSTANT.
1452
   Return 0 if could not change instruction to LOAD_COMMON_CONSTANT.
1453
   Return -1 on error.
1454
*/
1455
static int
1456
maybe_instr_make_load_common_const(cfg_instr *instr, PyObject *newconst)
1457
1.42M
{
1458
1.42M
    int oparg;
1459
1.42M
    if (newconst == Py_None) {
1460
123k
        oparg = CONSTANT_NONE;
1461
123k
    }
1462
1.30M
    else if (newconst == Py_True) {
1463
10.5k
        oparg = CONSTANT_TRUE;
1464
10.5k
    }
1465
1.28M
    else if (newconst == Py_False) {
1466
761
        oparg = CONSTANT_FALSE;
1467
761
    }
1468
1.28M
    else if (PyUnicode_CheckExact(newconst)
1469
112k
             && PyUnicode_GET_LENGTH(newconst) == 0) {
1470
7.05k
        oparg = CONSTANT_EMPTY_STR;
1471
7.05k
    }
1472
1.28M
    else if (PyTuple_CheckExact(newconst)
1473
104k
             && PyTuple_GET_SIZE(newconst) == 0) {
1474
20.3k
        oparg = CONSTANT_EMPTY_TUPLE;
1475
20.3k
    }
1476
1.26M
    else if (PyLong_CheckExact(newconst)) {
1477
515k
        int overflow;
1478
515k
        long val = PyLong_AsLongAndOverflow(newconst, &overflow);
1479
515k
        if (val == -1 && PyErr_Occurred()) {
1480
0
            return -1;
1481
0
        }
1482
515k
        if (overflow || val != -1) {
1483
481k
            return 0;
1484
481k
        }
1485
33.6k
        oparg = CONSTANT_MINUS_ONE;
1486
33.6k
    }
1487
746k
    else {
1488
746k
        return 0;
1489
746k
    }
1490
1.42M
    assert(_Py_IsImmortal(newconst));
1491
195k
    INSTR_SET_OP1(instr, LOAD_COMMON_CONSTANT, oparg);
1492
195k
    return 1;
1493
195k
}
1494
1495
/* Steals reference to "newconst" */
1496
static int
1497
instr_make_load_const(cfg_instr *instr, PyObject *newconst,
1498
                      PyObject *consts, PyObject *const_cache,
1499
                      _Py_hashtable_t *consts_index)
1500
775k
{
1501
775k
    int res = maybe_instr_make_load_smallint(instr, newconst, consts, const_cache);
1502
775k
    if (res < 0) {
1503
0
        Py_DECREF(newconst);
1504
0
        return ERROR;
1505
0
    }
1506
775k
    if (res > 0) {
1507
82.9k
        return SUCCESS;
1508
82.9k
    }
1509
692k
    res = maybe_instr_make_load_common_const(instr, newconst);
1510
692k
    if (res < 0) {
1511
0
        Py_DECREF(newconst);
1512
0
        return ERROR;
1513
0
    }
1514
692k
    if (res > 0) {
1515
42.6k
        return SUCCESS;
1516
42.6k
    }
1517
650k
    int oparg = add_const(newconst, consts, const_cache, consts_index);
1518
650k
    RETURN_IF_ERROR(oparg);
1519
650k
    INSTR_SET_OP1(instr, LOAD_CONST, oparg);
1520
650k
    return SUCCESS;
1521
650k
}
1522
1523
/* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n
1524
   with    LOAD_CONST (c1, c2, ... cn).
1525
   The consts table must still be in list form so that the
1526
   new constant (c1, c2, ... cn) can be appended.
1527
   Called with codestr pointing to the first LOAD_CONST.
1528
*/
1529
static int
1530
fold_tuple_of_constants(basicblock *bb, int i, PyObject *consts,
1531
                        PyObject *const_cache, _Py_hashtable_t *consts_index)
1532
72.3k
{
1533
    /* Pre-conditions */
1534
72.3k
    assert(PyDict_CheckExact(const_cache));
1535
72.3k
    assert(PyList_CheckExact(consts));
1536
1537
72.3k
    cfg_instr *instr = &bb->b_instr[i];
1538
72.3k
    assert(instr->i_opcode == BUILD_TUPLE);
1539
1540
72.3k
    int seq_size = instr->i_oparg;
1541
72.3k
    if (seq_size > _PY_STACK_USE_GUIDELINE) {
1542
13
        return SUCCESS;
1543
13
    }
1544
1545
72.3k
    cfg_instr *const_instrs[_PY_STACK_USE_GUIDELINE];
1546
72.3k
    if (!get_const_loading_instrs(bb, i-1, const_instrs, seq_size)) {
1547
        /* not a const sequence */
1548
34.1k
        return SUCCESS;
1549
34.1k
    }
1550
1551
38.1k
    PyObject *const_tuple = PyTuple_New((Py_ssize_t)seq_size);
1552
38.1k
    if (const_tuple == NULL) {
1553
0
        return ERROR;
1554
0
    }
1555
1556
99.5k
    for (int i = 0; i < seq_size; i++) {
1557
61.3k
        cfg_instr *inst = const_instrs[i];
1558
61.3k
        assert(loads_const(inst->i_opcode));
1559
61.3k
        PyObject *element = get_const_value(inst->i_opcode, inst->i_oparg, consts);
1560
61.3k
        if (element == NULL) {
1561
0
            Py_DECREF(const_tuple);
1562
0
            return ERROR;
1563
0
        }
1564
61.3k
        PyTuple_SET_ITEM(const_tuple, i, element);
1565
61.3k
    }
1566
1567
38.1k
    nop_out(const_instrs, seq_size);
1568
38.1k
    return instr_make_load_const(instr, const_tuple, consts, const_cache, consts_index);
1569
38.1k
}
1570
1571
/* Replace:
1572
    BUILD_LIST/BUILD_SET 0
1573
    LOAD_CONST c1
1574
    LIST_APPEND/SET_ADD 1
1575
    LOAD_CONST c2
1576
    LIST_APPEND/SET_ADD 1
1577
    ...
1578
    LOAD_CONST cN
1579
    LIST_APPEND/SET_ADD 1
1580
    [CALL_INTRINSIC_1 INTRINSIC_LIST_TO_TUPLE]   <-- optional
1581
   with:
1582
    LOAD_CONST (c1, c2, ... cN)
1583
   The instruction at `i` is either the LIST_TO_TUPLE intrinsic (so the
1584
   immediately preceding non-NOP instruction is expected to be a
1585
   LIST_APPEND, and only the BUILD_LIST/LIST_APPEND form is considered),
1586
   or the trailing LIST_APPEND or SET_ADD itself, in which case the
1587
   matching BUILD_LIST/BUILD_SET start is selected from its opcode, and
1588
   for sets the result is wrapped in a frozenset.
1589
*/
1590
static int
1591
fold_constant_seq_into_load_const(basicblock *bb, int i,
1592
                                  PyObject *consts, PyObject *const_cache,
1593
                                  _Py_hashtable_t *consts_index)
1594
2.87k
{
1595
2.87k
    assert(PyDict_CheckExact(const_cache));
1596
2.87k
    assert(PyList_CheckExact(consts));
1597
2.87k
    assert(i >= 0);
1598
2.87k
    assert(i < bb->b_iused);
1599
1600
2.87k
    cfg_instr *target = &bb->b_instr[i];
1601
2.87k
    assert(target->i_opcode == LIST_APPEND || target->i_opcode == SET_ADD ||
1602
2.87k
           (target->i_opcode == CALL_INTRINSIC_1 &&
1603
2.87k
            target->i_oparg == INTRINSIC_LIST_TO_TUPLE));
1604
2.87k
    bool expected_append = target->i_opcode == CALL_INTRINSIC_1;
1605
2.87k
    int append_op = expected_append ? LIST_APPEND : target->i_opcode;
1606
2.87k
    assert(append_op == LIST_APPEND || append_op == SET_ADD);
1607
2.87k
    int build_op = append_op == LIST_APPEND ? BUILD_LIST : BUILD_SET;
1608
2.87k
    int consts_found = 0;
1609
    /* Walking backward from `i`, we expect LIST_APPEND/SET_ADD and
1610
       LOAD_CONST to alternate. If `i` is the trailing LIST_TO_TUPLE
1611
       intrinsic, the next instruction back is an APPEND. If `i` is the
1612
       trailing APPEND itself, the next instruction back is a LOAD_CONST. */
1613
2.87k
    bool expect_append = expected_append;
1614
1615
66.5k
    for (int pos = i - 1; pos >= 0; pos--) {
1616
66.4k
        cfg_instr *instr = &bb->b_instr[pos];
1617
66.4k
        int opcode = instr->i_opcode;
1618
66.4k
        int oparg = instr->i_oparg;
1619
1620
66.4k
        if (opcode == NOP) {
1621
36.5k
            continue;
1622
36.5k
        }
1623
1624
29.9k
        if (opcode == build_op && oparg == 0) {
1625
103
            if (!expect_append) {
1626
                /* Not a sequence start. */
1627
1
                return SUCCESS;
1628
1
            }
1629
1630
            /* Sequence start, we are done. */
1631
102
            PyObject *newconst = PyTuple_New((Py_ssize_t)consts_found);
1632
102
            if (newconst == NULL) {
1633
0
                return ERROR;
1634
0
            }
1635
1636
102
            int newpos_start = expected_append ? i - 1 : i;
1637
43.0k
            for (int newpos = newpos_start; newpos >= pos; newpos--) {
1638
42.9k
                instr = &bb->b_instr[newpos];
1639
42.9k
                if (instr->i_opcode == NOP) {
1640
24.7k
                    continue;
1641
24.7k
                }
1642
18.2k
                if (loads_const(instr->i_opcode)) {
1643
9.06k
                    PyObject *constant = get_const_value(instr->i_opcode, instr->i_oparg, consts);
1644
9.06k
                    if (constant == NULL) {
1645
0
                        Py_DECREF(newconst);
1646
0
                        return ERROR;
1647
0
                    }
1648
9.06k
                    assert(consts_found > 0);
1649
9.06k
                    PyTuple_SET_ITEM(newconst, --consts_found, constant);
1650
9.06k
                }
1651
18.2k
                nop_out(&instr, 1);
1652
18.2k
            }
1653
102
            assert(consts_found == 0);
1654
1655
102
            if (build_op == BUILD_SET) {
1656
0
                PyObject *frozen = PyFrozenSet_New(newconst);
1657
0
                Py_DECREF(newconst);
1658
0
                if (frozen == NULL) {
1659
0
                    return ERROR;
1660
0
                }
1661
0
                newconst = frozen;
1662
0
            }
1663
102
            return instr_make_load_const(target, newconst, consts, const_cache, consts_index);
1664
102
        }
1665
1666
29.8k
        if (expect_append) {
1667
15.5k
            if (opcode != append_op || oparg != 1) {
1668
1.09k
                return SUCCESS;
1669
1.09k
            }
1670
15.5k
        }
1671
14.3k
        else {
1672
14.3k
            if (!loads_const(opcode)) {
1673
1.59k
                return SUCCESS;
1674
1.59k
            }
1675
12.7k
            consts_found++;
1676
12.7k
        }
1677
1678
27.1k
        expect_append = !expect_append;
1679
27.1k
    }
1680
1681
    /* Did not find sequence start. */
1682
80
    return SUCCESS;
1683
2.87k
}
1684
1685
34.8k
#define MIN_CONST_SEQUENCE_SIZE 3
1686
/*
1687
Optimize lists and sets for:
1688
    1. "for" loop, comprehension or "in"/"not in" tests:
1689
           Change literal list or set of constants into constant
1690
           tuple or frozenset respectively. Change list of
1691
           non-constants into tuple.
1692
    2. Constant literal lists/set with length >= MIN_CONST_SEQUENCE_SIZE:
1693
           Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cN, BUILD_LIST N
1694
           with BUILD_LIST 0, LOAD_CONST (c1, c2, ... cN), LIST_EXTEND 1,
1695
           or BUILD_SET & SET_UPDATE respectively.
1696
*/
1697
static int
1698
optimize_lists_and_sets(basicblock *bb, int i, int nextop,
1699
                        PyObject *consts, PyObject *const_cache,
1700
                        _Py_hashtable_t *consts_index)
1701
17.4k
{
1702
17.4k
    assert(PyDict_CheckExact(const_cache));
1703
17.4k
    assert(PyList_CheckExact(consts));
1704
1705
17.4k
    cfg_instr *instr = &bb->b_instr[i];
1706
17.4k
    assert(instr->i_opcode == BUILD_LIST || instr->i_opcode == BUILD_SET);
1707
1708
17.4k
    bool contains_or_iter = nextop == GET_ITER || nextop == CONTAINS_OP;
1709
17.4k
    int seq_size = instr->i_oparg;
1710
17.4k
    if (seq_size > _PY_STACK_USE_GUIDELINE ||
1711
17.4k
        (seq_size < MIN_CONST_SEQUENCE_SIZE && !contains_or_iter))
1712
12.2k
    {
1713
12.2k
        return SUCCESS;
1714
12.2k
    }
1715
1716
5.11k
    cfg_instr *const_instrs[_PY_STACK_USE_GUIDELINE];
1717
5.11k
    if (!get_const_loading_instrs(bb, i-1, const_instrs, seq_size)) {  /* not a const sequence */
1718
677
        if (contains_or_iter && instr->i_opcode == BUILD_LIST) {
1719
            /* iterate over a tuple instead of list */
1720
3
            INSTR_SET_OP1(instr, BUILD_TUPLE, instr->i_oparg);
1721
3
        }
1722
677
        return SUCCESS;
1723
677
    }
1724
1725
4.43k
    PyObject *const_result = PyTuple_New((Py_ssize_t)seq_size);
1726
4.43k
    if (const_result == NULL) {
1727
0
        return ERROR;
1728
0
    }
1729
1730
24.7k
    for (int i = 0; i < seq_size; i++) {
1731
20.3k
        cfg_instr *inst = const_instrs[i];
1732
20.3k
        assert(loads_const(inst->i_opcode));
1733
20.3k
        PyObject *element = get_const_value(inst->i_opcode, inst->i_oparg, consts);
1734
20.3k
        if (element == NULL) {
1735
0
            Py_DECREF(const_result);
1736
0
            return ERROR;
1737
0
        }
1738
20.3k
        PyTuple_SET_ITEM(const_result, i, element);
1739
20.3k
    }
1740
1741
4.43k
    if (instr->i_opcode == BUILD_SET) {
1742
4.29k
        PyObject *frozenset = PyFrozenSet_New(const_result);
1743
4.29k
        if (frozenset == NULL) {
1744
0
            Py_DECREF(const_result);
1745
0
            return ERROR;
1746
0
        }
1747
4.29k
        Py_SETREF(const_result, frozenset);
1748
4.29k
    }
1749
1750
4.43k
    int index = add_const(const_result, consts, const_cache, consts_index);
1751
4.43k
    RETURN_IF_ERROR(index);
1752
4.43k
    nop_out(const_instrs, seq_size);
1753
1754
4.43k
    if (contains_or_iter) {
1755
176
        INSTR_SET_OP1(instr, LOAD_CONST, index);
1756
176
    }
1757
4.25k
    else {
1758
4.25k
        assert(i >= 2);
1759
4.25k
        assert(instr->i_opcode == BUILD_LIST || instr->i_opcode == BUILD_SET);
1760
1761
4.25k
        INSTR_SET_LOC(&bb->b_instr[i-2], instr->i_loc);
1762
1763
4.25k
        INSTR_SET_OP1(&bb->b_instr[i-2], instr->i_opcode, 0);
1764
4.25k
        INSTR_SET_OP1(&bb->b_instr[i-1], LOAD_CONST, index);
1765
4.25k
        INSTR_SET_OP1(&bb->b_instr[i], instr->i_opcode == BUILD_LIST ? LIST_EXTEND : SET_UPDATE, 1);
1766
4.25k
    }
1767
4.43k
    return SUCCESS;
1768
4.43k
}
1769
1770
/* Check whether the total number of items in the (possibly nested) collection obj exceeds
1771
 * limit. Return a negative number if it does, and a non-negative number otherwise.
1772
 * Used to avoid creating constants which are slow to hash.
1773
 */
1774
static Py_ssize_t
1775
const_folding_check_complexity(PyObject *obj, Py_ssize_t limit)
1776
189k
{
1777
189k
    if (PyTuple_Check(obj)) {
1778
122k
        Py_ssize_t i;
1779
122k
        limit -= PyTuple_GET_SIZE(obj);
1780
281k
        for (i = 0; limit >= 0 && i < PyTuple_GET_SIZE(obj); i++) {
1781
159k
            limit = const_folding_check_complexity(PyTuple_GET_ITEM(obj, i), limit);
1782
159k
            if (limit < 0) {
1783
413
                return limit;
1784
413
            }
1785
159k
        }
1786
122k
    }
1787
189k
    return limit;
1788
189k
}
1789
1790
96.0k
#define MAX_INT_SIZE           128  /* bits */
1791
32.5k
#define MAX_COLLECTION_SIZE    256  /* items */
1792
14.0k
#define MAX_STR_SIZE          4096  /* characters */
1793
29.8k
#define MAX_TOTAL_ITEMS       1024  /* including nested collections */
1794
1795
static PyObject *
1796
const_folding_safe_multiply(PyObject *v, PyObject *w)
1797
187k
{
1798
187k
    if (PyLong_Check(v) && PyLong_Check(w) &&
1799
34.8k
        !_PyLong_IsZero((PyLongObject *)v) && !_PyLong_IsZero((PyLongObject *)w)
1800
187k
    ) {
1801
30.3k
        int64_t vbits = _PyLong_NumBits(v);
1802
30.3k
        int64_t wbits = _PyLong_NumBits(w);
1803
30.3k
        assert(vbits >= 0);
1804
30.3k
        assert(wbits >= 0);
1805
30.3k
        if (vbits + wbits > MAX_INT_SIZE) {
1806
448
            return NULL;
1807
448
        }
1808
30.3k
    }
1809
157k
    else if (PyLong_Check(v) && PyTuple_Check(w)) {
1810
33.0k
        Py_ssize_t size = PyTuple_GET_SIZE(w);
1811
33.0k
        if (size) {
1812
32.9k
            long n = PyLong_AsLong(v);
1813
32.9k
            if (n < 0 || n > MAX_COLLECTION_SIZE / size) {
1814
2.36k
                return NULL;
1815
2.36k
            }
1816
30.5k
            if (n && const_folding_check_complexity(w, MAX_TOTAL_ITEMS / n) < 0) {
1817
85
                return NULL;
1818
85
            }
1819
30.5k
        }
1820
33.0k
    }
1821
124k
    else if (PyLong_Check(v) && (PyUnicode_Check(w) || PyBytes_Check(w))) {
1822
20.4k
        Py_ssize_t size = PyUnicode_Check(w) ? PyUnicode_GET_LENGTH(w) :
1823
20.4k
                                               PyBytes_GET_SIZE(w);
1824
20.4k
        if (size) {
1825
14.3k
            long n = PyLong_AsLong(v);
1826
14.3k
            if (n < 0 || n > MAX_STR_SIZE / size) {
1827
920
                return NULL;
1828
920
            }
1829
14.3k
        }
1830
20.4k
    }
1831
103k
    else if (PyLong_Check(w) &&
1832
70.8k
             (PyTuple_Check(v) || PyUnicode_Check(v) || PyBytes_Check(v)))
1833
52.2k
    {
1834
52.2k
        return const_folding_safe_multiply(w, v);
1835
52.2k
    }
1836
1837
131k
    return PyNumber_Multiply(v, w);
1838
187k
}
1839
1840
static PyObject *
1841
const_folding_safe_power(PyObject *v, PyObject *w)
1842
116k
{
1843
116k
    if (PyLong_Check(v) && PyLong_Check(w) &&
1844
52.5k
        !_PyLong_IsZero((PyLongObject *)v) && _PyLong_IsPositive((PyLongObject *)w)
1845
116k
    ) {
1846
43.7k
        int64_t vbits = _PyLong_NumBits(v);
1847
43.7k
        size_t wbits = PyLong_AsSize_t(w);
1848
43.7k
        assert(vbits >= 0);
1849
43.7k
        if (wbits == (size_t)-1) {
1850
364
            return NULL;
1851
364
        }
1852
43.3k
        if ((uint64_t)vbits > MAX_INT_SIZE / wbits) {
1853
4.72k
            return NULL;
1854
4.72k
        }
1855
43.3k
    }
1856
1857
111k
    return PyNumber_Power(v, w, Py_None);
1858
116k
}
1859
1860
static PyObject *
1861
const_folding_safe_lshift(PyObject *v, PyObject *w)
1862
10.5k
{
1863
10.5k
    if (PyLong_Check(v) && PyLong_Check(w) &&
1864
10.1k
        !_PyLong_IsZero((PyLongObject *)v) && !_PyLong_IsZero((PyLongObject *)w)
1865
10.5k
    ) {
1866
8.73k
        int64_t vbits = _PyLong_NumBits(v);
1867
8.73k
        size_t wbits = PyLong_AsSize_t(w);
1868
8.73k
        assert(vbits >= 0);
1869
8.73k
        if (wbits == (size_t)-1) {
1870
759
            return NULL;
1871
759
        }
1872
7.97k
        if (wbits > MAX_INT_SIZE || (uint64_t)vbits > MAX_INT_SIZE - wbits) {
1873
1.66k
            return NULL;
1874
1.66k
        }
1875
7.97k
    }
1876
1877
8.11k
    return PyNumber_Lshift(v, w);
1878
10.5k
}
1879
1880
static PyObject *
1881
const_folding_safe_mod(PyObject *v, PyObject *w)
1882
34.8k
{
1883
34.8k
    if (PyUnicode_Check(v) || PyBytes_Check(v)) {
1884
138
        return NULL;
1885
138
    }
1886
1887
34.7k
    return PyNumber_Remainder(v, w);
1888
34.8k
}
1889
1890
static PyObject *
1891
eval_const_binop(PyObject *left, int op, PyObject *right)
1892
598k
{
1893
598k
    assert(left != NULL && right != NULL);
1894
598k
    assert(op >= 0 && op <= NB_OPARG_LAST);
1895
1896
598k
    PyObject *result = NULL;
1897
598k
    switch (op) {
1898
80.9k
        case NB_ADD:
1899
80.9k
            result = PyNumber_Add(left, right);
1900
80.9k
            break;
1901
81.3k
        case NB_SUBTRACT:
1902
81.3k
            result = PyNumber_Subtract(left, right);
1903
81.3k
            break;
1904
135k
        case NB_MULTIPLY:
1905
135k
            result = const_folding_safe_multiply(left, right);
1906
135k
            break;
1907
74.2k
        case NB_TRUE_DIVIDE:
1908
74.2k
            result = PyNumber_TrueDivide(left, right);
1909
74.2k
            break;
1910
24.6k
        case NB_FLOOR_DIVIDE:
1911
24.6k
            result = PyNumber_FloorDivide(left, right);
1912
24.6k
            break;
1913
34.8k
        case NB_REMAINDER:
1914
34.8k
            result = const_folding_safe_mod(left, right);
1915
34.8k
            break;
1916
116k
        case NB_POWER:
1917
116k
            result = const_folding_safe_power(left, right);
1918
116k
            break;
1919
10.5k
        case NB_LSHIFT:
1920
10.5k
            result = const_folding_safe_lshift(left, right);
1921
10.5k
            break;
1922
13.6k
        case NB_RSHIFT:
1923
13.6k
            result = PyNumber_Rshift(left, right);
1924
13.6k
            break;
1925
6.67k
        case NB_OR:
1926
6.67k
            result = PyNumber_Or(left, right);
1927
6.67k
            break;
1928
5.95k
        case NB_XOR:
1929
5.95k
            result = PyNumber_Xor(left, right);
1930
5.95k
            break;
1931
6.60k
        case NB_AND:
1932
6.60k
            result = PyNumber_And(left, right);
1933
6.60k
            break;
1934
6.40k
        case NB_SUBSCR:
1935
6.40k
            result = PyObject_GetItem(left, right);
1936
6.40k
            break;
1937
441
        case NB_MATRIX_MULTIPLY:
1938
            // No builtin constants implement matrix multiplication
1939
441
            break;
1940
0
        default:
1941
0
            Py_UNREACHABLE();
1942
598k
    }
1943
598k
    return result;
1944
598k
}
1945
1946
static int
1947
fold_const_binop(basicblock *bb, int i, PyObject *consts,
1948
                 PyObject *const_cache, _Py_hashtable_t *consts_index)
1949
807k
{
1950
1.35M
    #define BINOP_OPERAND_COUNT 2
1951
807k
    assert(PyDict_CheckExact(const_cache));
1952
807k
    assert(PyList_CheckExact(consts));
1953
1954
807k
    cfg_instr *binop = &bb->b_instr[i];
1955
807k
    assert(binop->i_opcode == BINARY_OP);
1956
1957
807k
    cfg_instr *operands_instrs[BINOP_OPERAND_COUNT];
1958
807k
    if (!get_const_loading_instrs(bb, i-1, operands_instrs, BINOP_OPERAND_COUNT)) {
1959
        /* not a const sequence */
1960
208k
        return SUCCESS;
1961
208k
    }
1962
1963
598k
    cfg_instr *lhs_instr = operands_instrs[0];
1964
598k
    assert(loads_const(lhs_instr->i_opcode));
1965
598k
    PyObject *lhs = get_const_value(lhs_instr->i_opcode, lhs_instr->i_oparg, consts);
1966
598k
    if (lhs == NULL) {
1967
0
        return ERROR;
1968
0
    }
1969
1970
598k
    cfg_instr *rhs_instr = operands_instrs[1];
1971
598k
    assert(loads_const(rhs_instr->i_opcode));
1972
598k
    PyObject *rhs = get_const_value(rhs_instr->i_opcode, rhs_instr->i_oparg, consts);
1973
598k
    if (rhs == NULL) {
1974
0
        Py_DECREF(lhs);
1975
0
        return ERROR;
1976
0
    }
1977
1978
598k
    PyObject *newconst = eval_const_binop(lhs, binop->i_oparg, rhs);
1979
598k
    Py_DECREF(lhs);
1980
598k
    Py_DECREF(rhs);
1981
598k
    if (newconst == NULL) {
1982
51.8k
        if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) {
1983
0
            return ERROR;
1984
0
        }
1985
51.8k
        PyErr_Clear();
1986
51.8k
        return SUCCESS;
1987
51.8k
    }
1988
1989
546k
    nop_out(operands_instrs, BINOP_OPERAND_COUNT);
1990
546k
    return instr_make_load_const(binop, newconst, consts, const_cache, consts_index);
1991
598k
}
1992
1993
static PyObject *
1994
eval_const_unaryop(PyObject *operand, int opcode, int oparg)
1995
192k
{
1996
192k
    assert(operand != NULL);
1997
192k
    assert(
1998
192k
        opcode == UNARY_NEGATIVE ||
1999
192k
        opcode == UNARY_INVERT ||
2000
192k
        opcode == UNARY_NOT ||
2001
192k
        (opcode == CALL_INTRINSIC_1 && oparg == INTRINSIC_UNARY_POSITIVE)
2002
192k
    );
2003
192k
    PyObject *result;
2004
192k
    switch (opcode) {
2005
145k
        case UNARY_NEGATIVE:
2006
145k
            result = PyNumber_Negative(operand);
2007
145k
            break;
2008
11.4k
        case UNARY_INVERT:
2009
            // XXX: This should be removed once the ~bool depreciation expires.
2010
11.4k
            if (PyBool_Check(operand)) {
2011
70
                return NULL;
2012
70
            }
2013
11.4k
            result = PyNumber_Invert(operand);
2014
11.4k
            break;
2015
61
        case UNARY_NOT: {
2016
61
            int r = PyObject_IsTrue(operand);
2017
61
            if (r < 0) {
2018
0
                return NULL;
2019
0
            }
2020
61
            result = PyBool_FromLong(!r);
2021
61
            break;
2022
61
        }
2023
35.8k
        case CALL_INTRINSIC_1:
2024
35.8k
            if (oparg != INTRINSIC_UNARY_POSITIVE) {
2025
0
                Py_UNREACHABLE();
2026
0
            }
2027
35.8k
            result = PyNumber_Positive(operand);
2028
35.8k
            break;
2029
0
        default:
2030
0
            Py_UNREACHABLE();
2031
192k
    }
2032
192k
    return result;
2033
192k
}
2034
2035
static int
2036
fold_const_unaryop(basicblock *bb, int i, PyObject *consts,
2037
                   PyObject *const_cache, _Py_hashtable_t *consts_index)
2038
227k
{
2039
418k
    #define UNARYOP_OPERAND_COUNT 1
2040
227k
    assert(PyDict_CheckExact(const_cache));
2041
227k
    assert(PyList_CheckExact(consts));
2042
227k
    cfg_instr *unaryop = &bb->b_instr[i];
2043
2044
227k
    cfg_instr *operand_instr;
2045
227k
    if (!get_const_loading_instrs(bb, i-1, &operand_instr, UNARYOP_OPERAND_COUNT)) {
2046
        /* not a const */
2047
34.9k
        return SUCCESS;
2048
34.9k
    }
2049
2050
227k
    assert(loads_const(operand_instr->i_opcode));
2051
192k
    PyObject *operand = get_const_value(
2052
192k
        operand_instr->i_opcode,
2053
192k
        operand_instr->i_oparg,
2054
192k
        consts
2055
192k
    );
2056
192k
    if (operand == NULL) {
2057
0
        return ERROR;
2058
0
    }
2059
2060
192k
    PyObject *newconst = eval_const_unaryop(operand, unaryop->i_opcode, unaryop->i_oparg);
2061
192k
    Py_DECREF(operand);
2062
192k
    if (newconst == NULL) {
2063
1.50k
        if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) {
2064
0
            return ERROR;
2065
0
        }
2066
1.50k
        PyErr_Clear();
2067
1.50k
        return SUCCESS;
2068
1.50k
    }
2069
2070
190k
    if (unaryop->i_opcode == UNARY_NOT) {
2071
61
        assert(PyBool_Check(newconst));
2072
61
    }
2073
190k
    nop_out(&operand_instr, UNARYOP_OPERAND_COUNT);
2074
190k
    return instr_make_load_const(unaryop, newconst, consts, const_cache, consts_index);
2075
190k
}
2076
2077
161k
#define VISITED (-1)
2078
2079
// Replace an arbitrary run of SWAPs and NOPs with an optimal one that has the
2080
// same effect.
2081
static int
2082
swaptimize(basicblock *block, int *ix)
2083
100k
{
2084
    // NOTE: "./python -m test test_patma" serves as a good, quick stress test
2085
    // for this function. Make sure to blow away cached *.pyc files first!
2086
100k
    assert(*ix < block->b_iused);
2087
100k
    cfg_instr *instructions = &block->b_instr[*ix];
2088
    // Find the length of the current sequence of SWAPs and NOPs, and record the
2089
    // maximum depth of the stack manipulations:
2090
100k
    assert(instructions[0].i_opcode == SWAP);
2091
100k
    int depth = instructions[0].i_oparg;
2092
100k
    int len = 0;
2093
100k
    int more = false;
2094
100k
    int limit = block->b_iused - *ix;
2095
114k
    while (++len < limit) {
2096
114k
        int opcode = instructions[len].i_opcode;
2097
114k
        if (opcode == SWAP) {
2098
14.0k
            depth = Py_MAX(depth, instructions[len].i_oparg);
2099
14.0k
            more = true;
2100
14.0k
        }
2101
100k
        else if (opcode != NOP) {
2102
100k
            break;
2103
100k
        }
2104
114k
    }
2105
    // It's already optimal if there's only one SWAP:
2106
100k
    if (!more) {
2107
87.6k
        return SUCCESS;
2108
87.6k
    }
2109
    // Create an array with elements {0, 1, 2, ..., depth - 1}:
2110
12.6k
    int *stack = PyMem_Malloc(depth * sizeof(int));
2111
12.6k
    if (stack == NULL) {
2112
0
        PyErr_NoMemory();
2113
0
        return ERROR;
2114
0
    }
2115
50.5k
    for (int i = 0; i < depth; i++) {
2116
37.8k
        stack[i] = i;
2117
37.8k
    }
2118
    // Simulate the combined effect of these instructions by "running" them on
2119
    // our "stack":
2120
39.3k
    for (int i = 0; i < len; i++) {
2121
26.7k
        if (instructions[i].i_opcode == SWAP) {
2122
26.7k
            int oparg = instructions[i].i_oparg;
2123
26.7k
            int top = stack[0];
2124
            // SWAPs are 1-indexed:
2125
26.7k
            stack[0] = stack[oparg - 1];
2126
26.7k
            stack[oparg - 1] = top;
2127
26.7k
        }
2128
26.7k
    }
2129
    // Now we can begin! Our approach here is based on a solution to a closely
2130
    // related problem (https://cs.stackexchange.com/a/13938). It's easiest to
2131
    // think of this algorithm as determining the steps needed to efficiently
2132
    // "un-shuffle" our stack. By performing the moves in *reverse* order,
2133
    // though, we can efficiently *shuffle* it! For this reason, we will be
2134
    // replacing instructions starting from the *end* of the run. Since the
2135
    // solution is optimal, we don't need to worry about running out of space:
2136
12.6k
    int current = len - 1;
2137
50.5k
    for (int i = 0; i < depth; i++) {
2138
        // Skip items that have already been visited, or just happen to be in
2139
        // the correct location:
2140
37.8k
        if (stack[i] == VISITED || stack[i] == i) {
2141
25.7k
            continue;
2142
25.7k
        }
2143
        // Okay, we've found an item that hasn't been visited. It forms a cycle
2144
        // with other items; traversing the cycle and swapping each item with
2145
        // the next will put them all in the correct place. The weird
2146
        // loop-and-a-half is necessary to insert 0 into every cycle, since we
2147
        // can only swap from that position:
2148
12.1k
        int j = i;
2149
48.8k
        while (true) {
2150
            // Skip the actual swap if our item is zero, since swapping the top
2151
            // item with itself is pointless:
2152
48.8k
            if (j) {
2153
24.6k
                assert(0 <= current);
2154
                // SWAPs are 1-indexed:
2155
24.6k
                instructions[current].i_opcode = SWAP;
2156
24.6k
                instructions[current--].i_oparg = j + 1;
2157
24.6k
            }
2158
48.8k
            if (stack[j] == VISITED) {
2159
                // Completed the cycle:
2160
12.1k
                assert(j == i);
2161
12.1k
                break;
2162
12.1k
            }
2163
36.7k
            int next_j = stack[j];
2164
36.7k
            stack[j] = VISITED;
2165
36.7k
            j = next_j;
2166
36.7k
        }
2167
12.1k
    }
2168
    // NOP out any unused instructions:
2169
14.7k
    while (0 <= current) {
2170
2.06k
        INSTR_SET_OP0(&instructions[current--], NOP);
2171
2.06k
    }
2172
12.6k
    PyMem_Free(stack);
2173
12.6k
    *ix += len - 1;
2174
12.6k
    return SUCCESS;
2175
12.6k
}
2176
2177
2178
// This list is pretty small, since it's only okay to reorder opcodes that:
2179
// - can't affect control flow (like jumping or raising exceptions)
2180
// - can't invoke arbitrary code (besides finalizers)
2181
// - only touch the TOS (and pop it when finished)
2182
#define SWAPPABLE(opcode) \
2183
118k
    ((opcode) == STORE_FAST || \
2184
118k
     (opcode) == STORE_FAST_MAYBE_NULL || \
2185
118k
     (opcode) == POP_TOP)
2186
2187
#define STORES_TO(instr) \
2188
1.63k
    (((instr).i_opcode == STORE_FAST || \
2189
1.63k
      (instr).i_opcode == STORE_FAST_MAYBE_NULL) \
2190
1.63k
     ? (instr).i_oparg : -1)
2191
2192
static int
2193
next_swappable_instruction(basicblock *block, int i, int lineno)
2194
127k
{
2195
127k
    while (++i < block->b_iused) {
2196
117k
        cfg_instr *instruction = &block->b_instr[i];
2197
117k
        if (0 <= lineno && instruction->i_loc.lineno != lineno) {
2198
            // Optimizing across this instruction could cause user-visible
2199
            // changes in the names bound between line tracing events!
2200
2
            return -1;
2201
2
        }
2202
117k
        if (instruction->i_opcode == NOP) {
2203
7
            continue;
2204
7
        }
2205
117k
        if (SWAPPABLE(instruction->i_opcode)) {
2206
28.2k
            return i;
2207
28.2k
        }
2208
89.5k
        return -1;
2209
117k
    }
2210
9.67k
    return -1;
2211
127k
}
2212
2213
// Attempt to apply SWAPs statically by swapping *instructions* rather than
2214
// stack items. For example, we can replace SWAP(2), POP_TOP, STORE_FAST(42)
2215
// with the more efficient NOP, STORE_FAST(42), POP_TOP.
2216
static void
2217
apply_static_swaps(basicblock *block, int i)
2218
100k
{
2219
    // SWAPs are to our left, and potential swaperands are to our right:
2220
102k
    for (; 0 <= i; i--) {
2221
102k
        assert(i < block->b_iused);
2222
102k
        cfg_instr *swap = &block->b_instr[i];
2223
102k
        if (swap->i_opcode != SWAP) {
2224
2.58k
            if (swap->i_opcode == NOP || SWAPPABLE(swap->i_opcode)) {
2225
                // Nope, but we know how to handle these. Keep looking:
2226
2.06k
                continue;
2227
2.06k
            }
2228
            // We can't reason about what this instruction does. Bail:
2229
523
            return;
2230
2.58k
        }
2231
99.7k
        int j = next_swappable_instruction(block, i, -1);
2232
99.7k
        if (j < 0) {
2233
80.7k
            return;
2234
80.7k
        }
2235
18.9k
        int k = j;
2236
18.9k
        int lineno = block->b_instr[j].i_loc.lineno;
2237
28.2k
        for (int count = swap->i_oparg - 1; 0 < count; count--) {
2238
27.6k
            k = next_swappable_instruction(block, k, lineno);
2239
27.6k
            if (k < 0) {
2240
18.4k
                return;
2241
18.4k
            }
2242
27.6k
        }
2243
        // The reordering is not safe if the two instructions to be swapped
2244
        // store to the same location, or if any intervening instruction stores
2245
        // to the same location as either of them.
2246
569
        int store_j = STORES_TO(block->b_instr[j]);
2247
569
        int store_k = STORES_TO(block->b_instr[k]);
2248
569
        if (store_j >= 0 || store_k >= 0) {
2249
564
            if (store_j == store_k) {
2250
0
                return;
2251
0
            }
2252
1.06k
            for (int idx = j + 1; idx < k; idx++) {
2253
501
                int store_idx = STORES_TO(block->b_instr[idx]);
2254
501
                if (store_idx >= 0 && (store_idx == store_j || store_idx == store_k)) {
2255
0
                    return;
2256
0
                }
2257
501
            }
2258
564
        }
2259
2260
        // Success!
2261
569
        INSTR_SET_OP0(swap, NOP);
2262
569
        cfg_instr temp = block->b_instr[j];
2263
569
        block->b_instr[j] = block->b_instr[k];
2264
569
        block->b_instr[k] = temp;
2265
569
    }
2266
100k
}
2267
2268
static int
2269
basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb,
2270
                               PyObject *consts, _Py_hashtable_t *consts_index)
2271
474k
{
2272
474k
    assert(PyDict_CheckExact(const_cache));
2273
474k
    assert(PyList_CheckExact(consts));
2274
474k
    int opcode = 0;
2275
474k
    int oparg = 0;
2276
5.46M
    for (int i = 0; i < bb->b_iused; i++) {
2277
4.99M
        cfg_instr *inst = &bb->b_instr[i];
2278
4.99M
        if (inst->i_opcode == LOAD_CONST) {
2279
1.24M
            PyObject *constant = get_const_value(inst->i_opcode, inst->i_oparg, consts);
2280
1.24M
            if (constant == NULL) {
2281
0
                return ERROR;
2282
0
            }
2283
1.24M
            int res = maybe_instr_make_load_smallint(inst, constant, consts, const_cache);
2284
1.24M
            Py_DECREF(constant);
2285
1.24M
            if (res < 0) {
2286
0
                return ERROR;
2287
0
            }
2288
1.24M
        }
2289
4.99M
        bool is_copy_of_load_const = (opcode == LOAD_CONST &&
2290
697k
                                      inst->i_opcode == COPY &&
2291
584
                                      inst->i_oparg == 1);
2292
4.99M
        if (! is_copy_of_load_const) {
2293
4.99M
            opcode = inst->i_opcode;
2294
4.99M
            oparg = inst->i_oparg;
2295
4.99M
        }
2296
4.99M
        assert(!IS_ASSEMBLER_OPCODE(opcode));
2297
4.99M
        if (!loads_const(opcode)) {
2298
3.72M
            continue;
2299
3.72M
        }
2300
1.26M
        int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0;
2301
1.26M
        switch(nextop) {
2302
1.32k
            case POP_JUMP_IF_FALSE:
2303
2.69k
            case POP_JUMP_IF_TRUE:
2304
3.73k
            case JUMP_IF_FALSE:
2305
4.63k
            case JUMP_IF_TRUE:
2306
4.63k
            {
2307
                /* Remove LOAD_CONST const; conditional jump */
2308
4.63k
                PyObject* cnt = get_const_value(opcode, oparg, consts);
2309
4.63k
                if (cnt == NULL) {
2310
0
                    return ERROR;
2311
0
                }
2312
4.63k
                int is_true = PyObject_IsTrue(cnt);
2313
4.63k
                Py_DECREF(cnt);
2314
4.63k
                if (is_true == -1) {
2315
0
                    return ERROR;
2316
0
                }
2317
4.63k
                if (PyCompile_OpcodeStackEffect(nextop, 0) == -1) {
2318
                    /* POP_JUMP_IF_FALSE or POP_JUMP_IF_TRUE */
2319
2.69k
                    INSTR_SET_OP0(inst, NOP);
2320
2.69k
                }
2321
4.63k
                int jump_if_true = (nextop == POP_JUMP_IF_TRUE || nextop == JUMP_IF_TRUE);
2322
4.63k
                if (is_true == jump_if_true) {
2323
2.37k
                    bb->b_instr[i+1].i_opcode = JUMP;
2324
2.37k
                }
2325
2.26k
                else {
2326
2.26k
                    INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
2327
2.26k
                }
2328
4.63k
                break;
2329
4.63k
            }
2330
4.63k
            case IS_OP:
2331
1.03k
            {
2332
                // Fold to POP_JUMP_IF_NONE:
2333
                // - LOAD_CONST(None) IS_OP(0) POP_JUMP_IF_TRUE
2334
                // - LOAD_CONST(None) IS_OP(1) POP_JUMP_IF_FALSE
2335
                // - LOAD_CONST(None) IS_OP(0) TO_BOOL POP_JUMP_IF_TRUE
2336
                // - LOAD_CONST(None) IS_OP(1) TO_BOOL POP_JUMP_IF_FALSE
2337
                // Fold to POP_JUMP_IF_NOT_NONE:
2338
                // - LOAD_CONST(None) IS_OP(0) POP_JUMP_IF_FALSE
2339
                // - LOAD_CONST(None) IS_OP(1) POP_JUMP_IF_TRUE
2340
                // - LOAD_CONST(None) IS_OP(0) TO_BOOL POP_JUMP_IF_FALSE
2341
                // - LOAD_CONST(None) IS_OP(1) TO_BOOL POP_JUMP_IF_TRUE
2342
1.03k
                PyObject *cnt = get_const_value(opcode, oparg, consts);
2343
1.03k
                if (cnt == NULL) {
2344
0
                    return ERROR;
2345
0
                }
2346
1.03k
                if (!Py_IsNone(cnt)) {
2347
1.00k
                    Py_DECREF(cnt);
2348
1.00k
                    break;
2349
1.00k
                }
2350
33
                if (bb->b_iused <= i + 2) {
2351
0
                    break;
2352
0
                }
2353
33
                cfg_instr *is_instr = &bb->b_instr[i + 1];
2354
33
                cfg_instr *jump_instr = &bb->b_instr[i + 2];
2355
                // Get rid of TO_BOOL regardless:
2356
33
                if (jump_instr->i_opcode == TO_BOOL) {
2357
0
                    INSTR_SET_OP0(jump_instr, NOP);
2358
0
                    if (bb->b_iused <= i + 3) {
2359
0
                        break;
2360
0
                    }
2361
0
                    jump_instr = &bb->b_instr[i + 3];
2362
0
                }
2363
33
                bool invert = is_instr->i_oparg;
2364
33
                if (jump_instr->i_opcode == POP_JUMP_IF_FALSE) {
2365
32
                    invert = !invert;
2366
32
                }
2367
1
                else if (jump_instr->i_opcode != POP_JUMP_IF_TRUE) {
2368
1
                    break;
2369
1
                }
2370
32
                INSTR_SET_OP0(inst, NOP);
2371
32
                INSTR_SET_OP0(is_instr, NOP);
2372
32
                jump_instr->i_opcode = invert ? POP_JUMP_IF_NOT_NONE
2373
32
                                              : POP_JUMP_IF_NONE;
2374
32
                break;
2375
32
            }
2376
2.75k
            case TO_BOOL:
2377
2.75k
            {
2378
2.75k
                PyObject *cnt = get_const_value(opcode, oparg, consts);
2379
2.75k
                if (cnt == NULL) {
2380
0
                    return ERROR;
2381
0
                }
2382
2.75k
                int is_true = PyObject_IsTrue(cnt);
2383
2.75k
                Py_DECREF(cnt);
2384
2.75k
                if (is_true == -1) {
2385
0
                    return ERROR;
2386
0
                }
2387
2.75k
                cnt = PyBool_FromLong(is_true);
2388
2.75k
                int index = add_const(cnt, consts, const_cache, consts_index);
2389
2.75k
                if (index < 0) {
2390
0
                    return ERROR;
2391
0
                }
2392
2.75k
                INSTR_SET_OP0(inst, NOP);
2393
2.75k
                INSTR_SET_OP1(&bb->b_instr[i + 1], LOAD_CONST, index);
2394
2.75k
                break;
2395
2.75k
            }
2396
1.26M
        }
2397
1.26M
        if (inst->i_opcode == LOAD_CONST) {
2398
730k
            PyObject *constant = get_const_value(inst->i_opcode, inst->i_oparg, consts);
2399
730k
            if (constant == NULL) {
2400
0
                return ERROR;
2401
0
            }
2402
730k
            int res = maybe_instr_make_load_common_const(inst, constant);
2403
730k
            Py_DECREF(constant);
2404
730k
            if (res < 0) {
2405
0
                return ERROR;
2406
0
            }
2407
730k
        }
2408
1.26M
    }
2409
474k
    return SUCCESS;
2410
474k
}
2411
2412
static int
2413
optimize_load_const(PyObject *const_cache, cfg_builder *g, PyObject *consts,
2414
52.7k
                    _Py_hashtable_t *consts_index) {
2415
527k
    for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
2416
474k
        RETURN_IF_ERROR(basicblock_optimize_load_const(const_cache, b, consts, consts_index));
2417
474k
    }
2418
52.7k
    return SUCCESS;
2419
52.7k
}
2420
2421
static int
2422
optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts,
2423
                     _Py_hashtable_t *consts_index)
2424
474k
{
2425
474k
    assert(PyDict_CheckExact(const_cache));
2426
474k
    assert(PyList_CheckExact(consts));
2427
474k
    cfg_instr nop;
2428
474k
    INSTR_SET_OP0(&nop, NOP);
2429
5.46M
    for (int i = 0; i < bb->b_iused; i++) {
2430
4.99M
        cfg_instr *inst = &bb->b_instr[i];
2431
4.99M
        cfg_instr *target;
2432
4.99M
        int opcode = inst->i_opcode;
2433
4.99M
        int oparg = inst->i_oparg;
2434
4.99M
        if (HAS_TARGET(opcode)) {
2435
303k
            assert(inst->i_target->b_iused > 0);
2436
303k
            target = &inst->i_target->b_instr[0];
2437
303k
            assert(!IS_ASSEMBLER_OPCODE(target->i_opcode));
2438
303k
        }
2439
4.69M
        else {
2440
4.69M
            target = &nop;
2441
4.69M
        }
2442
4.99M
        int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0;
2443
4.99M
        assert(!IS_ASSEMBLER_OPCODE(opcode));
2444
4.99M
        switch (opcode) {
2445
            /* Try to fold tuples of constants.
2446
               Skip over BUILD_TUPLE(1) UNPACK_SEQUENCE(1).
2447
               Replace BUILD_TUPLE(2) UNPACK_SEQUENCE(2) with SWAP(2).
2448
               Replace BUILD_TUPLE(3) UNPACK_SEQUENCE(3) with SWAP(3). */
2449
72.4k
            case BUILD_TUPLE:
2450
72.4k
                if (nextop == UNPACK_SEQUENCE && oparg == bb->b_instr[i+1].i_oparg) {
2451
136
                    switch(oparg) {
2452
43
                        case 1:
2453
43
                            INSTR_SET_OP0(inst, NOP);
2454
43
                            INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
2455
43
                            continue;
2456
17
                        case 2:
2457
71
                        case 3:
2458
71
                            INSTR_SET_OP0(inst, NOP);
2459
71
                            bb->b_instr[i+1].i_opcode = SWAP;
2460
71
                            continue;
2461
136
                    }
2462
136
                }
2463
72.3k
                RETURN_IF_ERROR(fold_tuple_of_constants(bb, i, consts, const_cache, consts_index));
2464
72.3k
                break;
2465
6.35k
            case BUILD_LIST:
2466
17.4k
            case BUILD_SET:
2467
17.4k
                RETURN_IF_ERROR(optimize_lists_and_sets(bb, i, nextop, consts, const_cache, consts_index));
2468
17.4k
                break;
2469
1.16k
            case POP_JUMP_IF_NOT_NONE:
2470
2.67k
            case POP_JUMP_IF_NONE:
2471
2.67k
                switch (target->i_opcode) {
2472
0
                    case JUMP:
2473
0
                        i -= jump_thread(bb, inst, target, inst->i_opcode);
2474
2.67k
                }
2475
2.67k
                break;
2476
82.9k
            case POP_JUMP_IF_FALSE:
2477
82.9k
                switch (target->i_opcode) {
2478
56
                    case JUMP:
2479
56
                        i -= jump_thread(bb, inst, target, POP_JUMP_IF_FALSE);
2480
82.9k
                }
2481
82.9k
                break;
2482
82.9k
            case POP_JUMP_IF_TRUE:
2483
12.6k
                switch (target->i_opcode) {
2484
1
                    case JUMP:
2485
1
                        i -= jump_thread(bb, inst, target, POP_JUMP_IF_TRUE);
2486
12.6k
                }
2487
12.6k
                break;
2488
12.6k
            case JUMP_IF_FALSE:
2489
3.20k
                switch (target->i_opcode) {
2490
0
                    case JUMP:
2491
0
                    case JUMP_IF_FALSE:
2492
0
                        i -= jump_thread(bb, inst, target, JUMP_IF_FALSE);
2493
0
                        continue;
2494
235
                    case JUMP_IF_TRUE:
2495
                        // No need to check for loops here, a block's b_next
2496
                        // cannot point to itself.
2497
235
                        assert(inst->i_target != inst->i_target->b_next);
2498
235
                        inst->i_target = inst->i_target->b_next;
2499
235
                        i--;
2500
235
                        continue;
2501
3.20k
                }
2502
2.96k
                break;
2503
2.96k
            case JUMP_IF_TRUE:
2504
2.21k
                switch (target->i_opcode) {
2505
0
                    case JUMP:
2506
1.12k
                    case JUMP_IF_TRUE:
2507
1.12k
                        i -= jump_thread(bb, inst, target, JUMP_IF_TRUE);
2508
1.12k
                        continue;
2509
0
                    case JUMP_IF_FALSE:
2510
                        // No need to check for loops here, a block's b_next
2511
                        // cannot point to itself.
2512
0
                        assert(inst->i_target != inst->i_target->b_next);
2513
0
                        inst->i_target = inst->i_target->b_next;
2514
0
                        i--;
2515
0
                        continue;
2516
2.21k
                }
2517
1.09k
                break;
2518
19.5k
            case JUMP:
2519
86.4k
            case JUMP_NO_INTERRUPT:
2520
86.4k
                switch (target->i_opcode) {
2521
53
                    case JUMP:
2522
53
                        i -= jump_thread(bb, inst, target, JUMP);
2523
53
                        continue;
2524
282
                    case JUMP_NO_INTERRUPT:
2525
282
                        i -= jump_thread(bb, inst, target, opcode);
2526
282
                        continue;
2527
86.4k
                }
2528
86.1k
                break;
2529
86.1k
            case FOR_ITER:
2530
2.46k
                if (target->i_opcode == JUMP) {
2531
                    /* This will not work now because the jump (at target) could
2532
                     * be forward or backward and FOR_ITER only jumps forward. We
2533
                     * can re-enable this if ever we implement a backward version
2534
                     * of FOR_ITER.
2535
                     */
2536
                    /*
2537
                    i -= jump_thread(bb, inst, target, FOR_ITER);
2538
                    */
2539
0
                }
2540
2.46k
                break;
2541
109k
            case STORE_FAST:
2542
109k
                if (opcode == nextop &&
2543
52.6k
                    oparg == bb->b_instr[i+1].i_oparg &&
2544
352
                    bb->b_instr[i].i_loc.lineno == bb->b_instr[i+1].i_loc.lineno) {
2545
349
                    bb->b_instr[i].i_opcode = POP_TOP;
2546
349
                    bb->b_instr[i].i_oparg = 0;
2547
349
                }
2548
109k
                break;
2549
114k
            case SWAP:
2550
114k
                if (oparg == 1) {
2551
0
                    INSTR_SET_OP0(inst, NOP);
2552
0
                }
2553
114k
                break;
2554
114k
            case LOAD_GLOBAL:
2555
82.5k
                if (nextop == PUSH_NULL && (oparg & 1) == 0) {
2556
1.73k
                    INSTR_SET_OP1(inst, LOAD_GLOBAL, oparg | 1);
2557
1.73k
                    INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
2558
1.73k
                }
2559
82.5k
                break;
2560
92.1k
            case COMPARE_OP:
2561
92.1k
                if (nextop == TO_BOOL) {
2562
3.77k
                    INSTR_SET_OP0(inst, NOP);
2563
3.77k
                    INSTR_SET_OP1(&bb->b_instr[i + 1], COMPARE_OP, oparg | 16);
2564
3.77k
                    continue;
2565
3.77k
                }
2566
88.3k
                break;
2567
88.3k
            case CONTAINS_OP:
2568
13.0k
            case IS_OP:
2569
13.0k
                if (nextop == TO_BOOL) {
2570
1.47k
                    INSTR_SET_OP0(inst, NOP);
2571
1.47k
                    INSTR_SET_OP1(&bb->b_instr[i + 1], opcode, oparg);
2572
1.47k
                    continue;
2573
1.47k
                }
2574
11.6k
                if (nextop == UNARY_NOT) {
2575
1.02k
                    INSTR_SET_OP0(inst, NOP);
2576
1.02k
                    int inverted = oparg ^ 1;
2577
1.02k
                    assert(inverted == 0 || inverted == 1);
2578
1.02k
                    INSTR_SET_OP1(&bb->b_instr[i + 1], opcode, inverted);
2579
1.02k
                    continue;
2580
1.02k
                }
2581
10.6k
                break;
2582
72.5k
            case TO_BOOL:
2583
72.5k
                if (nextop == TO_BOOL) {
2584
0
                    INSTR_SET_OP0(inst, NOP);
2585
0
                    continue;
2586
0
                }
2587
72.5k
                break;
2588
72.5k
            case UNARY_NOT:
2589
332
                if (nextop == TO_BOOL) {
2590
93
                    INSTR_SET_OP0(inst, NOP);
2591
93
                    INSTR_SET_OP0(&bb->b_instr[i + 1], UNARY_NOT);
2592
93
                    continue;
2593
93
                }
2594
239
                if (nextop == UNARY_NOT) {
2595
93
                    INSTR_SET_OP0(inst, NOP);
2596
93
                    INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
2597
93
                    continue;
2598
93
                }
2599
146
                _Py_FALLTHROUGH;
2600
11.9k
            case UNARY_INVERT:
2601
170k
            case UNARY_NEGATIVE:
2602
170k
                RETURN_IF_ERROR(fold_const_unaryop(bb, i, consts, const_cache, consts_index));
2603
170k
                break;
2604
76.5k
            case CALL_INTRINSIC_1:
2605
76.5k
                if (oparg == INTRINSIC_LIST_TO_TUPLE) {
2606
2.87k
                    RETURN_IF_ERROR(fold_constant_seq_into_load_const(bb, i, consts, const_cache, consts_index));
2607
2.87k
                    if (inst->i_opcode == CALL_INTRINSIC_1 && nextop == GET_ITER) {
2608
18
                        INSTR_SET_OP0(inst, NOP);
2609
18
                    }
2610
2.87k
                }
2611
73.6k
                else if (oparg == INTRINSIC_UNARY_POSITIVE) {
2612
57.3k
                    RETURN_IF_ERROR(fold_const_unaryop(bb, i, consts, const_cache, consts_index));
2613
57.3k
                }
2614
76.5k
                break;
2615
76.5k
            case LIST_APPEND:
2616
47.2k
            case SET_ADD:
2617
47.2k
                if (oparg == 1 && (nextop == GET_ITER || nextop == CONTAINS_OP)) {
2618
1
                    RETURN_IF_ERROR(fold_constant_seq_into_load_const(
2619
1
                        bb, i, consts, const_cache, consts_index));
2620
1
                }
2621
47.2k
                break;
2622
807k
            case BINARY_OP:
2623
807k
                RETURN_IF_ERROR(fold_const_binop(bb, i, consts, const_cache, consts_index));
2624
807k
                break;
2625
4.99M
        }
2626
4.99M
    }
2627
2628
5.45M
    for (int i = 0; i < bb->b_iused; i++) {
2629
4.97M
        cfg_instr *inst = &bb->b_instr[i];
2630
4.97M
        if (inst->i_opcode == SWAP) {
2631
100k
            if (swaptimize(bb, &i) < 0) {
2632
0
                goto error;
2633
0
            }
2634
100k
            apply_static_swaps(bb, i);
2635
100k
        }
2636
4.97M
    }
2637
474k
    return SUCCESS;
2638
0
error:
2639
0
    return ERROR;
2640
474k
}
2641
2642
static int resolve_line_numbers(cfg_builder *g, int firstlineno);
2643
2644
static int
2645
remove_redundant_nops_and_jumps(cfg_builder *g)
2646
109k
{
2647
109k
    int removed_nops, removed_jumps;
2648
116k
    do {
2649
        /* Convergence is guaranteed because the number of
2650
         * redundant jumps and nops only decreases.
2651
         */
2652
116k
        removed_nops = remove_redundant_nops(g);
2653
116k
        RETURN_IF_ERROR(removed_nops);
2654
116k
        removed_jumps = remove_redundant_jumps(g);
2655
116k
        RETURN_IF_ERROR(removed_jumps);
2656
116k
    } while(removed_nops + removed_jumps > 0);
2657
109k
    return SUCCESS;
2658
109k
}
2659
2660
/* Perform optimizations on a control flow graph.
2661
   The consts object should still be in list form to allow new constants
2662
   to be appended.
2663
2664
   Code trasnformations that reduce code size initially fill the gaps with
2665
   NOPs.  Later those NOPs are removed.
2666
*/
2667
static int
2668
optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache,
2669
             _Py_hashtable_t *consts_index, int firstlineno)
2670
52.7k
{
2671
52.7k
    assert(PyDict_CheckExact(const_cache));
2672
52.7k
    RETURN_IF_ERROR(check_cfg(g));
2673
52.7k
    RETURN_IF_ERROR(inline_small_or_no_lineno_blocks(g->g_entryblock));
2674
52.7k
    RETURN_IF_ERROR(remove_unreachable(g->g_entryblock));
2675
52.7k
    RETURN_IF_ERROR(resolve_line_numbers(g, firstlineno));
2676
52.7k
    RETURN_IF_ERROR(optimize_load_const(const_cache, g, consts, consts_index));
2677
527k
    for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
2678
474k
        RETURN_IF_ERROR(optimize_basic_block(const_cache, b, consts, consts_index));
2679
474k
    }
2680
52.7k
    RETURN_IF_ERROR(remove_redundant_nops_and_pairs(g->g_entryblock));
2681
52.7k
    RETURN_IF_ERROR(remove_unreachable(g->g_entryblock));
2682
52.7k
    RETURN_IF_ERROR(remove_redundant_nops_and_jumps(g));
2683
52.7k
    assert(no_redundant_jumps(g));
2684
52.7k
    return SUCCESS;
2685
52.7k
}
2686
2687
static void
2688
make_super_instruction(cfg_instr *inst1, cfg_instr *inst2, int super_op)
2689
48.2k
{
2690
48.2k
    int32_t line1 = inst1->i_loc.lineno;
2691
48.2k
    int32_t line2 = inst2->i_loc.lineno;
2692
    /* Skip if instructions are on different lines */
2693
48.2k
    if (line1 >= 0 && line2 >= 0 && line1 != line2) {
2694
171
        return;
2695
171
    }
2696
48.1k
    if (inst1->i_oparg >= 16 || inst2->i_oparg >= 16) {
2697
27.1k
        return;
2698
27.1k
    }
2699
21.0k
    INSTR_SET_OP1(inst1, super_op, (inst1->i_oparg << 4) | inst2->i_oparg);
2700
21.0k
    INSTR_SET_OP0(inst2, NOP);
2701
21.0k
}
2702
2703
static int
2704
insert_superinstructions(cfg_builder *g)
2705
52.7k
{
2706
527k
    for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
2707
2708
3.82M
        for (int i = 0; i < b->b_iused; i++) {
2709
3.35M
            cfg_instr *inst = &b->b_instr[i];
2710
3.35M
            int nextop = i+1 < b->b_iused ? b->b_instr[i+1].i_opcode : 0;
2711
3.35M
            switch(inst->i_opcode) {
2712
21.8k
                case LOAD_FAST:
2713
21.8k
                    if (nextop == LOAD_FAST) {
2714
3.46k
                        make_super_instruction(inst, &b->b_instr[i + 1], LOAD_FAST_LOAD_FAST);
2715
3.46k
                    }
2716
21.8k
                    break;
2717
94.1k
                case STORE_FAST:
2718
94.1k
                    switch (nextop) {
2719
4.13k
                        case LOAD_FAST:
2720
4.13k
                            make_super_instruction(inst, &b->b_instr[i + 1], STORE_FAST_LOAD_FAST);
2721
4.13k
                            break;
2722
40.6k
                        case STORE_FAST:
2723
40.6k
                            make_super_instruction(inst, &b->b_instr[i + 1], STORE_FAST_STORE_FAST);
2724
40.6k
                            break;
2725
94.1k
                    }
2726
94.1k
                    break;
2727
3.35M
            }
2728
3.35M
        }
2729
474k
    }
2730
52.7k
    int res = remove_redundant_nops(g);
2731
52.7k
    assert(no_redundant_nops(g));
2732
52.7k
    return res;
2733
52.7k
}
2734
2735
#define NOT_LOCAL -1
2736
113k
#define DUMMY_INSTR -1
2737
2738
typedef struct {
2739
    // Index of instruction that produced the reference or DUMMY_INSTR.
2740
    int instr;
2741
2742
    // The local to which the reference refers or NOT_LOCAL.
2743
    int local;
2744
} ref;
2745
2746
typedef struct {
2747
    ref *refs;
2748
    Py_ssize_t size;
2749
    Py_ssize_t capacity;
2750
} ref_stack;
2751
2752
static int
2753
ref_stack_push(ref_stack *stack, ref r)
2754
2.81M
{
2755
2.81M
    if (stack->size == stack->capacity) {
2756
53.1k
        Py_ssize_t new_cap = Py_MAX(32, stack->capacity * 2);
2757
53.1k
        ref *refs = PyMem_Realloc(stack->refs, sizeof(*stack->refs) * new_cap);
2758
53.1k
        if (refs == NULL) {
2759
0
            PyErr_NoMemory();
2760
0
            return -1;
2761
0
        }
2762
53.1k
        stack->refs = refs;
2763
53.1k
        stack->capacity = new_cap;
2764
53.1k
    }
2765
2.81M
    stack->refs[stack->size] = r;
2766
2.81M
    stack->size++;
2767
2.81M
    return 0;
2768
2.81M
}
2769
2770
static ref
2771
ref_stack_pop(ref_stack *stack)
2772
1.91M
{
2773
1.91M
    assert(stack->size > 0);
2774
1.91M
    stack->size--;
2775
1.91M
    ref r = stack->refs[stack->size];
2776
1.91M
    return r;
2777
1.91M
}
2778
2779
static void
2780
ref_stack_swap_top(ref_stack *stack, Py_ssize_t off)
2781
76.7k
{
2782
76.7k
    Py_ssize_t idx = stack->size - off;
2783
76.7k
    assert(idx >= 0 && idx < stack->size);
2784
76.7k
    ref tmp = stack->refs[idx];
2785
76.7k
    stack->refs[idx] = stack->refs[stack->size - 1];
2786
76.7k
    stack->refs[stack->size - 1] = tmp;
2787
76.7k
}
2788
2789
static ref
2790
ref_stack_at(ref_stack *stack, Py_ssize_t idx)
2791
7.54M
{
2792
7.54M
    assert(idx >= 0 && idx < stack->size);
2793
7.54M
    return stack->refs[idx];
2794
7.54M
}
2795
2796
static void
2797
ref_stack_clear(ref_stack *stack)
2798
255k
{
2799
255k
    stack->size = 0;
2800
255k
}
2801
2802
static void
2803
ref_stack_fini(ref_stack *stack)
2804
52.7k
{
2805
52.7k
    if (stack->refs != NULL) {
2806
52.7k
        PyMem_Free(stack->refs);
2807
52.7k
    }
2808
52.7k
    stack->refs = NULL;
2809
52.7k
    stack->capacity = 0;
2810
52.7k
    stack->size = 0;
2811
52.7k
}
2812
2813
typedef enum {
2814
    // The loaded reference is still on the stack when the local is killed
2815
    SUPPORT_KILLED  = 1,
2816
    // The loaded reference is stored into a local
2817
    STORED_AS_LOCAL = 2,
2818
    // The loaded reference is still on the stack at the end of the basic block
2819
    REF_UNCONSUMED  = 4,
2820
} LoadFastInstrFlag;
2821
2822
static void
2823
kill_local(uint8_t *instr_flags, ref_stack *refs, int local)
2824
122k
{
2825
6.60M
    for (Py_ssize_t i = 0; i < refs->size; i++) {
2826
6.47M
        ref r = ref_stack_at(refs, i);
2827
6.47M
        if (r.local == local) {
2828
271
            assert(r.instr >= 0);
2829
271
            instr_flags[r.instr] |= SUPPORT_KILLED;
2830
271
        }
2831
6.47M
    }
2832
122k
}
2833
2834
static void
2835
store_local(uint8_t *instr_flags, ref_stack *refs, int local, ref r)
2836
113k
{
2837
113k
    kill_local(instr_flags, refs, local);
2838
113k
    if (r.instr != DUMMY_INSTR) {
2839
105k
        instr_flags[r.instr] |= STORED_AS_LOCAL;
2840
105k
    }
2841
113k
}
2842
2843
static void
2844
load_fast_push_block(basicblock ***sp, basicblock *target,
2845
                     Py_ssize_t start_depth)
2846
274k
{
2847
274k
    assert(target->b_startdepth >= 0 && target->b_startdepth == start_depth);
2848
274k
    if (!target->b_visited) {
2849
202k
        target->b_visited = 1;
2850
202k
        *(*sp)++ = target;
2851
202k
    }
2852
274k
}
2853
2854
/*
2855
 * Strength reduce LOAD_FAST{_LOAD_FAST} instructions into faster variants that
2856
 * load borrowed references onto the operand stack.
2857
 *
2858
 * This is only safe when we can prove that the reference in the frame outlives
2859
 * the borrowed reference produced by the instruction. We make this tractable
2860
 * by enforcing the following lifetimes:
2861
 *
2862
 * 1. Borrowed references loaded onto the operand stack live until the end of
2863
 *    the instruction that consumes them from the stack. Any borrowed
2864
 *    references that would escape into the heap (e.g. into frame objects or
2865
 *    generators) are converted into new, strong references.
2866
 *
2867
 * 2. Locals live until they are either killed by an instruction
2868
 *    (e.g. STORE_FAST) or the frame is unwound. Any local that is overwritten
2869
 *    via `f_locals` is added to a tuple owned by the frame object.
2870
 *
2871
 * To simplify the problem of detecting which supporting references in the
2872
 * frame are killed by instructions that overwrite locals, we only allow
2873
 * borrowed references to be stored as a local in the frame if they were passed
2874
 * as an argument. {RETURN,YIELD}_VALUE convert borrowed references into new,
2875
 * strong references.
2876
 *
2877
 * Using the above, we can optimize any LOAD_FAST{_LOAD_FAST} instructions
2878
 * that meet the following criteria:
2879
 *
2880
 * 1. The produced reference must be consumed from the stack before the
2881
 *    supporting reference in the frame is killed.
2882
 *
2883
 * 2. The produced reference cannot be stored as a local.
2884
 *
2885
 * We use abstract interpretation to identify instructions that meet these
2886
 * criteria. For each basic block, we simulate the effect the bytecode has on a
2887
 * stack of abstract references and note any instructions that violate the
2888
 * criteria above. Once we've processed all the instructions in a block, any
2889
 * non-violating LOAD_FAST{_LOAD_FAST} can be optimized.
2890
 */
2891
static int
2892
optimize_load_fast(cfg_builder *g)
2893
52.7k
{
2894
52.7k
    int status;
2895
52.7k
    ref_stack refs = {0};
2896
52.7k
    int max_instrs = 0;
2897
52.7k
    basicblock *entryblock = g->g_entryblock;
2898
547k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
2899
494k
        max_instrs = Py_MAX(max_instrs, b->b_iused);
2900
494k
    }
2901
52.7k
    size_t instr_flags_size = max_instrs * sizeof(uint8_t);
2902
52.7k
    uint8_t *instr_flags = PyMem_Malloc(instr_flags_size);
2903
52.7k
    if (instr_flags == NULL) {
2904
0
        PyErr_NoMemory();
2905
0
        return ERROR;
2906
0
    }
2907
52.7k
    basicblock **blocks = make_cfg_traversal_stack(entryblock);
2908
52.7k
    if (blocks == NULL) {
2909
0
        status = ERROR;
2910
0
        goto done;
2911
0
    }
2912
52.7k
    basicblock **sp = blocks;
2913
52.7k
    *sp = entryblock;
2914
52.7k
    sp++;
2915
52.7k
    entryblock->b_startdepth = 0;
2916
52.7k
    entryblock->b_visited = 1;
2917
2918
52.7k
    #define PUSH_REF(instr, local)                \
2919
2.81M
        do {                                      \
2920
2.81M
            if (ref_stack_push(&refs, (ref){(instr), (local)}) < 0) { \
2921
0
                status = ERROR;                   \
2922
0
                goto done;                        \
2923
0
            }                                     \
2924
2.81M
        } while(0)
2925
2926
308k
    while (sp != blocks) {
2927
255k
        basicblock *block = *--sp;
2928
255k
        assert(block->b_startdepth > -1);
2929
2930
        // Reset per-block state.
2931
255k
        memset(instr_flags, 0, block->b_iused * sizeof(*instr_flags));
2932
2933
        // Reset the stack of refs. We don't track references on the stack
2934
        // across basic blocks, but the bytecode will expect their
2935
        // presence. Add dummy references as necessary.
2936
255k
        ref_stack_clear(&refs);
2937
1.11M
        for (int i = 0; i < block->b_startdepth; i++) {
2938
858k
            PUSH_REF(DUMMY_INSTR, NOT_LOCAL);
2939
858k
        }
2940
2941
2.94M
        for (int i = 0; i < block->b_iused; i++) {
2942
2.68M
            cfg_instr *instr = &block->b_instr[i];
2943
2.68M
            int opcode = instr->i_opcode;
2944
2.68M
            int oparg = instr->i_oparg;
2945
2.68M
            assert(opcode != EXTENDED_ARG);
2946
2.68M
            switch (opcode) {
2947
                // Opcodes that load and store locals
2948
3.12k
                case DELETE_FAST: {
2949
3.12k
                    kill_local(instr_flags, &refs, oparg);
2950
3.12k
                    break;
2951
0
                }
2952
2953
37.1k
                case LOAD_FAST: {
2954
37.1k
                    PUSH_REF(i, oparg);
2955
37.1k
                    break;
2956
37.1k
                }
2957
2958
37.1k
                case LOAD_FAST_AND_CLEAR: {
2959
5.82k
                    kill_local(instr_flags, &refs, oparg);
2960
5.82k
                    PUSH_REF(i, oparg);
2961
5.82k
                    break;
2962
5.82k
                }
2963
2964
5.82k
                case LOAD_FAST_LOAD_FAST: {
2965
2.85k
                    PUSH_REF(i, oparg >> 4);
2966
2.85k
                    PUSH_REF(i, oparg & 15);
2967
2.85k
                    break;
2968
2.85k
                }
2969
2970
80.2k
                case STORE_FAST: {
2971
80.2k
                    ref r = ref_stack_pop(&refs);
2972
80.2k
                    store_local(instr_flags, &refs, oparg, r);
2973
80.2k
                    break;
2974
2.85k
                }
2975
2976
3.20k
                case STORE_FAST_LOAD_FAST: {
2977
                    // STORE_FAST
2978
3.20k
                    ref r = ref_stack_pop(&refs);
2979
3.20k
                    store_local(instr_flags, &refs, oparg >> 4, r);
2980
                    // LOAD_FAST
2981
3.20k
                    PUSH_REF(i, oparg & 15);
2982
3.20k
                    break;
2983
3.20k
                }
2984
2985
14.9k
                case STORE_FAST_STORE_FAST: {
2986
                    // STORE_FAST
2987
14.9k
                    ref r = ref_stack_pop(&refs);
2988
14.9k
                    store_local(instr_flags, &refs, oparg >> 4, r);
2989
                    // STORE_FAST
2990
14.9k
                    r = ref_stack_pop(&refs);
2991
14.9k
                    store_local(instr_flags, &refs, oparg & 15, r);
2992
14.9k
                    break;
2993
3.20k
                }
2994
2995
                // Opcodes that shuffle values on the stack
2996
160k
                case COPY: {
2997
160k
                    assert(oparg > 0);
2998
160k
                    Py_ssize_t idx = refs.size - oparg;
2999
160k
                    ref r = ref_stack_at(&refs, idx);
3000
160k
                    PUSH_REF(r.instr, r.local);
3001
160k
                    break;
3002
160k
                }
3003
3004
160k
                case SWAP: {
3005
76.7k
                    assert(oparg >= 2);
3006
76.7k
                    ref_stack_swap_top(&refs, oparg);
3007
76.7k
                    break;
3008
76.7k
                }
3009
3010
                // We treat opcodes that do not consume all of their inputs on
3011
                // a case by case basis, as we have no generic way of knowing
3012
                // how many inputs should be left on the stack.
3013
3014
                // Opcodes that consume no inputs
3015
2.04k
                case FORMAT_SIMPLE:
3016
2.53k
                case GET_ANEXT:
3017
4.74k
                case GET_ITER:
3018
5.94k
                case GET_LEN:
3019
12.1k
                case IMPORT_FROM:
3020
12.1k
                case MATCH_KEYS:
3021
12.1k
                case MATCH_MAPPING:
3022
12.8k
                case MATCH_SEQUENCE:
3023
12.8k
                case WITH_EXCEPT_START: {
3024
12.8k
                    int num_popped = _PyOpcode_num_popped(opcode, oparg);
3025
12.8k
                    int num_pushed = _PyOpcode_num_pushed(opcode, oparg);
3026
12.8k
                    int net_pushed = num_pushed - num_popped;
3027
12.8k
                    assert(net_pushed >= 0);
3028
23.7k
                    for (int j = 0; j < net_pushed; j++) {
3029
10.8k
                        PUSH_REF(i, NOT_LOCAL);
3030
10.8k
                    }
3031
12.8k
                    break;
3032
12.8k
                }
3033
3034
                // Opcodes that consume some inputs and push no new values
3035
12.8k
                case DICT_MERGE:
3036
890
                case DICT_UPDATE:
3037
28.1k
                case LIST_APPEND:
3038
30.1k
                case LIST_EXTEND:
3039
30.5k
                case MAP_ADD:
3040
30.5k
                case RERAISE:
3041
34.3k
                case SET_ADD:
3042
43.4k
                case SET_UPDATE: {
3043
43.4k
                    int num_popped = _PyOpcode_num_popped(opcode, oparg);
3044
43.4k
                    int num_pushed = _PyOpcode_num_pushed(opcode, oparg);
3045
43.4k
                    int net_popped = num_popped - num_pushed;
3046
43.4k
                    assert(net_popped > 0);
3047
87.4k
                    for (int i = 0; i < net_popped; i++) {
3048
43.9k
                        ref_stack_pop(&refs);
3049
43.9k
                    }
3050
43.4k
                    break;
3051
43.4k
                }
3052
3053
19.9k
                case END_SEND: {
3054
19.9k
                    assert(_PyOpcode_num_popped(opcode, oparg) == 3);
3055
19.9k
                    assert(_PyOpcode_num_pushed(opcode, oparg) == 1);
3056
19.9k
                    ref tos = ref_stack_pop(&refs);
3057
19.9k
                    ref_stack_pop(&refs);
3058
19.9k
                    ref_stack_pop(&refs);
3059
19.9k
                    PUSH_REF(tos.instr, tos.local);
3060
19.9k
                    break;
3061
19.9k
                }
3062
3063
19.9k
                case SET_FUNCTION_ATTRIBUTE: {
3064
18.7k
                    assert(_PyOpcode_num_popped(opcode, oparg) == 2);
3065
18.7k
                    assert(_PyOpcode_num_pushed(opcode, oparg) == 1);
3066
18.7k
                    ref tos = ref_stack_pop(&refs);
3067
18.7k
                    ref_stack_pop(&refs);
3068
18.7k
                    PUSH_REF(tos.instr, tos.local);
3069
18.7k
                    break;
3070
18.7k
                }
3071
3072
                // Opcodes that consume some inputs and push new values
3073
18.7k
                case CHECK_EXC_MATCH: {
3074
0
                    ref_stack_pop(&refs);
3075
0
                    PUSH_REF(i, NOT_LOCAL);
3076
0
                    break;
3077
0
                }
3078
3079
2.20k
                case FOR_ITER: {
3080
2.20k
                    load_fast_push_block(&sp, instr->i_target, refs.size + 1);
3081
2.20k
                    PUSH_REF(i, NOT_LOCAL);
3082
2.20k
                    break;
3083
2.20k
                }
3084
3085
11.8k
                case LOAD_ATTR:
3086
12.3k
                case LOAD_SUPER_ATTR: {
3087
12.3k
                    ref self = ref_stack_pop(&refs);
3088
12.3k
                    if (opcode == LOAD_SUPER_ATTR) {
3089
521
                        ref_stack_pop(&refs);
3090
521
                        ref_stack_pop(&refs);
3091
521
                    }
3092
12.3k
                    PUSH_REF(i, NOT_LOCAL);
3093
12.3k
                    if (oparg & 1) {
3094
                        // A method call; conservatively assume that self is pushed
3095
                        // back onto the stack
3096
1.13k
                        PUSH_REF(self.instr, self.local);
3097
1.13k
                    }
3098
12.3k
                    break;
3099
12.3k
                }
3100
3101
20.6k
                case LOAD_SPECIAL:
3102
20.6k
                case PUSH_EXC_INFO: {
3103
20.6k
                    ref tos = ref_stack_pop(&refs);
3104
20.6k
                    PUSH_REF(i, NOT_LOCAL);
3105
20.6k
                    PUSH_REF(tos.instr, tos.local);
3106
20.6k
                    break;
3107
20.6k
                }
3108
3109
20.6k
                case SEND: {
3110
19.9k
                    load_fast_push_block(&sp, instr->i_target, refs.size);
3111
19.9k
                    ref_stack_pop(&refs);
3112
19.9k
                    PUSH_REF(i, NOT_LOCAL);
3113
19.9k
                    break;
3114
19.9k
                }
3115
3116
                // Opcodes that consume all of their inputs
3117
2.15M
                default: {
3118
2.15M
                    int num_popped = _PyOpcode_num_popped(opcode, oparg);
3119
2.15M
                    int num_pushed = _PyOpcode_num_pushed(opcode, oparg);
3120
2.15M
                    if (HAS_TARGET(instr->i_opcode)) {
3121
95.7k
                        load_fast_push_block(&sp, instr->i_target, refs.size - num_popped + num_pushed);
3122
95.7k
                    }
3123
2.15M
                    if (!IS_BLOCK_PUSH_OPCODE(instr->i_opcode)) {
3124
                        // Block push opcodes only affect the stack when jumping
3125
                        // to the target.
3126
3.75M
                        for (int j = 0; j < num_popped; j++) {
3127
1.60M
                            ref_stack_pop(&refs);
3128
1.60M
                        }
3129
3.77M
                        for (int j = 0; j < num_pushed; j++) {
3130
1.61M
                            PUSH_REF(i, NOT_LOCAL);
3131
1.61M
                        }
3132
2.15M
                    }
3133
2.15M
                    break;
3134
2.15M
                }
3135
2.68M
            }
3136
2.68M
        }
3137
3138
        // Push fallthrough block
3139
255k
        if (BB_HAS_FALLTHROUGH(block)) {
3140
156k
            assert(block->b_next != NULL);
3141
156k
            load_fast_push_block(&sp, block->b_next, refs.size);
3142
156k
        }
3143
3144
        // Mark instructions that produce values that are on the stack at the
3145
        // end of the basic block
3146
1.15M
        for (Py_ssize_t i = 0; i < refs.size; i++) {
3147
901k
            ref r = ref_stack_at(&refs, i);
3148
901k
            if (r.instr != -1) {
3149
277k
                instr_flags[r.instr] |= REF_UNCONSUMED;
3150
277k
            }
3151
901k
        }
3152
3153
        // Optimize instructions
3154
2.94M
        for (int i = 0; i < block->b_iused; i++) {
3155
2.68M
            if (!instr_flags[i]) {
3156
2.37M
                cfg_instr *instr = &block->b_instr[i];
3157
2.37M
                switch (instr->i_opcode) {
3158
36.1k
                    case LOAD_FAST:
3159
36.1k
                        instr->i_opcode = LOAD_FAST_BORROW;
3160
36.1k
                        break;
3161
2.85k
                    case LOAD_FAST_LOAD_FAST:
3162
2.85k
                        instr->i_opcode = LOAD_FAST_BORROW_LOAD_FAST_BORROW;
3163
2.85k
                        break;
3164
2.33M
                    default:
3165
2.33M
                        break;
3166
2.37M
                }
3167
2.37M
            }
3168
2.68M
        }
3169
255k
    }
3170
3171
52.7k
    #undef PUSH_REF
3172
3173
52.7k
    status = SUCCESS;
3174
3175
52.7k
done:
3176
52.7k
    ref_stack_fini(&refs);
3177
52.7k
    PyMem_Free(instr_flags);
3178
52.7k
    PyMem_Free(blocks);
3179
52.7k
    return status;
3180
52.7k
}
3181
3182
// helper functions for add_checks_for_loads_of_unknown_variables
3183
static inline void
3184
maybe_push(basicblock *b, uint64_t unsafe_mask, basicblock ***sp)
3185
1.47M
{
3186
    // Push b if the unsafe mask is giving us any new information.
3187
    // To avoid overflowing the stack, only allow each block once.
3188
    // Use b->b_visited=1 to mean that b is currently on the stack.
3189
1.47M
    uint64_t both = b->b_unsafe_locals_mask | unsafe_mask;
3190
1.47M
    if (b->b_unsafe_locals_mask != both) {
3191
85.4k
        b->b_unsafe_locals_mask = both;
3192
        // More work left to do.
3193
85.4k
        if (!b->b_visited) {
3194
            // not on the stack, so push it.
3195
84.8k
            *(*sp)++ = b;
3196
84.8k
            b->b_visited = 1;
3197
84.8k
        }
3198
85.4k
    }
3199
1.47M
}
3200
3201
static void
3202
scan_block_for_locals(basicblock *b, basicblock ***sp)
3203
377k
{
3204
    // bit i is set if local i is potentially uninitialized
3205
377k
    uint64_t unsafe_mask = b->b_unsafe_locals_mask;
3206
2.52M
    for (int i = 0; i < b->b_iused; i++) {
3207
2.14M
        cfg_instr *instr = &b->b_instr[i];
3208
2.14M
        assert(instr->i_opcode != EXTENDED_ARG);
3209
2.14M
        if (instr->i_except != NULL) {
3210
1.08M
            maybe_push(instr->i_except, unsafe_mask, sp);
3211
1.08M
        }
3212
2.14M
        if (instr->i_oparg >= 64) {
3213
244k
            continue;
3214
244k
        }
3215
2.14M
        assert(instr->i_oparg >= 0);
3216
1.90M
        uint64_t bit = (uint64_t)1 << instr->i_oparg;
3217
1.90M
        switch (instr->i_opcode) {
3218
5.77k
            case DELETE_FAST:
3219
18.5k
            case LOAD_FAST_AND_CLEAR:
3220
44.2k
            case STORE_FAST_MAYBE_NULL:
3221
44.2k
                unsafe_mask |= bit;
3222
44.2k
                break;
3223
216k
            case STORE_FAST:
3224
216k
                unsafe_mask &= ~bit;
3225
216k
                break;
3226
4.04k
            case LOAD_FAST_CHECK:
3227
                // If this doesn't raise, then the local is defined.
3228
4.04k
                unsafe_mask &= ~bit;
3229
4.04k
                break;
3230
46.7k
            case LOAD_FAST:
3231
46.7k
                if (unsafe_mask & bit) {
3232
4.04k
                    instr->i_opcode = LOAD_FAST_CHECK;
3233
4.04k
                }
3234
46.7k
                unsafe_mask &= ~bit;
3235
46.7k
                break;
3236
1.90M
        }
3237
1.90M
    }
3238
377k
    if (b->b_next && BB_HAS_FALLTHROUGH(b)) {
3239
191k
        maybe_push(b->b_next, unsafe_mask, sp);
3240
191k
    }
3241
377k
    cfg_instr *last = basicblock_last_instr(b);
3242
377k
    if (last && is_jump(last)) {
3243
170k
        assert(last->i_target != NULL);
3244
170k
        maybe_push(last->i_target, unsafe_mask, sp);
3245
170k
    }
3246
377k
}
3247
3248
static int
3249
fast_scan_many_locals(basicblock *entryblock, int nlocals)
3250
143
{
3251
143
    assert(nlocals > 64);
3252
143
    Py_ssize_t *states = PyMem_Calloc(nlocals - 64, sizeof(Py_ssize_t));
3253
143
    if (states == NULL) {
3254
0
        PyErr_NoMemory();
3255
0
        return ERROR;
3256
0
    }
3257
143
    Py_ssize_t blocknum = 0;
3258
    // state[i - 64] == blocknum if local i is guaranteed to
3259
    // be initialized, i.e., if it has had a previous LOAD_FAST or
3260
    // STORE_FAST within that basicblock (not followed by
3261
    // DELETE_FAST/LOAD_FAST_AND_CLEAR/STORE_FAST_MAYBE_NULL).
3262
1.26k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3263
1.12k
        blocknum++;
3264
66.3k
        for (int i = 0; i < b->b_iused; i++) {
3265
65.2k
            cfg_instr *instr = &b->b_instr[i];
3266
65.2k
            assert(instr->i_opcode != EXTENDED_ARG);
3267
65.2k
            int arg = instr->i_oparg;
3268
65.2k
            if (arg < 64) {
3269
62.7k
                continue;
3270
62.7k
            }
3271
65.2k
            assert(arg >= 0);
3272
2.53k
            switch (instr->i_opcode) {
3273
241
                case DELETE_FAST:
3274
367
                case LOAD_FAST_AND_CLEAR:
3275
619
                case STORE_FAST_MAYBE_NULL:
3276
619
                    states[arg - 64] = blocknum - 1;
3277
619
                    break;
3278
780
                case STORE_FAST:
3279
780
                    states[arg - 64] = blocknum;
3280
780
                    break;
3281
138
                case LOAD_FAST:
3282
138
                    if (states[arg - 64] != blocknum) {
3283
70
                        instr->i_opcode = LOAD_FAST_CHECK;
3284
70
                    }
3285
138
                    states[arg - 64] = blocknum;
3286
138
                    break;
3287
2.53k
                    Py_UNREACHABLE();
3288
2.53k
            }
3289
2.53k
        }
3290
1.12k
    }
3291
143
    PyMem_Free(states);
3292
143
    return SUCCESS;
3293
143
}
3294
3295
static int
3296
remove_unused_consts(basicblock *entryblock, PyObject *consts)
3297
52.7k
{
3298
52.7k
    assert(PyList_CheckExact(consts));
3299
52.7k
    Py_ssize_t nconsts = PyList_GET_SIZE(consts);
3300
52.7k
    if (nconsts == 0) {
3301
50
        return SUCCESS;  /* nothing to do */
3302
50
    }
3303
3304
52.7k
    Py_ssize_t *index_map = NULL;
3305
52.7k
    Py_ssize_t *reverse_index_map = NULL;
3306
52.7k
    int err = ERROR;
3307
3308
52.7k
    index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t));
3309
52.7k
    if (index_map == NULL) {
3310
0
        PyErr_NoMemory();
3311
0
        goto end;
3312
0
    }
3313
442k
    for (Py_ssize_t i = 1; i < nconsts; i++) {
3314
389k
        index_map[i] = -1;
3315
389k
    }
3316
    // The first constant may be docstring; keep it always.
3317
52.7k
    index_map[0] = 0;
3318
3319
    /* mark used consts */
3320
527k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3321
3.82M
        for (int i = 0; i < b->b_iused; i++) {
3322
3.34M
            int opcode = b->b_instr[i].i_opcode;
3323
3.34M
            if (OPCODE_HAS_CONST(opcode)) {
3324
333k
                int index = b->b_instr[i].i_oparg;
3325
333k
                index_map[index] = index;
3326
333k
            }
3327
3.34M
        }
3328
474k
    }
3329
    /* now index_map[i] == i if consts[i] is used, -1 otherwise */
3330
    /* condense consts */
3331
52.7k
    Py_ssize_t n_used_consts = 0;
3332
494k
    for (Py_ssize_t i = 0; i < nconsts; i++) {
3333
442k
        if (index_map[i] != -1) {
3334
171k
            assert(index_map[i] == i);
3335
171k
            index_map[n_used_consts++] = index_map[i];
3336
171k
        }
3337
442k
    }
3338
52.7k
    if (n_used_consts == nconsts) {
3339
        /* nothing to do */
3340
12.7k
        err = SUCCESS;
3341
12.7k
        goto end;
3342
12.7k
    }
3343
3344
    /* move all used consts to the beginning of the consts list */
3345
52.7k
    assert(n_used_consts < nconsts);
3346
182k
    for (Py_ssize_t i = 0; i < n_used_consts; i++) {
3347
142k
        Py_ssize_t old_index = index_map[i];
3348
142k
        assert(i <= old_index && old_index < nconsts);
3349
142k
        if (i != old_index) {
3350
61.6k
            PyObject *value = PyList_GET_ITEM(consts, index_map[i]);
3351
61.6k
            assert(value != NULL);
3352
61.6k
            PyList_SetItem(consts, i, Py_NewRef(value));
3353
61.6k
        }
3354
142k
    }
3355
3356
    /* truncate the consts list at its new size */
3357
39.9k
    if (PyList_SetSlice(consts, n_used_consts, nconsts, NULL) < 0) {
3358
0
        goto end;
3359
0
    }
3360
    /* adjust const indices in the bytecode */
3361
39.9k
    reverse_index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t));
3362
39.9k
    if (reverse_index_map == NULL) {
3363
0
        PyErr_NoMemory();
3364
0
        goto end;
3365
0
    }
3366
452k
    for (Py_ssize_t i = 0; i < nconsts; i++) {
3367
412k
        reverse_index_map[i] = -1;
3368
412k
    }
3369
182k
    for (Py_ssize_t i = 0; i < n_used_consts; i++) {
3370
142k
        assert(index_map[i] != -1);
3371
142k
        assert(reverse_index_map[index_map[i]] == -1);
3372
142k
        reverse_index_map[index_map[i]] = i;
3373
142k
    }
3374
3375
376k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3376
2.91M
        for (int i = 0; i < b->b_iused; i++) {
3377
2.58M
            int opcode = b->b_instr[i].i_opcode;
3378
2.58M
            if (OPCODE_HAS_CONST(opcode)) {
3379
311k
                int index = b->b_instr[i].i_oparg;
3380
311k
                assert(reverse_index_map[index] >= 0);
3381
311k
                assert(reverse_index_map[index] < n_used_consts);
3382
311k
                b->b_instr[i].i_oparg = (int)reverse_index_map[index];
3383
311k
            }
3384
2.58M
        }
3385
336k
    }
3386
3387
39.9k
    err = SUCCESS;
3388
52.7k
end:
3389
52.7k
    PyMem_Free(index_map);
3390
52.7k
    PyMem_Free(reverse_index_map);
3391
52.7k
    return err;
3392
39.9k
}
3393
3394
3395
3396
static int
3397
add_checks_for_loads_of_uninitialized_variables(basicblock *entryblock,
3398
                                                int nlocals,
3399
                                                int nparams)
3400
52.7k
{
3401
52.7k
    if (nlocals == 0) {
3402
27.0k
        return SUCCESS;
3403
27.0k
    }
3404
25.7k
    if (nlocals > 64) {
3405
        // To avoid O(nlocals**2) compilation, locals beyond the first
3406
        // 64 are only analyzed one basicblock at a time: initialization
3407
        // info is not passed between basicblocks.
3408
143
        if (fast_scan_many_locals(entryblock, nlocals) < 0) {
3409
0
            return ERROR;
3410
0
        }
3411
143
        nlocals = 64;
3412
143
    }
3413
25.7k
    basicblock **stack = make_cfg_traversal_stack(entryblock);
3414
25.7k
    if (stack == NULL) {
3415
0
        return ERROR;
3416
0
    }
3417
25.7k
    basicblock **sp = stack;
3418
3419
    // First origin of being uninitialized:
3420
    // The non-parameter locals in the entry block.
3421
25.7k
    uint64_t start_mask = 0;
3422
86.8k
    for (int i = nparams; i < nlocals; i++) {
3423
61.1k
        start_mask |= (uint64_t)1 << i;
3424
61.1k
    }
3425
25.7k
    maybe_push(entryblock, start_mask, &sp);
3426
3427
    // Second origin of being uninitialized:
3428
    // There could be DELETE_FAST somewhere, so
3429
    // be sure to scan each basicblock at least once.
3430
318k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3431
292k
        scan_block_for_locals(b, &sp);
3432
292k
    }
3433
    // Now propagate the uncertainty from the origins we found: Use
3434
    // LOAD_FAST_CHECK for any LOAD_FAST where the local could be undefined.
3435
110k
    while (sp > stack) {
3436
84.8k
        basicblock *b = *--sp;
3437
        // mark as no longer on stack
3438
84.8k
        b->b_visited = 0;
3439
84.8k
        scan_block_for_locals(b, &sp);
3440
84.8k
    }
3441
25.7k
    PyMem_Free(stack);
3442
25.7k
    return SUCCESS;
3443
25.7k
}
3444
3445
3446
static int
3447
36.1k
mark_warm(basicblock *entryblock) {
3448
36.1k
    basicblock **stack = make_cfg_traversal_stack(entryblock);
3449
36.1k
    if (stack == NULL) {
3450
0
        return ERROR;
3451
0
    }
3452
36.1k
    basicblock **sp = stack;
3453
3454
36.1k
    *sp++ = entryblock;
3455
36.1k
    entryblock->b_visited = 1;
3456
264k
    while (sp > stack) {
3457
227k
        basicblock *b = *(--sp);
3458
227k
        assert(!b->b_except_handler);
3459
227k
        b->b_warm = 1;
3460
227k
        basicblock *next = b->b_next;
3461
227k
        if (next && BB_HAS_FALLTHROUGH(b) && !next->b_visited) {
3462
125k
            *sp++ = next;
3463
125k
            next->b_visited = 1;
3464
125k
        }
3465
2.19M
        for (int i=0; i < b->b_iused; i++) {
3466
1.96M
            cfg_instr *instr = &b->b_instr[i];
3467
1.96M
            if (is_jump(instr) && !instr->i_target->b_visited) {
3468
65.9k
                *sp++ = instr->i_target;
3469
65.9k
                instr->i_target->b_visited = 1;
3470
65.9k
            }
3471
1.96M
        }
3472
227k
    }
3473
36.1k
    PyMem_Free(stack);
3474
36.1k
    return SUCCESS;
3475
36.1k
}
3476
3477
static int
3478
36.1k
mark_cold(basicblock *entryblock) {
3479
494k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3480
458k
        assert(!b->b_cold && !b->b_warm);
3481
458k
    }
3482
36.1k
    if (mark_warm(entryblock) < 0) {
3483
0
        return ERROR;
3484
0
    }
3485
3486
36.1k
    basicblock **stack = make_cfg_traversal_stack(entryblock);
3487
36.1k
    if (stack == NULL) {
3488
0
        return ERROR;
3489
0
    }
3490
3491
36.1k
    basicblock **sp = stack;
3492
494k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3493
458k
        if (b->b_except_handler) {
3494
74.8k
            assert(!b->b_warm);
3495
74.8k
            *sp++ = b;
3496
74.8k
            b->b_visited = 1;
3497
74.8k
        }
3498
458k
    }
3499
3500
217k
    while (sp > stack) {
3501
181k
        basicblock *b = *(--sp);
3502
181k
        b->b_cold = 1;
3503
181k
        basicblock *next = b->b_next;
3504
181k
        if (next && BB_HAS_FALLTHROUGH(b)) {
3505
105k
            if (!next->b_warm && !next->b_visited) {
3506
82.1k
                *sp++ = next;
3507
82.1k
                next->b_visited = 1;
3508
82.1k
            }
3509
105k
        }
3510
864k
        for (int i = 0; i < b->b_iused; i++) {
3511
683k
            cfg_instr *instr = &b->b_instr[i];
3512
683k
            if (is_jump(instr)) {
3513
76.1k
                assert(i == b->b_iused - 1);
3514
76.1k
                basicblock *target = b->b_instr[i].i_target;
3515
76.1k
                if (!target->b_warm && !target->b_visited) {
3516
24.5k
                    *sp++ = target;
3517
24.5k
                    target->b_visited = 1;
3518
24.5k
                }
3519
76.1k
            }
3520
683k
        }
3521
181k
    }
3522
36.1k
    PyMem_Free(stack);
3523
36.1k
    return SUCCESS;
3524
36.1k
}
3525
3526
3527
static int
3528
52.7k
push_cold_blocks_to_end(cfg_builder *g) {
3529
52.7k
    basicblock *entryblock = g->g_entryblock;
3530
52.7k
    if (entryblock->b_next == NULL) {
3531
        /* single basicblock, no need to reorder */
3532
16.6k
        return SUCCESS;
3533
16.6k
    }
3534
36.1k
    RETURN_IF_ERROR(mark_cold(entryblock));
3535
3536
36.1k
    int next_lbl = get_max_label(g->g_entryblock) + 1;
3537
3538
    /* If we have a cold block with fallthrough to a warm block, add */
3539
    /* an explicit jump instead of fallthrough */
3540
514k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3541
478k
        if (b->b_cold && BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_next->b_warm) {
3542
19.9k
            basicblock *explicit_jump = cfg_builder_new_block(g);
3543
19.9k
            if (explicit_jump == NULL) {
3544
0
                return ERROR;
3545
0
            }
3546
19.9k
            if (!IS_LABEL(b->b_next->b_label)) {
3547
0
                b->b_next->b_label.id = next_lbl++;
3548
0
            }
3549
19.9k
            basicblock_addop(explicit_jump, JUMP_NO_INTERRUPT, b->b_next->b_label.id,
3550
19.9k
                             NO_LOCATION);
3551
19.9k
            explicit_jump->b_cold = 1;
3552
19.9k
            explicit_jump->b_next = b->b_next;
3553
19.9k
            explicit_jump->b_predecessors = 1;
3554
19.9k
            b->b_next = explicit_jump;
3555
3556
            /* set target */
3557
19.9k
            cfg_instr *last = basicblock_last_instr(explicit_jump);
3558
19.9k
            last->i_target = explicit_jump->b_next;
3559
19.9k
        }
3560
478k
    }
3561
3562
36.1k
    assert(!entryblock->b_cold);  /* First block can't be cold */
3563
36.1k
    basicblock *cold_blocks = NULL;
3564
36.1k
    basicblock *cold_blocks_tail = NULL;
3565
3566
36.1k
    basicblock *b = entryblock;
3567
76.6k
    while(b->b_next) {
3568
76.6k
        assert(!b->b_cold);
3569
317k
        while (b->b_next && !b->b_next->b_cold) {
3570
240k
            b = b->b_next;
3571
240k
        }
3572
76.6k
        if (b->b_next == NULL) {
3573
            /* no more cold blocks */
3574
36.1k
            break;
3575
36.1k
        }
3576
3577
        /* b->b_next is the beginning of a cold streak */
3578
76.6k
        assert(!b->b_cold && b->b_next->b_cold);
3579
3580
40.4k
        basicblock *b_end = b->b_next;
3581
201k
        while (b_end->b_next && b_end->b_next->b_cold) {
3582
161k
            b_end = b_end->b_next;
3583
161k
        }
3584
3585
        /* b_end is the end of the cold streak */
3586
40.4k
        assert(b_end && b_end->b_cold);
3587
40.4k
        assert(b_end->b_next == NULL || !b_end->b_next->b_cold);
3588
3589
40.4k
        if (cold_blocks == NULL) {
3590
3.99k
            cold_blocks = b->b_next;
3591
3.99k
        }
3592
36.4k
        else {
3593
36.4k
            cold_blocks_tail->b_next = b->b_next;
3594
36.4k
        }
3595
40.4k
        cold_blocks_tail = b_end;
3596
40.4k
        b->b_next = b_end->b_next;
3597
40.4k
        b_end->b_next = NULL;
3598
40.4k
    }
3599
36.1k
    assert(b != NULL && b->b_next == NULL);
3600
36.1k
    b->b_next = cold_blocks;
3601
3602
36.1k
    if (cold_blocks != NULL) {
3603
3.99k
        RETURN_IF_ERROR(remove_redundant_nops_and_jumps(g));
3604
3.99k
    }
3605
36.1k
    return SUCCESS;
3606
36.1k
}
3607
3608
static int
3609
convert_pseudo_conditional_jumps(cfg_builder *g)
3610
52.7k
{
3611
52.7k
    basicblock *entryblock = g->g_entryblock;
3612
547k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3613
3.83M
        for (int i = 0; i < b->b_iused; i++) {
3614
3.33M
            cfg_instr *instr = &b->b_instr[i];
3615
3.33M
            if (instr->i_opcode == JUMP_IF_FALSE || instr->i_opcode == JUMP_IF_TRUE) {
3616
3.98k
                assert(i == b->b_iused - 1);
3617
3.98k
                instr->i_opcode = instr->i_opcode == JUMP_IF_FALSE ?
3618
2.94k
                                          POP_JUMP_IF_FALSE : POP_JUMP_IF_TRUE;
3619
3.98k
                location loc = instr->i_loc;
3620
3.98k
                basicblock *except = instr->i_except;
3621
3.98k
                cfg_instr copy = {
3622
3.98k
                            .i_opcode = COPY,
3623
3.98k
                            .i_oparg = 1,
3624
3.98k
                            .i_loc = loc,
3625
3.98k
                            .i_target = NULL,
3626
3.98k
                            .i_except = except,
3627
3.98k
                };
3628
3.98k
                RETURN_IF_ERROR(basicblock_insert_instruction(b, i++, &copy));
3629
3.98k
                cfg_instr to_bool = {
3630
3.98k
                            .i_opcode = TO_BOOL,
3631
3.98k
                            .i_oparg = 0,
3632
3.98k
                            .i_loc = loc,
3633
3.98k
                            .i_target = NULL,
3634
3.98k
                            .i_except = except,
3635
3.98k
                };
3636
3.98k
                RETURN_IF_ERROR(basicblock_insert_instruction(b, i++, &to_bool));
3637
3.98k
            }
3638
3.33M
        }
3639
494k
    }
3640
52.7k
    return SUCCESS;
3641
52.7k
}
3642
3643
static int
3644
convert_pseudo_ops(cfg_builder *g)
3645
52.7k
{
3646
52.7k
    basicblock *entryblock = g->g_entryblock;
3647
547k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3648
3.86M
        for (int i = 0; i < b->b_iused; i++) {
3649
3.36M
            cfg_instr *instr = &b->b_instr[i];
3650
3.36M
            if (is_block_push(instr)) {
3651
74.8k
                INSTR_SET_OP0(instr, NOP);
3652
74.8k
            }
3653
3.29M
            else if (instr->i_opcode == LOAD_CLOSURE) {
3654
18.4k
                assert(is_pseudo_target(LOAD_CLOSURE, LOAD_FAST));
3655
18.4k
                instr->i_opcode = LOAD_FAST;
3656
18.4k
            }
3657
3.27M
            else if (instr->i_opcode == STORE_FAST_MAYBE_NULL) {
3658
13.1k
                assert(is_pseudo_target(STORE_FAST_MAYBE_NULL, STORE_FAST));
3659
13.1k
                instr->i_opcode = STORE_FAST;
3660
13.1k
            }
3661
3.36M
        }
3662
494k
    }
3663
52.7k
    return remove_redundant_nops_and_jumps(g);
3664
52.7k
}
3665
3666
static inline bool
3667
923k
is_exit_or_eval_check_without_lineno(basicblock *b) {
3668
923k
    if (basicblock_exits_scope(b) || basicblock_has_eval_break(b)) {
3669
322k
        return basicblock_has_no_lineno(b);
3670
322k
    }
3671
601k
    else {
3672
601k
        return false;
3673
601k
    }
3674
923k
}
3675
3676
3677
/* PEP 626 mandates that the f_lineno of a frame is correct
3678
 * after a frame terminates. It would be prohibitively expensive
3679
 * to continuously update the f_lineno field at runtime,
3680
 * so we make sure that all exiting instruction (raises and returns)
3681
 * have a valid line number, allowing us to compute f_lineno lazily.
3682
 * We can do this by duplicating the exit blocks without line number
3683
 * so that none have more than one predecessor. We can then safely
3684
 * copy the line number from the sole predecessor block.
3685
 */
3686
static int
3687
duplicate_exits_without_lineno(cfg_builder *g)
3688
105k
{
3689
105k
    int next_lbl = get_max_label(g->g_entryblock) + 1;
3690
3691
    /* Copy all exit blocks without line number that are targets of a jump.
3692
     */
3693
105k
    basicblock *entryblock = g->g_entryblock;
3694
1.07M
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3695
969k
        cfg_instr *last = basicblock_last_instr(b);
3696
969k
        if (last == NULL) {
3697
99.9k
            continue;
3698
99.9k
        }
3699
869k
        if (is_jump(last)) {
3700
443k
            basicblock *target = next_nonempty_block(last->i_target);
3701
443k
            if (is_exit_or_eval_check_without_lineno(target) && target->b_predecessors > 1) {
3702
2.09k
                basicblock *new_target = copy_basicblock(g, target);
3703
2.09k
                if (new_target == NULL) {
3704
0
                    return ERROR;
3705
0
                }
3706
2.09k
                new_target->b_instr[0].i_loc = last->i_loc;
3707
2.09k
                last->i_target = new_target;
3708
2.09k
                target->b_predecessors--;
3709
2.09k
                new_target->b_predecessors = 1;
3710
2.09k
                new_target->b_next = target->b_next;
3711
2.09k
                new_target->b_label.id = next_lbl++;
3712
2.09k
                target->b_next = new_target;
3713
2.09k
            }
3714
443k
        }
3715
869k
    }
3716
3717
    /* Any remaining reachable exit blocks without line number can only be reached by
3718
     * fall through, and thus can only have a single predecessor */
3719
1.07M
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3720
969k
        if (BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_iused > 0) {
3721
480k
            if (is_exit_or_eval_check_without_lineno(b->b_next)) {
3722
13.9k
                cfg_instr *last = basicblock_last_instr(b);
3723
13.9k
                assert(last != NULL);
3724
13.9k
                b->b_next->b_instr[0].i_loc = last->i_loc;
3725
13.9k
            }
3726
480k
        }
3727
969k
    }
3728
105k
    return SUCCESS;
3729
105k
}
3730
3731
3732
/* If an instruction has no line number, but it's predecessor in the BB does,
3733
 * then copy the line number. If a successor block has no line number, and only
3734
 * one predecessor, then inherit the line number.
3735
 * This ensures that all exit blocks (with one predecessor) receive a line number.
3736
 * Also reduces the size of the line number table,
3737
 * but has no impact on the generated line number events.
3738
 */
3739
3740
static inline void
3741
maybe_propagate_location(basicblock *b, int i, location loc)
3742
8.71M
{
3743
8.71M
    assert(b->b_iused > i);
3744
8.71M
    if (b->b_instr[i].i_loc.lineno == NO_LOCATION.lineno) {
3745
613k
         b->b_instr[i].i_loc = loc;
3746
613k
    }
3747
8.71M
}
3748
3749
static void
3750
propagate_line_numbers(basicblock *entryblock)
3751
105k
{
3752
1.07M
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3753
969k
        cfg_instr *last = basicblock_last_instr(b);
3754
969k
        if (last == NULL) {
3755
99.9k
            continue;
3756
99.9k
        }
3757
3758
869k
        location prev_location = NO_LOCATION;
3759
9.19M
        for (int i = 0; i < b->b_iused; i++) {
3760
8.32M
            maybe_propagate_location(b, i, prev_location);
3761
8.32M
            prev_location = b->b_instr[i].i_loc;
3762
8.32M
        }
3763
869k
        if (BB_HAS_FALLTHROUGH(b) && b->b_next->b_predecessors == 1) {
3764
307k
            if (b->b_next->b_iused > 0) {
3765
306k
                maybe_propagate_location(b->b_next, 0, prev_location);
3766
306k
            }
3767
307k
        }
3768
869k
        if (is_jump(last)) {
3769
443k
            basicblock *target = last->i_target;
3770
443k
            while (target->b_iused == 0 && target->b_predecessors == 1) {
3771
20
                target = target->b_next;
3772
20
            }
3773
443k
            if (target->b_predecessors == 1) {
3774
84.6k
                maybe_propagate_location(target, 0, prev_location);
3775
84.6k
            }
3776
443k
        }
3777
869k
    }
3778
105k
}
3779
3780
static int
3781
resolve_line_numbers(cfg_builder *g, int firstlineno)
3782
105k
{
3783
105k
    RETURN_IF_ERROR(duplicate_exits_without_lineno(g));
3784
105k
    propagate_line_numbers(g->g_entryblock);
3785
105k
    return SUCCESS;
3786
105k
}
3787
3788
int
3789
_PyCfg_OptimizeCodeUnit(cfg_builder *g, PyObject *consts, PyObject *const_cache,
3790
                        int nlocals, int nparams, int firstlineno)
3791
52.7k
{
3792
52.7k
    assert(cfg_builder_check(g));
3793
52.7k
    assert(g->g_entryblock->b_iused > 0);
3794
    /** Preprocessing **/
3795
    /* Map labels to targets and mark exception handlers */
3796
52.7k
    RETURN_IF_ERROR(translate_jump_labels_to_targets(g->g_entryblock));
3797
52.7k
    RETURN_IF_ERROR(mark_except_handlers(g->g_entryblock));
3798
52.7k
    RETURN_IF_ERROR(label_exception_targets(g->g_entryblock));
3799
3800
    /** Optimization **/
3801
3802
52.7k
    _Py_hashtable_t *consts_index = _Py_hashtable_new(
3803
52.7k
        _Py_hashtable_hash_ptr, _Py_hashtable_compare_direct);
3804
52.7k
    if (consts_index == NULL) {
3805
0
        PyErr_NoMemory();
3806
0
        return ERROR;
3807
0
    }
3808
3809
330k
    for (Py_ssize_t i = 0; i < PyList_GET_SIZE(consts); i++) {
3810
277k
        PyObject *item = PyList_GET_ITEM(consts, i);
3811
277k
        if (_Py_hashtable_get_entry(consts_index, (void *)item) != NULL) {
3812
0
            continue;
3813
0
        }
3814
277k
        if (_Py_hashtable_set(consts_index, (void *)item,
3815
277k
                              (void *)(uintptr_t)i) < 0) {
3816
0
            _Py_hashtable_destroy(consts_index);
3817
0
            PyErr_NoMemory();
3818
0
            return ERROR;
3819
0
        }
3820
277k
    }
3821
3822
52.7k
    int ret = optimize_cfg(g, consts, const_cache, consts_index, firstlineno);
3823
3824
52.7k
    _Py_hashtable_destroy(consts_index);
3825
3826
52.7k
    RETURN_IF_ERROR(ret);
3827
3828
52.7k
    RETURN_IF_ERROR(remove_unused_consts(g->g_entryblock, consts));
3829
52.7k
    RETURN_IF_ERROR(
3830
52.7k
        add_checks_for_loads_of_uninitialized_variables(
3831
52.7k
            g->g_entryblock, nlocals, nparams));
3832
52.7k
    RETURN_IF_ERROR(insert_superinstructions(g));
3833
3834
52.7k
    RETURN_IF_ERROR(push_cold_blocks_to_end(g));
3835
52.7k
    RETURN_IF_ERROR(resolve_line_numbers(g, firstlineno));
3836
    // temporarily remove assert. See https://github.com/python/cpython/issues/125845
3837
    // assert(all_exits_have_lineno(g->g_entryblock));
3838
52.7k
    return SUCCESS;
3839
52.7k
}
3840
3841
static int *
3842
build_cellfixedoffsets(_PyCompile_CodeUnitMetadata *umd)
3843
52.7k
{
3844
52.7k
    int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames);
3845
52.7k
    int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars);
3846
52.7k
    int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars);
3847
3848
52.7k
    int noffsets = ncellvars + nfreevars;
3849
52.7k
    int *fixed = PyMem_New(int, noffsets);
3850
52.7k
    if (fixed == NULL) {
3851
0
        PyErr_NoMemory();
3852
0
        return NULL;
3853
0
    }
3854
77.1k
    for (int i = 0; i < noffsets; i++) {
3855
24.3k
        fixed[i] = nlocals + i;
3856
24.3k
    }
3857
3858
52.7k
    PyObject *varname, *cellindex;
3859
52.7k
    Py_ssize_t pos = 0;
3860
64.7k
    while (PyDict_Next(umd->u_cellvars, &pos, &varname, &cellindex)) {
3861
11.9k
        PyObject *varindex;
3862
11.9k
        if (PyDict_GetItemRef(umd->u_varnames, varname, &varindex) < 0) {
3863
0
            goto error;
3864
0
        }
3865
11.9k
        if (varindex == NULL) {
3866
11.8k
            continue;
3867
11.8k
        }
3868
3869
104
        int argoffset = PyLong_AsInt(varindex);
3870
104
        Py_DECREF(varindex);
3871
104
        if (argoffset == -1 && PyErr_Occurred()) {
3872
0
            goto error;
3873
0
        }
3874
3875
104
        int oldindex = PyLong_AsInt(cellindex);
3876
104
        if (oldindex == -1 && PyErr_Occurred()) {
3877
0
            goto error;
3878
0
        }
3879
104
        fixed[oldindex] = argoffset;
3880
104
    }
3881
52.7k
    return fixed;
3882
3883
0
error:
3884
0
    PyMem_Free(fixed);
3885
0
    return NULL;
3886
52.7k
}
3887
3888
#define IS_GENERATOR(CF) \
3889
    ((CF) & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR))
3890
3891
static int
3892
insert_prefix_instructions(_PyCompile_CodeUnitMetadata *umd, basicblock *entryblock,
3893
                           int *fixed, int nfreevars)
3894
52.7k
{
3895
52.7k
    assert(umd->u_firstlineno > 0);
3896
3897
    /* Set up cells for any variable that escapes, to be put in a closure. */
3898
52.7k
    const int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars);
3899
52.7k
    if (ncellvars) {
3900
        // umd->u_cellvars has the cells out of order so we sort them
3901
        // before adding the MAKE_CELL instructions.  Note that we
3902
        // adjust for arg cells, which come first.
3903
11.1k
        const int nvars = ncellvars + (int)PyDict_GET_SIZE(umd->u_varnames);
3904
11.1k
        int *sorted = PyMem_RawCalloc(nvars, sizeof(int));
3905
11.1k
        if (sorted == NULL) {
3906
0
            PyErr_NoMemory();
3907
0
            return ERROR;
3908
0
        }
3909
23.1k
        for (int i = 0; i < ncellvars; i++) {
3910
11.9k
            sorted[fixed[i]] = i + 1;
3911
11.9k
        }
3912
30.8k
        for (int i = 0, ncellsused = 0; ncellsused < ncellvars; i++) {
3913
19.6k
            int oldindex = sorted[i] - 1;
3914
19.6k
            if (oldindex == -1) {
3915
7.71k
                continue;
3916
7.71k
            }
3917
11.9k
            cfg_instr make_cell = {
3918
11.9k
                .i_opcode = MAKE_CELL,
3919
                // This will get fixed in offset_derefs().
3920
11.9k
                .i_oparg = oldindex,
3921
11.9k
                .i_loc = NO_LOCATION,
3922
11.9k
                .i_target = NULL,
3923
11.9k
                .i_except = NULL,
3924
11.9k
            };
3925
11.9k
            if (basicblock_insert_instruction(entryblock, ncellsused, &make_cell) < 0) {
3926
0
                PyMem_RawFree(sorted);
3927
0
                return ERROR;
3928
0
            }
3929
11.9k
            ncellsused += 1;
3930
11.9k
        }
3931
11.1k
        PyMem_RawFree(sorted);
3932
11.1k
    }
3933
3934
52.7k
    if (nfreevars) {
3935
10.9k
        cfg_instr copy_frees = {
3936
10.9k
            .i_opcode = COPY_FREE_VARS,
3937
10.9k
            .i_oparg = nfreevars,
3938
10.9k
            .i_loc = NO_LOCATION,
3939
10.9k
            .i_target = NULL,
3940
10.9k
            .i_except = NULL,
3941
10.9k
        };
3942
10.9k
        RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 0, &copy_frees));
3943
10.9k
    }
3944
3945
52.7k
    return SUCCESS;
3946
52.7k
}
3947
3948
static int
3949
fix_cell_offsets(_PyCompile_CodeUnitMetadata *umd, basicblock *entryblock, int *fixedmap)
3950
52.7k
{
3951
52.7k
    int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames);
3952
52.7k
    int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars);
3953
52.7k
    int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars);
3954
52.7k
    int noffsets = ncellvars + nfreevars;
3955
3956
    // First deal with duplicates (arg cells).
3957
52.7k
    int numdropped = 0;
3958
77.1k
    for (int i = 0; i < noffsets ; i++) {
3959
24.3k
        if (fixedmap[i] == i + nlocals) {
3960
24.2k
            fixedmap[i] -= numdropped;
3961
24.2k
        }
3962
104
        else {
3963
            // It was a duplicate (cell/arg).
3964
104
            numdropped += 1;
3965
104
        }
3966
24.3k
    }
3967
3968
    // Then update offsets, either relative to locals or by cell2arg.
3969
547k
    for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
3970
3.86M
        for (int i = 0; i < b->b_iused; i++) {
3971
3.36M
            cfg_instr *inst = &b->b_instr[i];
3972
            // This is called before extended args are generated.
3973
3.36M
            assert(inst->i_opcode != EXTENDED_ARG);
3974
3.36M
            int oldoffset = inst->i_oparg;
3975
3.36M
            switch(inst->i_opcode) {
3976
11.9k
                case MAKE_CELL:
3977
30.4k
                case LOAD_CLOSURE:
3978
49.2k
                case LOAD_DEREF:
3979
59.2k
                case STORE_DEREF:
3980
59.2k
                case DELETE_DEREF:
3981
62.0k
                case LOAD_FROM_DICT_OR_DEREF:
3982
62.0k
                    assert(oldoffset >= 0);
3983
62.0k
                    assert(oldoffset < noffsets);
3984
62.0k
                    assert(fixedmap[oldoffset] >= 0);
3985
62.0k
                    inst->i_oparg = fixedmap[oldoffset];
3986
3.36M
            }
3987
3.36M
        }
3988
494k
    }
3989
3990
52.7k
    return numdropped;
3991
52.7k
}
3992
3993
static int
3994
prepare_localsplus(_PyCompile_CodeUnitMetadata *umd, cfg_builder *g)
3995
52.7k
{
3996
52.7k
    assert(PyDict_GET_SIZE(umd->u_varnames) < INT_MAX);
3997
52.7k
    assert(PyDict_GET_SIZE(umd->u_cellvars) < INT_MAX);
3998
52.7k
    assert(PyDict_GET_SIZE(umd->u_freevars) < INT_MAX);
3999
52.7k
    int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames);
4000
52.7k
    int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars);
4001
52.7k
    int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars);
4002
52.7k
    assert(INT_MAX - nlocals - ncellvars > 0);
4003
52.7k
    assert(INT_MAX - nlocals - ncellvars - nfreevars > 0);
4004
52.7k
    int nlocalsplus = nlocals + ncellvars + nfreevars;
4005
52.7k
    int* cellfixedoffsets = build_cellfixedoffsets(umd);
4006
52.7k
    if (cellfixedoffsets == NULL) {
4007
0
        return ERROR;
4008
0
    }
4009
4010
    // This must be called before fix_cell_offsets().
4011
52.7k
    if (insert_prefix_instructions(umd, g->g_entryblock, cellfixedoffsets, nfreevars)) {
4012
0
        PyMem_Free(cellfixedoffsets);
4013
0
        return ERROR;
4014
0
    }
4015
4016
52.7k
    int numdropped = fix_cell_offsets(umd, g->g_entryblock, cellfixedoffsets);
4017
52.7k
    PyMem_Free(cellfixedoffsets);  // At this point we're done with it.
4018
52.7k
    cellfixedoffsets = NULL;
4019
52.7k
    if (numdropped < 0) {
4020
0
        return ERROR;
4021
0
    }
4022
4023
52.7k
    nlocalsplus -= numdropped;
4024
52.7k
    return nlocalsplus;
4025
52.7k
}
4026
4027
cfg_builder *
4028
_PyCfg_FromInstructionSequence(_PyInstructionSequence *seq)
4029
52.7k
{
4030
52.7k
    if (_PyInstructionSequence_ApplyLabelMap(seq) < 0) {
4031
0
        return NULL;
4032
0
    }
4033
52.7k
    cfg_builder *g = _PyCfgBuilder_New();
4034
52.7k
    if (g == NULL) {
4035
0
        return NULL;
4036
0
    }
4037
5.10M
    for (int i = 0; i < seq->s_used; i++) {
4038
5.05M
        seq->s_instrs[i].i_target = 0;
4039
5.05M
    }
4040
5.10M
    for (int i = 0; i < seq->s_used; i++) {
4041
5.05M
        _PyInstruction *instr = &seq->s_instrs[i];
4042
5.05M
        if (HAS_TARGET(instr->i_opcode)) {
4043
313k
            assert(instr->i_oparg >= 0 && instr->i_oparg < seq->s_used);
4044
313k
            seq->s_instrs[instr->i_oparg].i_target = 1;
4045
313k
        }
4046
5.05M
    }
4047
52.7k
    int offset = 0;
4048
5.10M
    for (int i = 0; i < seq->s_used; i++) {
4049
5.05M
        _PyInstruction *instr = &seq->s_instrs[i];
4050
5.05M
        if (instr->i_opcode == ANNOTATIONS_PLACEHOLDER) {
4051
10.0k
            if (seq->s_annotations_code != NULL) {
4052
599
                assert(seq->s_annotations_code->s_labelmap_size == 0
4053
599
                    && seq->s_annotations_code->s_nested == NULL);
4054
2.39k
                for (int j = 0; j < seq->s_annotations_code->s_used; j++) {
4055
1.79k
                    _PyInstruction *ann_instr = &seq->s_annotations_code->s_instrs[j];
4056
1.79k
                    assert(!HAS_TARGET(ann_instr->i_opcode));
4057
1.79k
                    if (_PyCfgBuilder_Addop(g, ann_instr->i_opcode, ann_instr->i_oparg, ann_instr->i_loc) < 0) {
4058
0
                        goto error;
4059
0
                    }
4060
1.79k
                }
4061
599
                offset += seq->s_annotations_code->s_used - 1;
4062
599
            }
4063
9.48k
            else {
4064
9.48k
                offset -= 1;
4065
9.48k
            }
4066
10.0k
            continue;
4067
10.0k
        }
4068
5.04M
        if (instr->i_target) {
4069
239k
            jump_target_label lbl_ = {i + offset};
4070
239k
            if (_PyCfgBuilder_UseLabel(g, lbl_) < 0) {
4071
0
                goto error;
4072
0
            }
4073
239k
        }
4074
5.04M
        int opcode = instr->i_opcode;
4075
5.04M
        int oparg = instr->i_oparg;
4076
5.04M
        if (HAS_TARGET(opcode)) {
4077
313k
            oparg += offset;
4078
313k
        }
4079
5.04M
        if (_PyCfgBuilder_Addop(g, opcode, oparg, instr->i_loc) < 0) {
4080
0
            goto error;
4081
0
        }
4082
5.04M
    }
4083
52.7k
    if (_PyCfgBuilder_CheckSize(g) < 0) {
4084
0
        goto error;
4085
0
    }
4086
52.7k
    return g;
4087
0
error:
4088
0
    _PyCfgBuilder_Free(g);
4089
0
    return NULL;
4090
52.7k
}
4091
4092
int
4093
_PyCfg_ToInstructionSequence(cfg_builder *g, _PyInstructionSequence *seq)
4094
52.7k
{
4095
52.7k
    int lbl = 0;
4096
547k
    for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
4097
494k
        b->b_label = (jump_target_label){lbl};
4098
494k
        lbl += 1;
4099
494k
    }
4100
547k
    for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
4101
494k
        RETURN_IF_ERROR(_PyInstructionSequence_UseLabel(seq, b->b_label.id));
4102
3.87M
        for (int i = 0; i < b->b_iused; i++) {
4103
3.38M
            cfg_instr *instr = &b->b_instr[i];
4104
3.38M
            if (HAS_TARGET(instr->i_opcode)) {
4105
                /* Set oparg to the label id (it will later be mapped to an offset) */
4106
214k
                instr->i_oparg = instr->i_target->b_label.id;
4107
214k
            }
4108
3.38M
            RETURN_IF_ERROR(
4109
3.38M
                _PyInstructionSequence_Addop(
4110
3.38M
                    seq, instr->i_opcode, instr->i_oparg, instr->i_loc));
4111
4112
3.38M
            _PyExceptHandlerInfo *hi = &seq->s_instrs[seq->s_used-1].i_except_handler_info;
4113
3.38M
            if (instr->i_except != NULL) {
4114
1.03M
                hi->h_label = instr->i_except->b_label.id;
4115
1.03M
                hi->h_startdepth = instr->i_except->b_startdepth;
4116
1.03M
                hi->h_preserve_lasti = instr->i_except->b_preserve_lasti;
4117
1.03M
            }
4118
2.34M
            else {
4119
2.34M
                hi->h_label = -1;
4120
2.34M
            }
4121
3.38M
        }
4122
494k
    }
4123
52.7k
    if (_PyInstructionSequence_ApplyLabelMap(seq) < 0) {
4124
0
        return ERROR;
4125
0
    }
4126
52.7k
    return SUCCESS;
4127
52.7k
}
4128
4129
4130
int
4131
_PyCfg_OptimizedCfgToInstructionSequence(cfg_builder *g,
4132
                                     _PyCompile_CodeUnitMetadata *umd,
4133
                                     int *stackdepth, int *nlocalsplus,
4134
                                     _PyInstructionSequence *seq)
4135
52.7k
{
4136
52.7k
    RETURN_IF_ERROR(convert_pseudo_conditional_jumps(g));
4137
4138
52.7k
    *stackdepth = calculate_stackdepth(g);
4139
52.7k
    if (*stackdepth < 0) {
4140
0
        return ERROR;
4141
0
    }
4142
4143
52.7k
    *nlocalsplus = prepare_localsplus(umd, g);
4144
52.7k
    if (*nlocalsplus < 0) {
4145
0
        return ERROR;
4146
0
    }
4147
4148
52.7k
    RETURN_IF_ERROR(convert_pseudo_ops(g));
4149
4150
    /* Order of basic blocks must have been determined by now */
4151
4152
52.7k
    RETURN_IF_ERROR(normalize_jumps(g));
4153
52.7k
    assert(no_redundant_jumps(g));
4154
4155
    /* Can't modify the bytecode after inserting instructions that produce
4156
     * borrowed references.
4157
     */
4158
52.7k
    RETURN_IF_ERROR(optimize_load_fast(g));
4159
4160
    /* Can't modify the bytecode after computing jump offsets. */
4161
52.7k
    if (_PyCfg_ToInstructionSequence(g, seq) < 0) {
4162
0
        return ERROR;
4163
0
    }
4164
4165
52.7k
    return SUCCESS;
4166
52.7k
}
4167
4168
/* This is used by _PyCompile_Assemble to fill in the jump and exception
4169
 * targets in a synthetic CFG (which is not the output of the builtin compiler).
4170
 */
4171
int
4172
_PyCfg_JumpLabelsToTargets(cfg_builder *g)
4173
0
{
4174
0
    RETURN_IF_ERROR(translate_jump_labels_to_targets(g->g_entryblock));
4175
0
    RETURN_IF_ERROR(label_exception_targets(g->g_entryblock));
4176
0
    return SUCCESS;
4177
0
}
4178
4179
/* Exported API functions */
4180
4181
int
4182
PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump)
4183
0
{
4184
0
    stack_effects effs;
4185
0
    if (get_stack_effects(opcode, oparg, jump, &effs) < 0) {
4186
0
        return PY_INVALID_STACK_EFFECT;
4187
0
    }
4188
0
    return effs.net;
4189
0
}
4190
4191
int
4192
PyCompile_OpcodeStackEffect(int opcode, int oparg)
4193
4.63k
{
4194
4.63k
    stack_effects effs;
4195
4.63k
    if (get_stack_effects(opcode, oparg, -1, &effs) < 0) {
4196
0
        return PY_INVALID_STACK_EFFECT;
4197
0
    }
4198
4.63k
    return effs.net;
4199
4.63k
}
4200
4201
/* Access to compiler optimizations for unit tests.
4202
4203
 * _PyCompile_OptimizeCfg takes an instruction list, constructs
4204
 * a CFG, optimizes it and converts back to an instruction list.
4205
 */
4206
4207
static PyObject *
4208
cfg_to_instruction_sequence(cfg_builder *g)
4209
0
{
4210
0
    _PyInstructionSequence *seq = (_PyInstructionSequence *)_PyInstructionSequence_New();
4211
0
    if (seq == NULL) {
4212
0
        return NULL;
4213
0
    }
4214
0
    if (_PyCfg_ToInstructionSequence(g, seq) < 0) {
4215
0
        PyInstructionSequence_Fini(seq);
4216
0
        return NULL;
4217
0
    }
4218
0
    return (PyObject*)seq;
4219
0
}
4220
4221
PyObject *
4222
_PyCompile_OptimizeCfg(PyObject *seq, PyObject *consts, int nlocals)
4223
0
{
4224
0
    if (!_PyInstructionSequence_Check(seq)) {
4225
0
        PyErr_SetString(PyExc_ValueError, "expected an instruction sequence");
4226
0
        return NULL;
4227
0
    }
4228
0
    if (!PyList_Check(consts)) {
4229
0
        PyErr_SetString(PyExc_TypeError, "consts must be a list");
4230
0
        return NULL;
4231
0
    }
4232
0
    PyObject *const_cache = PyDict_New();
4233
0
    if (const_cache == NULL) {
4234
0
        return NULL;
4235
0
    }
4236
4237
0
    PyObject *res = NULL;
4238
0
    cfg_builder *g = _PyCfg_FromInstructionSequence((_PyInstructionSequence*)seq);
4239
0
    if (g == NULL) {
4240
0
        goto error;
4241
0
    }
4242
0
    int nparams = 0, firstlineno = 1;
4243
0
    if (_PyCfg_OptimizeCodeUnit(g, consts, const_cache, nlocals,
4244
0
                                nparams, firstlineno) < 0) {
4245
0
        goto error;
4246
0
    }
4247
4248
0
    if (calculate_stackdepth(g) == ERROR) {
4249
0
        goto error;
4250
0
    }
4251
4252
0
    if (optimize_load_fast(g) != SUCCESS) {
4253
0
        goto error;
4254
0
    }
4255
4256
0
    res = cfg_to_instruction_sequence(g);
4257
0
error:
4258
0
    Py_DECREF(const_cache);
4259
0
    _PyCfgBuilder_Free(g);
4260
0
    return res;
4261
0
}