From 11f653045aff88fa8f3e09a85415f2b24cdaefc3 Mon Sep 17 00:00:00 2001 From: Paweł Dybiec Date: Sun, 13 Jan 2019 23:54:28 +0100 Subject: Almost working live variable analysis --- source/mod_student/live_variables.ml | 73 ++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/source/mod_student/live_variables.ml b/source/mod_student/live_variables.ml index 580892b..47b7c71 100644 --- a/source/mod_student/live_variables.ml +++ b/source/mod_student/live_variables.ml @@ -30,14 +30,81 @@ module Make() = struct List.iter set @@ ControlFlowGraph.labels cfg; table - + let union set list= + List.fold_left (fun x y->RegSet.add y x) set list + + let diff set list = + List.fold_left (fun x y->RegSet.remove y x) set list + let result : LiveVariables.table = initialize_table () + let transfer_instr instr input = + let output = union (diff input (Ir_utils.defined_registers_instr instr)) (Ir_utils.used_registers_instr instr) in + (Knowledge.make ~pre:output ~post:input),instr + + let transfer_terminator t input = + let output = union (diff input (Ir_utils.defined_registers_terminator t)) (Ir_utils.used_registers_terminator t) in + (Knowledge.make ~pre:output ~post:input),t + + let rec transfer_instr_list instr input = match instr with + | [] -> [],input + | x::xs -> let ys,input = transfer_instr_list xs input in + let y= transfer_instr x input in + let output = Knowledge.pre (fst y) in + (y::ys,output) + + let transfer_basic_block l current_knowledge = + if l = ControlFlowGraph.exit_label cfg then current_knowledge else + if l = ControlFlowGraph.entry_label cfg then current_knowledge else + let t = ControlFlowGraph.terminator cfg l in + let instr = ControlFlowGraph.block cfg l in + let input = BlockKnowledge.post current_knowledge in + let t_res = transfer_terminator t input in + let input2 = Knowledge.pre @@ fst t_res in + let instr_res,output = transfer_instr_list instr input2 in + let block = Knowledge.make ~pre:output ~post:input in + BlockKnowledge.make_complex ~block ~body:instr_res ~terminator:t_res + let changed = ref true + + let update_in label = + let input = List.fold_left RegSet.union RegSet.empty + (List.map (fun l -> BlockKnowledge.pre (Hashtbl.find result l)) + (ControlFlowGraph.successors cfg label) ) in + let old = (Hashtbl.find result label) in + let old_input = BlockKnowledge.post old in + if input=old_input then () else + changed:=true; + let new_kn = BlockKnowledge.alter_prepost ~post:input old in + Hashtbl.replace result label new_kn + + let update_ins () = + let labels = ControlFlowGraph.labels cfg in + List.iter update_in labels + + + let update_out label = + let old = (Hashtbl.find result label) in + let old_input = BlockKnowledge.post old in + let new_kn = transfer_basic_block label old in + if new_kn=old then () else + changed:=true; + Hashtbl.replace result label new_kn + + let update_outs () = + let labels = ControlFlowGraph.labels cfg in + List.iter update_out labels + let rec compute_fixpoint () = - failwith "Not yet implemented" + changed := false; + update_ins (); + update_outs (); + if not !changed then () else + compute_fixpoint () + + let analyse () = - compute_fixpoint (); + compute_fixpoint (); result end -- cgit 1.4.1