charon_lib/transform/
remove_unused_locals.rs1use std::collections::{HashMap, HashSet};
6use std::mem;
7
8use crate::ast::*;
9use crate::transform::TransformCtx;
10
11use super::ctx::TransformPass;
12
13fn remove_unused_locals<Body: BodyVisitable>(body: &mut GExprBody<Body>) {
14 let mut used_locals: HashSet<LocalId> = (0..(body.locals.arg_count + 1))
17 .map(|i| LocalId::new(i))
18 .collect();
19 body.body.dyn_visit_in_body(|lid: &LocalId| {
20 used_locals.insert(*lid);
21 });
22 trace!("used_locals: {:?}", used_locals);
23
24 let mut ids_map: HashMap<LocalId, LocalId> = HashMap::new();
26 for local in mem::take(&mut body.locals.locals) {
27 if used_locals.contains(&local.index) {
28 let old_id = local.index;
29 let new_id = body
30 .locals
31 .locals
32 .push_with(|index| Local { index, ..local });
33 ids_map.insert(old_id, new_id);
34 }
35 }
36 trace!("ids_maps: {:?}", ids_map);
37
38 body.body.dyn_visit_in_body_mut(|lid: &mut LocalId| {
40 *lid = *ids_map.get(lid).unwrap();
41 });
42}
43
44pub struct Transform;
45impl TransformPass for Transform {
46 fn transform_ctx(&self, ctx: &mut TransformCtx) {
47 ctx.for_each_fun_decl(|_ctx, fun| {
48 if let Ok(body) = &mut fun.body {
49 match body {
50 Body::Unstructured(body) => remove_unused_locals(body),
51 Body::Structured(body) => remove_unused_locals(body),
52 }
53 }
54 });
55 }
56}