Updated hw6 to a newer version

Signed-off-by: jmug <u.g.a.mariano@gmail.com>
This commit is contained in:
Mariano Uvalle 2025-01-24 21:23:08 -08:00
parent 9224001a22
commit 0c04936ccf
356 changed files with 8408 additions and 4725 deletions

122
hw6/bin/solver.ml Normal file
View file

@ -0,0 +1,122 @@
open Datastructures
(* dataflow analysis graph signature ---------------------------------------- *)
(* Interface for dataflow graphs structured in a way to facilitate
the general iterative dataflow analysis algorithm.
The AsGraph functor in cfg.ml provides an implementation of this
DFA_GRAPH signature that converts an LL IR control-flow graph to
this representation.
NOTE: The direction of the analysis is goverened by how preds and
succs are instantiated and how the corresponding flow function
is defined. This module pretends that all information is flowing
"forward", but e.g. liveness instantiates the graph so that "forward"
here is "backward" in the control-flow graph.
This means that for a node n, the output information is explicitly
represented by the "find_fact" function:
out[n] = find_fact g n
The input information for [n] is implicitly represented by:
in[n] = combine preds[n] (out[n])
*)
module type DFA_GRAPH =
sig
module NodeS : SetS
(* type of nodes in this graph *)
type node = NodeS.elt
(* dataflow facts associated with the out-edges of the nodes in the graph *)
type fact
(* the abstract type of dataflow graphs *)
type t
val preds : t -> node -> NodeS.t
val succs : t -> node -> NodeS.t
val nodes : t -> NodeS.t
(* the flow function:
given a graph node and input fact, compute the resulting fact on the
output edge of the node
*)
val flow : t -> node -> fact -> fact
(* lookup / modify the dataflow annotations associated with a node *)
val out : t -> node -> fact
val add_fact : node -> fact -> t -> t
(* printing *)
(*
val to_string : t -> string
val printer : Format.formatter -> t -> unit
*)
end
(* abstract dataflow lattice signature -------------------------------------- *)
(* The general algorithm works over a generic lattice of abstract "facts".
- facts can be combined (this is the 'meet' operation)
- facts can be compared *)
module type FACT =
sig
type t
val combine : t list -> t
val compare : t -> t -> int
val to_string : t -> string
end
(* generic iterative dataflow solver ---------------------------------------- *)
(* This functor takes two modules:
Fact - the implementation of the lattice
Graph - the dataflow anlaysis graph
It produces a module that has a single function 'solve', which
implements the iterative dataflow analysis described in lecture.
- using a worklist (or workset) nodes
[initialized with the set of all nodes]
- process the worklist until empty:
. choose a node from the worklist
. find the node's predecessors and combine their flow facts
. apply the flow function to the combined input to find the new
output
. if the output has changed, update the graph and add the node's
successors to the worklist
TASK: complete the [solve] function, which implements the above algorithm.
*)
module Make (Fact : FACT) (Graph : DFA_GRAPH with type fact := Fact.t) =
(* I used ChatGPT here to help me understand functors and find some helper functions, like "choose, remove, union, and add" *)
struct
let solve (g:Graph.t) : Graph.t =
let worklist = Graph.nodes g in
let rec solve_helper g worklist =
if Graph.NodeS.is_empty worklist then g else
(* choose a node from the worklist *)
let current_node = Graph.NodeS.choose worklist in
(* find the node's predecessors and combine their flow facts *)
let preds : Graph.NodeS.t = Graph.preds g current_node in
let pred_fact = Graph.NodeS.fold
(fun pred acc -> Fact.combine [Graph.out g pred; acc])
preds (Fact.combine []) in
(* apply the flow function to the combined input to find the new output *)
let out_fact = Graph.flow g current_node pred_fact in
(* if the output has changed, update the graph and add the node's successors to the worklist *)
let is_zero = Fact.compare out_fact (Graph.out g current_node) in
let new_worklist = Graph.NodeS.remove current_node worklist in
if is_zero != 0 then let succs = Graph.succs g current_node in
solve_helper (Graph.add_fact current_node out_fact g) (Graph.NodeS.union succs new_worklist)
else (* it has not changed *)
solve_helper g new_worklist
in
let new_g = solve_helper g worklist in new_g
end