1 | |
---|
2 | (** This module performs a switch simplification: they are replaced by |
---|
3 | equivalent if-then-else statements. This is a temporary hack before |
---|
4 | implementing switch tables. *) |
---|
5 | |
---|
6 | let type_of (Clight.Expr (_, t)) = t |
---|
7 | |
---|
8 | let rec simplify_switch e cases stmts = match cases, stmts with |
---|
9 | | Clight.LSdefault _, stmt :: _ -> stmt |
---|
10 | | Clight.LScase (i, _, lbl_stmts), stmt :: stmts -> |
---|
11 | let next_cases = simplify_switch e lbl_stmts stmts in |
---|
12 | let ret_type = Clight.Tint (Clight.I32, AST.Signed) in |
---|
13 | let cst_i = Clight.Expr (Clight.Econst_int i, type_of e) in |
---|
14 | let test = Clight.Expr (Clight.Ebinop (Clight.Oeq, e, cst_i), ret_type) in |
---|
15 | Clight.Sifthenelse (test, stmt, next_cases) |
---|
16 | | _ -> assert false (* do not use on these arguments *) |
---|
17 | |
---|
18 | let f_expr e _ = e |
---|
19 | |
---|
20 | let f_stmt stmt sub_exprs_res sub_stmts_res = match stmt, sub_stmts_res with |
---|
21 | | Clight.Sswitch (e, cases), sub_stmts -> simplify_switch e cases sub_stmts |
---|
22 | | _ -> ClightFold.statement_fill_subs stmt sub_exprs_res sub_stmts_res |
---|
23 | |
---|
24 | let simplify_statement = ClightFold.statement2 f_expr f_stmt |
---|
25 | |
---|
26 | let simplify_fundef = function |
---|
27 | | Clight.Internal cfun -> |
---|
28 | let cfun = |
---|
29 | { cfun with Clight.fn_body = simplify_statement cfun.Clight.fn_body } in |
---|
30 | Clight.Internal cfun |
---|
31 | | fundef -> fundef |
---|
32 | |
---|
33 | let simplify p = |
---|
34 | let f (id, fundef) = (id, simplify_fundef fundef) in |
---|
35 | { p with Clight.prog_funct = List.map f p.Clight.prog_funct } |
---|