Skip to content

Commit

Permalink
Everything but spec and benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
Pat-Lafon committed Dec 28, 2020
1 parent 57f8ace commit d4913d5
Show file tree
Hide file tree
Showing 13 changed files with 656 additions and 226 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ yarn.lock
.pytest_cache/
hypothesis_*
__pycache__
.vscode
3 changes: 3 additions & 0 deletions benchmarks/turnt_brilirs.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
command = "bril2json < {filename} | cargo run --manifest-path ../../brilirs/Cargo.toml -- -p {args}"
output.out = "-"
output.prof = "2"
2 changes: 1 addition & 1 deletion bril-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ pub enum Literal {

impl Literal {
pub fn get_type(&self) -> Type {
match *self {
match self {
Literal::Int(_) => Type::Int,
Literal::Bool(_) => Type::Bool,
#[cfg(feature = "float")]
Expand Down
12 changes: 12 additions & 0 deletions brilirs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
TESTS := ../test/interp/*.bril \
../test/mem/*.bril \
../test/fail/*.bril \
../benchmarks/*.bril

.PHONY: test
test:
turnt -c turnt_brilirs.toml $(TESTS)

.PHONY: example
example:
bril2json < ../test/fail/double_free.bril | cargo run --
114 changes: 65 additions & 49 deletions brilirs/src/basic_block.rs
Original file line number Diff line number Diff line change
@@ -1,81 +1,97 @@
use std::collections::HashMap;

// A program composed of basic blocks.
// (BB index of main program, list of BBs, mapping of label -> BB index)
pub type BBProgram = (Option<usize>, Vec<BasicBlock>, HashMap<String, usize>);

pub type BBProgram = HashMap<String, BBFunction>;

pub struct BBFunction {
pub name: String,
pub args: Vec<bril_rs::Argument>,
pub return_type: Option<bril_rs::Type>,
pub blocks: Vec<BasicBlock>,
pub label_map: HashMap<String, usize>,
}

#[derive(Debug)]
pub struct BasicBlock {
pub instrs: Vec<bril_rs::Code>,
pub label: Option<String>,
pub instrs: Vec<bril_rs::Instruction>,
pub exit: Vec<usize>,
}

impl BasicBlock {
fn new() -> BasicBlock {
BasicBlock {
label: None,
instrs: Vec::new(),
exit: Vec::new(),
}
}
}

pub fn find_basic_blocks(prog: bril_rs::Program) -> BBProgram {
let mut main_fn = None;
fn find_basic_blocks(func: bril_rs::Function) -> BBFunction {
let mut blocks = Vec::new();
let mut labels = HashMap::new();
let mut label_map = HashMap::new();

let mut bb_helper = |func: bril_rs::Function| -> usize {
let mut curr_block = BasicBlock::new();
let root_block = blocks.len();
let mut curr_label = None;
for instr in func.instrs.into_iter() {
match instr {
bril_rs::Code::Label { ref label } => {
if !curr_block.instrs.is_empty() {
blocks.push(curr_block);
if let Some(old_label) = curr_label {
labels.insert(old_label, blocks.len() - 1);
}
curr_block = BasicBlock::new();
let mut curr_block = BasicBlock::new();
for instr in func.instrs.into_iter() {
match instr {
bril_rs::Code::Label { ref label } => {
if !curr_block.instrs.is_empty() {
if let Some(old_label) = curr_block.label.as_ref() {
label_map.insert(old_label.to_string(), blocks.len());
}
curr_label = Some(label.clone());
}
bril_rs::Code::Instruction(bril_rs::Instruction::Effect { op, .. })
if op == bril_rs::EffectOps::Jump
|| op == bril_rs::EffectOps::Branch
|| op == bril_rs::EffectOps::Return =>
{
curr_block.instrs.push(instr);
blocks.push(curr_block);
if let Some(l) = curr_label {
labels.insert(l, blocks.len() - 1);
curr_label = None;
}
curr_block = BasicBlock::new();
}
_ => {
curr_block.instrs.push(instr);
curr_block.label = Some(label.clone());
}
bril_rs::Code::Instruction(bril_rs::Instruction::Effect {
op,
args,
funcs,
labels,
}) if op == bril_rs::EffectOps::Jump
|| op == bril_rs::EffectOps::Branch
|| op == bril_rs::EffectOps::Return =>
{
curr_block.instrs.push(bril_rs::Instruction::Effect {
op,
args,
funcs,
labels,
});
if let Some(l) = curr_block.label.as_ref() {
label_map.insert(l.to_string(), blocks.len());
}
blocks.push(curr_block);
curr_block = BasicBlock::new();
}
}

if !curr_block.instrs.is_empty() {
blocks.push(curr_block);
if let Some(l) = curr_label {
labels.insert(l, blocks.len() - 1);
bril_rs::Code::Instruction(code) => {
curr_block.instrs.push(code);
}
}
}

root_block
};

for func in prog.functions.into_iter() {
let func_name = func.name.clone();
let func_block = bb_helper(func);
if func_name == "main" {
main_fn = Some(func_block);
if !curr_block.instrs.is_empty() {
if let Some(l) = curr_block.label.as_ref() {
label_map.insert(l.to_string(), blocks.len());
}
blocks.push(curr_block);
}

(main_fn, blocks, labels)
BBFunction {
name: func.name,
args: func.args,
return_type: func.return_type,
blocks,
label_map,
}
}

pub fn to_bbprogram(prog: bril_rs::Program) -> BBProgram {
prog
.functions
.into_iter()
.map(|func| (func.name.clone(), find_basic_blocks(func)))
.collect()
}
24 changes: 9 additions & 15 deletions brilirs/src/cfg.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
use crate::basic_block::BasicBlock;
use crate::basic_block::{BBFunction, BBProgram};

use std::collections::HashMap;

type CFG = Vec<BasicBlock>;

pub fn build_cfg(mut blocks: Vec<BasicBlock>, label_to_block_idx: &HashMap<String, usize>) -> CFG {
let last_idx = blocks.len() - 1;
for (i, block) in blocks.iter_mut().enumerate() {
fn build_cfg_func(func: &mut BBFunction) {
let last_idx = func.blocks.len() - 1;
for (i, block) in func.blocks.iter_mut().enumerate() {
// If we're before the last block
if i < last_idx {
// Get the last instruction
let last_instr: &bril_rs::Code = block.instrs.last().unwrap();
if let bril_rs::Code::Instruction(bril_rs::Instruction::Effect { op, labels, .. }) =
last_instr
{
if let Some(bril_rs::Instruction::Effect { op, labels, .. }) = block.instrs.last() {
match op {
bril_rs::EffectOps::Jump | bril_rs::EffectOps::Branch => {
for l in labels {
block.exit.push(label_to_block_idx[l]);
block.exit.push(func.label_map[l]);
}
}
bril_rs::EffectOps::Return => {}
// TODO(yati): Do all effect ops end a BB?
_ => {}
}
} else {
block.exit.push(i + 1);
}
}
}
}

blocks
pub fn build_cfg(prog: &mut BBProgram) {
prog.iter_mut().for_each(|(_, func)| build_cfg_func(func))
}
Loading

0 comments on commit d4913d5

Please sign in to comment.