gh-99955: use SUCCESS/ERROR return values in optimizer and assembler. Use RETURN_IF_ERROR where appropriate. Fix a couple of bugs. (#101412)

This commit is contained in:
Irit Katriel 2023-01-31 00:06:19 +00:00 committed by GitHub
parent e867c1b753
commit af7b2db384
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 142 additions and 189 deletions

View File

@ -176,13 +176,11 @@ static struct jump_target_label_ NO_LABEL = {-1};
#define NEW_JUMP_TARGET_LABEL(C, NAME) \
jump_target_label NAME = cfg_new_label(CFG_BUILDER(C)); \
if (!IS_LABEL(NAME)) { \
return 0; \
return ERROR; \
}
#define USE_LABEL(C, LBL) \
if (cfg_builder_use_label(CFG_BUILDER(C), LBL) < 0) { \
return 0; \
}
RETURN_IF_ERROR(cfg_builder_use_label(CFG_BUILDER(C), LBL))
struct instr {
int i_opcode;
@ -619,8 +617,9 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident)
maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj);
result = PyUnicode_New(1 + nlen + plen, maxchar);
if (!result)
return 0;
if (!result) {
return NULL;
}
/* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */
PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_');
if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) {
@ -991,11 +990,11 @@ basicblock_append_instructions(basicblock *target, basicblock *source)
for (int i = 0; i < source->b_iused; i++) {
int n = basicblock_next_instr(target);
if (n < 0) {
return -1;
return ERROR;
}
target->b_instr[n] = source->b_instr[i];
}
return 0;
return SUCCESS;
}
static basicblock *
@ -1029,7 +1028,7 @@ basicblock_next_instr(basicblock *b)
DEFAULT_BLOCK_SIZE, sizeof(struct instr));
if (b->b_instr == NULL) {
PyErr_NoMemory();
return -1;
return ERROR;
}
b->b_ialloc = DEFAULT_BLOCK_SIZE;
}
@ -1041,19 +1040,19 @@ basicblock_next_instr(basicblock *b)
if (oldsize > (SIZE_MAX >> 1)) {
PyErr_NoMemory();
return -1;
return ERROR;
}
if (newsize == 0) {
PyErr_NoMemory();
return -1;
return ERROR;
}
b->b_ialloc <<= 1;
tmp = (struct instr *)PyObject_Realloc(
(void *)b->b_instr, newsize);
if (tmp == NULL) {
PyErr_NoMemory();
return -1;
return ERROR;
}
b->b_instr = tmp;
memset((char *)b->b_instr + oldsize, 0, newsize - oldsize);
@ -1371,21 +1370,19 @@ cfg_builder_maybe_start_new_block(cfg_builder *g)
if (cfg_builder_current_block_is_terminated(g)) {
basicblock *b = cfg_builder_new_block(g);
if (b == NULL) {
return -1;
return ERROR;
}
b->b_label = g->g_current_label.id;
g->g_current_label = NO_LABEL;
cfg_builder_use_next_block(g, b);
}
return 0;
return SUCCESS;
}
static int
cfg_builder_addop(cfg_builder *g, int opcode, int oparg, location loc)
{
if (cfg_builder_maybe_start_new_block(g) != 0) {
return -1;
}
RETURN_IF_ERROR(cfg_builder_maybe_start_new_block(g));
return basicblock_addop(g->g_curblock, opcode, oparg, loc);
}
@ -1405,16 +1402,16 @@ dict_add_o(PyObject *dict, PyObject *o)
v = PyDict_GetItemWithError(dict, o);
if (!v) {
if (PyErr_Occurred()) {
return -1;
return ERROR;
}
arg = PyDict_GET_SIZE(dict);
v = PyLong_FromSsize_t(arg);
if (!v) {
return -1;
return ERROR;
}
if (PyDict_SetItem(dict, o, v) < 0) {
Py_DECREF(v);
return -1;
return ERROR;
}
Py_DECREF(v);
}
@ -1536,7 +1533,7 @@ compiler_add_const(struct compiler *c, PyObject *o)
{
PyObject *key = merge_consts_recursive(c->c_const_cache, o);
if (key == NULL) {
return -1;
return ERROR;
}
Py_ssize_t arg = dict_add_o(c->u->u_consts, key);
@ -1622,7 +1619,7 @@ cfg_builder_addop_j(cfg_builder *g, location loc,
#define ADDOP_IN_SCOPE(C, LOC, OP) { \
if (cfg_builder_addop_noarg(CFG_BUILDER(C), (OP), (LOC)) < 0) { \
compiler_exit_scope(C); \
return -1; \
return ERROR; \
} \
}
@ -1697,8 +1694,7 @@ cfg_builder_addop_j(cfg_builder *g, location loc,
asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \
for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
if (compiler_visit_ ## TYPE((C), elt) < 0) \
return ERROR; \
RETURN_IF_ERROR(compiler_visit_ ## TYPE((C), elt)); \
} \
}
@ -2232,7 +2228,7 @@ get_ref_type(struct compiler *c, PyObject *name)
name,
c->u->u_name, c->u->u_ste->ste_id,
c->u->u_ste->ste_symbols, c->u->u_varnames, c->u->u_names);
return -1;
return ERROR;
}
return scope;
}
@ -2240,10 +2236,10 @@ get_ref_type(struct compiler *c, PyObject *name)
static int
compiler_lookup_arg(PyObject *dict, PyObject *name)
{
PyObject *v;
v = PyDict_GetItemWithError(dict, name);
if (v == NULL)
return -1;
PyObject *v = PyDict_GetItemWithError(dict, name);
if (v == NULL) {
return ERROR;
}
return PyLong_AS_LONG(v);
}
@ -3022,7 +3018,7 @@ compiler_lambda(struct compiler *c, expr_ty e)
location loc = LOC(e);
funcflags = compiler_default_arguments(c, loc, args);
if (funcflags == -1) {
return 0;
return ERROR;
}
_Py_DECLARE_STR(anon_lambda, "<lambda>");
@ -5083,9 +5079,9 @@ ex_call:
if (n ==0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
}
else if (starunpack_helper(c, loc, args, n, BUILD_LIST,
LIST_APPEND, LIST_EXTEND, 1) < 0) {
return ERROR;
else {
RETURN_IF_ERROR(starunpack_helper(c, loc, args, n, BUILD_LIST,
LIST_APPEND, LIST_EXTEND, 1));
}
/* Then keyword arguments */
if (nkwelts) {
@ -7115,7 +7111,7 @@ stackdepth(basicblock *entryblock, int code_flags)
}
basicblock **stack = make_cfg_traversal_stack(entryblock);
if (!stack) {
return -1;
return ERROR;
}
int maxdepth = 0;
@ -7138,7 +7134,7 @@ stackdepth(basicblock *entryblock, int code_flags)
PyErr_Format(PyExc_SystemError,
"compiler stack_effect(opcode=%d, arg=%i) failed",
instr->i_opcode, instr->i_oparg);
return -1;
return ERROR;
}
int new_depth = depth + effect;
assert(new_depth >= 0); /* invalid code or bug in stackdepth() */
@ -7194,12 +7190,12 @@ assemble_init(struct assembler *a, int firstlineno)
if (a->a_except_table == NULL) {
goto error;
}
return 0;
return SUCCESS;
error:
Py_XDECREF(a->a_bytecode);
Py_XDECREF(a->a_linetable);
Py_XDECREF(a->a_except_table);
return -1;
return ERROR;
}
static void
@ -7270,13 +7266,13 @@ static int
label_exception_targets(basicblock *entryblock) {
basicblock **todo_stack = make_cfg_traversal_stack(entryblock);
if (todo_stack == NULL) {
return -1;
return ERROR;
}
ExceptStack *except_stack = make_except_stack();
if (except_stack == NULL) {
PyMem_Free(todo_stack);
PyErr_NoMemory();
return -1;
return ERROR;
}
except_stack->depth = 0;
todo_stack[0] = entryblock;
@ -7354,11 +7350,11 @@ label_exception_targets(basicblock *entryblock) {
}
#endif
PyMem_Free(todo_stack);
return 0;
return SUCCESS;
error:
PyMem_Free(todo_stack);
PyMem_Free(except_stack);
return -1;
return ERROR;
}
@ -7377,14 +7373,14 @@ mark_except_handlers(basicblock *entryblock) {
}
}
}
return 0;
return SUCCESS;
}
static int
mark_warm(basicblock *entryblock) {
basicblock **stack = make_cfg_traversal_stack(entryblock);
if (stack == NULL) {
return -1;
return ERROR;
}
basicblock **sp = stack;
@ -7408,7 +7404,7 @@ mark_warm(basicblock *entryblock) {
}
}
PyMem_Free(stack);
return 0;
return SUCCESS;
}
static int
@ -7417,12 +7413,12 @@ mark_cold(basicblock *entryblock) {
assert(!b->b_cold && !b->b_warm);
}
if (mark_warm(entryblock) < 0) {
return -1;
return ERROR;
}
basicblock **stack = make_cfg_traversal_stack(entryblock);
if (stack == NULL) {
return -1;
return ERROR;
}
basicblock **sp = stack;
@ -7457,7 +7453,7 @@ mark_cold(basicblock *entryblock) {
}
}
PyMem_Free(stack);
return 0;
return SUCCESS;
}
static int
@ -7468,11 +7464,9 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) {
basicblock *entryblock = g->g_entryblock;
if (entryblock->b_next == NULL) {
/* single basicblock, no need to reorder */
return 0;
}
if (mark_cold(entryblock) < 0) {
return -1;
return SUCCESS;
}
RETURN_IF_ERROR(mark_cold(entryblock));
/* If we have a cold block with fallthrough to a warm block, add */
/* an explicit jump instead of fallthrough */
@ -7480,7 +7474,7 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) {
if (b->b_cold && BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_next->b_warm) {
basicblock *explicit_jump = cfg_builder_new_block(g);
if (explicit_jump == NULL) {
return -1;
return ERROR;
}
basicblock_addop(explicit_jump, JUMP, b->b_next->b_label, NO_LOCATION);
explicit_jump->b_cold = 1;
@ -7534,11 +7528,9 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) {
b->b_next = cold_blocks;
if (cold_blocks != NULL) {
if (remove_redundant_jumps(g) < 0) {
return -1;
}
RETURN_IF_ERROR(remove_redundant_jumps(g));
}
return 0;
return SUCCESS;
}
static void
@ -7596,9 +7588,7 @@ assemble_emit_exception_table_entry(struct assembler *a, int start, int end, bas
{
Py_ssize_t len = PyBytes_GET_SIZE(a->a_except_table);
if (a->a_except_table_off + MAX_SIZE_OF_ENTRY >= len) {
if (_PyBytes_Resize(&a->a_except_table, len * 2) < 0) {
return -1;
}
RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, len * 2));
}
int size = end-start;
assert(end > start);
@ -7613,7 +7603,7 @@ assemble_emit_exception_table_entry(struct assembler *a, int start, int end, bas
assemble_emit_exception_table_item(a, size, 0);
assemble_emit_exception_table_item(a, target, 0);
assemble_emit_exception_table_item(a, depth_lasti, 0);
return 0;
return SUCCESS;
}
static int
@ -7629,9 +7619,8 @@ assemble_exception_table(struct assembler *a, basicblock *entryblock)
struct instr *instr = &b->b_instr[i];
if (instr->i_except != handler) {
if (handler != NULL) {
if (assemble_emit_exception_table_entry(a, start, ioffset, handler) < 0) {
return -1;
}
RETURN_IF_ERROR(
assemble_emit_exception_table_entry(a, start, ioffset, handler));
}
start = ioffset;
handler = instr->i_except;
@ -7640,11 +7629,9 @@ assemble_exception_table(struct assembler *a, basicblock *entryblock)
}
}
if (handler != NULL) {
if (assemble_emit_exception_table_entry(a, start, ioffset, handler) < 0) {
return -1;
}
RETURN_IF_ERROR(assemble_emit_exception_table_entry(a, start, ioffset, handler));
}
return 0;
return SUCCESS;
}
/* Code location emitting code. See locations.md for a description of the format. */
@ -7746,13 +7733,11 @@ write_location_info_entry(struct assembler* a, location loc, int isize)
Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable);
if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) {
assert(len > THEORETICAL_MAX_ENTRY_SIZE);
if (_PyBytes_Resize(&a->a_linetable, len*2) < 0) {
return -1;
}
RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2));
}
if (loc.lineno < 0) {
write_location_info_none(a, isize);
return 0;
return SUCCESS;
}
int line_delta = loc.lineno - a->a_lineno;
int column = loc.col_offset;
@ -7763,35 +7748,33 @@ write_location_info_entry(struct assembler* a, location loc, int isize)
if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) {
write_location_info_no_column(a, isize, line_delta);
a->a_lineno = loc.lineno;
return 0;
return SUCCESS;
}
}
else if (loc.end_lineno == loc.lineno) {
if (line_delta == 0 && column < 80 && end_column - column < 16 && end_column >= column) {
write_location_info_short_form(a, isize, column, end_column);
return 0;
return SUCCESS;
}
if (line_delta >= 0 && line_delta < 3 && column < 128 && end_column < 128) {
write_location_info_oneline_form(a, isize, line_delta, column, end_column);
a->a_lineno = loc.lineno;
return 0;
return SUCCESS;
}
}
write_location_info_long_form(a, loc, isize);
a->a_lineno = loc.lineno;
return 0;
return SUCCESS;
}
static int
assemble_emit_location(struct assembler* a, location loc, int isize)
{
if (isize == 0) {
return 0;
return SUCCESS;
}
while (isize > 8) {
if (write_location_info_entry(a, loc, 8)) {
return -1;
}
RETURN_IF_ERROR(write_location_info_entry(a, loc, 8));
isize -= 8;
}
return write_location_info_entry(a, loc, isize);
@ -7811,34 +7794,32 @@ assemble_emit(struct assembler *a, struct instr *i)
int size = instr_size(i);
if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) {
if (len > PY_SSIZE_T_MAX / 2) {
return -1;
}
if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0) {
return -1;
return ERROR;
}
RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, len * 2));
}
code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
a->a_offset += size;
write_instr(code, i, size);
return 0;
return SUCCESS;
}
static int
normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
struct instr *last = basicblock_last_instr(b);
if (last == NULL || !is_jump(last)) {
return 0;
return SUCCESS;
}
assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
bool is_forward = last->i_target->b_visited == 0;
switch(last->i_opcode) {
case JUMP:
last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
return 0;
return SUCCESS;
case JUMP_NO_INTERRUPT:
last->i_opcode = is_forward ?
JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
return 0;
return SUCCESS;
}
int reversed_opcode = 0;
switch(last->i_opcode) {
@ -7868,10 +7849,10 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
last->i_opcode == JUMP_IF_TRUE_OR_POP ?
"JUMP_IF_TRUE_OR_POP" : "JUMP_IF_FALSE_OR_POP");
}
return 0;
return SUCCESS;
}
if (is_forward) {
return 0;
return SUCCESS;
}
/* transform 'conditional jump T' to
@ -7881,7 +7862,7 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
basicblock *target = last->i_target;
basicblock *backwards_jump = cfg_builder_new_block(g);
if (backwards_jump == NULL) {
return -1;
return ERROR;
}
basicblock_addop(backwards_jump, JUMP, target->b_label, NO_LOCATION);
backwards_jump->b_instr[0].i_target = target;
@ -7891,7 +7872,7 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
backwards_jump->b_cold = b->b_cold;
backwards_jump->b_next = b->b_next;
b->b_next = backwards_jump;
return 0;
return SUCCESS;
}
static int
@ -7903,11 +7884,9 @@ normalize_jumps(cfg_builder *g)
}
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
b->b_visited = 1;
if (normalize_jumps_in_block(g, b) < 0) {
return -1;
}
RETURN_IF_ERROR(normalize_jumps_in_block(g, b));
}
return 0;
return SUCCESS;
}
static void
@ -8047,7 +8026,7 @@ fast_scan_many_locals(basicblock *entryblock, int nlocals)
Py_ssize_t *states = PyMem_Calloc(nlocals - 64, sizeof(Py_ssize_t));
if (states == NULL) {
PyErr_NoMemory();
return -1;
return ERROR;
}
Py_ssize_t blocknum = 0;
// state[i - 64] == blocknum if local i is guaranteed to
@ -8083,7 +8062,7 @@ fast_scan_many_locals(basicblock *entryblock, int nlocals)
}
}
PyMem_Free(states);
return 0;
return SUCCESS;
}
static int
@ -8092,20 +8071,20 @@ add_checks_for_loads_of_uninitialized_variables(basicblock *entryblock,
{
int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames);
if (nlocals == 0) {
return 0;
return SUCCESS;
}
if (nlocals > 64) {
// To avoid O(nlocals**2) compilation, locals beyond the first
// 64 are only analyzed one basicblock at a time: initialization
// info is not passed between basicblocks.
if (fast_scan_many_locals(entryblock, nlocals) < 0) {
return -1;
return ERROR;
}
nlocals = 64;
}
basicblock **stack = make_cfg_traversal_stack(entryblock);
if (stack == NULL) {
return -1;
return ERROR;
}
basicblock **sp = stack;
@ -8134,7 +8113,7 @@ add_checks_for_loads_of_uninitialized_variables(basicblock *entryblock,
scan_block_for_locals(b, &sp);
}
PyMem_Free(stack);
return 0;
return SUCCESS;
}
static PyObject *
@ -8220,17 +8199,17 @@ merge_const_one(PyObject *const_cache, PyObject **obj)
PyDict_CheckExact(const_cache);
PyObject *key = _PyCode_ConstantKey(*obj);
if (key == NULL) {
return -1;
return ERROR;
}
// t is borrowed reference
PyObject *t = PyDict_SetDefault(const_cache, key, key);
Py_DECREF(key);
if (t == NULL) {
return -1;
return ERROR;
}
if (t == key) { // obj is new constant.
return 0;
return SUCCESS;
}
if (PyTuple_CheckExact(t)) {
@ -8239,7 +8218,7 @@ merge_const_one(PyObject *const_cache, PyObject **obj)
}
Py_SETREF(*obj, Py_NewRef(t));
return 0;
return SUCCESS;
}
// This is in codeobject.c.
@ -8482,18 +8461,14 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock,
.i_loc = LOCATION(c->u->u_firstlineno, c->u->u_firstlineno, -1, -1),
.i_target = NULL,
};
if (insert_instruction(entryblock, 0, &make_gen) < 0) {
return -1;
}
RETURN_IF_ERROR(insert_instruction(entryblock, 0, &make_gen));
struct instr pop_top = {
.i_opcode = POP_TOP,
.i_oparg = 0,
.i_loc = NO_LOCATION,
.i_target = NULL,
};
if (insert_instruction(entryblock, 1, &pop_top) < 0) {
return -1;
}
RETURN_IF_ERROR(insert_instruction(entryblock, 1, &pop_top));
}
/* Set up cells for any variable that escapes, to be put in a closure. */
@ -8506,7 +8481,7 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock,
int *sorted = PyMem_RawCalloc(nvars, sizeof(int));
if (sorted == NULL) {
PyErr_NoMemory();
return -1;
return ERROR;
}
for (int i = 0; i < ncellvars; i++) {
sorted[fixed[i]] = i + 1;
@ -8523,9 +8498,7 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock,
.i_loc = NO_LOCATION,
.i_target = NULL,
};
if (insert_instruction(entryblock, ncellsused, &make_cell) < 0) {
return -1;
}
RETURN_IF_ERROR(insert_instruction(entryblock, ncellsused, &make_cell));
ncellsused += 1;
}
PyMem_RawFree(sorted);
@ -8538,13 +8511,10 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock,
.i_loc = NO_LOCATION,
.i_target = NULL,
};
if (insert_instruction(entryblock, 0, &copy_frees) < 0) {
return -1;
}
RETURN_IF_ERROR(insert_instruction(entryblock, 0, &copy_frees));
}
return 0;
return SUCCESS;
}
/* Make sure that all returns have a line number, even if early passes
@ -8704,7 +8674,7 @@ remove_redundant_jumps(cfg_builder *g) {
if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
if (last->i_target == NULL) {
PyErr_SetString(PyExc_SystemError, "jump with NULL target");
return -1;
return ERROR;
}
if (last->i_target == b->b_next) {
assert(b->b_next->b_iused);
@ -8712,7 +8682,7 @@ remove_redundant_jumps(cfg_builder *g) {
}
}
}
return 0;
return SUCCESS;
}
static int
@ -8729,7 +8699,7 @@ prepare_localsplus(struct compiler* c, int code_flags)
int nlocalsplus = nlocals + ncellvars + nfreevars;
int* cellfixedoffsets = build_cellfixedoffsets(c);
if (cellfixedoffsets == NULL) {
return -1;
return ERROR;
}
cfg_builder* g = CFG_BUILDER(c);
@ -8737,14 +8707,14 @@ prepare_localsplus(struct compiler* c, int code_flags)
// This must be called before fix_cell_offsets().
if (insert_prefix_instructions(c, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) {
PyMem_Free(cellfixedoffsets);
return -1;
return ERROR;
}
int numdropped = fix_cell_offsets(c, g->g_entryblock, cellfixedoffsets);
PyMem_Free(cellfixedoffsets); // At this point we're done with it.
cellfixedoffsets = NULL;
if (numdropped < 0) {
return -1;
return ERROR;
}
nlocalsplus -= numdropped;
return nlocalsplus;
@ -8825,7 +8795,7 @@ assemble(struct compiler *c, int addNone)
if (add_checks_for_loads_of_uninitialized_variables(g->g_entryblock, c) < 0) {
goto error;
}
if (remove_unused_consts(g->g_entryblock, consts)) {
if (remove_unused_consts(g->g_entryblock, consts) < 0) {
goto error;
}
@ -8967,27 +8937,27 @@ fold_tuple_on_constants(PyObject *const_cache,
for (int i = 0; i < n; i++) {
if (!HAS_CONST(inst[i].i_opcode)) {
return 0;
return SUCCESS;
}
}
/* Buildup new tuple of constants */
PyObject *newconst = PyTuple_New(n);
if (newconst == NULL) {
return -1;
return ERROR;
}
for (int i = 0; i < n; i++) {
int op = inst[i].i_opcode;
int arg = inst[i].i_oparg;
PyObject *constant = get_const_value(op, arg, consts);
if (constant == NULL) {
return -1;
return ERROR;
}
PyTuple_SET_ITEM(newconst, i, constant);
}
if (merge_const_one(const_cache, &newconst) < 0) {
Py_DECREF(newconst);
return -1;
return ERROR;
}
Py_ssize_t index;
@ -9000,11 +8970,11 @@ fold_tuple_on_constants(PyObject *const_cache,
if ((size_t)index >= (size_t)INT_MAX - 1) {
Py_DECREF(newconst);
PyErr_SetString(PyExc_OverflowError, "too many constants");
return -1;
return ERROR;
}
if (PyList_Append(consts, newconst)) {
Py_DECREF(newconst);
return -1;
return ERROR;
}
}
Py_DECREF(newconst);
@ -9012,7 +8982,7 @@ fold_tuple_on_constants(PyObject *const_cache,
INSTR_SET_OP0(&inst[i], NOP);
}
INSTR_SET_OP1(&inst[n], LOAD_CONST, (int)index);
return 0;
return SUCCESS;
}
#define VISITED (-1)
@ -9045,13 +9015,13 @@ swaptimize(basicblock *block, int *ix)
}
// It's already optimal if there's only one SWAP:
if (!more) {
return 0;
return SUCCESS;
}
// Create an array with elements {0, 1, 2, ..., depth - 1}:
int *stack = PyMem_Malloc(depth * sizeof(int));
if (stack == NULL) {
PyErr_NoMemory();
return -1;
return ERROR;
}
for (int i = 0; i < depth; i++) {
stack[i] = i;
@ -9112,7 +9082,7 @@ swaptimize(basicblock *block, int *ix)
}
PyMem_Free(stack);
*ix += len - 1;
return 0;
return SUCCESS;
}
// This list is pretty small, since it's only okay to reorder opcodes that:
@ -9418,7 +9388,7 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
INSTR_SET_OP0(inst, NOP);
break;
}
if (swaptimize(bb, &i)) {
if (swaptimize(bb, &i) < 0) {
goto error;
}
apply_static_swaps(bb, i);
@ -9436,9 +9406,9 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
assert (!HAS_CONST(inst->i_opcode));
}
}
return 0;
return SUCCESS;
error:
return -1;
return ERROR;
}
/* If this block ends with an unconditional jump to a small exit block, then
@ -9457,9 +9427,7 @@ inline_small_exit_blocks(basicblock *bb) {
basicblock *target = last->i_target;
if (basicblock_exits_scope(target) && target->b_iused <= MAX_COPY_SIZE) {
INSTR_SET_OP0(last, NOP);
if (basicblock_append_instructions(bb, target) < 0) {
return -1;
}
RETURN_IF_ERROR(basicblock_append_instructions(bb, target));
return 1;
}
return 0;
@ -9528,19 +9496,19 @@ check_cfg(cfg_builder *g) {
if (IS_TERMINATOR_OPCODE(opcode)) {
if (i != b->b_iused - 1) {
PyErr_SetString(PyExc_SystemError, "malformed control flow graph.");
return -1;
return ERROR;
}
}
}
}
return 0;
return SUCCESS;
}
static int
mark_reachable(basicblock *entryblock) {
basicblock **stack = make_cfg_traversal_stack(entryblock);
if (stack == NULL) {
return -1;
return ERROR;
}
basicblock **sp = stack;
entryblock->b_predecessors = 1;
@ -9569,7 +9537,7 @@ mark_reachable(basicblock *entryblock) {
}
}
PyMem_Free(stack);
return 0;
return SUCCESS;
}
static void
@ -9658,7 +9626,7 @@ translate_jump_labels_to_targets(basicblock *entryblock)
basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize);
if (!label2block) {
PyErr_NoMemory();
return -1;
return ERROR;
}
memset(label2block, 0, mapsize);
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
@ -9680,7 +9648,7 @@ translate_jump_labels_to_targets(basicblock *entryblock)
}
}
PyMem_Free(label2block);
return 0;
return SUCCESS;
}
/* Perform optimizations on a control flow graph.
@ -9695,31 +9663,22 @@ static int
optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache)
{
assert(PyDict_CheckExact(const_cache));
if (check_cfg(g) < 0) {
return -1;
}
RETURN_IF_ERROR(check_cfg(g));
eliminate_empty_basic_blocks(g);
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
if (inline_small_exit_blocks(b) < 0) {
return -1;
}
RETURN_IF_ERROR(inline_small_exit_blocks(b));
}
assert(no_empty_basic_blocks(g));
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
if (optimize_basic_block(const_cache, b, consts)) {
return -1;
}
RETURN_IF_ERROR(optimize_basic_block(const_cache, b, consts));
remove_redundant_nops(b);
assert(b->b_predecessors == 0);
}
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
if (inline_small_exit_blocks(b) < 0) {
return -1;
}
}
if (mark_reachable(g->g_entryblock)) {
return -1;
RETURN_IF_ERROR(inline_small_exit_blocks(b));
}
RETURN_IF_ERROR(mark_reachable(g->g_entryblock));
/* Delete unreachable instructions */
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
if (b->b_predecessors == 0) {
@ -9731,10 +9690,8 @@ optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache)
}
eliminate_empty_basic_blocks(g);
assert(no_redundant_nops(g));
if (remove_redundant_jumps(g) < 0) {
return -1;
}
return 0;
RETURN_IF_ERROR(remove_redundant_jumps(g));
return SUCCESS;
}
@ -9744,12 +9701,12 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
assert(PyList_CheckExact(consts));
Py_ssize_t nconsts = PyList_GET_SIZE(consts);
if (nconsts == 0) {
return 0; /* nothing to do */
return SUCCESS; /* nothing to do */
}
Py_ssize_t *index_map = NULL;
Py_ssize_t *reverse_index_map = NULL;
int err = 1;
int err = ERROR;
index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t));
if (index_map == NULL) {
@ -9784,7 +9741,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
}
if (n_used_consts == nconsts) {
/* nothing to do */
err = 0;
err = SUCCESS;
goto end;
}
@ -9832,7 +9789,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
}
}
err = 0;
err = SUCCESS;
end:
PyMem_Free(index_map);
PyMem_Free(reverse_index_map);
@ -9876,7 +9833,7 @@ duplicate_exits_without_lineno(cfg_builder *g)
if (is_exit_without_lineno(target) && target->b_predecessors > 1) {
basicblock *new_target = copy_basicblock(g, target);
if (new_target == NULL) {
return -1;
return ERROR;
}
new_target->b_instr[0].i_loc = last->i_loc;
last->i_target = new_target;
@ -9899,7 +9856,7 @@ duplicate_exits_without_lineno(cfg_builder *g)
}
}
}
return 0;
return SUCCESS;
}
@ -9928,54 +9885,50 @@ instructions_to_cfg(PyObject *instructions, cfg_builder *g)
if (PyLong_Check(item)) {
int lbl_id = PyLong_AsLong(item);
if (PyErr_Occurred()) {
return -1;
return ERROR;
}
if (lbl_id <= 0 || lbl_id > instr_size) {
/* expect label in a reasonable range */
PyErr_SetString(PyExc_ValueError, "label out of range");
return -1;
return ERROR;
}
jump_target_label lbl = {lbl_id};
if (cfg_builder_use_label(g, lbl) < 0) {
return -1;
}
RETURN_IF_ERROR(cfg_builder_use_label(g, lbl));
}
else {
if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
return -1;
return ERROR;
}
int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
if (PyErr_Occurred()) {
return -1;
return ERROR;
}
int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
if (PyErr_Occurred()) {
return -1;
return ERROR;
}
location loc;
loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2));
if (PyErr_Occurred()) {
return -1;
return ERROR;
}
loc.end_lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 3));
if (PyErr_Occurred()) {
return -1;
return ERROR;
}
loc.col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 4));
if (PyErr_Occurred()) {
return -1;
return ERROR;
}
loc.end_col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 5));
if (PyErr_Occurred()) {
return -1;
}
if (cfg_builder_addop(g, opcode, oparg, loc) < 0) {
return -1;
return ERROR;
}
RETURN_IF_ERROR(cfg_builder_addop(g, opcode, oparg, loc));
}
}
return 0;
return SUCCESS;
}
static PyObject *