From 20df57b5be1004e8b0543dbf688b54edb1a23d65 Mon Sep 17 00:00:00 2001 From: Jessica Ruan Date: Tue, 4 Feb 2025 10:30:30 -0500 Subject: [PATCH] SSA draft --- src/codegen/context.rs | 7 ++++--- src/codegen/mod.rs | 2 +- src/codegen/ssa.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 src/codegen/ssa.rs diff --git a/src/codegen/context.rs b/src/codegen/context.rs index 36544ed..9337f80 100644 --- a/src/codegen/context.rs +++ b/src/codegen/context.rs @@ -1,7 +1,7 @@ +use crate::codegen::ssa::{BasicBlock, SSABuilder}; use crate::lexer::Token; use crate::parser::{Block, Expr, FnDeclaration, Program, Statement, VarDeclaration}; use std::collections::HashMap; -use std::mem::uninitialized; #[derive(Debug)] pub enum AbstractAssemblyInstruction { @@ -81,6 +81,8 @@ pub struct Context { label_counter: usize, /// Given a variable name, get the associated temp var_to_temp: HashMap, + /// For converting to SSA form + ssa_builder: SSABuilder, } impl Context { @@ -90,9 +92,8 @@ impl Context { instructions: Vec::new(), temp_counter: 0, label_counter: 0, - /// TODO: if we're converting to SSA, then we'd want to create a new version of each variable - /// for each assignment, as well as for each branch. Also some way of placing phi nodes var_to_temp: HashMap::new(), + ssa_builder: SSABuilder::new(), } } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 5a312e2..da232e7 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -6,8 +6,8 @@ use std::path::PathBuf; mod context; use context::Context; - mod emit; +mod ssa; pub enum Target { AbstractAssembly, diff --git a/src/codegen/ssa.rs b/src/codegen/ssa.rs new file mode 100644 index 0000000..922276e --- /dev/null +++ b/src/codegen/ssa.rs @@ -0,0 +1,40 @@ +use crate::codegen::context::{AbstractAssemblyInstruction, AsmLabel, Context}; +use std::collections::HashMap; + +pub struct SSABuilder { + cfg: ControlFlowGraph, + /// Track current block for SSABuilder + current_block: BasicBlock, +} + +pub struct ControlFlowGraph { + blocks: HashMap, + edges: HashMap, Option)>, +} + +#[derive(Debug)] +pub struct BasicBlock { + id: BasicBlockId, + label: Option, + instructions: Vec, +} + +#[derive(Debug)] +pub struct BasicBlockId(usize); + +impl SSABuilder { + pub fn new() -> Self {} + + pub fn convert_to_ssa(context: &Context) -> Context { + // 1. Build CFG from context.instructions + // 2. Compute dominance frontiers + // 3. Insert phi nodes at dominance frontiers + // 4. Rename variables + } + + fn compute_dominance_frontiers(&mut self) {} + + fn insert_phi_nodes(&mut self, context: &mut Context) {} + + fn rename_variables(&mut self, context: &mut Context) {} +}