Skip to content

Commit c771427

Browse files
authored
Use stack_effect_info for getting pop&push count (#6913)
1 parent ba8749b commit c771427

File tree

2 files changed

+6
-60
lines changed

2 files changed

+6
-60
lines changed

crates/codegen/src/ir.rs

Lines changed: 3 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ impl CodeInfo {
713713
// (or NOT_LOCAL if not from LOAD_FAST/LOAD_FAST_LOAD_FAST).
714714
//
715715
// CPython (flowgraph.c optimize_load_fast) pre-fills the stack with
716-
// dummy refs for values inherited from predecessor blocks. We take
716+
// dummy refs for values inherited from predecessor blocks. We take
717717
// the simpler approach of aborting the optimisation for the whole
718718
// block on stack underflow.
719719
let mut stack: Vec<usize> = Vec::new();
@@ -724,62 +724,8 @@ impl CodeInfo {
724724
continue;
725725
};
726726

727-
// Decompose into (pops, pushes).
728-
//
729-
// stack_effect() returns pushes − pops, which is ambiguous for
730-
// instructions that both pop and push (e.g. BinaryOp: effect=-1
731-
// is pop 2 push 1, not pop 1 push 0). We list those explicitly;
732-
// the fallback under-pops and under-pushes, which is conservative
733-
// (may miss optimisation opportunities but never miscompiles).
734-
let effect = instr.stack_effect(info.arg.into());
735-
let (pops, pushes) = match instr {
736-
// --- pop 2, push 1 ---
737-
Instruction::BinaryOp { .. }
738-
| Instruction::BinaryOpInplaceAddUnicode
739-
| Instruction::CompareOp { .. }
740-
| Instruction::ContainsOp(_)
741-
| Instruction::IsOp(_)
742-
| Instruction::ImportName { .. }
743-
| Instruction::FormatWithSpec => (2, 1),
744-
745-
// --- pop 1, push 1 ---
746-
Instruction::UnaryInvert
747-
| Instruction::UnaryNegative
748-
| Instruction::UnaryNot
749-
| Instruction::ToBool
750-
| Instruction::GetIter
751-
| Instruction::GetAIter
752-
| Instruction::FormatSimple
753-
| Instruction::LoadFromDictOrDeref(_)
754-
| Instruction::LoadFromDictOrGlobals(_) => (1, 1),
755-
756-
// LoadAttr: pop receiver, push attr.
757-
// method=true: push (method, self_or_null) → (1, 2)
758-
Instruction::LoadAttr { idx } => {
759-
let (_, is_method) =
760-
rustpython_compiler_core::bytecode::decode_load_attr_arg(
761-
idx.get(info.arg),
762-
);
763-
if is_method { (1, 2) } else { (1, 1) }
764-
}
765-
766-
// --- pop 3, push 1 ---
767-
Instruction::BinarySlice => (3, 1),
768-
769-
// --- variable pops, push 1 ---
770-
Instruction::Call { nargs } => (nargs.get(info.arg) as usize + 2, 1),
771-
Instruction::CallKw { nargs } => (nargs.get(info.arg) as usize + 3, 1),
772-
773-
// --- conservative fallback ---
774-
// under-pops (≤ actual pops) and under-pushes (≤ actual pushes),
775-
// which keeps extra refs on the stack → marks them unconsumed →
776-
// prevents optimisation. Safe but may miss opportunities.
777-
_ => {
778-
let p = if effect < 0 { (-effect) as usize } else { 0 };
779-
let q = if effect > 0 { effect as usize } else { 0 };
780-
(p, q)
781-
}
782-
};
727+
let stack_effect_info = instr.stack_effect_info(info.arg.into());
728+
let (pushes, pops) = (stack_effect_info.pushed(), stack_effect_info.popped());
783729

784730
// Pop values from stack
785731
for _ in 0..pops {

crates/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)