mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
gh-87092: in compiler, move the detection of exception handlers before the CFG optimization stage (GH-96935)
This commit is contained in:
parent
fc05107af9
commit
98e785d364
1 changed files with 32 additions and 16 deletions
|
@ -258,10 +258,8 @@ typedef struct basicblock_ {
|
||||||
int b_iused;
|
int b_iused;
|
||||||
/* length of instruction array (b_instr) */
|
/* length of instruction array (b_instr) */
|
||||||
int b_ialloc;
|
int b_ialloc;
|
||||||
/* Number of predecssors that a block has. */
|
/* Number of predecessors that a block has. */
|
||||||
int b_predecessors;
|
int b_predecessors;
|
||||||
/* Number of predecssors that a block has as an exception handler. */
|
|
||||||
int b_except_predecessors;
|
|
||||||
/* depth of stack upon entry of block, computed by stackdepth() */
|
/* depth of stack upon entry of block, computed by stackdepth() */
|
||||||
int b_startdepth;
|
int b_startdepth;
|
||||||
/* instruction offset for block, computed by assemble_jump_offsets() */
|
/* instruction offset for block, computed by assemble_jump_offsets() */
|
||||||
|
@ -270,6 +268,8 @@ typedef struct basicblock_ {
|
||||||
unsigned b_preserve_lasti : 1;
|
unsigned b_preserve_lasti : 1;
|
||||||
/* Used by compiler passes to mark whether they have visited a basic block. */
|
/* Used by compiler passes to mark whether they have visited a basic block. */
|
||||||
unsigned b_visited : 1;
|
unsigned b_visited : 1;
|
||||||
|
/* b_except_handler is used by the cold-detection algorithm to mark exception targets */
|
||||||
|
unsigned b_except_handler : 1;
|
||||||
/* b_cold is true if this block is not perf critical (like an exception handler) */
|
/* b_cold is true if this block is not perf critical (like an exception handler) */
|
||||||
unsigned b_cold : 1;
|
unsigned b_cold : 1;
|
||||||
/* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
|
/* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
|
||||||
|
@ -7296,6 +7296,25 @@ error:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
mark_except_handlers(basicblock *entryblock) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
|
||||||
|
assert(!b->b_except_handler);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
|
||||||
|
for (int i=0; i < b->b_iused; i++) {
|
||||||
|
struct instr *instr = &b->b_instr[i];
|
||||||
|
if (is_block_push(instr)) {
|
||||||
|
instr->i_target->b_except_handler = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mark_warm(basicblock *entryblock) {
|
mark_warm(basicblock *entryblock) {
|
||||||
basicblock **stack = make_cfg_traversal_stack(entryblock);
|
basicblock **stack = make_cfg_traversal_stack(entryblock);
|
||||||
|
@ -7308,7 +7327,7 @@ mark_warm(basicblock *entryblock) {
|
||||||
entryblock->b_visited = 1;
|
entryblock->b_visited = 1;
|
||||||
while (sp > stack) {
|
while (sp > stack) {
|
||||||
basicblock *b = *(--sp);
|
basicblock *b = *(--sp);
|
||||||
assert(!b->b_except_predecessors);
|
assert(!b->b_except_handler);
|
||||||
b->b_warm = 1;
|
b->b_warm = 1;
|
||||||
basicblock *next = b->b_next;
|
basicblock *next = b->b_next;
|
||||||
if (next && BB_HAS_FALLTHROUGH(b) && !next->b_visited) {
|
if (next && BB_HAS_FALLTHROUGH(b) && !next->b_visited) {
|
||||||
|
@ -7343,8 +7362,7 @@ mark_cold(basicblock *entryblock) {
|
||||||
|
|
||||||
basicblock **sp = stack;
|
basicblock **sp = stack;
|
||||||
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
|
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
|
||||||
if (b->b_except_predecessors) {
|
if (b->b_except_handler) {
|
||||||
assert(b->b_except_predecessors == b->b_predecessors);
|
|
||||||
assert(!b->b_warm);
|
assert(!b->b_warm);
|
||||||
*sp++ = b;
|
*sp++ = b;
|
||||||
b->b_visited = 1;
|
b->b_visited = 1;
|
||||||
|
@ -8257,8 +8275,8 @@ static void
|
||||||
dump_basicblock(const basicblock *b)
|
dump_basicblock(const basicblock *b)
|
||||||
{
|
{
|
||||||
const char *b_return = basicblock_returns(b) ? "return " : "";
|
const char *b_return = basicblock_returns(b) ? "return " : "";
|
||||||
fprintf(stderr, "%d: [%d %d %d %p] used: %d, depth: %d, offset: %d %s\n",
|
fprintf(stderr, "%d: [EH=%d CLD=%d WRM=%d NO_FT=%d %p] used: %d, depth: %d, offset: %d %s\n",
|
||||||
b->b_label, b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused,
|
b->b_label, b->b_except_handler, b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused,
|
||||||
b->b_startdepth, b->b_offset, b_return);
|
b->b_startdepth, b->b_offset, b_return);
|
||||||
if (b->b_instr) {
|
if (b->b_instr) {
|
||||||
int i;
|
int i;
|
||||||
|
@ -8616,6 +8634,12 @@ assemble(struct compiler *c, int addNone)
|
||||||
if (calculate_jump_targets(g->g_entryblock)) {
|
if (calculate_jump_targets(g->g_entryblock)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (mark_except_handlers(g->g_entryblock) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (label_exception_targets(g->g_entryblock)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (optimize_cfg(g, consts, c->c_const_cache)) {
|
if (optimize_cfg(g, consts, c->c_const_cache)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -8634,9 +8658,6 @@ assemble(struct compiler *c, int addNone)
|
||||||
}
|
}
|
||||||
/* TO DO -- For 3.12, make sure that `maxdepth <= MAX_ALLOWED_STACK_USE` */
|
/* TO DO -- For 3.12, make sure that `maxdepth <= MAX_ALLOWED_STACK_USE` */
|
||||||
|
|
||||||
if (label_exception_targets(g->g_entryblock)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
convert_exception_handlers_to_nops(g->g_entryblock);
|
convert_exception_handlers_to_nops(g->g_entryblock);
|
||||||
|
|
||||||
if (push_cold_blocks_to_end(g, code_flags) < 0) {
|
if (push_cold_blocks_to_end(g, code_flags) < 0) {
|
||||||
|
@ -9353,11 +9374,6 @@ mark_reachable(basicblock *entryblock) {
|
||||||
*sp++ = target;
|
*sp++ = target;
|
||||||
}
|
}
|
||||||
target->b_predecessors++;
|
target->b_predecessors++;
|
||||||
if (is_block_push(instr)) {
|
|
||||||
target->b_except_predecessors++;
|
|
||||||
}
|
|
||||||
assert(target->b_except_predecessors == 0 ||
|
|
||||||
target->b_except_predecessors == target->b_predecessors);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue