Skip to content

Commit 401dad6

Browse files
committed
add instruction ids to instructions along with start / end indexes on blocks
1 parent f7d0657 commit 401dad6

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
@@ -38,6 +38,22 @@ const DUMMY_HIR_BLOCK_ID: usize = usize::MAX;
3838
/// Dummy RPO index used when creating test or invalid LIR blocks
3939
const DUMMY_RPO_INDEX: usize = usize::MAX;
4040

41+
/// LIR Instruction ID. Unique ID for each instruction in the LIR.
42+
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, PartialOrd, Ord)]
43+
pub struct InsnId(pub usize);
44+
45+
impl From<InsnId> for usize {
46+
fn from(val: InsnId) -> Self {
47+
val.0
48+
}
49+
}
50+
51+
impl std::fmt::Display for InsnId {
52+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
53+
write!(f, "i{}", self.0)
54+
}
55+
}
56+
4157
#[derive(Debug, PartialEq, Clone)]
4258
pub struct BranchEdge {
4359
pub target: BlockId,
@@ -58,11 +74,18 @@ pub struct BasicBlock {
5874
// Instructions in this basic block
5975
pub insns: Vec<Insn>,
6076

77+
// Instruction IDs for each instruction (same length as insns)
78+
pub insn_ids: Vec<Option<InsnId>>,
79+
6180
// Input parameters for this block
6281
pub parameters: Vec<Opnd>,
6382

6483
// RPO position of the source HIR block
6584
pub rpo_index: usize,
85+
86+
// Range of instruction IDs in this block (inclusive start, exclusive end)
87+
pub from: InsnId,
88+
pub to: InsnId,
6689
}
6790

6891
pub struct EdgePair(Option<BranchEdge>, Option<BranchEdge>);
@@ -74,8 +97,11 @@ impl BasicBlock {
7497
hir_block_id,
7598
is_entry,
7699
insns: vec![],
100+
insn_ids: vec![],
77101
parameters: vec![],
78102
rpo_index,
103+
from: InsnId(0),
104+
to: InsnId(0),
79105
}
80106
}
81107

@@ -85,6 +111,7 @@ impl BasicBlock {
85111

86112
pub fn push_insn(&mut self, insn: Insn) {
87113
self.insns.push(insn);
114+
self.insn_ids.push(None);
88115
}
89116

90117
pub fn edges(&self) -> EdgePair {
@@ -2304,6 +2331,38 @@ impl Assembler
23042331
}
23052332
result
23062333
}
2334+
2335+
/// Number all instructions in the LIR in reverse postorder.
2336+
/// This assigns a unique InsnId to each instruction across all blocks.
2337+
/// Also sets the from/to range on each block.
2338+
/// Returns the next available instruction ID after numbering.
2339+
pub fn number_instructions(&mut self, start: usize) -> usize {
2340+
let rpo_order = self.rpo();
2341+
let mut insn_id = start;
2342+
for block_id in rpo_order {
2343+
let block = &mut self.basic_blocks[block_id.0];
2344+
let block_start = insn_id;
2345+
for id_slot in &mut block.insn_ids {
2346+
*id_slot = Some(InsnId(insn_id));
2347+
insn_id += 2;
2348+
}
2349+
block.from = InsnId(block_start);
2350+
block.to = InsnId(insn_id);
2351+
}
2352+
insn_id
2353+
}
2354+
2355+
/// Iterate over all instructions mutably with their block ID, instruction ID, and instruction index within the block.
2356+
/// Returns an iterator of (BlockId, Option<InsnId>, usize, &mut Insn).
2357+
pub fn iter_insns_mut(&mut self) -> impl Iterator<Item = (BlockId, Option<InsnId>, usize, &mut Insn)> {
2358+
self.basic_blocks.iter_mut().flat_map(|block| {
2359+
let block_id = block.id;
2360+
block.insns.iter_mut()
2361+
.zip(block.insn_ids.iter().copied())
2362+
.enumerate()
2363+
.map(move |(idx, (insn, insn_id))| (block_id, insn_id, idx, insn))
2364+
})
2365+
}
23072366
}
23082367

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

0 commit comments

Comments
 (0)