Skip to content

Commit

Permalink
Implement simple Graph phase
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Jun 17, 2023
1 parent 90a0044 commit 34d61b1
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 4 deletions.
13 changes: 10 additions & 3 deletions boa_cli/src/debug/optimizer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use boa_engine::{
object::{FunctionObjectBuilder, ObjectInitializer},
optimizer::{control_flow_graph::ControlFlowGraph, OptimizerOptions},
optimizer::{
control_flow_graph::{ControlFlowGraph, GraphSimplification},
OptimizerOptions,
},
property::Attribute,
Context, JsArgs, JsNativeError, JsObject, JsResult, JsValue, NativeFunction,
};
Expand Down Expand Up @@ -71,8 +74,12 @@ fn graph(_: &JsValue, args: &[JsValue], _context: &mut Context<'_>) -> JsResult<
let bytecode = cfg.finalize();
assert_eq!(code.bytecode(), &bytecode);

let cfg = ControlFlowGraph::generate(&bytecode);
println!("{:#?}", cfg);
let mut cfg = ControlFlowGraph::generate(&bytecode);
println!("Original\n{:#?}\n", cfg);

let changed = GraphSimplification::perform(&mut cfg);
println!("Simplified({changed}) \n{:#?}", cfg);

Ok(JsValue::undefined())
}

Expand Down
60 changes: 59 additions & 1 deletion boa_engine/src/optimizer/control_flow_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ pub enum Terminator {
None,

/// TODO: doc
//
// TODO: add true and false and unconditional jump.
Jump(Opcode, RcBasicBlock),

/// TODO: doc
Expand Down Expand Up @@ -510,7 +512,22 @@ impl BasicBlock {
/// Insert nth instruction in the [`BasicBlock`].
fn insert(&mut self, nth: usize, instruction: &[u8]) -> bool {
let start = if let Some(value) = self.get(nth) {
value.next_opcode_pc.saturating_sub(1)
value.next_opcode_pc
} else {
0
};

for i in 0..instruction.len() {
self.bytecode.insert(start + i, instruction[i]);
}

true
}

/// Insert instruction in the last position in the [`BasicBlock`].
fn insert_last(&mut self, instruction: &[u8]) -> bool {
let start = if let Some(value) = BytecodeIterator::new(&self.bytecode).last() {
value.next_opcode_pc
} else {
0
};
Expand Down Expand Up @@ -988,3 +1005,44 @@ impl Drop for ControlFlowGraph {
}
}
}

/// Simplifies the [`ControlFlowGraph`].
///
/// # Operations
///
/// - Branch to same blocks -> jump
#[derive(Clone, Copy)]
pub struct GraphSimplification;

impl GraphSimplification {
/// TODO: doc
pub fn perform(graph: &mut ControlFlowGraph) -> bool {
let mut changed = false;
for basic_block_ptr in &graph.basic_blocks {
{
let mut basic_block = basic_block_ptr.borrow_mut();

match basic_block.terminator.clone() {
Terminator::None => {}
Terminator::Return { .. } => {}
Terminator::Jump(opcode, successor)
if opcode != Opcode::Jump && opcode != Opcode::Default =>
{
let Some(next) = &basic_block.next else {
continue;
};

if next == &successor {
basic_block.insert_last(&[Opcode::Pop as u8]);
basic_block.terminator = Terminator::Jump(Opcode::Jump, successor);

changed |= true;
}
}
_ => {}
}
}
}
changed
}
}

0 comments on commit 34d61b1

Please sign in to comment.