X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cspell.dict/cpython.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ CODEUNIT
CONIN
CONOUT
constevaluator
consti
CONVFUNC
convparam
copyslot
Expand Down
842 changes: 449 additions & 393 deletions crates/codegen/src/compile.rs

Large diffs are not rendered by default.

63 changes: 39 additions & 24 deletions crates/codegen/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,19 +387,19 @@ impl CodeInfo {
op = match op {
Instruction::JumpForward { .. } if target_offset <= current_offset => {
Instruction::JumpBackward {
target: Arg::marker(),
delta: Arg::marker(),
}
}
Instruction::JumpBackward { .. } if target_offset > current_offset => {
Instruction::JumpForward {
target: Arg::marker(),
delta: Arg::marker(),
}
}
Instruction::JumpBackwardNoInterrupt { .. }
if target_offset > current_offset =>
{
Instruction::JumpForward {
target: Arg::marker(),
delta: Arg::marker(),
}
}
_ => op,
Expand Down Expand Up @@ -632,7 +632,10 @@ impl CodeInfo {
}

// Replace BUILD_TUPLE with LOAD_CONST
block.instructions[i].instr = Instruction::LoadConst { idx: Arg::marker() }.into();
block.instructions[i].instr = Instruction::LoadConst {
consti: Arg::marker(),
}
.into();
block.instructions[i].arg = OpArg::new(const_idx as u32);

i += 1;
Expand All @@ -659,27 +662,31 @@ impl CodeInfo {

match (curr_instr, next_instr) {
// LoadFast + LoadFast -> LoadFastLoadFast (if both indices < 16)
(Instruction::LoadFast(_), Instruction::LoadFast(_)) => {
(Instruction::LoadFast { .. }, Instruction::LoadFast { .. }) => {
let idx1 = u32::from(curr.arg);
let idx2 = u32::from(next.arg);
if idx1 < 16 && idx2 < 16 {
let packed = (idx1 << 4) | idx2;
Some((
Instruction::LoadFastLoadFast { arg: Arg::marker() },
Instruction::LoadFastLoadFast {
var_nums: Arg::marker(),
},
OpArg::new(packed),
))
} else {
None
}
}
// StoreFast + StoreFast -> StoreFastStoreFast (if both indices < 16)
(Instruction::StoreFast(_), Instruction::StoreFast(_)) => {
(Instruction::StoreFast { .. }, Instruction::StoreFast { .. }) => {
let idx1 = u32::from(curr.arg);
let idx2 = u32::from(next.arg);
if idx1 < 16 && idx2 < 16 {
let packed = (idx1 << 4) | idx2;
Some((
Instruction::StoreFastStoreFast { arg: Arg::marker() },
Instruction::StoreFastStoreFast {
var_nums: Arg::marker(),
},
OpArg::new(packed),
))
} else {
Expand Down Expand Up @@ -712,7 +719,7 @@ impl CodeInfo {
let curr = &block.instructions[i];
let next = &block.instructions[i + 1];

let (Some(Instruction::LoadGlobal(_)), Some(Instruction::PushNull)) =
let (Some(Instruction::LoadGlobal { .. }), Some(Instruction::PushNull)) =
(curr.instr.real(), next.instr.real())
else {
i += 1;
Expand Down Expand Up @@ -755,7 +762,7 @@ impl CodeInfo {
// Check if it's in small int range: -5 to 256 (_PY_IS_SMALL_INT)
if let Some(small) = value.to_i32().filter(|v| (-5..=256).contains(v)) {
// Convert LOAD_CONST to LOAD_SMALL_INT
instr.instr = Instruction::LoadSmallInt { idx: Arg::marker() }.into();
instr.instr = Instruction::LoadSmallInt { i: Arg::marker() }.into();
// The arg is the i32 value stored as u32 (two's complement)
instr.arg = OpArg::new(small as u32);
}
Expand Down Expand Up @@ -895,7 +902,7 @@ impl CodeInfo {

// Push values to stack with source instruction index
let source = match instr {
Instruction::LoadFast(_) | Instruction::LoadFastLoadFast { .. } => i,
Instruction::LoadFast { .. } | Instruction::LoadFastLoadFast { .. } => i,
_ => NOT_LOCAL,
};
for _ in 0..pushes {
Expand Down Expand Up @@ -923,12 +930,17 @@ impl CodeInfo {
continue;
};
match instr {
Instruction::LoadFast(_) => {
info.instr = Instruction::LoadFastBorrow(Arg::marker()).into();
Instruction::LoadFast { .. } => {
info.instr = Instruction::LoadFastBorrow {
var_num: Arg::marker(),
}
.into();
}
Instruction::LoadFastLoadFast { .. } => {
info.instr =
Instruction::LoadFastBorrowLoadFastBorrow { arg: Arg::marker() }.into();
info.instr = Instruction::LoadFastBorrowLoadFastBorrow {
var_nums: Arg::marker(),
}
.into();
}
_ => {}
}
Expand Down Expand Up @@ -1415,7 +1427,7 @@ fn push_cold_blocks_to_end(blocks: &mut Vec<Block>) {
};
jump_block.instructions.push(InstructionInfo {
instr: PseudoInstruction::JumpNoInterrupt {
target: Arg::marker(),
delta: Arg::marker(),
}
.into(),
arg: OpArg::new(0),
Expand Down Expand Up @@ -1566,25 +1578,25 @@ fn normalize_jumps(blocks: &mut [Block]) {
AnyInstruction::Pseudo(PseudoInstruction::Jump { .. }) => {
if target_pos > source_pos {
Instruction::JumpForward {
target: Arg::marker(),
delta: Arg::marker(),
}
.into()
} else {
Instruction::JumpBackward {
target: Arg::marker(),
delta: Arg::marker(),
}
.into()
}
}
AnyInstruction::Pseudo(PseudoInstruction::JumpNoInterrupt { .. }) => {
if target_pos > source_pos {
Instruction::JumpForward {
target: Arg::marker(),
delta: Arg::marker(),
}
.into()
} else {
Instruction::JumpBackwardNoInterrupt {
target: Arg::marker(),
delta: Arg::marker(),
}
.into()
}
Expand Down Expand Up @@ -1750,18 +1762,21 @@ pub(crate) fn convert_pseudo_ops(blocks: &mut [Block], varnames_len: u32) {
info.instr = Instruction::Nop.into();
}
// LOAD_CLOSURE → LOAD_FAST (with varnames offset)
PseudoInstruction::LoadClosure(idx) => {
let new_idx = varnames_len + idx.get(info.arg);
PseudoInstruction::LoadClosure { i } => {
let new_idx = varnames_len + i.get(info.arg);
info.arg = OpArg::new(new_idx);
info.instr = Instruction::LoadFast(Arg::marker()).into();
info.instr = Instruction::LoadFast {
var_num: Arg::marker(),
}
.into();
}
// Jump pseudo ops are resolved during block linearization
PseudoInstruction::Jump { .. } | PseudoInstruction::JumpNoInterrupt { .. } => {}
// These should have been resolved earlier
PseudoInstruction::AnnotationsPlaceholder
| PseudoInstruction::JumpIfFalse { .. }
| PseudoInstruction::JumpIfTrue { .. }
| PseudoInstruction::StoreFastMaybeNull(_) => {
| PseudoInstruction::StoreFastMaybeNull { .. } => {
unreachable!("Unexpected pseudo instruction in convert_pseudo_ops: {pseudo:?}")
}
}
Expand Down
Loading
X Tutup