diff Python/compile.c @ 38588:5dfb21a37f19 legacy-trunk

Patch #1346214: correctly optimize away "if 0"-style stmts (thanks to Neal for review)
author Georg Brandl <georg@python.org>
date Sun, 04 Jun 2006 21:56:52 +0000
parents 8f7c7aeac3a5
children 47d8d19ccadc
line wrap: on
line diff
--- a/Python/compile.c	Sun Jun 04 21:46:16 2006 +0000
+++ b/Python/compile.c	Sun Jun 04 21:56:52 2006 +0000
@@ -2148,7 +2148,7 @@
 compiler_if(struct compiler *c, stmt_ty s)
 {
 	basicblock *end, *next;
-
+	int constant;
 	assert(s->kind == If_kind);
 	end = compiler_new_block(c);
 	if (end == NULL)
@@ -2156,15 +2156,27 @@
 	next = compiler_new_block(c);
 	if (next == NULL)
 	    return 0;
-	VISIT(c, expr, s->v.If.test);
-	ADDOP_JREL(c, JUMP_IF_FALSE, next);
-	ADDOP(c, POP_TOP);
-	VISIT_SEQ(c, stmt, s->v.If.body);
-	ADDOP_JREL(c, JUMP_FORWARD, end);
-	compiler_use_next_block(c, next);
-	ADDOP(c, POP_TOP);
-	if (s->v.If.orelse)
-	    VISIT_SEQ(c, stmt, s->v.If.orelse);
+	
+	constant = expr_constant(s->v.If.test);
+	/* constant = 0: "if 0"
+	 * constant = 1: "if 1", "if 2", ...
+	 * constant = -1: rest */
+	if (constant == 0) {
+		if (s->v.If.orelse)
+			VISIT_SEQ(c, stmt, s->v.If.orelse);
+	} else if (constant == 1) {
+		VISIT_SEQ(c, stmt, s->v.If.body);
+	} else {
+		VISIT(c, expr, s->v.If.test);
+		ADDOP_JREL(c, JUMP_IF_FALSE, next);
+		ADDOP(c, POP_TOP);
+		VISIT_SEQ(c, stmt, s->v.If.body);
+		ADDOP_JREL(c, JUMP_FORWARD, end);
+		compiler_use_next_block(c, next);
+		ADDOP(c, POP_TOP);
+		if (s->v.If.orelse)
+	    		VISIT_SEQ(c, stmt, s->v.If.orelse);
+	}
 	compiler_use_next_block(c, end);
 	return 1;
 }
@@ -2639,10 +2651,6 @@
 		if (c->u->u_ste->ste_type != FunctionBlock)
 			return compiler_error(c, "'return' outside function");
 		if (s->v.Return.value) {
-			if (c->u->u_ste->ste_generator) {
-				return compiler_error(c,
-				    "'return' with argument inside generator");
-			}
 			VISIT(c, expr, s->v.Return.value);
 		}
 		else
@@ -3356,6 +3364,13 @@
 		return PyObject_IsTrue(e->v.Num.n);
 	case Str_kind:
 		return PyObject_IsTrue(e->v.Str.s);
+	case Name_kind:
+		/* __debug__ is not assignable, so we can optimize
+		 * it away in if and while statements */
+		if (strcmp(PyString_AS_STRING(e->v.Name.id),
+		           "__debug__") == 0)
+			   return ! Py_OptimizeFlag;
+		/* fall through */
 	default:
 		return -1;
 	}