Skip to content

Commit 9130dd8

Browse files
authored
Unify BINARY_OP bytecodes (RustPython#6317)
* Unify BINARY_OP bytecodes * Add missing op to `as_inplace` * Fix doc example * Fix jit * Fix doc * Use correct opname * Fix dis fmt * Inplace ops support in JIT
1 parent 8e0a86d commit 9130dd8

File tree

4 files changed

+255
-128
lines changed

4 files changed

+255
-128
lines changed

crates/codegen/src/compile.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3301,7 +3301,7 @@ impl Compiler {
33013301
// Subtract to compute the correct index.
33023302
emit!(
33033303
self,
3304-
Instruction::BinaryOperation {
3304+
Instruction::BinaryOp {
33053305
op: BinaryOperator::Subtract
33063306
}
33073307
);
@@ -4339,26 +4339,24 @@ impl Compiler {
43394339
}
43404340

43414341
fn compile_op(&mut self, op: &Operator, inplace: bool) {
4342-
let op = match op {
4343-
Operator::Add => bytecode::BinaryOperator::Add,
4344-
Operator::Sub => bytecode::BinaryOperator::Subtract,
4345-
Operator::Mult => bytecode::BinaryOperator::Multiply,
4346-
Operator::MatMult => bytecode::BinaryOperator::MatrixMultiply,
4347-
Operator::Div => bytecode::BinaryOperator::Divide,
4348-
Operator::FloorDiv => bytecode::BinaryOperator::FloorDivide,
4349-
Operator::Mod => bytecode::BinaryOperator::Modulo,
4350-
Operator::Pow => bytecode::BinaryOperator::Power,
4351-
Operator::LShift => bytecode::BinaryOperator::Lshift,
4352-
Operator::RShift => bytecode::BinaryOperator::Rshift,
4353-
Operator::BitOr => bytecode::BinaryOperator::Or,
4354-
Operator::BitXor => bytecode::BinaryOperator::Xor,
4355-
Operator::BitAnd => bytecode::BinaryOperator::And,
4342+
let bin_op = match op {
4343+
Operator::Add => BinaryOperator::Add,
4344+
Operator::Sub => BinaryOperator::Subtract,
4345+
Operator::Mult => BinaryOperator::Multiply,
4346+
Operator::MatMult => BinaryOperator::MatrixMultiply,
4347+
Operator::Div => BinaryOperator::TrueDivide,
4348+
Operator::FloorDiv => BinaryOperator::FloorDivide,
4349+
Operator::Mod => BinaryOperator::Remainder,
4350+
Operator::Pow => BinaryOperator::Power,
4351+
Operator::LShift => BinaryOperator::Lshift,
4352+
Operator::RShift => BinaryOperator::Rshift,
4353+
Operator::BitOr => BinaryOperator::Or,
4354+
Operator::BitXor => BinaryOperator::Xor,
4355+
Operator::BitAnd => BinaryOperator::And,
43564356
};
4357-
if inplace {
4358-
emit!(self, Instruction::BinaryOperationInplace { op })
4359-
} else {
4360-
emit!(self, Instruction::BinaryOperation { op })
4361-
}
4357+
4358+
let op = if inplace { bin_op.as_inplace() } else { bin_op };
4359+
emit!(self, Instruction::BinaryOp { op })
43624360
}
43634361

43644362
/// Implement boolean short circuit evaluation logic.

crates/compiler-core/src/bytecode.rs

Lines changed: 131 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -594,10 +594,7 @@ pub enum Instruction {
594594
UnaryOperation {
595595
op: Arg<UnaryOperator>,
596596
},
597-
BinaryOperation {
598-
op: Arg<BinaryOperator>,
599-
},
600-
BinaryOperationInplace {
597+
BinaryOp {
601598
op: Arg<BinaryOperator>,
602599
},
603600
BinarySubscript,
@@ -1094,32 +1091,142 @@ op_arg_enum!(
10941091

10951092
op_arg_enum!(
10961093
/// The possible Binary operators
1094+
///
10971095
/// # Examples
10981096
///
1099-
/// ```ignore
1100-
/// use rustpython_compiler_core::Instruction::BinaryOperation;
1101-
/// use rustpython_compiler_core::BinaryOperator::Add;
1102-
/// let op = BinaryOperation {op: Add};
1097+
/// ```rust
1098+
/// use rustpython_compiler_core::bytecode::{Arg, BinaryOperator, Instruction};
1099+
/// let (op, _) = Arg::new(BinaryOperator::Add);
1100+
/// let instruction = Instruction::BinaryOp { op };
11031101
/// ```
1104-
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1102+
///
1103+
/// See also:
1104+
/// - [_PyEval_BinaryOps](https://github.com/python/cpython/blob/8183fa5e3f78ca6ab862de7fb8b14f3d929421e0/Python/ceval.c#L316-L343)
11051105
#[repr(u8)]
1106+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11061107
pub enum BinaryOperator {
1107-
Power = 0,
1108-
Multiply = 1,
1109-
MatrixMultiply = 2,
1110-
Divide = 3,
1111-
FloorDivide = 4,
1112-
Modulo = 5,
1113-
Add = 6,
1114-
Subtract = 7,
1115-
Lshift = 8,
1108+
/// `+`
1109+
Add = 0,
1110+
/// `&`
1111+
And = 1,
1112+
/// `//`
1113+
FloorDivide = 2,
1114+
/// `<<`
1115+
Lshift = 3,
1116+
/// `@`
1117+
MatrixMultiply = 4,
1118+
/// `*`
1119+
Multiply = 5,
1120+
/// `%`
1121+
Remainder = 6,
1122+
/// `|`
1123+
Or = 7,
1124+
/// `**`
1125+
Power = 8,
1126+
/// `>>`
11161127
Rshift = 9,
1117-
And = 10,
1118-
Xor = 11,
1119-
Or = 12,
1128+
/// `-`
1129+
Subtract = 10,
1130+
/// `/`
1131+
TrueDivide = 11,
1132+
/// `^`
1133+
Xor = 12,
1134+
/// `+=`
1135+
InplaceAdd = 13,
1136+
/// `&=`
1137+
InplaceAnd = 14,
1138+
/// `//=`
1139+
InplaceFloorDivide = 15,
1140+
/// `<<=`
1141+
InplaceLshift = 16,
1142+
/// `@=`
1143+
InplaceMatrixMultiply = 17,
1144+
/// `*=`
1145+
InplaceMultiply = 18,
1146+
/// `%=`
1147+
InplaceRemainder = 19,
1148+
/// `|=`
1149+
InplaceOr = 20,
1150+
/// `**=`
1151+
InplacePower = 21,
1152+
/// `>>=`
1153+
InplaceRshift = 22,
1154+
/// `-=`
1155+
InplaceSubtract = 23,
1156+
/// `/=`
1157+
InplaceTrueDivide = 24,
1158+
/// `^=`
1159+
InplaceXor = 25,
11201160
}
11211161
);
11221162

1163+
impl BinaryOperator {
1164+
/// Get the "inplace" version of the operator.
1165+
/// This has no effect if `self` is already an "inplace" operator.
1166+
///
1167+
/// # Example
1168+
/// ```rust
1169+
/// use rustpython_compiler_core::bytecode::BinaryOperator;
1170+
///
1171+
/// assert_eq!(BinaryOperator::Power.as_inplace(), BinaryOperator::InplacePower);
1172+
///
1173+
/// assert_eq!(BinaryOperator::InplaceSubtract.as_inplace(), BinaryOperator::InplaceSubtract);
1174+
/// ```
1175+
#[must_use]
1176+
pub const fn as_inplace(self) -> Self {
1177+
match self {
1178+
Self::Add => Self::InplaceAdd,
1179+
Self::And => Self::InplaceAnd,
1180+
Self::FloorDivide => Self::InplaceFloorDivide,
1181+
Self::Lshift => Self::InplaceLshift,
1182+
Self::MatrixMultiply => Self::InplaceMatrixMultiply,
1183+
Self::Multiply => Self::InplaceMultiply,
1184+
Self::Remainder => Self::InplaceRemainder,
1185+
Self::Or => Self::InplaceOr,
1186+
Self::Power => Self::InplacePower,
1187+
Self::Rshift => Self::InplaceRshift,
1188+
Self::Subtract => Self::InplaceSubtract,
1189+
Self::TrueDivide => Self::InplaceTrueDivide,
1190+
Self::Xor => Self::InplaceXor,
1191+
_ => self,
1192+
}
1193+
}
1194+
}
1195+
1196+
impl fmt::Display for BinaryOperator {
1197+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1198+
let op = match self {
1199+
Self::Add => "+",
1200+
Self::And => "&",
1201+
Self::FloorDivide => "//",
1202+
Self::Lshift => "<<",
1203+
Self::MatrixMultiply => "@",
1204+
Self::Multiply => "*",
1205+
Self::Remainder => "%",
1206+
Self::Or => "|",
1207+
Self::Power => "**",
1208+
Self::Rshift => ">>",
1209+
Self::Subtract => "-",
1210+
Self::TrueDivide => "/",
1211+
Self::Xor => "^",
1212+
Self::InplaceAdd => "+=",
1213+
Self::InplaceAnd => "&=",
1214+
Self::InplaceFloorDivide => "//=",
1215+
Self::InplaceLshift => "<<=",
1216+
Self::InplaceMatrixMultiply => "@=",
1217+
Self::InplaceMultiply => "*=",
1218+
Self::InplaceRemainder => "%=",
1219+
Self::InplaceOr => "|=",
1220+
Self::InplacePower => "**=",
1221+
Self::InplaceRshift => ">>=",
1222+
Self::InplaceSubtract => "-=",
1223+
Self::InplaceTrueDivide => "/=",
1224+
Self::InplaceXor => "^=",
1225+
};
1226+
write!(f, "{op}")
1227+
}
1228+
}
1229+
11231230
op_arg_enum!(
11241231
/// The possible unary operators
11251232
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -1514,7 +1621,7 @@ impl Instruction {
15141621
DeleteAttr { .. } => -1,
15151622
LoadConst { .. } => 1,
15161623
UnaryOperation { .. } => 0,
1517-
BinaryOperation { .. } | BinaryOperationInplace { .. } | CompareOperation { .. } => -1,
1624+
BinaryOp { .. } | CompareOperation { .. } => -1,
15181625
BinarySubscript => -1,
15191626
CopyItem { .. } => 1,
15201627
Pop => -1,
@@ -1719,8 +1826,8 @@ impl Instruction {
17191826
DeleteAttr { idx } => w!(DeleteAttr, name = idx),
17201827
LoadConst { idx } => fmt_const("LoadConst", arg, f, idx),
17211828
UnaryOperation { op } => w!(UnaryOperation, ?op),
1722-
BinaryOperation { op } => w!(BinaryOperation, ?op),
1723-
BinaryOperationInplace { op } => w!(BinaryOperationInplace, ?op),
1829+
BinaryOp { op } => write!(f, "{:pad$}({})", "BINARY_OP", op.get(arg)),
1830+
17241831
BinarySubscript => w!(BinarySubscript),
17251832
LoadAttr { idx } => w!(LoadAttr, name = idx),
17261833
CompareOperation { op } => w!(CompareOperation, ?op),

0 commit comments

Comments
 (0)