mirror of
https://github.com/RustPython/Parser.git
synced 2025-09-24 11:02:25 +00:00
Add tuple unpacking optimization
This commit is contained in:
parent
347d6c006a
commit
4cb8cc34e4
1 changed files with 38 additions and 20 deletions
|
@ -10,8 +10,8 @@ struct InstructionMetadata {
|
||||||
labels: Vec<Label>,
|
labels: Vec<Label>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InstructionMetadata {
|
impl From<Vec<InstructionMetadata>> for InstructionMetadata {
|
||||||
fn from_multiple(metas: Vec<Self>) -> Self {
|
fn from(metas: Vec<Self>) -> Self {
|
||||||
debug_assert!(!metas.is_empty(), "`metas` must not be empty");
|
debug_assert!(!metas.is_empty(), "`metas` must not be empty");
|
||||||
InstructionMetadata {
|
InstructionMetadata {
|
||||||
loc: metas[0].loc.clone(),
|
loc: metas[0].loc.clone(),
|
||||||
|
@ -69,28 +69,28 @@ impl<O: OutputStream> PeepholeOptimizer<O> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn optimize(&mut self, instruction: Instruction, meta: InstructionMetadata) {
|
fn optimize(&mut self, instruction: Instruction, meta: InstructionMetadata) {
|
||||||
|
macro_rules! lc {
|
||||||
|
($name:ident {$($field:tt)*}) => {
|
||||||
|
Instruction::LoadConst {
|
||||||
|
value: bytecode::Constant::$name {$($field)*},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($name:ident, $($value:tt)*) => {
|
||||||
|
lc!($name { value: $($value)* })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! emitconst {
|
||||||
|
([$($metas:expr),*], $($arg:tt)*) => {
|
||||||
|
self.emit(
|
||||||
|
lc!($($arg)*),
|
||||||
|
InstructionMetadata::from(vec![$($metas),*]),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
match instruction {
|
match instruction {
|
||||||
Instruction::BinaryOperation { op, inplace } => {
|
Instruction::BinaryOperation { op, inplace } => {
|
||||||
let (rhs, rhs_meta) = self.pop();
|
let (rhs, rhs_meta) = self.pop();
|
||||||
let (lhs, lhs_meta) = self.pop();
|
let (lhs, lhs_meta) = self.pop();
|
||||||
macro_rules! lc {
|
|
||||||
($name:ident {$($field:tt)*}) => {
|
|
||||||
Instruction::LoadConst {
|
|
||||||
value: bytecode::Constant::$name {$($field)*},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
($name:ident, $($value:tt)*) => {
|
|
||||||
lc!($name { value: $($value)* })
|
|
||||||
};
|
|
||||||
}
|
|
||||||
macro_rules! emitconst {
|
|
||||||
([$($metas:expr),*], $($arg:tt)*) => {
|
|
||||||
self.emit(
|
|
||||||
lc!($($arg)*),
|
|
||||||
InstructionMetadata::from_multiple(vec![$($metas),*]),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
macro_rules! op {
|
macro_rules! op {
|
||||||
($op:ident) => {
|
($op:ident) => {
|
||||||
bytecode::BinaryOperator::$op
|
bytecode::BinaryOperator::$op
|
||||||
|
@ -129,6 +129,24 @@ impl<O: OutputStream> PeepholeOptimizer<O> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Instruction::UnpackSequence { size } => {
|
||||||
|
let (arg, arg_meta) = self.pop();
|
||||||
|
match arg {
|
||||||
|
Instruction::BuildTuple {
|
||||||
|
size: tup_size,
|
||||||
|
unpack,
|
||||||
|
} if !unpack && tup_size == size => {
|
||||||
|
self.emit(
|
||||||
|
Instruction::Reverse { amount: size },
|
||||||
|
vec![arg_meta, meta].into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
arg => {
|
||||||
|
self.emit(arg, arg_meta);
|
||||||
|
self.emit(instruction, meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
other => self.emit(other, meta),
|
other => self.emit(other, meta),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue