Skip to content

Commit

Permalink
transfer terminator
Browse files Browse the repository at this point in the history
  • Loading branch information
Medowhill committed Jan 12, 2024
1 parent 304adab commit b637699
Show file tree
Hide file tree
Showing 3 changed files with 254 additions and 58 deletions.
24 changes: 13 additions & 11 deletions src/relational/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_data_structures::graph::WithSuccessors;
use rustc_hir::{def_id::DefId, ItemKind};
use rustc_index::bit_set::BitSet;
use rustc_middle::{
mir::{BasicBlock, Body, Local, Location},
mir::{BasicBlock, Body, Local, Location, Operand},
ty::{AdtKind, Ty, TyCtxt, TyKind, TypeAndMut},
};
use rustc_mir_dataflow::Analysis;
Expand Down Expand Up @@ -68,13 +68,14 @@ pub fn analyze(tcx: TyCtxt<'_>) -> AnalysisResults {
.collect();
let analyzer = Analyzer {
tcx,
body,
def_id,
rpo_map,
dead_locals,
local_tys,
local_ptr_tys,
};
analyzer.analyze_body(body);
analyzer.analyze();

for bbd in body.basic_blocks.iter() {
for stmt in &bbd.statements {
Expand All @@ -92,6 +93,7 @@ pub struct AnalysisResults;
#[allow(missing_debug_implementations)]
pub struct Analyzer<'tcx> {
pub tcx: TyCtxt<'tcx>,
pub body: &'tcx Body<'tcx>,
pub def_id: DefId,
pub rpo_map: HashMap<BasicBlock, usize>,
pub dead_locals: Vec<BitSet<Local>>,
Expand All @@ -100,7 +102,7 @@ pub struct Analyzer<'tcx> {
}

impl<'tcx> Analyzer<'tcx> {
fn analyze_body(&self, body: &Body<'tcx>) {
fn analyze(&self) {
let bot = AbsMem::bot();

let mut work_list = WorkList::new(&self.rpo_map);
Expand All @@ -110,17 +112,13 @@ impl<'tcx> Analyzer<'tcx> {

while let Some(location) = work_list.pop() {
let state = states.get(&location).unwrap_or(&bot);
let bbd = &body.basic_blocks[location.block];
let mut next_state = state.clone();
let bbd = &self.body.basic_blocks[location.block];
let nexts = if let Some(stmt) = bbd.statements.get(location.statement_index) {
let mut next_state = state.clone();
self.transfer_stmt(stmt, &mut next_state);

let mut next_location = location;
next_location.statement_index += 1;

vec![(next_location, next_state)]
vec![(location.successor_within_block(), next_state)]
} else {
self.transfer_term(bbd.terminator())
self.transfer_term(bbd.terminator(), &next_state)
};
for (next_location, new_next_state) in nexts {
let next_state = states.get(&next_location).unwrap_or(&bot);
Expand All @@ -136,6 +134,10 @@ impl<'tcx> Analyzer<'tcx> {
}
}

pub fn ty(&self, operand: &Operand<'tcx>) -> Ty<'tcx> {
operand.ty(&self.body.local_decls, self.tcx)
}

// fn def_id_to_string(&self, def_id: DefId) -> String {
// self.tcx.def_path(def_id).to_string_no_crate_verbose()
// }
Expand Down
87 changes: 83 additions & 4 deletions src/relational/domains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@ impl AbsMem {
}

#[inline]
pub fn g(&mut self) -> &mut Graph {
pub fn g(&self) -> &Graph {
match self {
Self::Bot => panic!(),
Self::Mem(g) => g,
}
}

#[inline]
pub fn gm(&mut self) -> &mut Graph {
match self {
Self::Bot => panic!(),
Self::Mem(g) => g,
Expand Down Expand Up @@ -136,6 +144,23 @@ impl Obj {
self
}
}

fn substitute(&mut self, old_id: NodeId, new_id: NodeId) {
match self {
Obj::Ptr(loc) => {
if loc.root == old_id {
assert!(loc.projection.is_empty());
loc.root = new_id;
}
}
Obj::Compound(fs) => {
for obj in fs.values_mut() {
obj.substitute(old_id, new_id);
}
}
Obj::Index(_, box obj) => obj.substitute(old_id, new_id),
}
}
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -359,7 +384,8 @@ impl Graph {
let (id, _) = self.get_local_node_mut(x.local);
let mut loc = self.get_pointed_loc_mut(id, &[]);
loc.projection.extend(x.projection.to_owned());
let obj = self.get_obj_mut(x);
let node = &mut self.nodes[loc.root];
let obj = node.obj.project_mut(&loc.projection);
*obj = Obj::Ptr(Location::new(n_id, vec![]));
}

Expand All @@ -372,10 +398,51 @@ impl Graph {
let (id, _) = self.get_local_node_mut(x.local);
let mut loc = self.get_pointed_loc_mut(id, &[]);
loc.projection.extend(x.projection.to_owned());
let obj = self.get_obj_mut(x);
let node = &mut self.nodes[loc.root];
let obj = node.obj.project_mut(&loc.projection);
*obj = Obj::new();
}

pub fn filter_x_int(&mut self, x: &AccPath, n: Int) {
let obj = self.get_obj_mut(x);
let Obj::Ptr(ptr) = obj else { unreachable!() };
assert!(ptr.projection.is_empty());
let id = ptr.root;

if let Some(n_id) = self.ints.get(&n) {
let n_id = *n_id;
self.substitute(id, n_id);
} else {
self.nodes[id].at_addr = Some(n);
self.ints.insert(n, id);
}
}

pub fn filter_deref_x_int(&mut self, x: &AccPath, n: Int) {
let (id, _) = self.get_local_node_mut(x.local);
let mut loc = self.get_pointed_loc_mut(id, &[]);
loc.projection.extend(x.projection.to_owned());
let node = &mut self.nodes[loc.root];
let obj = node.obj.project_mut(&loc.projection);
let Obj::Ptr(ptr) = obj else { unreachable!() };
assert!(ptr.projection.is_empty());
let id = ptr.root;

if let Some(n_id) = self.ints.get(&n) {
let n_id = *n_id;
self.substitute(id, n_id);
} else {
self.nodes[id].at_addr = Some(n);
self.ints.insert(n, id);
}
}

fn substitute(&mut self, old_id: NodeId, new_id: NodeId) {
for node in &mut self.nodes {
node.obj.substitute(old_id, new_id);
}
}

pub fn find_aliases(&self, local: Local) -> HashSet<Local> {
let mut aliases = HashSet::new();
let loc1 = self.loc_pointed_by_local(local).unwrap();
Expand All @@ -398,7 +465,7 @@ impl Graph {
}
}

pub fn get_int_value(&self, x: &AccPath) -> Option<Int> {
pub fn get_x_as_int(&self, x: &AccPath) -> Option<Int> {
let id = self.locals.get(&x.local)?;
let loc = self.get_pointed_loc(*id, &x.projection)?;
if loc.projection.is_empty() {
Expand All @@ -408,6 +475,18 @@ impl Graph {
}
}

pub fn get_deref_x_as_int(&self, x: &AccPath) -> Option<Int> {
let id = self.locals.get(&x.local)?;
let mut loc = self.get_pointed_loc(*id, &[])?;
loc.projection.extend(x.projection.to_owned());
let loc = self.get_pointed_loc(loc.root, &loc.projection)?;
if loc.projection.is_empty() {
self.nodes[loc.root].at_addr
} else {
None
}
}

fn get_pointed_loc(&self, node_id: NodeId, proj: &[AccElem]) -> Option<Location> {
let obj = self.nodes[node_id].obj.project(proj)?;
let Obj::Ptr(loc) = obj else { return None };
Expand Down
Loading

0 comments on commit b637699

Please sign in to comment.