source: Deliverables/D2.2/8051/src/RTL/RTLToERTL.ml @ 1542

Last change on this file since 1542 was 1542, checked in by tranquil, 8 years ago

merge of indexed labels branch

File size: 18.3 KB
RevLine 
[486]1
2(** This module provides a translation of [RTL] programs to [ERTL]
3    programs. *)
4
5
6let error_prefix = "RTL to ERTL"
7let error = Error.global_error error_prefix
8
9
10(* Helper functions *)
11
12let change_exit_label lbl def =
13  { def with ERTL.f_exit = lbl }
14
15let add_graph lbl stmt def =
16  { def with ERTL.f_graph = Label.Map.add lbl stmt def.ERTL.f_graph }
17
18let fresh_label def = Label.Gen.fresh def.ERTL.f_luniverse
19
20let change_label lbl = function
21  | ERTL.St_skip _ -> ERTL.St_skip lbl
22  | ERTL.St_comment (s, _) -> ERTL.St_comment (s, lbl)
23  | ERTL.St_cost (cost_lbl, _) -> ERTL.St_cost (cost_lbl, lbl)
[1542]24  | ERTL.St_ind_0 (i, _) -> ERTL.St_ind_0 (i, lbl)
25  | ERTL.St_ind_inc (i, _) -> ERTL.St_ind_inc (i, lbl)
[486]26  | ERTL.St_get_hdw (r1, r2, _) -> ERTL.St_get_hdw (r1, r2, lbl)
27  | ERTL.St_set_hdw (r1, r2, _) -> ERTL.St_set_hdw (r1, r2, lbl)
28  | ERTL.St_hdw_to_hdw (r1, r2, _) -> ERTL.St_hdw_to_hdw (r1, r2, lbl)
29  | ERTL.St_newframe _ -> ERTL.St_newframe lbl
30  | ERTL.St_delframe _ -> ERTL.St_delframe lbl
31  | ERTL.St_framesize (r, _) -> ERTL.St_framesize (r, lbl)
32  | ERTL.St_pop (r, _) -> ERTL.St_pop (r, lbl)
33  | ERTL.St_push (r, _) -> ERTL.St_push (r, lbl)
34  | ERTL.St_addrH (r, id, _) -> ERTL.St_addrH (r, id, lbl)
35  | ERTL.St_addrL (r, id, _) -> ERTL.St_addrL (r, id, lbl)
36  | ERTL.St_int (r, i, _) -> ERTL.St_int (r, i, lbl)
37  | ERTL.St_move (r1, r2, _) -> ERTL.St_move (r1, r2, lbl)
[818]38  | ERTL.St_opaccsA (opaccs, dstr, srcr1, srcr2, _) ->
39    ERTL.St_opaccsA (opaccs, dstr, srcr1, srcr2, lbl)
40  | ERTL.St_opaccsB (opaccs, dstr, srcr1, srcr2, _) ->
41    ERTL.St_opaccsB (opaccs, dstr, srcr1, srcr2, lbl)
[486]42  | ERTL.St_op1 (op1, dstr, srcr, _) -> ERTL.St_op1 (op1, dstr, srcr, lbl)
43  | ERTL.St_op2 (op2, dstr, srcr1, srcr2, _) ->
44    ERTL.St_op2 (op2, dstr, srcr1, srcr2, lbl)
45  | ERTL.St_clear_carry _ -> ERTL.St_clear_carry lbl
[818]46  | ERTL.St_set_carry _ -> ERTL.St_set_carry lbl
[486]47  | ERTL.St_load (dstrs, addr1, addr2, _) ->
48    ERTL.St_load (dstrs, addr1, addr2, lbl)
49  | ERTL.St_store (addr1, addr2, srcrs, _) ->
50    ERTL.St_store (addr1, addr2, srcrs, lbl)
51  | ERTL.St_call_id (f, nb_args, _) -> ERTL.St_call_id (f, nb_args, lbl)
[1462]52  | ERTL.St_call_ptr (f1, f2, nb_args, _) ->
53    ERTL.St_call_ptr (f1, f2, nb_args, lbl)
[818]54  | ERTL.St_cond _ as inst -> inst
[486]55  | ERTL.St_return _ as inst -> inst
56
57(* Add a list of instruction in a graph, from one label to another, by creating
58   fresh labels inbetween. *)
59
60let rec adds_graph stmt_list start_lbl dest_lbl def = match stmt_list with
[818]61  | [] -> add_graph start_lbl (ERTL.St_skip dest_lbl) def
[486]62  | [stmt] ->
63    add_graph start_lbl (change_label dest_lbl stmt) def
64  | stmt :: stmt_list ->
65    let tmp_lbl = fresh_label def in
66    let stmt = change_label tmp_lbl stmt in
67    let def = add_graph start_lbl stmt def in
68    adds_graph stmt_list tmp_lbl dest_lbl def
69
70(* Process a list of function that adds a list of instructions to a graph, from
71   one label to another, and by creating fresh labels inbetween. *)
72
73let rec add_translates translate_list start_lbl dest_lbl def =
74  match translate_list with
[818]75    | [] -> add_graph start_lbl (ERTL.St_skip dest_lbl) def
[486]76    | [trans] -> trans start_lbl dest_lbl def
77    | trans :: translate_list ->
78      let tmp_lbl = fresh_label def in
79      let def = trans start_lbl tmp_lbl def in
80      add_translates translate_list tmp_lbl dest_lbl def
81
82let fresh_reg def =
83  let r = Register.fresh def.ERTL.f_runiverse in
84  let locals = Register.Set.add r def.ERTL.f_locals in
85  ({ def with ERTL.f_locals = locals }, r)
86
87let rec fresh_regs def n =
88  if n = 0 then (def, [])
89  else
90    let (def, res) = fresh_regs def (n-1) in
91    let (def, r) = fresh_reg def in
92    (def, r :: res)
93
94
95(* Translation *)
96
97let save_hdws l =
98  let f (destr, srcr) start_lbl =
99    adds_graph [ERTL.St_get_hdw (destr, srcr, start_lbl)] start_lbl in
100  List.map f l
101
102let restore_hdws l =
103  let f (destr, srcr) start_lbl =
104    adds_graph [ERTL.St_set_hdw (destr, srcr, start_lbl)] start_lbl in
105  List.map f (List.map (fun (x, y) -> (y, x)) l)
106
107let get_params_hdw params =
108  if List.length params = 0 then
109    [fun start_lbl -> adds_graph [ERTL.St_skip start_lbl] start_lbl]
110  else
111    let l = MiscPottier.combine params I8051.parameters in
112    save_hdws l
113
114let get_param_stack off destr start_lbl dest_lbl def =
115  let (def, addr1) = fresh_reg def in
116  let (def, addr2) = fresh_reg def in
117  let (def, tmpr) = fresh_reg def in
118  adds_graph
[740]119    [ERTL.St_framesize (addr1, start_lbl) ;
[486]120     ERTL.St_int (tmpr, off+I8051.int_size, start_lbl) ;
[740]121     ERTL.St_op2 (I8051.Sub, addr1, addr1, tmpr, start_lbl) ;
[486]122     ERTL.St_get_hdw (tmpr, I8051.spl, start_lbl) ;
[740]123     ERTL.St_op2 (I8051.Add, addr1, addr1, tmpr, start_lbl) ;
124     ERTL.St_int (addr2, 0, start_lbl) ;
[486]125     ERTL.St_get_hdw (tmpr, I8051.sph, start_lbl) ;
[740]126     ERTL.St_op2 (I8051.Addc, addr2, addr2, tmpr, start_lbl) ;
[486]127     ERTL.St_load (destr, addr1, addr2, start_lbl)]
128    start_lbl dest_lbl def
129
130let get_params_stack params =
131  if List.length params = 0 then
132    [fun start_lbl -> adds_graph [ERTL.St_skip start_lbl] start_lbl]
133  else
134    let f i r = get_param_stack i r in
135    MiscPottier.mapi f params
136
137(* Parameters are taken from the physical parameter registers first. If there
138   are not enough such of these, then the remaining parameters are taken from
139   the stack. *)
140
141let get_params params =
142  let n = min (List.length params) (List.length I8051.parameters) in
143  let (hdw_params, stack_params) = MiscPottier.split params n in
144  (get_params_hdw hdw_params) @ (get_params_stack stack_params)
145
[740]146let add_prologue params sral srah sregs def =
[486]147  let start_lbl = def.ERTL.f_entry in
148  let tmp_lbl = fresh_label def in
149  let last_stmt = Label.Map.find start_lbl def.ERTL.f_graph in
150  let def =
151    add_translates
152      ([adds_graph [ERTL.St_comment ("Prologue", start_lbl)]] @
153       (* new frame *)
154       (adds_graph [ERTL.St_comment ("New frame", start_lbl) ;
155                    ERTL.St_newframe start_lbl]) ::
156       (* save the return address *)
157       (adds_graph [ERTL.St_comment ("Save return address", start_lbl) ;
158                    ERTL.St_pop (sral, start_lbl) ;
159                    ERTL.St_pop (srah, start_lbl)]) ::
160       (* save callee-saved registers *)
161       [adds_graph [ERTL.St_comment ("Save callee-saved registers",
162                                     start_lbl)]] @
163       (save_hdws sregs) @
164       (* fetch parameters *)
165       [adds_graph [ERTL.St_comment ("Fetch parameters", start_lbl)]] @
166       (get_params params) @
167       [adds_graph [ERTL.St_comment ("End Prologue", start_lbl)]])
168      start_lbl tmp_lbl def in
169  add_graph tmp_lbl last_stmt def
170
171
172(* Save the result of a function in a place that cannot be written, even after
173   register allocation. This way, the cleaning sequence of returning from a
174   function will not interfere with the result value, that can be restored right
175   before jumping out of the function. *)
176
[818]177let save_return ret_regs start_lbl dest_lbl def =
178  let (def, tmpr) = fresh_reg def in
179  let ((common1, rest1), (common2, _)) =
180    MiscPottier.reduce I8051.sts ret_regs in
181  let init_tmpr = ERTL.St_int (tmpr, 0, start_lbl) in
182  let f_save st r = ERTL.St_set_hdw (st, r, start_lbl) in
183  let saves = List.map2 f_save common1 common2 in
184  let f_default st = ERTL.St_set_hdw (st, tmpr, start_lbl) in
185  let defaults = List.map f_default rest1 in
186  adds_graph (init_tmpr :: saves @ defaults) start_lbl dest_lbl def
[486]187
[818]188let assign_result start_lbl =
189  let ((common1, _), (common2, _)) = MiscPottier.reduce I8051.rets I8051.sts in
190  let f ret st = ERTL.St_hdw_to_hdw (ret, st, start_lbl) in
191  let insts = List.map2 f common1 common2 in
192  adds_graph insts start_lbl
193
[740]194let add_epilogue ret_regs sral srah sregs def =
[486]195  let start_lbl = def.ERTL.f_exit in
196  let tmp_lbl = fresh_label def in
197  let last_stmt = Label.Map.find start_lbl def.ERTL.f_graph in
198  let def =
199    add_translates
200      ([adds_graph [ERTL.St_comment ("Epilogue", start_lbl)]] @
201       (* save return value *)
[818]202       [save_return ret_regs] @
[486]203       (* restore callee-saved registers *)
204       [adds_graph [ERTL.St_comment ("Restore callee-saved registers",
205                                     start_lbl)]] @
206       (restore_hdws sregs) @
207       (* restore the return address *)
208       [adds_graph [ERTL.St_comment ("Restore return address", start_lbl) ;
209                    ERTL.St_push (srah, start_lbl) ;
210                    ERTL.St_push (sral, start_lbl)]] @
211       (* delete frame *)
212       [adds_graph [ERTL.St_comment ("Delete frame", start_lbl) ;
213                    ERTL.St_delframe start_lbl]] @
214       (* assign the result to actual return registers *)
215       [adds_graph [ERTL.St_comment ("Set result", start_lbl)]] @
[818]216       [assign_result] @
217       [adds_graph [ERTL.St_comment ("End Epilogue", start_lbl)]])
[486]218      start_lbl tmp_lbl def in
219  let def = add_graph tmp_lbl last_stmt def in
220  change_exit_label tmp_lbl def
221
222
223let allocate_regs saved def =
224  let f r (def, sregs) =
225    let (def, r') = fresh_reg def in
226    (def, (r', r) :: sregs) in
227  I8051.RegisterSet.fold f saved (def, [])
228
229let add_pro_and_epilogue params ret_regs def =
230  (* Allocate registers to hold the return address. *)
231  let (def, sra) = fresh_regs def 2 in
[740]232  let sral = List.nth sra 0 in
233  let srah = List.nth sra 1 in
[486]234  (* Allocate registers to save callee-saved registers. *)
235  let (def, sregs) = allocate_regs I8051.callee_saved def in
236  (* Add a prologue and a epilogue. *)
[740]237  let def = add_prologue params sral srah sregs def in
238  let def = add_epilogue ret_regs sral srah sregs def in
[486]239  def
240
241
242let set_params_hdw params =
243  if List.length params = 0 then
244    [fun start_lbl -> adds_graph [ERTL.St_skip start_lbl] start_lbl]
245  else
246    let l = MiscPottier.combine params I8051.parameters in
247    restore_hdws l
248
249let set_param_stack off srcr start_lbl dest_lbl def =
250  let (def, addr1) = fresh_reg def in
251  let (def, addr2) = fresh_reg def in
252  let (def, tmpr) = fresh_reg def in
253  adds_graph
[818]254    [ERTL.St_int (addr1, off+I8051.int_size, start_lbl) ;
[486]255     ERTL.St_get_hdw (tmpr, I8051.spl, start_lbl) ;
256     ERTL.St_clear_carry start_lbl ;
[740]257     ERTL.St_op2 (I8051.Sub, addr1, tmpr, addr1, start_lbl) ;
258     ERTL.St_get_hdw (tmpr, I8051.sph, start_lbl) ;
259     ERTL.St_int (addr2, 0, start_lbl) ;
[486]260     ERTL.St_op2 (I8051.Sub, addr2, tmpr, addr2, start_lbl) ;
261     ERTL.St_store (addr1, addr2, srcr, start_lbl)]
262    start_lbl dest_lbl def
263
264let set_params_stack params =
265  if List.length params = 0 then
266    [fun start_lbl -> adds_graph [ERTL.St_skip start_lbl] start_lbl]
267  else
268    let f i r = set_param_stack i r in
269    MiscPottier.mapi f params
270
271(* Parameters are put in the physical parameter registers first. If there are
272   not enough such of these, then the remaining parameters are passed on the
273   stack. *)
274
275let set_params params =
276  let n = min (List.length params) (List.length I8051.parameters) in
277  let (hdw_params, stack_params) = MiscPottier.split params n in
278  (set_params_hdw hdw_params) @ (set_params_stack stack_params)
279
280(* Fetching the result depends on the type of the function, or say, the number
[619]281   of registers that are waiting for a value. Temporary non allocatable
282   registers are used. Indeed, moving directly from DPL to a pseudo-register may
283   cause a bug: DPL might be used to compute the address of the
284   pseudo-register. *)
[486]285
[818]286let fetch_result ret_regs start_lbl =
287  let ((common1, _), (common2, _)) = MiscPottier.reduce I8051.sts I8051.rets in
288  let f_save st ret = ERTL.St_hdw_to_hdw (st, ret, start_lbl) in
289  let saves = List.map2 f_save common1 common2 in
290  let ((common1, _), (common2, _)) = MiscPottier.reduce ret_regs I8051.sts in
291  let f_restore r st = ERTL.St_get_hdw (r, st, start_lbl) in
292  let restores = List.map2 f_restore common1 common2 in
293  adds_graph (saves @ restores) start_lbl
[486]294
295(* When calling a function, we need to set its parameters in specific locations:
296   the physical parameter registers as much as possible, and then the stack
297   below. When the called function returns, we put the result where the calling
298   function expect it to be. *)
[1462]299let translate_call stmt args ret_regs start_lbl dest_lbl def =
[486]300  let nb_args = List.length args in
301  add_translates
302    ([adds_graph [ERTL.St_comment ("Starting a call", start_lbl)] ;
303      adds_graph [ERTL.St_comment ("Setting up parameters", start_lbl)]] @
[818]304     set_params args @
[1462]305     [adds_graph [stmt nb_args] ;
[818]306      adds_graph [ERTL.St_comment ("Fetching result", start_lbl)] ;
307      fetch_result ret_regs ;
308      adds_graph [ERTL.St_comment ("End of call sequence", start_lbl)]])
[486]309    start_lbl dest_lbl def
310
311(*
312  let translate_tailcall_id f args start_lbl def = def (* TODO *)
313*)
314
315let translate_stmt lbl stmt def = match stmt with
316
317  | RTL.St_skip lbl' ->
318    add_graph lbl (ERTL.St_skip lbl') def
319
320  | RTL.St_cost (cost_lbl, lbl') ->
321    add_graph lbl (ERTL.St_cost (cost_lbl, lbl')) def
322
[1542]323  | RTL.St_ind_0 (i, lbl') ->
324    add_graph lbl (ERTL.St_ind_0 (i, lbl')) def
325
326  | RTL.St_ind_inc (i, lbl') ->
327    add_graph lbl (ERTL.St_ind_inc (i, lbl')) def
328
[486]329  | RTL.St_addr (r1, r2, x, lbl') ->
330    adds_graph
[740]331      [ERTL.St_addrL (r1, x, lbl) ; ERTL.St_addrH (r2, x, lbl) ;]
[486]332      lbl lbl' def
333
334  | RTL.St_stackaddr (r1, r2, lbl') ->
335    adds_graph
[740]336      [ERTL.St_get_hdw (r1, I8051.spl, lbl) ;
337       ERTL.St_get_hdw (r2, I8051.sph, lbl)]
[486]338      lbl lbl' def
339
340  | RTL.St_int (r, i, lbl') ->
341    add_graph lbl (ERTL.St_int (r, i, lbl')) def
342
343  | RTL.St_move (r1, r2, lbl') ->
344    add_graph lbl (ERTL.St_move (r1, r2, lbl')) def
345
[818]346  | RTL.St_opaccs (op, destr1, destr2, srcr1, srcr2, lbl') ->
347    adds_graph [ERTL.St_opaccsA (op, destr1, srcr1, srcr2, lbl) ;
348                ERTL.St_opaccsB (op, destr2, srcr1, srcr2, lbl) ;]
349      lbl lbl' def
[486]350
351  | RTL.St_op1 (op1, destr, srcr, lbl') ->
352    add_graph lbl (ERTL.St_op1 (op1, destr, srcr, lbl')) def
353
354  | RTL.St_op2 (op2, destr, srcr1, srcr2, lbl') ->
355    add_graph lbl (ERTL.St_op2 (op2, destr, srcr1, srcr2, lbl')) def
356
357  | RTL.St_clear_carry lbl' ->
358    add_graph lbl (ERTL.St_clear_carry lbl') def
359
[818]360  | RTL.St_set_carry lbl' ->
361    add_graph lbl (ERTL.St_set_carry lbl') def
362
[486]363  | RTL.St_load (destr, addr1, addr2, lbl') ->
364    add_graph lbl (ERTL.St_load (destr, addr1, addr2, lbl')) def
365
366  | RTL.St_store (addr1, addr2, srcr, lbl') ->
367    add_graph lbl (ERTL.St_store (addr1, addr2, srcr, lbl')) def
368
369  | RTL.St_call_id (f, args, ret_regs, lbl') ->
[1462]370    let stmt nb_args = ERTL.St_call_id (f, nb_args, lbl) in
371    translate_call stmt args ret_regs lbl lbl' def
[486]372
[1462]373  | RTL.St_call_ptr (f1, f2, args, ret_regs, lbl') ->
374    let stmt nb_args = ERTL.St_call_ptr (f1, f2, nb_args, lbl) in
375    translate_call stmt args ret_regs lbl lbl' def
[486]376
377  (*
378    | RTL.St_tailcall_id (f, args) ->
379    translate_tailcall_id f args lbl def
380
381    | RTL.St_tailcall_ptr _ ->
382    def (* TODO *)
383  *)
384
[818]385  | RTL.St_cond (srcr, lbl_true, lbl_false) ->
386    add_graph lbl (ERTL.St_cond (srcr, lbl_true, lbl_false)) def
[486]387
388  | RTL.St_return ret_regs ->
389    add_graph lbl (ERTL.St_return ret_regs) def
390
391  | RTL.St_tailcall_id _ | RTL.St_tailcall_ptr _ ->
392    assert false (* impossible: the RTL program is supposed to be simplified:
393                    no tailcalls. *)
394
395
396let translate_internal def =
397  let nb_params = List.length (def.RTL.f_params) in
398  (* The stack size is augmented by the number of parameters that cannot fit
399     into physical registers. *)
400  let added_stacksize = max 0 (nb_params - (List.length I8051.parameters)) in
401  let def' =
402    { ERTL.f_luniverse = def.RTL.f_luniverse ;
403      ERTL.f_runiverse = def.RTL.f_runiverse ;
404      ERTL.f_params    = nb_params ;
405      (* ERTL does not know about parameter registers. We need to add them to
406         the locals. *)
407      ERTL.f_locals    = Register.Set.union def.RTL.f_locals
408                         (Register.Set.of_list def.RTL.f_params) ;
409      ERTL.f_stacksize = def.RTL.f_stacksize + added_stacksize ;
410      ERTL.f_graph     = Label.Map.empty ;
411      ERTL.f_entry     = def.RTL.f_entry ;
412      ERTL.f_exit      = def.RTL.f_exit } in
413  let def' = Label.Map.fold translate_stmt def.RTL.f_graph def' in
414  let def' = add_pro_and_epilogue def.RTL.f_params def.RTL.f_result def' in
415  def'
416
417
418let translate_funct (id, def) =
419  let def' = match def with
420    | RTL.F_int def -> ERTL.F_int (translate_internal def)
421    | RTL.F_ext def -> ERTL.F_ext def
422  in
423  (id, def')
424
425
[619]426(* Move the first cost label of each function at the beginning of the
427   function. Indeed, the instructions for calling conventions (stack allocation
428   for example) are added at the very beginning of the function, thus before the
429   first cost label. *)
430
431let generate stmt def =
432  let entry = Label.Gen.fresh def.ERTL.f_luniverse in
433  let def =
434    { def with ERTL.f_graph = Label.Map.add entry stmt def.ERTL.f_graph } in
435  { def with ERTL.f_entry = entry }
436
437let find_and_remove_first_cost_label def =
438  let rec aux lbl = match Label.Map.find lbl def.ERTL.f_graph with
439    | ERTL.St_cost (cost_label, next_lbl) ->
440      let graph = Label.Map.add lbl (ERTL.St_skip next_lbl) def.ERTL.f_graph in
[624]441      (Some cost_label, { def with ERTL.f_graph = graph })
[1542]442    | ERTL.St_ind_0 (_, lbl) | ERTL.St_ind_inc (_, lbl)
[619]443    | ERTL.St_skip lbl | ERTL.St_comment (_, lbl) | ERTL.St_get_hdw (_, _, lbl)
444    | ERTL.St_set_hdw (_, _, lbl) | ERTL.St_hdw_to_hdw (_, _, lbl)
445    | ERTL.St_pop (_, lbl) | ERTL.St_push (_, lbl) | ERTL.St_addrH (_, _, lbl)
446    | ERTL.St_addrL (_, _, lbl) | ERTL.St_int (_, _, lbl)
[818]447    | ERTL.St_move (_, _, lbl) | ERTL.St_opaccsA (_, _, _, _, lbl)
448    | ERTL.St_opaccsB (_, _, _, _, lbl)
[619]449    | ERTL.St_op1 (_, _, _, lbl) | ERTL.St_op2 (_, _, _, _, lbl)
[818]450    | ERTL.St_clear_carry lbl | ERTL.St_set_carry lbl
451    | ERTL.St_load (_, _, _, lbl)
[619]452    | ERTL.St_store (_, _, _, lbl) | ERTL.St_call_id (_, _, lbl)
[1462]453    | ERTL.St_call_ptr (_, _, _, lbl)
[619]454    | ERTL.St_newframe lbl | ERTL.St_delframe lbl | ERTL.St_framesize (_, lbl)
455      ->
456      aux lbl
[818]457    | ERTL.St_cond _ | ERTL.St_return _ ->
[624]458      (* No cost label found (no labelling performed). Indeed, the first cost
459         label must after some linear instructions. *)
460      (None, def) in
[619]461  aux def.ERTL.f_entry
462
463let move_first_cost_label_up_internal def =
464  let (cost_label, def) = find_and_remove_first_cost_label def in
[624]465  match cost_label with
466    | None -> def
467    | Some cost_label ->
468      generate (ERTL.St_cost (cost_label, def.ERTL.f_entry)) def
[619]469
470let move_first_cost_label_up (id, def) =
471  let def' = match def with
472    | ERTL.F_int int_fun ->
473      ERTL.F_int (move_first_cost_label_up_internal int_fun)
474    | _ -> def in
475  (id, def')
476
477
[486]478let translate p =
479  (* We simplify tail calls as regular calls for now. *)
480  let p = RTLtailcall.simplify p in
[619]481  (* The tranformation on each RTL function: create an ERTL function and move
482     its first cost label at the very beginning. *)
483  let f funct = move_first_cost_label_up (translate_funct funct) in
[486]484  { ERTL.vars   = p.RTL.vars ;
[619]485    ERTL.functs = List.map f p.RTL.functs ;
[486]486    ERTL.main   = p.RTL.main }
Note: See TracBrowser for help on using the repository browser.