@@ -450,6 +450,8 @@ pub enum Terminator {
450450 None ,
451451
452452 /// TODO: doc
453+ //
454+ // TODO: add true and false and unconditional jump.
453455 Jump ( Opcode , RcBasicBlock ) ,
454456
455457 /// TODO: doc
@@ -510,7 +512,22 @@ impl BasicBlock {
510512 /// Insert nth instruction in the [`BasicBlock`].
511513 fn insert ( & mut self , nth : usize , instruction : & [ u8 ] ) -> bool {
512514 let start = if let Some ( value) = self . get ( nth) {
513- value. next_opcode_pc . saturating_sub ( 1 )
515+ value. next_opcode_pc
516+ } else {
517+ 0
518+ } ;
519+
520+ for i in 0 ..instruction. len ( ) {
521+ self . bytecode . insert ( start + i, instruction[ i] ) ;
522+ }
523+
524+ true
525+ }
526+
527+ /// Insert instruction in the last position in the [`BasicBlock`].
528+ fn insert_last ( & mut self , instruction : & [ u8 ] ) -> bool {
529+ let start = if let Some ( value) = BytecodeIterator :: new ( & self . bytecode ) . last ( ) {
530+ value. next_opcode_pc
514531 } else {
515532 0
516533 } ;
@@ -988,3 +1005,44 @@ impl Drop for ControlFlowGraph {
9881005 }
9891006 }
9901007}
1008+
1009+ /// Simplifies the [`ControlFlowGraph`].
1010+ ///
1011+ /// # Operations
1012+ ///
1013+ /// - Branch to same blocks -> jump
1014+ #[ derive( Clone , Copy ) ]
1015+ pub struct GraphSimplification ;
1016+
1017+ impl GraphSimplification {
1018+ /// TODO: doc
1019+ pub fn perform ( graph : & mut ControlFlowGraph ) -> bool {
1020+ let mut changed = false ;
1021+ for basic_block_ptr in & graph. basic_blocks {
1022+ {
1023+ let mut basic_block = basic_block_ptr. borrow_mut ( ) ;
1024+
1025+ match basic_block. terminator . clone ( ) {
1026+ Terminator :: None => { }
1027+ Terminator :: Return { .. } => { }
1028+ Terminator :: Jump ( opcode, successor)
1029+ if opcode != Opcode :: Jump && opcode != Opcode :: Default =>
1030+ {
1031+ let Some ( next) = & basic_block. next else {
1032+ continue ;
1033+ } ;
1034+
1035+ if next == & successor {
1036+ basic_block. insert_last ( & [ Opcode :: Pop as u8 ] ) ;
1037+ basic_block. terminator = Terminator :: Jump ( Opcode :: Jump , successor) ;
1038+
1039+ changed |= true ;
1040+ }
1041+ }
1042+ _ => { }
1043+ }
1044+ }
1045+ }
1046+ changed
1047+ }
1048+ }
0 commit comments