charon_lib/transform/simplify_output/
ops_to_function_calls.rs1use crate::llbc_ast::*;
6use crate::transform::TransformCtx;
7
8use crate::transform::ctx::LlbcPass;
9
10fn transform_st(s: &mut Statement) {
11 match &s.kind {
12 StatementKind::Assign(
14 p,
15 Rvalue::UnaryOp(
16 UnOp::Cast(CastKind::Unsize(src_ty, tgt_ty, UnsizingMetadata::Length(_))),
17 op,
18 ),
19 ) => {
20 if let (
21 TyKind::Ref(_, deref!(TyKind::Array(arr_ty, len)), kind1),
22 TyKind::Ref(_, deref!(TyKind::Slice(_)), kind2),
23 ) = (src_ty.kind(), tgt_ty.kind())
24 {
25 assert!(kind1 == kind2);
30 let id = match *kind1 {
33 RefKind::Mut => BuiltinFunId::ArrayToSliceMut,
34 RefKind::Shared => BuiltinFunId::ArrayToSliceShared,
35 };
36 let func = FnPtrKind::mk_builtin(id);
37 let generics = GenericArgs::new(
38 [Region::Erased].into(),
39 [arr_ty.clone()].into(),
40 [*len.clone()].into(),
41 [].into(),
42 );
43 s.kind = StatementKind::Call(Call {
44 func: FnOperand::Regular(FnPtr::new(func, generics)),
45 args: vec![op.clone()],
46 dest: p.clone(),
47 });
48 }
49 }
50 StatementKind::Assign(p, Rvalue::Repeat(op, ty, cg)) => {
52 let id = BuiltinFunId::ArrayRepeat;
55 let func = FnPtrKind::mk_builtin(id);
56 let generics = GenericArgs::new(
57 [].into(),
58 [ty.clone()].into(),
59 [*cg.clone()].into(),
60 [].into(),
61 );
62 s.kind = StatementKind::Call(Call {
63 func: FnOperand::Regular(FnPtr::new(func, generics)),
64 args: vec![op.clone()],
65 dest: p.clone(),
66 });
67 }
68 StatementKind::Assign(p, Rvalue::Aggregate(AggregateKind::RawPtr(ty, is_mut), ops)) => {
70 let id = BuiltinFunId::PtrFromParts(is_mut.clone());
71 let func = FnPtrKind::mk_builtin(id);
72 let generics = GenericArgs::new(
73 [Region::Erased].into(),
74 [ty.clone()].into(),
75 [].into(),
76 [].into(),
77 );
78
79 s.kind = StatementKind::Call(Call {
80 func: FnOperand::Regular(FnPtr::new(func, generics)),
81 args: ops.clone(),
82 dest: p.clone(),
83 });
84 }
85 _ => {}
86 }
87}
88
89pub struct Transform;
90impl LlbcPass for Transform {
91 fn should_run(&self, options: &crate::options::TranslateOptions) -> bool {
92 options.ops_to_function_calls
93 }
94
95 fn transform_body(&self, _ctx: &mut TransformCtx, b: &mut ExprBody) {
96 b.body.visit_statements(&mut transform_st);
97 }
98}