MCPcopy Create free account
hub / github.com/dylan-sutton-chavez/edge-python / constant_fold

Function constant_fold

compiler/src/modules/vm/optimizer.rs:10–81  ·  view source on GitHub ↗
(chunk: &mut SSAChunk)

Source from the content-addressed store, hash-verified

8use alloc::{vec, vec::Vec};
9
10pub fn constant_fold(chunk: &mut SSAChunk) {
11 let n = chunk.instructions.len();
12 if n == 0 {
13 for (_, body, _, _) in chunk.functions.iter_mut() { constant_fold(body); }
14 for class_body in chunk.classes.iter_mut() { constant_fold(class_body); }
15 return;
16 }
17
18 let mut dead = vec![false; n];
19
20 for ip in 0..n {
21 if dead[ip] { continue; }
22 let opcode = chunk.instructions[ip].opcode;
23
24 match opcode {
25 OpCode::Add | OpCode::Sub | OpCode::Mul | OpCode::Div
26 | OpCode::Mod | OpCode::FloorDiv
27 | OpCode::Eq | OpCode::NotEq
28 | OpCode::Lt | OpCode::Gt | OpCode::LtEq | OpCode::GtEq
29 | OpCode::BitAnd | OpCode::BitOr | OpCode::BitXor
30 | OpCode::Shl | OpCode::Shr => {
31 try_fold_binop(chunk, &mut dead, ip);
32 }
33 OpCode::Not => try_fold_not(chunk, &mut dead, ip),
34 OpCode::Minus => try_fold_neg(chunk, &mut dead, ip),
35 _ => {}
36 }
37 }
38
39 // Pass 2: Phi-noop elimination; capture source pairs before marking dead.
40 let mut surviving_pairs: Vec<(u16, u16)> = Vec::new();
41 if !chunk.phi_map.is_empty() && !chunk.phi_sources.is_empty() {
42 for (ip, ins) in chunk.instructions.iter().enumerate() {
43 if dead[ip] || ins.opcode != OpCode::Phi { continue; }
44 let phi_idx = chunk.phi_map[ip];
45 let Some(&(a, b)) = chunk.phi_sources.get(phi_idx) else { continue };
46 // Sources + dest collapsed to one slot, `slots[X] = slots[X]` is a no-op.
47 if a == b && a == ins.operand {
48 dead[ip] = true;
49 } else {
50 surviving_pairs.push((a, b));
51 }
52 }
53 }
54
55 if dead.iter().any(|&d| d) {
56 compact_with_jump_remap(chunk, &dead);
57 // Rebuild phi_map; surviving Phis keep their relative order, so pair them sequentially.
58 if !surviving_pairs.is_empty() {
59 chunk.phi_sources = surviving_pairs;
60 chunk.phi_map = vec![0; chunk.instructions.len()];
61 let mut idx = 0usize;
62 for (i, ins) in chunk.instructions.iter().enumerate() {
63 if ins.opcode == OpCode::Phi {
64 chunk.phi_map[i] = idx;
65 idx += 1;
66 }
67 }

Callers 4

run_startFunction · 0.85
runFunction · 0.85
test_casesFunction · 0.85
strict_casesFunction · 0.85

Calls 10

try_fold_binopFunction · 0.85
try_fold_notFunction · 0.85
try_fold_negFunction · 0.85
compact_with_jump_remapFunction · 0.85
pushMethod · 0.80
lenMethod · 0.45
is_emptyMethod · 0.45
iterMethod · 0.45
getMethod · 0.45
clearMethod · 0.45

Tested by 2

test_casesFunction · 0.68
strict_casesFunction · 0.68