diff --git a/compiler/src/compile.rs b/compiler/src/compile.rs index b1b5f62bb..403b1487d 100644 --- a/compiler/src/compile.rs +++ b/compiler/src/compile.rs @@ -848,7 +848,9 @@ impl Compiler { // Emit None at end: match body.last().map(|s| &s.node) { - Some(ast::StatementType::Return { .. }) => {} + Some(ast::StatementType::Return { .. }) => { + // the last instruction is a ReturnValue already, we don't need to emit it + } _ => { self.emit(Instruction::LoadConst { value: bytecode::Constant::None, diff --git a/compiler/src/peephole.rs b/compiler/src/peephole.rs index 2eff20c70..3a64380bd 100644 --- a/compiler/src/peephole.rs +++ b/compiler/src/peephole.rs @@ -92,7 +92,7 @@ impl PeepholeOptimizer { } fn optimize(&mut self) { - apply_optimizations!(self, operator, unpack, useless_const); + apply_optimizations!(self, operator, unpack); } } @@ -123,8 +123,6 @@ impl OptimizationBuffer for PeepholeOptimizer { } } -// OPTIMIZATION - pub trait OptimizationBuffer { fn emit(&mut self, instruction: Instruction, meta: InstructionMetadata); fn pop(&mut self) -> (Instruction, InstructionMetadata); diff --git a/compiler/src/peephole/optimizations.rs b/compiler/src/peephole/optimizations.rs index ee8f1f0d5..b0fb7531a 100644 --- a/compiler/src/peephole/optimizations.rs +++ b/compiler/src/peephole/optimizations.rs @@ -2,6 +2,11 @@ use rustpython_bytecode::bytecode::{self, Instruction}; use super::{InstructionMetadata, OptimizationBuffer}; +macro_rules! metas { + [$($metas:expr),*$(,)?] => { + InstructionMetadata::from(vec![$($metas),*]) + }; +} macro_rules! lc { ($name:ident {$($field:tt)*}) => { Instruction::LoadConst { @@ -13,10 +18,10 @@ macro_rules! lc { }; } macro_rules! emitconst { - ($buf:expr, [$($metas:expr),*], $($arg:tt)*) => { + ($buf:expr, [$($metas:expr),*$(,)?], $($arg:tt)*) => { $buf.emit( lc!($($arg)*), - InstructionMetadata::from(vec![$($metas),*]), + metas![$($metas),*], ) }; } @@ -91,20 +96,3 @@ pub fn unpack(buf: &mut impl OptimizationBuffer) { buf.emit(instruction, meta) } } - -pub fn useless_const(buf: &mut impl OptimizationBuffer) { - let (instruction, meta) = buf.pop(); - if instruction == Instruction::Pop { - let (arg, arg_meta) = buf.pop(); - if let Instruction::LoadConst { .. } = arg { - // just ignore it all - drop(arg); - drop(instruction); - } else { - buf.emit(arg, arg_meta); - buf.emit(instruction, meta); - } - } else { - buf.emit(instruction, meta); - } -} diff --git a/tests/snippets/dismod.py b/tests/snippets/dismod.py index 88282d3eb..e9951ef40 100644 --- a/tests/snippets/dismod.py +++ b/tests/snippets/dismod.py @@ -2,9 +2,19 @@ import dis dis.dis(compile("5 + x + 5 or 2", "", "eval")) print("\n") -dis.dis(compile("def f(x):\n return 1", "", "exec")) +dis.dis(compile(""" +def f(x): + return 1 +""", "", "exec")) print("\n") -dis.dis(compile("if a:\n 1 or 2\nelif x == 'hello':\n 3\nelse:\n 4", "", "exec")) +dis.dis(compile(""" +if a: + 1 or 2 +elif x == 'hello': + 3 +else: + 4 +""", "", "exec")) print("\n") dis.dis(compile("f(x=1, y=2)", "", "eval")) print("\n")