Better styling for miniImp

This commit is contained in:
elvis
2025-01-27 01:17:53 +01:00
parent 5e8b339440
commit 4ab0b40cca
10 changed files with 677 additions and 360 deletions

View File

@ -71,20 +71,20 @@ let reduceregisters (n: int) (cfg: RISCCfg.t) : RISCCfg.t =
match cfg.inputOutputVar with
| None -> all_variables
| Some (i, _o) -> (
match List.assoc_opt i all_variables with
| None -> (i, 1) :: all_variables
| Some f -> (i, f+1) :: (List.remove_assoc i all_variables)
)
match List.assoc_opt i all_variables with
| None -> (i, 1) :: all_variables
| Some f -> (i, f+1) :: (List.remove_assoc i all_variables)
)
in
let all_variables =
match cfg.inputOutputVar with
| None -> all_variables
| Some (_i, o) -> (
match List.assoc_opt o all_variables with
| None -> (o, 1) :: all_variables
| Some f -> (o, f+1) :: (List.remove_assoc o all_variables)
)
match List.assoc_opt o all_variables with
| None -> (o, 1) :: all_variables
| Some f -> (o, f+1) :: (List.remove_assoc o all_variables)
)
in
(* replace each operation with a list of operations that have the new
@ -181,7 +181,7 @@ let reduceregisters (n: int) (cfg: RISCCfg.t) : RISCCfg.t =
Store (tmpreg2, tmpreg1)]
| _ -> failwith ("ReduceRegisters: fail to partition a set, some" ^
" registers have no binding.")
)
)
| URegOp (urop, r1, r3) ->(
match ( VariableMap.find_opt r1.index remappedregisters,
VariableMap.find_opt r3.index remappedregisters,
@ -274,7 +274,7 @@ let reduceregisters (n: int) (cfg: RISCCfg.t) : RISCCfg.t =
Store (tmpreg2, tmpreg1)]
| _ -> failwith ("ReduceRegisters: fail to partition a set, some" ^
" registers have no binding.")
)
)
in
List.map aux code |> List.concat
@ -289,14 +289,16 @@ let reduceregisters (n: int) (cfg: RISCCfg.t) : RISCCfg.t =
List.sort (fun (_a, fa) (_b, fb) -> Int.compare fb fa) all_variables
|> Utility.take (n-2)
in
let most_frequent = fst (List.split most_frequent) in
let least_frequent = fst (List.split least_frequent) in
let most_frequent, _frequencies = List.split most_frequent in
let least_frequent, _frequencies = List.split least_frequent in
(* we map the most frequent to new registers, so that the first two are
always free *)
let most_frequent_mapping = (* +3 because starts at 0, but we want to start
at 1*)
List.mapi (fun n v -> (v, (string_of_int (n+3): Variable.t))) most_frequent
List.mapi
(fun n v -> (v, (string_of_int (n+3): Variable.t)))
most_frequent
|> VariableMap.of_list
in
(* we map the least to memory *)
@ -321,119 +323,120 @@ let reduceregisters (n: int) (cfg: RISCCfg.t) : RISCCfg.t =
) cfg.content}
in
match newcfg.inputOutputVar with
| None -> newcfg (* if no input or output variables we ignore *)
| Some (i, o) -> (
match (VariableMap.find_opt i most_frequent_mapping,
VariableMap.find_opt o most_frequent_mapping,
VariableMap.find_opt i least_frequent_mapping,
VariableMap.find_opt o least_frequent_mapping )
with (*we check if in and out are simply remapped or are put in memory*)
| Some i, Some o, _, _ ->
{ newcfg with inputOutputVar = Some (i, o) }
| Some i, None, _, Some mo -> ( (* since the output simbol is in memory
we need to first retrive it and then
put the result in a temporary
register *)
match newcfg.terminal with (* we check for the terminal node, if not
present we are very confused and dont
modify the out variable *)
| None -> { newcfg with inputOutputVar = Some (i, o)}
| Some n -> (
let terminalcontent = (
match Cfg.NodeMap.find_opt n newcfg.content with
| None -> []
| Some x -> x
) @ [LoadI (mo, {index = "2"});
Load ({index = "2"}, {index = "2"})]
in
let content = Cfg.NodeMap.add n terminalcontent newcfg.content in
{ newcfg with
inputOutputVar = Some (i, "2");
content = content
}
)
if newcfg.inputOutputVar = None
then newcfg (* if no input or output variables we ignore *)
else
let i, o = Option.get newcfg.inputOutputVar in
match (VariableMap.find_opt i most_frequent_mapping,
VariableMap.find_opt o most_frequent_mapping,
VariableMap.find_opt i least_frequent_mapping,
VariableMap.find_opt o least_frequent_mapping,
newcfg.initial,
newcfg.terminal )
with (*we check if in and out are simply remapped or are put in memory*)
| Some i, Some o, _, _, _, _ ->
{ newcfg with inputOutputVar = Some (i, o) }
| Some i, None, _, Some _, _, None ->
(* we check for the terminal node, if not present we are very confused
and dont modify the out variable *)
{ newcfg with inputOutputVar = Some (i, o)}
| Some i, None, _, Some mo, _, Some n ->
(* since the output simbol is in memory we need to first retrive it
and then put the result in a temporary register *)
let terminalcontent = (
match Cfg.NodeMap.find_opt n newcfg.content with
| None -> []
| Some x -> x
) @ [LoadI (mo, {index = "2"});
Load ({index = "2"}, {index = "2"})]
in
let content =
Cfg.NodeMap.add n terminalcontent newcfg.content
in
{ newcfg with
inputOutputVar = Some (i, "2");
content = content
}
| None, Some o, Some _, _, _, None ->
{ newcfg with inputOutputVar = Some (i, o) }
| None, Some o, Some mi, _, _, Some n -> (
(* the input simbol should be stored in memory *)
let initialcontent =
[(LoadI (mi, {index = "2"}) : RISCCfg.elt);
Store ({index = "1"}, {index = "2"})] @ (
match Cfg.NodeMap.find_opt n newcfg.content with
| None -> []
| Some x -> x
)
in
let content = Cfg.NodeMap.add n initialcontent newcfg.content in
{ newcfg with
inputOutputVar = Some ("1", o);
content = content
}
)
| None, None, Some _, Some _, None, None ->
{ newcfg with inputOutputVar = Some (i, o) }
| None, None, Some _, Some mo, None, Some n ->
(* both simbols should be in memory *)
let terminalcontent = (
match Cfg.NodeMap.find_opt n newcfg.content with
| None -> []
| Some x -> x
) @ [LoadI (mo, {index = "2"});
Load ({index = "2"}, {index = "2"})]
in
let content =
Cfg.NodeMap.add n terminalcontent newcfg.content
in
{ newcfg with
inputOutputVar = Some (i, "2");
content = content
}
| None, None, Some mi, Some _, Some n, None ->
(* both simbols should be in memory *)
let initialcontent =
[(LoadI (mi, {index = "2"}) : RISCCfg.elt);
Store ({index = "1"}, {index = "2"})] @ (
match Cfg.NodeMap.find_opt n newcfg.content with
| None -> []
| Some x -> x
)
| None, Some o, Some mi, _ -> ( (* the input simbol should be stored in
memory *)
match newcfg.initial with
| None -> { newcfg with inputOutputVar = Some (i, o) }
| Some n -> (
let initialcontent =
[(LoadI (mi, {index = "2"}) : RISCCfg.elt);
Store ({index = "1"}, {index = "2"})] @ (
match Cfg.NodeMap.find_opt n newcfg.content with
| None -> []
| Some x -> x
)
in
let content = Cfg.NodeMap.add n initialcontent newcfg.content in
{ newcfg with
inputOutputVar = Some ("1", o);
content = content
}
)
in
let content = Cfg.NodeMap.add n initialcontent newcfg.content in
{ newcfg with
inputOutputVar = Some ("1", o);
content = content
}
| None, None, Some mi, Some mo, Some ni, Some no ->
(* both simbols should be in memory *)
let initialcontent =
[(LoadI (mi, {index = "2"}) : RISCCfg.elt);
Store ({index = "1"}, {index = "2"})] @ (
match Cfg.NodeMap.find_opt ni newcfg.content with
| None -> []
| Some x -> x
)
| None, None, Some mi, Some mo -> ( (* both simbols should be in
memory *)
match newcfg.initial, newcfg.terminal with
| None, None -> { newcfg with inputOutputVar = Some (i, o) }
| None, Some n -> (
let terminalcontent = (
match Cfg.NodeMap.find_opt n newcfg.content with
| None -> []
| Some x -> x
) @ [LoadI (mo, {index = "2"});
Load ({index = "2"}, {index = "2"})]
in
let content = Cfg.NodeMap.add n terminalcontent newcfg.content in
{ newcfg with
inputOutputVar = Some (i, "2");
content = content
}
)
| Some n, None -> (
let initialcontent =
[(LoadI (mi, {index = "2"}) : RISCCfg.elt);
Store ({index = "1"}, {index = "2"})] @ (
match Cfg.NodeMap.find_opt n newcfg.content with
| None -> []
| Some x -> x
)
in
let content = Cfg.NodeMap.add n initialcontent newcfg.content in
{ newcfg with
inputOutputVar = Some ("1", o);
content = content
}
)
| Some ni, Some no -> (
let initialcontent =
[(LoadI (mi, {index = "2"}) : RISCCfg.elt);
Store ({index = "1"}, {index = "2"})] @ (
match Cfg.NodeMap.find_opt ni newcfg.content with
| None -> []
| Some x -> x
)
in
let terminalcontent = (
match Cfg.NodeMap.find_opt no newcfg.content with
| None -> []
| Some x -> x
) @ [LoadI (mo, {index = "2"});
Load ({index = "2"}, {index = "2"})]
in
let content = Cfg.NodeMap.add ni initialcontent newcfg.content in
let content = Cfg.NodeMap.add no terminalcontent content in
{ newcfg with
inputOutputVar = Some ("1", "2");
content = content
}
)
)
| _ -> failwith ("ReduceRegisters: fail to partition a set, some" ^
" registers have no binding.")
)
in
let terminalcontent = (
match Cfg.NodeMap.find_opt no newcfg.content with
| None -> []
| Some x -> x
) @ [LoadI (mo, {index = "2"});
Load ({index = "2"}, {index = "2"})]
in
let content =
Cfg.NodeMap.add ni initialcontent newcfg.content
in
let content =
Cfg.NodeMap.add no terminalcontent content
in
{ newcfg with
inputOutputVar = Some ("1", "2");
content = content
}
| _ -> failwith ("ReduceRegisters: fail to partition a set, some" ^
" registers have no binding.")
in
( if List.length all_variables <= n