Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

lustrec / src / optimize_machine.ml @ b38ffff3

History | View | Annotate | Download (4.4 KB)

1
(********************************************************************)
2
(*                                                                  *)
3
(*  The LustreC compiler toolset   /  The LustreC Development Team  *)
4
(*  Copyright 2012 -    --   ONERA - CNRS - INPT                    *)
5
(*                                                                  *)
6
(*  LustreC is free software, distributed WITHOUT ANY WARRANTY      *)
7
(*  under the terms of the GNU Lesser General Public License        *)
8
(*  version 2.1.                                                    *)
9
(*                                                                  *)
10
(********************************************************************)
11

    
12
open LustreSpec 
13
open Corelang
14
open Machine_code 
15

    
16
let rec eliminate elim instr =
17
  let e_expr = eliminate_expr elim in
18
  match instr with  
19
  | MLocalAssign (i,v) -> MLocalAssign (i, e_expr v)
20
  | MStateAssign (i,v) -> MStateAssign (i, e_expr v)
21
  | MReset i           -> instr
22
  | MStep (il, i, vl)  -> MStep(il, i, List.map e_expr vl)
23
  | MBranch (g,hl)     -> 
24
    MBranch
25
      (e_expr g, 
26
       (List.map 
27
	  (fun (l, il) -> l, List.map (eliminate elim) il) 
28
	  hl
29
       )
30
      )
31
    
32
and eliminate_expr elim expr =
33
  match expr with
34
  | LocalVar v -> if List.mem_assoc v elim then List.assoc v elim else expr
35
  | Fun (id, vl) -> Fun (id, List.map (eliminate_expr elim) vl)
36
  | Array(vl) -> Array(List.map (eliminate_expr elim) vl)
37
  | Access(v1, v2) -> Access(eliminate_expr elim v1, eliminate_expr elim v2)
38
  | Power(v1, v2) -> Access(eliminate_expr elim v1, eliminate_expr elim v2)
39
  | Cst _ | StateVar _ -> expr
40

    
41
(* see if elim has to take in account the provided instr:
42
   if so, upodate elim and return the remove flag,
43
   otherwise, the expression should be kept and elim is left untouched *)
44
let update_elim outputs elim instr =
45
(*  Format.eprintf "SHOULD WE STORE THE EXPRESSION IN INSTR %a TO ELIMINATE IT@." pp_instr instr;*)
46
	  
47
  let apply elim v new_e = 
48
    (v, new_e)::List.map (fun (v, e) -> v, eliminate_expr [v, new_e] e) elim 
49
  in
50
  match instr with
51
  (* Simple cases*)
52
  | MLocalAssign (v, (Cst _ as e)) 
53
  | MLocalAssign (v, (LocalVar _ as e)) 
54
  | MLocalAssign (v, (StateVar _ as e)) -> 
55
    if not (List.mem v outputs) then  true, apply elim v e else false, elim
56
  (* When optimization >= 3, we also inline any basic operator call. 
57
     All those are returning a single ouput *)
58
  | MStep([v], id, vl) when
59
      Basic_library.is_internal_fun id
60
      && !Options.optimization >= 3
61
      -> 	  assert false 
62
(*    true, apply elim v (Fun(id, vl))*)
63

    
64
    
65
  | MLocalAssign (v, ((Fun (id, il)) as e)) when 
66
      not (List.mem v outputs) 
67
      && Basic_library.is_internal_fun id (* this will avoid inlining ite *)
68
      && !Options.optimization >= 3 
69
	-> (
70
(*	  Format.eprintf "WE STORE THE EXPRESSION DEFINING %s TO ELIMINATE IT@." v.var_id; *)
71
	  true, apply elim v e
72
	)
73
  | _ -> 
74
    (* default case, we keep the instruction and do not modify elim *)
75
    false, elim
76
  
77

    
78
(** We iterate in the order, recording simple local assigns in an accumulator
79
    1. each expression is rewritten according to the accumulator
80
    2. local assigns then rewrite occurrences of the lhs in the computed accumulator
81
*)
82
let optimize_minstrs outputs instrs = 
83
  let rev_instrs, eliminate = 
84
    List.fold_left (fun (rinstrs, elim) instr ->
85
      (* each subexpression in instr that could be rewritten by the elim set is
86
	 rewritten *)
87
      let instr = eliminate elim instr in
88
      (* if instr is a simple local assign, then (a) elim is simplified with it (b) it
89
	 is stored as the elim set *)
90
      let remove, elim = update_elim outputs elim instr in
91
      (if remove then rinstrs else instr::rinstrs), elim
92
    ) ([],[]) instrs 
93
  in
94
  let eliminated_vars = List.map fst eliminate in
95
  eliminated_vars, List.rev rev_instrs
96

    
97
(** Perform optimization on machine code:
98
    - iterate through step instructions and remove simple local assigns
99
    
100
*)
101
let optimize_machine machine =
102
  let eliminated_vars, new_instrs = optimize_minstrs machine.mstep.step_outputs machine.mstep.step_instrs in
103
  let new_locals = 
104
    List.filter (fun v -> not (List.mem v eliminated_vars)) machine.mstep.step_locals 
105
  in
106
  {
107
    machine with
108
      mstep = { 
109
	machine.mstep with 
110
	  step_locals = new_locals;
111
	  step_instrs = new_instrs
112
      }
113
  }
114
    
115

    
116

    
117
let optimize_machines machines =
118
  List.map optimize_machine machines
119

    
120

    
121
(* Local Variables: *)
122
(* compile-command:"make -C .." *)
123
(* End: *)