diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 1998-10-19 17:21:45 +0000 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 1998-10-19 17:21:45 +0000 |
commit | fc77f415d8b9a43840f35a26c3f5a34fb901f177 (patch) | |
tree | 6da1a254f67a31050c3ece5e038b1e76666732e7 | |
parent | b7bf7cf69d483d856bba307ebd299d6ccc2cffd3 (diff) |
Scheduler les checkbound avant les load correspondants
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@2123 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r-- | asmcomp/schedgen.ml | 51 | ||||
-rw-r--r-- | asmcomp/schedgen.mli | 2 |
2 files changed, 40 insertions, 13 deletions
diff --git a/asmcomp/schedgen.ml b/asmcomp/schedgen.ml index f306255d2..a42bb4901 100644 --- a/asmcomp/schedgen.ml +++ b/asmcomp/schedgen.ml @@ -37,19 +37,24 @@ let dummy_node = (* The code dag itself is represented by two tables from registers to nodes: - "results" maps registers to the instructions that produced them; - "uses" maps registers to the instructions that use them. - In addition, code_stores contains the latest store nodes emitted so far - and code_loads contains all load nodes emitted since the last store. *) + In addition: + - code_stores contains the latest store nodes emitted so far + - code_loads contains all load nodes emitted since the last store + - code_checkbounds contains the latest checkbound node not matched + by a subsequent load or store. *) let code_results = (Hashtbl.create 31 : (location, code_dag_node) Hashtbl.t) let code_uses = (Hashtbl.create 31 : (location, code_dag_node) Hashtbl.t) let code_stores = ref ([] : code_dag_node list) let code_loads = ref ([] : code_dag_node list) +let code_checkbounds = ref ([] : code_dag_node list) let clear_code_dag () = Hashtbl.clear code_results; Hashtbl.clear code_uses; code_stores := []; - code_loads := [] + code_loads := []; + code_checkbounds := [] (* Add an edge to the code DAG *) @@ -57,6 +62,8 @@ let add_edge ancestor son delay = ancestor.sons <- (son, delay) :: ancestor.sons; son.ancestors <- son.ancestors + 1 +let add_edge_after son ancestor = add_edge ancestor son 0 + (* Compute length of longest path to a result. For leafs of the DAG, see whether their result is used in the instruction immediately following the basic block (a "critical" output). *) @@ -140,6 +147,11 @@ method is_load = function Iload(_, _) -> true | _ -> false +method is_checkbound = function + Iintop Icheckbound -> true + | Iintop_imm(Icheckbound, _) -> true + | _ -> false + method private instr_is_store instr = match instr.desc with Lop op -> self#is_store op @@ -150,6 +162,11 @@ method private instr_is_load instr = Lop op -> self#is_load op | _ -> false +method private instr_is_checkbound instr = + match instr.desc with + Lop op -> self#is_checkbound op + | _ -> false + (* Estimate the latency of an operation. *) method virtual oper_latency : Mach.operation -> int @@ -207,7 +224,7 @@ method private add_instruction ready_queue instr = of this instruction (WAR dependencies). *) for i = 0 to Array.length instr.res - 1 do let ancestors = Hashtbl.find_all code_uses instr.res.(i).loc in - List.iter (fun ancestor -> add_edge ancestor node 0) ancestors + List.iter (add_edge_after node) ancestors done; (* Also add edges from all instructions that have already defined one of the results of this instruction (WAW dependencies). *) @@ -219,21 +236,29 @@ method private add_instruction ready_queue instr = () done; (* If this is a load, add edges from the most recent store viewed so - far (if any) and remember the load *) + far (if any) and remember the load. Also add edges from the most + recent checkbound and forget that checkbound. *) if self#instr_is_load instr then begin - List.iter (fun store -> add_edge store node 0) !code_stores; - code_loads := node :: !code_loads + List.iter (add_edge_after node) !code_stores; + code_loads := node :: !code_loads; + List.iter (add_edge_after node) !code_checkbounds; + code_checkbounds := [] end (* If this is a store, add edges from the most recent store, - as well as all loads viewed since then. Remember the store, - discarding the previous store and loads. *) + as well as all loads viewed since then, and also the most recent + checkbound. Remember the store, + discarding the previous stores, loads and checkbounds. *) else if self#instr_is_store instr then begin - List.iter (fun store -> add_edge store node 0) !code_stores; - List.iter (fun load -> add_edge load node 0) !code_loads; + List.iter (add_edge_after node) !code_stores; + List.iter (add_edge_after node) !code_loads; + List.iter (add_edge_after node) !code_checkbounds; code_stores := [node]; - code_loads := [] + code_loads := []; + code_checkbounds := [] + end + else if self#instr_is_checkbound instr then begin + code_checkbounds := [node] end; - (* Remember the registers used and produced by this instruction *) for i = 0 to Array.length instr.res - 1 do Hashtbl.add code_results instr.res.(i).loc node diff --git a/asmcomp/schedgen.mli b/asmcomp/schedgen.mli index e32f35317..8f02467d4 100644 --- a/asmcomp/schedgen.mli +++ b/asmcomp/schedgen.mli @@ -38,6 +38,8 @@ class virtual scheduler_generic : object (* Says whether the given operation is a memory store *) method is_load : Mach.operation -> bool (* Says whether the given operation is a memory load *) + method is_checkbound : Mach.operation -> bool + (* Says whether the given operation is a checkbound *) (* Entry point *) method schedule_fundecl : Linearize.fundecl -> Linearize.fundecl end |