-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
gh-123958: move assert optimization from codegen to ast_opt #124143
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Assertions are now removed from an optimized AST in optimization level > 0.y |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
typedef struct { | ||
int optimize; | ||
int ff_features; | ||
PyObject *filename; | ||
|
||
int recursion_depth; /* current recursion depth */ | ||
int recursion_limit; /* recursion limit */ | ||
|
@@ -51,6 +52,12 @@ make_const(expr_ty node, PyObject *val, PyArena *arena) | |
return 1; | ||
} | ||
|
||
static void | ||
make_pass(stmt_ty node) | ||
{ | ||
node->kind = Pass_kind; | ||
} | ||
|
||
#define COPY_NODE(TO, FROM) (memcpy((TO), (FROM), sizeof(struct _expr))) | ||
|
||
static int | ||
|
@@ -1005,6 +1012,29 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) | |
case Assert_kind: | ||
CALL(astfold_expr, expr_ty, node_->v.Assert.test); | ||
CALL_OPT(astfold_expr, expr_ty, node_->v.Assert.msg); | ||
/* Always emit a warning if the test is a non-zero length tuple */ | ||
if ((node_->v.Assert.test->kind == Tuple_kind && | ||
asdl_seq_LEN(node_->v.Assert.test->v.Tuple.elts) > 0) || | ||
(node_->v.Assert.test->kind == Constant_kind && | ||
PyTuple_Check(node_->v.Assert.test->v.Constant.value) && | ||
PyTuple_Size(node_->v.Assert.test->v.Constant.value) > 0)) | ||
{ | ||
PyObject *msg = PyUnicode_FromString("assertion is always true, " | ||
"perhaps remove parentheses?"); | ||
if (msg == NULL) { | ||
return 0; | ||
} | ||
int ret = _PyErr_EmitSyntaxWarning(msg, state->filename, | ||
node_->lineno, node_->col_offset + 1, | ||
node_->end_lineno, node_->end_col_offset + 1); | ||
Py_DECREF(msg); | ||
if (ret < 0) { | ||
return 0; | ||
} | ||
} | ||
if (state->optimize) { | ||
make_pass(node_); | ||
Comment on lines
+1035
to
+1036
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically speaking, this is not the removal of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pass becomes a NOP, which gets removed later. This is how we get rid of code. However, I did forget to wipe out the location information (a NOP is not removed if it's the only instruction from its line in the source code). |
||
} | ||
break; | ||
case Expr_kind: | ||
CALL(astfold_expr, expr_ty, node_->v.Expr.value); | ||
|
@@ -1125,14 +1155,15 @@ astfold_type_param(type_param_ty node_, PyArena *ctx_, _PyASTOptimizeState *stat | |
#undef CALL_SEQ | ||
|
||
int | ||
_PyAST_Optimize(mod_ty mod, PyArena *arena, int optimize, int ff_features) | ||
_PyAST_Optimize(mod_ty mod, PyArena *arena, int optimize, int ff_features, PyObject *filename) | ||
{ | ||
PyThreadState *tstate; | ||
int starting_recursion_depth; | ||
|
||
_PyASTOptimizeState state; | ||
state.optimize = optimize; | ||
state.ff_features = ff_features; | ||
state.filename = filename; | ||
|
||
/* Setup recursion depth check counters */ | ||
tstate = _PyThreadState_GET(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2792,20 +2792,7 @@ codegen_from_import(compiler *c, stmt_ty s) | |
static int | ||
codegen_assert(compiler *c, stmt_ty s) | ||
{ | ||
/* Always emit a warning if the test is a non-zero length tuple */ | ||
if ((s->v.Assert.test->kind == Tuple_kind && | ||
asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) || | ||
(s->v.Assert.test->kind == Constant_kind && | ||
PyTuple_Check(s->v.Assert.test->v.Constant.value) && | ||
PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0)) | ||
{ | ||
RETURN_IF_ERROR( | ||
_PyCompile_Warn(c, LOC(s), "assertion is always true, " | ||
"perhaps remove parentheses?")); | ||
} | ||
if (OPTIMIZATION_LEVEL(c)) { | ||
return SUCCESS; | ||
} | ||
assert(!OPTIMIZATION_LEVEL(c)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Left this here to convince ourselves of correctness. I'll remove it before committing. |
||
NEW_JUMP_TARGET_LABEL(c, end); | ||
RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.Assert.test, end, 1)); | ||
ADDOP_I(c, LOC(s), LOAD_COMMON_CONSTANT, CONSTANT_ASSERTIONERROR); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like we no longer raise an error in optimized mode if there is an invalid await. That seems wrong and doesn't align with what we decided on in #121637.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to stick with this then we probably can't optimise the assertions in ast_opt.