10000 Revert "bpo-38135: Fix depth-first-search computation in compile.c" by Yhg1s · Pull Request #16050 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

Revert "bpo-38135: Fix depth-first-search computation in compile.c" #16050

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 12, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 30 additions & 24 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -5373,7 +5373,7 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
/* End of the compiler section, beginning of the assembler section */

/* do depth-first search of basic block graph, starting with block.
a_order records the block indices in order.
post records the block indices in post-order.

XXX must handle implicit jumps from one block to next
*/
Expand All @@ -5382,29 +5382,36 @@ struct assembler {
PyObject *a_bytecode; /* string containing bytecode */
int a_offset; /* offset into bytecode */
int a_nblocks; /* number of reachable blocks */
basicblock **a_order; /* list of blocks in dfs order */
basicblock **a_postorder; /* list of blocks in dfs postorder */
PyObject *a_lnotab; /* string containing lnotab */
int a_lnotab_off; /* offset into lnotab */
int a_lineno; /* last lineno of emitted instruction */
int a_lineno_off; /* bytecode offset of last lineno */
};

static void
dfs(struct compiler *c, basicblock *entry, struct assembler *a)
dfs(struct compiler *c, basicblock *b, struct assembler *a, int end)
{
/* Avoid excessive recursion by following 'next' links to the
* end of the chain before handling any branches */
for (basicblock *b = entry; b; b = b->b_next) {
int i, j;

/* Get rid of recursion for normal control flow.
Since the number of blocks is limited, unused space in a_postorder
(from a_nblocks to end) can be used as a stack for still not ordered
blocks. */
for (j = end; b && !b->b_seen; b = b->b_next) {
b->b_seen = 1;
a->a_order[a->a_nblocks++] = b;
assert(a->a_nblocks < j);
a->a_postorder[--j] = b;
}
for (basicblock *b = entry; b; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
basicblock *target = b->b_instr[i].i_target;
if (target && !target->b_seen) {
dfs(c, target, a);
}
while (j < end) {
b = a->a_postorder[j++];
for (i = 0; i < b->b_iused; i++) {
struct instr *instr = &b->b_instr[i];
if (instr->i_jrel || instr->i_jabs)
dfs(c, instr->i_target, a, j);
}
assert(a->a_nblocks < j);
a->a_postorder[a->a_nblocks++] = b;
}
}

Expand Down Expand Up @@ -5510,9 +5517,9 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno)
PyErr_NoMemory();
return 0;
}
a->a_order = (basicblock **)PyObject_Malloc(
a->a_postorder = (basicblock **)PyObject_Malloc(
sizeof(basicblock *) * nblocks);
if (!a->a_order) {
if (!a->a_postorder) {
PyErr_NoMemory();
return 0;
}
Expand All @@ -5524,8 +5531,8 @@ assemble_free(struct assembler *a)
{
Py_XDECREF(a->a_bytecode);
Py_XDECREF(a->a_lnotab);
if (a->a_order)
PyObject_Free(a->a_order);
if (a->a_postorder)
PyObject_Free(a->a_postorder);
}

static int
Expand Down Expand Up @@ -5686,8 +5693,8 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c)
Replace block pointer with position in bytecode. */
do {
totsize = 0;
for (i = 0; i < a->a_nblocks; i++) {
b = a->a_order[i];
for (i = a->a_nblocks - 1; i >= 0; i--) {
b = a->a_postorder[i];
bsize = blocksize(b);
b->b_offset = totsize;
totsize += bsize;
Expand Down Expand Up @@ -5991,15 +5998,14 @@ assemble(struct compiler *c, int addNone)
}
if (!assemble_init(&a, nblocks, c->u->u_firstlineno))
goto error;
dfs(c, entryblock, &a);
assert(a.a_nblocks <= nblocks);
dfs(c, entryblock, &a, nblocks);

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

/* Emit code in order from dfs. */
for (i = 0; i < a.a_nblocks; i++) {
b = a.a_order[i];
/* Emit code in reverse postorder from dfs. */
for (i = a.a_nblocks - 1; i >= 0; i--) {
b = a.a_postorder[i];
for (j = 0; j < b->b_iused; j++)
if (!assemble_emit(&a, &b->b_instr[j]))
goto error;
Expand Down
0