Skip to content

Commit 34d61b1

Browse files
committed
Implement simple Graph phase
1 parent 90a0044 commit 34d61b1

File tree

2 files changed

+69
-4
lines changed

2 files changed

+69
-4
lines changed

boa_cli/src/debug/optimizer.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use boa_engine::{
22
object::{FunctionObjectBuilder, ObjectInitializer},
3-
optimizer::{control_flow_graph::ControlFlowGraph, OptimizerOptions},
3+
optimizer::{
4+
control_flow_graph::{ControlFlowGraph, GraphSimplification},
5+
OptimizerOptions,
6+
},
47
property::Attribute,
58
Context, JsArgs, JsNativeError, JsObject, JsResult, JsValue, NativeFunction,
69
};
@@ -71,8 +74,12 @@ fn graph(_: &JsValue, args: &[JsValue], _context: &mut Context<'_>) -> JsResult<
7174
let bytecode = cfg.finalize();
7275
assert_eq!(code.bytecode(), &bytecode);
7376

74-
let cfg = ControlFlowGraph::generate(&bytecode);
75-
println!("{:#?}", cfg);
77+
let mut cfg = ControlFlowGraph::generate(&bytecode);
78+
println!("Original\n{:#?}\n", cfg);
79+
80+
let changed = GraphSimplification::perform(&mut cfg);
81+
println!("Simplified({changed}) \n{:#?}", cfg);
82+
7683
Ok(JsValue::undefined())
7784
}
7885

boa_engine/src/optimizer/control_flow_graph/mod.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)