8000 Revert "Fix depth-first-search computation in compile.c (GH-16042)" (… · python/cpython@99b54d6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 99b54d6

Browse files
Yhg1sgpshead
authored andcommitted
Revert "Fix depth-first-search computation in compile.c (GH-16042)" (GH-16050)
This reverts commit 355f3e1. bpo-38135
1 parent 355f3e1 commit 99b54d6

File tree

1 file changed

+30
-24
lines changed

1 file changed

+30
-24
lines changed

Python/compile.c

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5373,7 +5373,7 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
53735373
/* End of the compiler section, beginning of the assembler section */
53745374

53755375
/* do depth-first search of basic block graph, starting with block.
5376-
a_order records the block indices in order.
5376+
post records the block indices in post-order.
53775377
53785378
XXX must handle implicit jumps from one block to next
53795379
*/
@@ -5382,29 +5382,36 @@ struct assembler {
53825382
PyObject *a_bytecode; /* string containing bytecode */
53835383
int a_offset; /* offset into bytecode */
53845384
int a_nblocks; /* number of reachable blocks */
5385-
basicblock **a_order; /* list of blocks in dfs order */
5385+
basicblock **a_postorder; /* list of blocks in dfs postorder */
53865386
PyObject *a_lnotab; /* string containing lnotab */
53875387
int a_lnotab_off; /* offset into lnotab */
53885388
int a_lineno; /* last lineno of emitted instruction */
53895389
int a_lineno_off; /* bytecode offset of last lineno */
53905390
};
53915391

53925392
static void
5393-
dfs(struct compiler *c, basicblock *entry, struct assembler *a)
5393+
dfs(struct compiler *c, basicblock *b, struct assembler *a, int end)
53945394
{
5395-
/* Avoid excessive recursion by following 'next' links to the
5396-
* end of the chain before handling any branches */
5397-
for (basicblock *b = entry; b; b = b->b_next) {
5395+
int i, j;
5396+
5397+
/* Get rid of recursion for normal control flow.
5398+
Since the number of blocks is limited, unused space in a_postorder
5399+
(from a_nblocks to end) can be used as a stack for still not ordered
5400+
blocks. */
5401+
for (j = end; b && !b->b_seen; b = b->b_next) {
53985402
b->b_seen = 1;
5399-
a->a_order[a->a_nblocks++] = b;
5403+
assert(a->a_nblocks < j);
5404+
a->a_postorder[--j] = b;
54005405
}
5401-
for (basicblock *b = entry; b; b = b->b_next) {
5402-
for (int i = 0; i < b->b_iused; i++) {
5403-
basicblock *target = b->b_instr[i].i_target;
5404-
if (target && !target->b_seen) {
5405-
dfs(c, target, a);
5406-
}
5406+
while (j < end) {
5407+
b = a->a_postorder[j++];
5408+
for (i = 0; i < b->b_iused; i++) {
5409+
struct instr *instr = &b->b_instr[i];
5410+
if (instr->i_jrel || instr->i_jabs)
5411+
dfs(c, instr->i_target, a, j);
54075412
}
5413+
assert(a->a_nblocks < j);
5414+
a->a_postorder[a->a_nblocks++] = b;
54085415
}
54095416
}
54105417

@@ -5510,9 +5517,9 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno)
55105517
PyErr_NoMemory();
55115518
return 0;
55125519
}
5513-
a->a_order = (basicblock **)PyObject_Malloc(
5520+
a->a_postorder = (basicblock **)PyObject_Malloc(
55145521
sizeof(basicblock *) * nblocks);
5515-
if (!a->a_order) {
5522+
if (!a->a_postorder) {
55165523
PyErr_NoMemory();
55175524
return 0;
55185525
}
@@ -5524,8 +5531,8 @@ assemble_free(struct assembler *a)
55245531
{
55255532
Py_XDECREF(a->a_bytecode);
55265533
Py_XDECREF(a->a_lnotab);
5527-
if (a->a_order)
5528-
PyObject_Free(a->a_order);
5534+
if (a->a_postorder)
5535+
PyObject_Free(a->a_postorder);
55295536
}
55305537

55315538
static int
@@ -5686,8 +5693,8 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c)
56865693
Replace block pointer with position in bytecode. */
56875694
do {
56885695
totsize = 0;
5689-
for (i = 0; i < a->a_nblocks; i++) {
5690-
b = a->a_order[i];
5696+
for (i = a->a_nblocks - 1; i >= 0; i--) {
5697+
b = a->a_postorder[i];
56915698
bsize = blocksize(b);
56925699
b->b_offset = totsize;
56935700
totsize += bsize;
@@ -5991,15 +5998,14 @@ assemble(struct compiler *c, int addNone)
59915998
}
59925999
if (!assemble_init(&a, nblocks, c->u->u_firstlineno))
59936000
goto error;
5994-
dfs(c, entryblock, &a);
5995-
assert(a.a_nblocks <= nblocks);
6001+
dfs(c, entryblock, &a, nblocks);
59966002

59976003
/* Can't modify the bytecode after computing jump offsets. */
59986004
assemble_jump_offsets(&a, c);
59996005

6000-
/* Emit code in order from dfs. */
6001-
for (i = 0; i < a.a_nblocks; i++) {
6002-
b = a.a_order[i];
6006+
/* Emit code in reverse postorder from dfs. */
6007+
for (i = a.a_nblocks - 1; i >= 0; i--) {
6008+
b = a.a_postorder[i];
60036009
for (j = 0; j < b->b_iused; j++)
60046010
if (!assemble_emit(&a, &b->b_instr[j]))
60056011
goto error;

0 commit comments

Comments
 (0)
0