@@ -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 ) ]
3753pub 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
6184pub 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