Skip to content

Commit

Permalink
analyze: run equiv remapping before pointee_type pass
Browse files Browse the repository at this point in the history
  • Loading branch information
spernsteiner committed Dec 3, 2024
1 parent 724d957 commit e3057de
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 78 deletions.
70 changes: 30 additions & 40 deletions c2rust-analyze/src/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,45 +587,18 @@ fn run(tcx: TyCtxt) {
do_recent_writes(&gacx, &mut func_info, &all_fn_ldids);

// ----------------------------------
// Infer pointee types
// ----------------------------------

let mut global_pointee_types = do_pointee_type(&mut gacx, &mut func_info, &all_fn_ldids);
debug_print_pointee_types(
&mut gacx,
&mut func_info,
&all_fn_ldids,
&global_pointee_types,
);

// ----------------------------------
// Compute dataflow constraints
// Remap `PointerId`s by equivalence class
// ----------------------------------

// Initial pass to assign local `PointerId`s and gather equivalence constraints, which state
// that two pointer types must be converted to the same reference type. Some additional data
// computed during this the process is kept around for use in later passes.
// Initial pass to gather equivalence constraints, which state that two pointer types must be
// converted to the same reference type. Some additional data computed during this the process
// is kept around for use in later passes.
let global_equiv = build_equiv_constraints(&mut gacx, &mut func_info, &all_fn_ldids);
build_dataflow_constraints(
&mut gacx,
&mut func_info,
&all_fn_ldids,
&global_pointee_types,
);

// ----------------------------------
// Remap `PointerId`s by equivalence class
// ----------------------------------

// Remap pointers based on equivalence classes, so all members of an equivalence class now use
// the same `PointerId`.
let (global_counter, global_equiv_map) = global_equiv.renumber();
debug!("global_equiv_map = {global_equiv_map:?}");
pointee_type::remap_pointers_global(
&mut global_pointee_types,
&global_equiv_map,
global_counter.num_pointers(),
);
gacx.remap_pointers(&global_equiv_map, global_counter.num_pointers());

let mut local_counter = global_counter.into_local();
Expand All @@ -637,15 +610,6 @@ fn run(tcx: TyCtxt) {
.local_equiv
.renumber(&global_equiv_map, &mut local_counter);
debug!("local_equiv_map = {local_equiv_map:?}");
if info.local_pointee_types.is_set() {
pointee_type::remap_pointers_local(
&mut global_pointee_types,
&mut info.local_pointee_types,
global_equiv_map.and(&local_equiv_map),
local_base,
local_count,
);
}
info.acx_data.remap_pointers(
&mut gacx,
global_equiv_map.and(&local_equiv_map),
Expand All @@ -659,6 +623,32 @@ fn run(tcx: TyCtxt) {
info.local_equiv.clear();
}

// ----------------------------------
// Infer pointee types
// ----------------------------------

// This runs after equivalence class remapping because it lets us get better pointee results in
// pointer-to-pointer cases without implementing full type unification.

let global_pointee_types = do_pointee_type(&mut gacx, &mut func_info, &all_fn_ldids);
debug_print_pointee_types(
&mut gacx,
&mut func_info,
&all_fn_ldids,
&global_pointee_types,
);

// ----------------------------------
// Compute dataflow constraints
// ----------------------------------

build_dataflow_constraints(
&mut gacx,
&mut func_info,
&all_fn_ldids,
&global_pointee_types,
);

// ----------------------------------
// Build initial assignment
// ----------------------------------
Expand Down
33 changes: 0 additions & 33 deletions c2rust-analyze/src/pointee_type/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::context::AnalysisCtxt;
use crate::pointer_id::{GlobalPointerTable, LocalPointerTable, PointerId, PointerTable};
use rustc_middle::mir::Body;
use std::mem;

mod constraint_set;
mod solve;
Expand All @@ -17,34 +15,3 @@ pub fn generate_constraints<'tcx>(
) -> ConstraintSet<'tcx> {
type_check::visit(acx, mir, vars)
}

pub fn remap_pointers_global<'tcx>(
pointee_types: &mut GlobalPointerTable<PointeeTypes<'tcx>>,
map: &GlobalPointerTable<PointerId>,
count: usize,
) {
let mut old = mem::replace(pointee_types, GlobalPointerTable::new(count));
let new = pointee_types;
for (old_ptr, old_val) in old.iter_mut() {
// If there are multiple old pointers that map to the same new pointer, merge their sets.
new[map[old_ptr]].merge(mem::take(old_val));
}
}

pub fn remap_pointers_local<'tcx>(
global_pointee_types: &mut GlobalPointerTable<PointeeTypes<'tcx>>,
local_pointee_types: &mut LocalPointerTable<PointeeTypes<'tcx>>,
map: PointerTable<PointerId>,
local_base: u32,
local_count: usize,
) {
let mut old = mem::replace(
local_pointee_types,
LocalPointerTable::new(local_base, local_count),
);
let mut new = global_pointee_types.and_mut(local_pointee_types);
for (old_ptr, old_val) in old.iter_mut() {
// If there are multiple old pointers that map to the same new pointer, merge their sets.
new[map[old_ptr]].merge(mem::take(old_val));
}
}
4 changes: 0 additions & 4 deletions c2rust-analyze/src/pointee_type/solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,6 @@ impl<'tcx> PointeeTypes<'tcx> {
}
}

pub fn merge(&mut self, other: PointeeTypes<'tcx>) {
self.tys.extend(other.tys);
}

pub fn simplify(&mut self, vars: &VarTable<'tcx>) {
let mut add = Vec::new();
let mut remove = Vec::new();
Expand Down
4 changes: 3 additions & 1 deletion c2rust-analyze/tests/filecheck/pointee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ unsafe fn remove_cast() {
unsafe fn malloc_fresh() {
let mut p = 0 as *mut libc::c_void;
let fresh = &mut p;
// CHECK: malloc(4)
// CHECK-NOT: malloc(4)
// CHECK: Box::new
// CHECK-NOT: malloc(4)
let q = malloc(4);
*fresh = q;
*(p as *mut i32) = 1;
Expand Down

0 comments on commit e3057de

Please sign in to comment.