@@ -10,7 +10,10 @@ module Vec = Basic_vec
1010
1111let slot = ref 0
1212let vfuncs: VFunc. t Vec. t = Vec. empty ()
13+ let globals: (string * int ) Vec. t = Vec. empty()
14+ let extarrs: extern_array Vec. t = Vec. empty ()
1315let vblocks: (string , VBlock. t) Hashtbl. t = Hashtbl. create 512
16+ let vloopvars: (string , Slot. t Vec. t) Hashtbl. t = Hashtbl. create 512
1417let slot_map: (string , Slot. t) Hashtbl. t = Hashtbl. create 2048
1518
1619(* We don't need to use stamp. *)
@@ -349,14 +352,45 @@ let gen_fn (f: fn) =
349352 };
350353
351354 let blocks = get_blocks f.fn in
355+ let bodies = Hashtbl. create 128 in
356+ let terminators = Hashtbl. create 128 in
357+ Hashtbl. clear phis;
352358 List. iter (fun x -> Hashtbl. add phis x (Vec. empty () )) blocks;
359+ List. iter (fun x -> Hashtbl. add vloopvars x (Vec. empty () )) blocks;
353360 List. iter (fun x ->
354361 let block = block_of x in
355362 let body = Vec. empty () in
356363 let term = ref (Term. Ret Unit ) in
357364 Vec. iter (convert_single x body term) block.body;
365+ Hashtbl. add bodies x body;
366+ Hashtbl. add terminators x ! term
367+ ) blocks;
368+
369+ Hashtbl. iter (fun name phi_insts ->
370+ (* Destruct phi instructions *)
371+ Vec. iter (fun ({ rd; rs } : phi ) ->
372+ List. iter (fun (v , from ) ->
373+ Vec. push (Hashtbl. find bodies from) (Inst. Mv { rd = slot_v rd; rs = slot_v v })
374+ ) rs
375+ ) phi_insts;
376+
377+ (* If this is loop head, record its loop variables for its predecessors *)
378+ if String. starts_with ~prefix: " loophead_" name then (
379+ let block = block_of name in
380+ Vec. iter (fun pred ->
381+ Vec. iter (fun ({ rd; _ } : phi ) ->
382+ Vec. push (Hashtbl. find vloopvars pred) (slot_v rd)
383+ ) (Hashtbl. find phis name)
384+ ) block.pred
385+ )
386+ ) phis;
387+
388+ List. iter (fun x ->
389+ let block = block_of x in
358390 Hashtbl. add vblocks x {
359- body; term = ! term; preds =
391+ body = Hashtbl. find bodies x;
392+ term = Hashtbl. find terminators x;
393+ preds =
360394 Vec. to_list block.pred
361395 |> List. map (fun pred ->
362396 (* The labels are fixed for loops in `riscv_generate.ml`. *)
@@ -370,9 +404,11 @@ let gen_fn (f: fn) =
370404 ) blocks;
371405 ()
372406
373- let gen_var v = ()
407+ let gen_var { name; ty } =
408+ Vec. push globals (name, sizeof ty)
374409
375- let gen_extarr arr = ()
410+ let gen_extarr arr =
411+ Vec. push extarrs arr
376412
377413(* * On calling this function, `ssa` must be coherent with basic block information in `opt` *)
378414let virtasm_of_ssa (ssa : Riscv_ssa.t list ) =
@@ -390,18 +426,20 @@ let virtasm_of_ssa (ssa : Riscv_ssa.t list) =
390426 Hashtbl. to_seq vblocks |> List. of_seq |> List. map (fun (k , v ) -> (label_of k, v))
391427 ) in
392428
429+ let loop_vars = Label.Map. of_list (
430+ Hashtbl. to_seq vloopvars |> List. of_seq |>
431+ List. map (fun (k , v ) -> (label_of k, SlotSet. of_list (Vec. to_list v)))
432+ ) in
433+
434+ let vprog = ({
435+ funcs; blocks;
436+ consts = Label.Map. empty;
437+ loop_vars;
438+ globals = Vec. to_list globals;
439+ extarrs = Vec. to_list extarrs;
440+ }: VProg. t) in
393441
394442 let out = Printf. sprintf " %s.vasm" ! Driver_config.Linkcore_Opt. output_file in
395- Basic_io. write out (String. concat " \n\n "
396- (Hashtbl. to_seq vblocks |> List. of_seq |>
397- List. map (fun (k , (v : VBlock.t )) -> Printf. sprintf " %s:\n %s%s%s" k (
398- String. concat " \n " (Vec. to_list v.body |> List. map Inst. to_string)
399- ) (if Vec. length v.body = 0 then " " else " \n " ) (Term. to_string v.term))
400- ));
443+ Basic_io. write out (VProg. to_string vprog);
444+ vprog
401445
402- ({
403- funcs; blocks;
404- consts = Label.Map. empty;
405- loop_vars = Label.Map. empty;
406- }: VProg. t)
407-
0 commit comments