turn goto into do while loop

This commit is contained in:
Benjamin Peterson 2009-11-20 02:15:50 +00:00
parent 009b89d22a
commit cef9782810

View file

@ -3586,49 +3586,47 @@ static void
assemble_jump_offsets(struct assembler *a, struct compiler *c) assemble_jump_offsets(struct assembler *a, struct compiler *c)
{ {
basicblock *b; basicblock *b;
int bsize, totsize, extended_arg_count, last_extended_arg_count = 0; int bsize, totsize, extended_arg_count = 0, last_extended_arg_count;
int i; int i;
/* Compute the size of each block and fixup jump args. /* Compute the size of each block and fixup jump args.
Replace block pointer with position in bytecode. */ Replace block pointer with position in bytecode. */
start: do {
totsize = 0; totsize = 0;
for (i = a->a_nblocks - 1; i >= 0; i--) { for (i = a->a_nblocks - 1; i >= 0; i--) {
b = a->a_postorder[i]; b = a->a_postorder[i];
bsize = blocksize(b); bsize = blocksize(b);
b->b_offset = totsize; b->b_offset = totsize;
totsize += bsize; totsize += bsize;
} }
extended_arg_count = 0; last_extended_arg_count = extended_arg_count;
for (b = c->u->u_blocks; b != NULL; b = b->b_list) { extended_arg_count = 0;
bsize = b->b_offset; for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
for (i = 0; i < b->b_iused; i++) { bsize = b->b_offset;
struct instr *instr = &b->b_instr[i]; for (i = 0; i < b->b_iused; i++) {
/* Relative jumps are computed relative to struct instr *instr = &b->b_instr[i];
the instruction pointer after fetching /* Relative jumps are computed relative to
the jump instruction. the instruction pointer after fetching
*/ the jump instruction.
bsize += instrsize(instr); */
if (instr->i_jabs) bsize += instrsize(instr);
instr->i_oparg = instr->i_target->b_offset; if (instr->i_jabs)
else if (instr->i_jrel) { instr->i_oparg = instr->i_target->b_offset;
int delta = instr->i_target->b_offset - bsize; else if (instr->i_jrel) {
instr->i_oparg = delta; int delta = instr->i_target->b_offset - bsize;
} instr->i_oparg = delta;
else }
continue; else
if (instr->i_oparg > 0xffff) continue;
extended_arg_count++; if (instr->i_oparg > 0xffff)
extended_arg_count++;
}
} }
}
/* XXX: This is an awful hack that could hurt performance, but /* XXX: This is an awful hack that could hurt performance, but
on the bright side it should work until we come up on the bright side it should work until we come up
with a better solution. with a better solution.
In the meantime, should the goto be dropped in favor
of a loop?
The issue is that in the first loop blocksize() is called The issue is that in the first loop blocksize() is called
which calls instrsize() which requires i_oparg be set which calls instrsize() which requires i_oparg be set
appropriately. There is a bootstrap problem because appropriately. There is a bootstrap problem because
@ -3639,10 +3637,7 @@ start:
ones in jump instructions. So this should converge ones in jump instructions. So this should converge
fairly quickly. fairly quickly.
*/ */
if (last_extended_arg_count != extended_arg_count) { } while (last_extended_arg_count != extended_arg_count);
last_extended_arg_count = extended_arg_count;
goto start;
}
} }
static PyObject * static PyObject *