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(slice_ty)), kind2),
23 ) = (src_ty.kind(), tgt_ty.kind())
24 {
25 assert!(arr_ty == slice_ty);
30 assert!(kind1 == kind2);
31 let id = match *kind1 {
34 RefKind::Mut => BuiltinFunId::ArrayToSliceMut,
35 RefKind::Shared => BuiltinFunId::ArrayToSliceShared,
36 };
37 let func = FnPtrKind::mk_builtin(id);
38 let generics = GenericArgs::new(
39 [Region::Erased].into(),
40 [arr_ty.clone()].into(),
41 [len.clone()].into(),
42 [].into(),
43 );
44 s.kind = StatementKind::Call(Call {
45 func: FnOperand::Regular(FnPtr::new(func, generics)),
46 args: vec![op.clone()],
47 dest: p.clone(),
48 });
49 }
50 }
51 StatementKind::Assign(p, Rvalue::Repeat(op, ty, cg)) => {
53 let id = BuiltinFunId::ArrayRepeat;
56 let func = FnPtrKind::mk_builtin(id);
57 let generics = GenericArgs::new(
58 [].into(),
59 [ty.clone()].into(),
60 [cg.clone()].into(),
61 [].into(),
62 );
63 s.kind = StatementKind::Call(Call {
64 func: FnOperand::Regular(FnPtr::new(func, generics)),
65 args: vec![op.clone()],
66 dest: p.clone(),
67 });
68 }
69 StatementKind::Assign(p, Rvalue::Aggregate(AggregateKind::RawPtr(ty, is_mut), ops)) => {
71 let id = BuiltinFunId::PtrFromParts(is_mut.clone());
72 let func = FnPtrKind::mk_builtin(id);
73 let generics = GenericArgs::new(
74 [Region::Erased].into(),
75 [ty.clone()].into(),
76 [].into(),
77 [].into(),
78 );
79
80 s.kind = StatementKind::Call(Call {
81 func: FnOperand::Regular(FnPtr::new(func, generics)),
82 args: ops.clone(),
83 dest: p.clone(),
84 });
85 }
86 _ => {}
87 }
88}
89
90pub struct Transform;
91impl LlbcPass for Transform {
92 fn should_run(&self, options: &crate::options::TranslateOptions) -> bool {
93 options.ops_to_function_calls
94 }
95
96 fn transform_body(&self, _ctx: &mut TransformCtx, b: &mut ExprBody) {
97 b.body.visit_statements(&mut transform_st);
98 }
99}