Skip to content

Commit

Permalink
Get a buggy version of LICM working
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinjoseph1995 committed Jan 12, 2025
1 parent 2f3cd9b commit b30eac1
Show file tree
Hide file tree
Showing 4 changed files with 333 additions and 48 deletions.
94 changes: 81 additions & 13 deletions common/src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,86 @@ impl Cfg {
pub fn get_basic_block_mut(&mut self, index: NodeIndex) -> &mut BasicBlock {
&mut self.dag.nodes.get_mut(index).unwrap().data
}

pub fn insert_new_parent(
&mut self,
index: NodeIndex,
mut node_data: BasicBlock,
new_node_name: String,
) {
let node_name = self.dag.get_node_name(index).to_string();
node_data.instruction_stream.push(Instruction::Effect {
op: bril_rs::EffectOps::Jump,
args: vec![],
funcs: vec![],
labels: vec![self.dag.get_node_name(index).to_string()],
pos: None,
});
let new_node_index = self.dag.nodes.len();
self.dag.nodes.push(Node {
data: node_data,
name: new_node_name.clone(),
successor_indices: SmallVec::new(),
predecessor_indices: SmallVec::new(),
});
let current_node_parents = self.dag.nodes[index].predecessor_indices.clone();
for parent_index in current_node_parents.iter() {
{
let parent = &mut self.dag.nodes[*parent_index];
let successor_index = parent
.successor_indices
.iter()
.position(|successor| *successor == index)
.unwrap();
parent.successor_indices[successor_index] = new_node_index;
self.dag.nodes[new_node_index]
.predecessor_indices
.push(*parent_index);
}
{
let parent_basic_block = &mut self.dag.nodes[*parent_index].data;
let mut insert_jmp = false;
match parent_basic_block
.instruction_stream
.last_mut()
.expect("Expected at least 1 instruction")
{
Instruction::Effect {
op: bril_rs::EffectOps::Jump,
labels,
..
} => {
// Update the jump label to the new node
*labels = vec![new_node_name.clone()];
}
Instruction::Effect {
op: bril_rs::EffectOps::Branch,
labels,
..
} => {
// Update the branch label to the new node
let pos = labels.iter().position(|l| *l == node_name);
labels[pos.unwrap()] = new_node_name.clone();
}
_ => {
insert_jmp = true;
}
}
if insert_jmp {
parent_basic_block
.instruction_stream
.push(Instruction::Effect {
op: bril_rs::EffectOps::Jump,
args: vec![],
funcs: vec![],
labels: vec![new_node_name.clone()],
pos: None,
});
}
}
}
self.dag.nodes[new_node_index].successor_indices.push(index);
}
}

impl<'a> Dominators<'a> {
Expand Down Expand Up @@ -650,8 +730,8 @@ pub fn convert_from_ssa<'a>(ssa_program: Program) -> Program {
mod tests {
use super::*;
use crate::cfg::convert_to_ssa;
use crate::get_program_output;
use bril_rs::Program;
use brilirs::{basic_block::BBProgram, interp};
use indoc::indoc;
use std::collections::HashSet;
use std::sync::LazyLock;
Expand Down Expand Up @@ -792,18 +872,6 @@ mod tests {
}
}
}
fn get_program_output(program: Program, input_args: &[String]) -> String {
let bbprog: BBProgram = program.clone().try_into().expect("Invalid program");
let mut stdout = Vec::<u8>::new();
let mut stderr = Vec::<u8>::new();
let result = interp::execute_main(&bbprog, &mut stdout, input_args, true, &mut stderr);
if let Some(error) = result.err() {
eprintln!("{}", error);
panic!("Program execution failed");
}

String::from_utf8(stdout).unwrap()
}

fn is_ssa(program: &Program) -> bool {
let mut assigned: HashSet<&str> = HashSet::new();
Expand Down
14 changes: 14 additions & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod cfg;

use bril_rs::{Code, Instruction, Program};
use brilirs::{basic_block::BBProgram, interp};
use std::{error::Error, fmt::Display};

#[derive(Debug, Clone)]
Expand All @@ -9,6 +10,19 @@ pub struct BasicBlock {
pub instruction_stream: Vec<Instruction>,
}

pub fn get_program_output(program: Program, input_args: &[String]) -> String {
let bbprog: BBProgram = program.clone().try_into().expect("Invalid program");
let mut stdout = Vec::<u8>::new();
let mut stderr = Vec::<u8>::new();
let result = interp::execute_main(&bbprog, &mut stdout, input_args, true, &mut stderr);
if let Some(error) = result.err() {
eprintln!("{}", error);
panic!("Program execution failed");
}

String::from_utf8(stdout).unwrap()
}

pub fn construct_basic_block_stream<'a>(instructions: &'a [Code]) -> Vec<BasicBlock> {
let mut current_basic_block_start: usize = 0;
let mut blocks: Vec<BasicBlock> = Vec::new();
Expand Down
18 changes: 9 additions & 9 deletions dataflow_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashSet;
use std::fmt::Display;
use std::hash::Hash;

use bril_rs::{Argument, Program};
use bril_rs::Program;
use clap::ValueEnum;
use common::cfg::{Cfg, NodeIndex};
use derivative::Derivative;
Expand Down Expand Up @@ -158,13 +158,13 @@ impl LiveVariableAnalysis {
}

#[derive(Derivative)]
#[derivative(Eq, PartialEq, Hash)]
#[derivative(Eq, PartialEq, Hash, Debug)]
pub struct Definition<'a> {
destination_variable: &'a str,
basic_block_index: usize,
instruction_index: usize,
arg_index: Option<usize>,
#[derivative(PartialEq = "ignore", Hash = "ignore")]
pub destination_variable: &'a str,
pub basic_block_index: usize,
pub instruction_index: usize,
pub arg_index: Option<usize>,
#[derivative(PartialEq = "ignore", Hash = "ignore", Debug = "ignore")]
cfg: &'a Cfg,
}

Expand Down Expand Up @@ -335,8 +335,8 @@ pub fn run_analysis(dataflow_analysis_name: DataflowAnalyses, program: &Program)
program
.functions
.iter()
.map(|f| (f, Cfg::new(f)))
.for_each(|(f, cfg)| match dataflow_analysis_name {
.map(|f| Cfg::new(f))
.for_each(|cfg| match dataflow_analysis_name {
DataflowAnalyses::LiveVariable => {
let _ = LiveVariableAnalysis {}.run_analysis(&cfg, Some(true));
}
Expand Down
Loading

0 comments on commit b30eac1

Please sign in to comment.