Update the peephole optimizer to remove more dead code (jumps after returns)
and inline jumps to returns.
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index 4385a84..02b04e0 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -161,6 +161,41 @@
         self.assert_('(None)' not in asm)
         self.assertEqual(asm.split().count('RETURN_VALUE'), 1)
 
+    def test_elim_jump_to_return(self):
+        # JUMP_FORWARD to RETURN -->  RETURN
+        def f(cond, true_value, false_value):
+            return true_value if cond else false_value
+        asm = disassemble(f)
+        self.assert_('JUMP_FORWARD' not in asm)
+        self.assert_('JUMP_ABSOLUTE' not in asm)
+        self.assertEqual(asm.split().count('RETURN_VALUE'), 2)
+
+    def test_elim_jump_after_return1(self):
+        # Eliminate dead code: jumps immediately after returns can't be reached
+        def f(cond1, cond2):
+            if cond1: return 1
+            if cond2: return 2
+            while 1:
+                return 3
+            while 1:
+                if cond1: return 4
+                return 5
+            return 6
+        asm = disassemble(f)
+        self.assert_('JUMP_FORWARD' not in asm)
+        self.assert_('JUMP_ABSOLUTE' not in asm)
+        self.assertEqual(asm.split().count('RETURN_VALUE'), 6)
+
+    def test_elim_jump_after_return2(self):
+        # Eliminate dead code: jumps immediately after returns can't be reached
+        def f(cond1, cond2):
+            while 1:
+                if cond1: return 4
+        asm = disassemble(f)
+        self.assert_('JUMP_FORWARD' not in asm)
+        # There should be one jump for the while loop.
+        self.assertEqual(asm.split().count('JUMP_ABSOLUTE'), 1)
+        self.assertEqual(asm.split().count('RETURN_VALUE'), 2)
 
 
 def test_main(verbose=None):
diff --git a/Misc/NEWS b/Misc/NEWS
index cd21eea..9800a9b 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@
 Core and builtins
 -----------------
 
+- Update the peephole optimizer to remove more dead code (jumps after returns)
+  and inline unconditional jumps to returns.
+
 - Bug #1545497: when given an explicit base, int() did ignore NULs
   embedded in the string to convert.
 
diff --git a/Python/import.c b/Python/import.c
index a90729a..45c5507 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -65,9 +65,10 @@
        Python 2.5c1: 62121 (fix wrong lnotab with for loops and
        			    storing constants that should have been removed)
        Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)
+       Python 2.6a0: 62141 (peephole optimizations)
 .
 */
-#define MAGIC (62131 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define MAGIC (62141 | ((long)'\r'<<16) | ((long)'\n'<<24))
 
 /* Magic word as global; note that _PyImport_Init() can change the
    value of this global to accommodate for alterations of how the
diff --git a/Python/peephole.c b/Python/peephole.c
index 1d94319..f2fe6ce 100644
--- a/Python/peephole.c
+++ b/Python/peephole.c
@@ -523,6 +523,13 @@
 			case SETUP_EXCEPT:
 			case SETUP_FINALLY:
 				tgt = GETJUMPTGT(codestr, i);
+				/* Replace JUMP_* to a RETURN into just a RETURN */
+				if (UNCONDITIONAL_JUMP(opcode) &&
+				    codestr[tgt] == RETURN_VALUE) {
+					codestr[i] = RETURN_VALUE;
+					memset(codestr+i+1, NOP, 2);
+					continue;
+				}
 				if (!UNCONDITIONAL_JUMP(codestr[tgt]))
 					continue;
 				tgttgt = GETJUMPTGT(codestr, tgt);
@@ -540,12 +547,16 @@
 				goto exitUnchanged;
 
 				/* Replace RETURN LOAD_CONST None RETURN with just RETURN */
+				/* Remove unreachable JUMPs after RETURN */
 			case RETURN_VALUE:
-				if (i+4 >= codelen  ||
-				    codestr[i+4] != RETURN_VALUE	 ||
-				    !ISBASICBLOCK(blocks,i,5))
+				if (i+4 >= codelen)
 					continue;
-				memset(codestr+i+1, NOP, 4);
+				if (codestr[i+4] == RETURN_VALUE &&
+				    ISBASICBLOCK(blocks,i,5))
+					memset(codestr+i+1, NOP, 4);
+				else if (UNCONDITIONAL_JUMP(codestr[i+1]) &&
+				         ISBASICBLOCK(blocks,i,4))
+					memset(codestr+i+1, NOP, 3);
 				break;
 		}
 	}