[Python-checkins] r52332 - in python/trunk: Lib/test/test_peepholer.py Misc/NEWS Python/import.c Python/peephole.c

neal.norwitz python-checkins at python.org
Sat Oct 14 23:33:40 CEST 2006


Author: neal.norwitz
Date: Sat Oct 14 23:33:38 2006
New Revision: 52332
Modified:
 python/trunk/Lib/test/test_peepholer.py
 python/trunk/Misc/NEWS
 python/trunk/Python/import.c
 python/trunk/Python/peephole.c
Log:
Update the peephole optimizer to remove more dead code (jumps after returns)
and inline jumps to returns.
Modified: python/trunk/Lib/test/test_peepholer.py
==============================================================================
--- python/trunk/Lib/test/test_peepholer.py	(original)
+++ python/trunk/Lib/test/test_peepholer.py	Sat Oct 14 23:33:38 2006
@@ -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):
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Sat Oct 14 23:33:38 2006
@@ -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.
 
Modified: python/trunk/Python/import.c
==============================================================================
--- python/trunk/Python/import.c	(original)
+++ python/trunk/Python/import.c	Sat Oct 14 23:33:38 2006
@@ -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
Modified: python/trunk/Python/peephole.c
==============================================================================
--- python/trunk/Python/peephole.c	(original)
+++ python/trunk/Python/peephole.c	Sat Oct 14 23:33:38 2006
@@ -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;
 		}
 	}


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /