Skip to content

Commit 171cec4

Browse files
committed
add instruction ids to instructions along with start / end indexes on blocks
1 parent 16a4144 commit 171cec4

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

zjit/src/backend/lir.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ impl std::fmt::Display for BlockId {
3333
}
3434
}
3535

36+
/// LIR Instruction ID. Unique ID for each instruction in the LIR.
37+
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, PartialOrd, Ord)]
38+
pub struct InsnId(pub usize);
39+
40+
impl From<InsnId> for usize {
41+
fn from(val: InsnId) -> Self {
42+
val.0
43+
}
44+
}
45+
46+
impl std::fmt::Display for InsnId {
47+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
48+
write!(f, "i{}", self.0)
49+
}
50+
}
51+
3652
#[derive(Debug, PartialEq, Clone)]
3753
pub struct BranchEdge {
3854
pub target: BlockId,
@@ -51,11 +67,18 @@ pub struct BasicBlock {
5167
// Instructions in this basic block
5268
pub insns: Vec<Insn>,
5369

70+
// Instruction IDs for each instruction (same length as insns)
71+
pub insn_ids: Vec<Option<InsnId>>,
72+
5473
// Input parameters for this block
5574
pub parameters: Vec<Opnd>,
5675

5776
// RPO position of the source HIR block
5877
pub rpo_index: usize,
78+
79+
// Range of instruction IDs in this block (inclusive start, exclusive end)
80+
pub from: InsnId,
81+
pub to: InsnId,
5982
}
6083

6184
pub struct EdgePair(Option<BranchEdge>, Option<BranchEdge>);
@@ -67,8 +90,11 @@ impl BasicBlock {
6790
hir_block_id,
6891
entry,
6992
insns: vec![],
93+
insn_ids: vec![],
7094
parameters: vec![],
7195
rpo_index,
96+
from: InsnId(0),
97+
to: InsnId(0),
7298
}
7399
}
74100

@@ -78,6 +104,7 @@ impl BasicBlock {
78104

79105
pub fn push_insn(&mut self, insn: Insn) {
80106
self.insns.push(insn);
107+
self.insn_ids.push(None);
81108
}
82109

83110

@@ -2273,6 +2300,38 @@ impl Assembler
22732300
}
22742301
result
22752302
}
2303+
2304+
/// Number all instructions in the LIR in reverse postorder.
2305+
/// This assigns a unique InsnId to each instruction across all blocks.
2306+
/// Also sets the from/to range on each block.
2307+
/// Returns the next available instruction ID after numbering.
2308+
pub fn number_instructions(&mut self, start: usize) -> usize {
2309+
let rpo_order = self.rpo();
2310+
let mut insn_id = start;
2311+
for block_id in rpo_order {
2312+
let block = &mut self.basic_blocks[block_id.0];
2313+
let block_start = insn_id;
2314+
for id_slot in &mut block.insn_ids {
2315+
*id_slot = Some(InsnId(insn_id));
2316+
insn_id += 2;
2317+
}
2318+
block.from = InsnId(block_start);
2319+
block.to = InsnId(insn_id);
2320+
}
2321+
insn_id
2322+
}
2323+
2324+
/// Iterate over all instructions mutably with their block ID, instruction ID, and instruction index within the block.
2325+
/// Returns an iterator of (BlockId, Option<InsnId>, usize, &mut Insn).
2326+
pub fn iter_insns_mut(&mut self) -> impl Iterator<Item = (BlockId, Option<InsnId>, usize, &mut Insn)> {
2327+
self.basic_blocks.iter_mut().flat_map(|block| {
2328+
let block_id = block.id;
2329+
block.insns.iter_mut()
2330+
.zip(block.insn_ids.iter().copied())
2331+
.enumerate()
2332+
.map(move |(idx, (insn, insn_id))| (block_id, insn_id, idx, insn))
2333+
})
2334+
}
22762335
}
22772336

22782337
/// Return a result of fmt::Display for Assembler without escape sequence

0 commit comments

Comments
 (0)