diff options
Diffstat (limited to 'asmcomp/schedgen.ml')
-rw-r--r-- | asmcomp/schedgen.ml | 70 |
1 files changed, 48 insertions, 22 deletions
diff --git a/asmcomp/schedgen.ml b/asmcomp/schedgen.ml index adb56583cb..885c945404 100644 --- a/asmcomp/schedgen.ml +++ b/asmcomp/schedgen.ml @@ -10,8 +10,6 @@ (* *) (***********************************************************************) -(* $Id: schedgen.ml 12858 2012-08-10 14:45:51Z maranget $ *) - (* Instruction scheduling *) open Reg @@ -64,6 +62,33 @@ let add_edge ancestor son delay = let add_edge_after son ancestor = add_edge ancestor son 0 +(* Add edges from all instructions that define a pseudoregister [arg] being used + as argument to node [node] (RAW dependencies *) + +let add_RAW_dependencies node arg = + try + let ancestor = Hashtbl.find code_results arg.loc in + add_edge ancestor node ancestor.delay + with Not_found -> + () + +(* Add edges from all instructions that use a pseudoregister [res] that is + defined by node [node] (WAR dependencies). *) + +let add_WAR_dependencies node res = + let ancestors = Hashtbl.find_all code_uses res.loc in + List.iter (add_edge_after node) ancestors + +(* Add edges from all instructions that have already defined a pseudoregister + [res] that is defined by node [node] (WAW dependencies). *) + +let add_WAW_dependencies node res = + try + let ancestor = Hashtbl.find code_results res.loc in + add_edge ancestor node 0 + with Not_found -> + () + (* 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). *) @@ -199,10 +224,19 @@ method private instr_issue_cycles instr = | Lreloadretaddr -> self#reload_retaddr_issue_cycles | _ -> assert false +(* Pseudoregisters destroyed by an instruction *) + +method private destroyed_by_instr instr = + match instr.desc with + | Lop op -> Proc.destroyed_at_oper (Iop op) + | Lreloadretaddr -> [||] + | _ -> assert false + (* Add an instruction to the code dag *) method private add_instruction ready_queue instr = let delay = self#instr_latency instr in + let destroyed = self#destroyed_by_instr instr in let node = { instr = instr; delay = delay; @@ -213,28 +247,17 @@ method private add_instruction ready_queue instr = emitted_ancestors = 0 } in (* Add edges from all instructions that define one of the registers used (RAW dependencies) *) - for i = 0 to Array.length instr.arg - 1 do - try - let ancestor = Hashtbl.find code_results instr.arg.(i).loc in - add_edge ancestor node ancestor.delay - with Not_found -> - () - done; + Array.iter (add_RAW_dependencies node) instr.arg; (* Also add edges from all instructions that use one of the result regs - 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 (add_edge_after node) ancestors - done; + of this instruction, or a reg destroyed by this instruction + (WAR dependencies). *) + Array.iter (add_WAR_dependencies node) instr.res; + Array.iter (add_WAR_dependencies node) destroyed; (* PR#5731 *) (* Also add edges from all instructions that have already defined one - of the results of this instruction (WAW dependencies). *) - for i = 0 to Array.length instr.res - 1 do - try - let ancestor = Hashtbl.find code_results instr.res.(i).loc in - add_edge ancestor node 0 - with Not_found -> - () - done; + of the results of this instruction, or a reg destroyed by + this instruction (WAW dependencies). *) + Array.iter (add_WAW_dependencies node) instr.res; + Array.iter (add_WAW_dependencies node) destroyed; (* PR#5731 *) (* If this is a load, add edges from the most recent store viewed so far (if any) and remember the load. Also add edges from the most recent checkbound and forget that checkbound. *) @@ -263,6 +286,9 @@ method private add_instruction ready_queue instr = for i = 0 to Array.length instr.res - 1 do Hashtbl.add code_results instr.res.(i).loc node done; + for i = 0 to Array.length destroyed - 1 do + Hashtbl.add code_results destroyed.(i).loc node (* PR#5731 *) + done; for i = 0 to Array.length instr.arg - 1 do Hashtbl.add code_uses instr.arg.(i).loc node done; |