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<String, usize>,
+    /// 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<BasicBlockId, BasicBlock>,
+    edges: HashMap<BasicBlockId, (Option<BasicBlockId>, Option<BasicBlockId>)>,
+}
+
+#[derive(Debug)]
+pub struct BasicBlock {
+    id: BasicBlockId,
+    label: Option<AsmLabel>,
+    instructions: Vec<AbstractAssemblyInstruction>,
+}
+
+#[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) {}
+}