-
Notifications
You must be signed in to change notification settings - Fork 237
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is a simple recursive implementation of the `call` operation (both in the value and effect contexts). I originally tried an iterative version, but the borrow checker gave me a tough fight. This is much more readable than tracking a stack of function call environments directly anyway.
- Loading branch information
1 parent
7896a09
commit f7ca8bf
Showing
7 changed files
with
368 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,28 @@ | ||
use crate::basic_block::BasicBlock; | ||
use crate::basic_block::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() { | ||
pub fn build_cfg(prog: &mut BBProgram) { | ||
let last_idx = prog.blocks.len() - 1; | ||
for (i, block) in prog.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 | ||
{ | ||
match op { | ||
bril_rs::EffectOps::Jump | bril_rs::EffectOps::Branch => { | ||
for l in labels { | ||
block.exit.push(label_to_block_idx[l]); | ||
} | ||
let label_index = &prog.func_index[&block.func].label_index; | ||
if let bril_rs::EffectOps::Jump | bril_rs::EffectOps::Branch = op { | ||
for l in labels { | ||
block.exit.push( | ||
*label_index | ||
.get(l) | ||
.expect(&format!("No label {} found.", &l)), | ||
); | ||
} | ||
bril_rs::EffectOps::Return => {} | ||
// TODO(yati): Do all effect ops end a BB? | ||
_ => {} | ||
} | ||
} else { | ||
block.exit.push(i + 1); | ||
} | ||
} | ||
} | ||
|
||
blocks | ||
} |
Oops, something went wrong.