Better styling for miniImp
This commit is contained in:
@ -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
|
||||
|
||||
Reference in New Issue
Block a user