summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>1995-07-25 13:04:41 +0000
committerXavier Leroy <xavier.leroy@inria.fr>1995-07-25 13:04:41 +0000
commit4878271adfa7d4e69b927fe17c3f087b09b2506b (patch)
tree0ae9280253df3c052277719f7b674ab4cfff0de8
parentd1e2b83c19f18d20072cc486d95d64e481767ad7 (diff)
downloadocaml-4878271adfa7d4e69b927fe17c3f087b09b2506b.tar.gz
Suppression de Cmodify / Imodify.
Strength reduction sur les multiplications, divisions, modulo de puissances de 2. git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@147 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--asmcomp/arch_i386.ml1
-rw-r--r--asmcomp/cmm.ml1
-rw-r--r--asmcomp/cmm.mli1
-rw-r--r--asmcomp/emit_alpha.mlp30
-rw-r--r--asmcomp/emit_i386.mlp10
-rw-r--r--asmcomp/emit_mips.mlp2
-rw-r--r--asmcomp/emit_sparc.mlp64
-rw-r--r--asmcomp/mach.ml1
-rw-r--r--asmcomp/mach.mli1
-rw-r--r--asmcomp/printcmm.ml1
-rw-r--r--asmcomp/printmach.ml1
-rw-r--r--asmcomp/proc_i386.ml8
-rw-r--r--asmcomp/proc_sparc.ml10
-rw-r--r--asmcomp/selection.ml10
14 files changed, 58 insertions, 83 deletions
diff --git a/asmcomp/arch_i386.ml b/asmcomp/arch_i386.ml
index b58f9b4abe..21983aff1f 100644
--- a/asmcomp/arch_i386.ml
+++ b/asmcomp/arch_i386.ml
@@ -76,4 +76,3 @@ let print_specific_operation printreg op arg =
| Ioffset_loc(n, addr) ->
print_string "["; print_addressing printreg addr arg;
print_string "] +:= "; print_int n
-
diff --git a/asmcomp/cmm.ml b/asmcomp/cmm.ml
index 524ddf99ac..c3ba95002f 100644
--- a/asmcomp/cmm.ml
+++ b/asmcomp/cmm.ml
@@ -56,7 +56,6 @@ type operation =
| Calloc
| Cstore
| Cstorechunk of memory_chunk
- | Cmodify
| Caddi | Csubi | Cmuli | Cdivi | Cmodi
| Cand | Cor | Cxor | Clsl | Clsr | Casr
| Ccmpi of comparison
diff --git a/asmcomp/cmm.mli b/asmcomp/cmm.mli
index 1c8290b3fe..520a4ee4d8 100644
--- a/asmcomp/cmm.mli
+++ b/asmcomp/cmm.mli
@@ -42,7 +42,6 @@ type operation =
| Calloc
| Cstore
| Cstorechunk of memory_chunk
- | Cmodify
| Caddi | Csubi | Cmuli | Cdivi | Cmodi
| Cand | Cor | Cxor | Clsl | Clsr | Casr
| Ccmpi of comparison
diff --git a/asmcomp/emit_alpha.mlp b/asmcomp/emit_alpha.mlp
index ae1f250b64..a3d44e1646 100644
--- a/asmcomp/emit_alpha.mlp
+++ b/asmcomp/emit_alpha.mlp
@@ -393,23 +393,6 @@ let emit_instr i =
end;
` addq $13, 8, {emit_reg i.res.(0)}\n`
end
- | Lop(Imodify) ->
- if !fastcode_flag then begin
- ` ldq $24, -8({emit_reg i.arg.(0)})\n`;
- ` and $24, 1024, $25\n`;
- let lbl_call_modify = new_label() in
- let lbl_continue = new_label() in
- ` beq $25, {emit_label lbl_call_modify}\n`;
- modify_sites :=
- { mod_lbl = lbl_call_modify;
- mod_return_lbl = lbl_continue;
- mod_instr = i } :: !modify_sites;
- `{emit_label lbl_continue}:`
- end else begin
- ` mov {emit_reg i.arg.(0)}, $25\n`;
- liveregs i live_25;
- ` jsr caml_modify\n` (* Pointer in $25 *)
- end
| Lop(Iintop(Icomp cmp)) ->
let (comp, test) = name_for_int_comparison cmp in
` {emit_string comp} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n`;
@@ -422,11 +405,24 @@ let emit_instr i =
| Lop(Iintop op) ->
let instr = name_for_int_operation op in
` {emit_string instr} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n`
+ | Lop(Iintop_imm(Idiv, n)) when n = 1 lsl (Misc.log2 n) ->
+ let l = Misc.log2 n in
+ ` addq {emit_reg i.arg.(0)}, {emit_int(n-1)}, $25\n`;
+ ` cmovge {emit_reg i.arg.(0)}, {emit_reg i.arg.(0)}, $25\n`;
+ ` sra $25, {emit_int l}, {emit_reg i.res.(0)}\n`
+ | Lop(Iintop_imm(Imod, n)) when n = 1 lsl (Misc.log2 n) ->
+ let l = Misc.log2 n in
+ ` and {emit_reg i.arg.(0)}, {emit_int(n-1)}, $25\n`;
+ ` subq $25, {emit_int n}, $24\n`;
+ ` cmovge {emit_reg i.arg.(0)}, $25, $24\n`;
+ ` cmoveq $25, $25, $24\n`;
+ ` move $24, {emit_reg i.res.(0)}\n`
| Lop(Iintop_imm(Icomp cmp, n)) ->
let (comp, test) = name_for_int_comparison cmp in
` {emit_string comp} {emit_reg i.arg.(0)}, {emit_int n}, {emit_reg i.res.(0)}\n`;
if not test then
` xor {emit_reg i.res.(0)}, 1, {emit_reg i.res.(0)}\n`
+
| Lop(Iintop_imm(Icheckbound, n)) ->
if !range_check_trap = 0 then range_check_trap := new_label();
` cmpule {emit_reg i.arg.(0)}, {emit_int n}, $25\n`;
diff --git a/asmcomp/emit_i386.mlp b/asmcomp/emit_i386.mlp
index cc8e50bf32..ab486a2abd 100644
--- a/asmcomp/emit_i386.mlp
+++ b/asmcomp/emit_i386.mlp
@@ -279,16 +279,6 @@ let emit_instr i =
end;
`{record_frame i.live} leal 4(%eax), {emit_reg i.res.(0)}\n`
end
- | Lop(Imodify) ->
- (* Argument is in eax *)
- if !fastcode_flag then begin
- ` testb $4, -3(%eax)\n`;
- let lbl_cont = new_label() in
- ` jne {emit_label lbl_cont}\n`;
- ` call _caml_fast_modify\n`;
- `{emit_label lbl_cont}:\n`
- end else
- ` call _caml_modify\n`
| Lop(Iintop(Icomp cmp)) ->
` cmpl {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`;
let b = name_for_cond_branch cmp in
diff --git a/asmcomp/emit_mips.mlp b/asmcomp/emit_mips.mlp
index 4a720afec8..96fb7ea11e 100644
--- a/asmcomp/emit_mips.mlp
+++ b/asmcomp/emit_mips.mlp
@@ -319,8 +319,6 @@ let emit_instr i =
end;
` addu {emit_reg i.res.(0)}, $22, 4\n`
end
- | Lop(Imodify) ->
- fatal_error "Emit_mips: Imodify"
| Lop(Iintop(Icheckbound)) ->
if !range_check_trap = 0 then range_check_trap := new_label();
` bleu {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_label !range_check_trap}\n`
diff --git a/asmcomp/emit_sparc.mlp b/asmcomp/emit_sparc.mlp
index e4af35a507..fb2d6acaf6 100644
--- a/asmcomp/emit_sparc.mlp
+++ b/asmcomp/emit_sparc.mlp
@@ -344,20 +344,6 @@ let emit_instr i =
` mov {emit_int n}, %g4\n`;
` add %g6, 4, {emit_reg i.res.(0)}\n`
end
- | Lop(Imodify) ->
- if !fastcode_flag then begin
- ` ld [{emit_reg i.arg.(0)} - 4], %g4\n`;
- ` andcc %g4, 1024, %g0\n`;
- let lbl_continue = new_label() in
- ` bne {emit_label lbl_continue}\n`;
- ` nop\n`;
- ` call _caml_fast_modify\n`;
- ` mov {emit_reg i.arg.(0)}, %g1\n`;
- `{emit_label lbl_continue}:\n`
- end else begin
- ` call _caml_modify\n`;
- ` mov {emit_reg i.arg.(0)}, %g1\n`
- end
| Lop(Iintop Idiv) ->
` sra {emit_reg i.arg.(0)}, 31, %g1\n`;
` wr %g0, %g1, %y\n`;
@@ -389,21 +375,43 @@ let emit_instr i =
let instr = name_for_int_operation op in
` {emit_string instr} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n`
| Lop(Iintop_imm(Idiv, n)) ->
- ` sra {emit_reg i.arg.(0)}, 31, %g1\n`;
- ` wr %g0, %g1, %y\n`;
- ` nop\n`;
- ` nop\n`;
- ` nop\n`;
- ` sdiv {emit_reg i.arg.(0)}, {emit_int n}, {emit_reg i.res.(0)}\n`
+ let l = Misc.log2 n in
+ if n = 1 lsl l then begin
+ let lbl = new_label() in
+ ` tst {emit_reg i.arg.(0)}\n`;
+ ` bge {emit_label lbl}\n`;
+ ` mov {emit_reg i.arg.(0)}, %g1\n` (* in delay slot *)
+ ` add %g1, {emit_int (n-1)}, %g1\n`
+ `{emit_label lbl}: sra %g1, {emit_int n}, {emit_reg i.res.(0)}\n`
+ end else begin
+ ` sra {emit_reg i.arg.(0)}, 31, %g1\n`;
+ ` wr %g0, %g1, %y\n`;
+ ` nop\n`;
+ ` nop\n`;
+ ` nop\n`;
+ ` sdiv {emit_reg i.arg.(0)}, {emit_int n}, {emit_reg i.res.(0)}\n`
+ end
| Lop(Iintop_imm(Imod, n)) ->
- ` sra {emit_reg i.arg.(0)}, 31, %g1\n`;
- ` wr %g0, %g1, %y\n`;
- ` nop\n`;
- ` nop\n`;
- ` nop\n`;
- ` sdiv {emit_reg i.arg.(0)}, {emit_int n}, %g1\n`;
- ` smul %g1, {emit_int n}, %g1\n`;
- ` sub {emit_reg i.arg.(0)}, %g1, {emit_reg i.res.(0)}\n`
+ let l = Misc.log2 n in
+ if n = 1 lsl l then begin
+ let lbl = new_label() in
+ ` tst {emit_reg i.arg.(0)}\n`;
+ ` bge {emit_label lbl}\n`;
+ ` andcc {emit_reg i.arg.(0)}, {emit_int (n-1)}, {emit_reg i.res.(0)}\n`; (* in delay slot *)
+ ` be {emit_label lbl}\n`;
+ ` nop\n`;
+ ` sub {emit_reg i.res.(0)}, {emit_int n}, {emit_reg i.res.(0)}\n`;
+ `{emit_label lbl}:\n`
+ end else begin
+ ` sra {emit_reg i.arg.(0)}, 31, %g1\n`;
+ ` wr %g0, %g1, %y\n`;
+ ` nop\n`;
+ ` nop\n`;
+ ` nop\n`;
+ ` sdiv {emit_reg i.arg.(0)}, {emit_int n}, %g1\n`;
+ ` smul %g1, {emit_int n}, %g1\n`;
+ ` sub {emit_reg i.arg.(0)}, %g1, {emit_reg i.res.(0)}\n`
+ end
| Lop(Iintop_imm(Icomp cmp, n)) ->
let comp = name_for_int_comparison cmp in
` cmp {emit_reg i.arg.(0)}, {emit_int n}\n`;
diff --git a/asmcomp/mach.ml b/asmcomp/mach.ml
index 16e2887586..a79fa21ad4 100644
--- a/asmcomp/mach.ml
+++ b/asmcomp/mach.ml
@@ -35,7 +35,6 @@ type operation =
| Iload of Cmm.memory_chunk * Arch.addressing_mode
| Istore of Cmm.memory_chunk * Arch.addressing_mode
| Ialloc of int
- | Imodify
| Iintop of integer_operation
| Iintop_imm of integer_operation * int
| Iaddf | Isubf | Imulf | Idivf
diff --git a/asmcomp/mach.mli b/asmcomp/mach.mli
index 74aca86fca..afcb8aba1b 100644
--- a/asmcomp/mach.mli
+++ b/asmcomp/mach.mli
@@ -35,7 +35,6 @@ type operation =
| Iload of Cmm.memory_chunk * Arch.addressing_mode
| Istore of Cmm.memory_chunk * Arch.addressing_mode
| Ialloc of int
- | Imodify
| Iintop of integer_operation
| Iintop_imm of integer_operation * int
| Iaddf | Isubf | Imulf | Idivf
diff --git a/asmcomp/printcmm.ml b/asmcomp/printcmm.ml
index 578ce81b8c..b3f5f63527 100644
--- a/asmcomp/printcmm.ml
+++ b/asmcomp/printcmm.ml
@@ -43,7 +43,6 @@ let operation = function
| Calloc -> print_string "alloc"
| Cstore -> print_string "store"
| Cstorechunk c -> print_string "store "; chunk c
- | Cmodify -> print_string "modify"
| Caddi -> print_string "+"
| Csubi -> print_string "-"
| Cmuli -> print_string "*"
diff --git a/asmcomp/printmach.ml b/asmcomp/printmach.ml
index 94fa367eca..38b6248f9b 100644
--- a/asmcomp/printmach.ml
+++ b/asmcomp/printmach.ml
@@ -117,7 +117,6 @@ let operation op arg res =
print_string "] := ";
reg arg.(0)
| Ialloc n -> print_string "alloc "; print_int n
- | Imodify -> print_string "modify "; reg arg.(0)
| Iintop(op) -> reg arg.(0); intop op; reg arg.(1)
| Iintop_imm(op, n) -> reg arg.(0); intop op; print_int n
| Iaddf -> reg arg.(0); print_string " +f "; reg arg.(1)
diff --git a/asmcomp/proc_i386.ml b/asmcomp/proc_i386.ml
index 338acad40b..9ee1a97bc5 100644
--- a/asmcomp/proc_i386.ml
+++ b/asmcomp/proc_i386.ml
@@ -195,16 +195,13 @@ let pseudoregs_for_operation op arg res =
| Iintop(Imod) ->
([|phys_reg 0; arg.(1)|], [|phys_reg 3|])
(* For storing a byte, the argument must be in eax...edx.
- For storing a word, any reg is ok.
+ For storing a halfword, any reg is ok.
Keep it simple, just force it to be in edx in both cases. *)
| Istore(Word, addr) -> raise Use_default
| Istore(chunk, addr) ->
let newarg = Array.copy arg in
newarg.(0) <- phys_reg 3;
(newarg, res)
- (* For modify, the argument must be in eax *)
- | Imodify ->
- ([|phys_reg 0|], [||])
(* Other instructions are more or less regular *)
| _ -> raise Use_default
@@ -268,7 +265,6 @@ let destroyed_at_oper = function
| Iop(Iextcall(_, false)) -> destroyed_at_c_call
| Iop(Iintop(Idiv | Imod)) -> [| phys_reg 0; phys_reg 3 |] (* eax, edx *)
| Iop(Ialloc _) -> [| phys_reg 0|] (* eax *)
- | Iop(Imodify) -> [| phys_reg 0 |] (* eax *)
| Iop(Iintop(Icomp _) | Iintop_imm(Icomp _, _)) -> [| phys_reg 0 |] (* eax *)
| Iop(Iintoffloat) -> [| phys_reg 0 |] (* eax *)
| Iifthenelse(Ifloattest _, _, _) -> [| phys_reg 0 |] (* eax *)
@@ -283,7 +279,7 @@ let safe_register_pressure op = 4
let max_register_pressure = function
Iextcall(_, _) -> [| 4; 4 |]
| Iintop(Idiv | Imod) -> [| 5; 4 |]
- | Ialloc _ | Imodify | Iintop(Icomp _) | Iintop_imm(Icomp _, _) |
+ | Ialloc _ | Iintop(Icomp _) | Iintop_imm(Icomp _, _) |
Iintoffloat -> [| 6; 4 |]
| _ -> [|7; 4|]
diff --git a/asmcomp/proc_sparc.ml b/asmcomp/proc_sparc.ml
index ed38e5fe5f..2a8fa1d980 100644
--- a/asmcomp/proc_sparc.ml
+++ b/asmcomp/proc_sparc.ml
@@ -45,15 +45,7 @@ let select_addressing exp =
(* Instruction selection *)
-let select_oper op args =
- match (op, args) with
- (Cmuli, [arg1; Cconst_int n]) ->
- let shift = Misc.log2 n in
- if n = 1 lsl shift
- then (Iintop_imm(Ilsl, shift), [arg1])
- else raise Use_default
- | _ ->
- raise Use_default
+let select_oper op args = raise Use_default
let select_store addr exp = raise Use_default
diff --git a/asmcomp/selection.ml b/asmcomp/selection.ml
index 855c6b7782..b3f2f22a68 100644
--- a/asmcomp/selection.ml
+++ b/asmcomp/selection.ml
@@ -16,7 +16,6 @@ let oper_result_type = function
| Calloc -> typ_addr
| Cstore -> typ_void
| Cstorechunk c -> typ_void
- | Cmodify -> typ_void
| Caddi | Csubi | Cmuli | Cdivi | Cmodi
| Cand | Cor | Cxor | Clsl | Clsr | Casr
| Ccmpi _ | Ccmpa _ | Ccmpf _ -> typ_int
@@ -58,7 +57,7 @@ let rec size_expr env = function
let cheap_operation = function
(* The following may have side effects *)
Capply _ | Cextcall(_, _, _) | Calloc | Cstore | Cstorechunk _ |
- Cmodify | Craise -> false
+ Craise -> false
(* The following are expensive to compute, better start them early *)
| Caddf | Csubf | Cmulf | Cdivf | Cfloatofint | Cintoffloat -> false
(* The remaining operations are cheap *)
@@ -84,9 +83,13 @@ let rec sel_operation op args =
let (addr, eloc) = Proc.select_addressing arg1 in
(Istore(chunk, addr), eloc :: rem)
| (Calloc, _) -> (Ialloc 0, args)
- | (Cmodify, _) -> (Imodify, args)
| (Caddi, _) -> sel_arith_comm Iadd args
| (Csubi, _) -> sel_arith Isub args
+ | (Cmuli, [arg1; Cconst_int n]) ->
+ let l = Misc.log2 n in
+ if n = 1 lsl l
+ then (Iintop_imm(Ilsl, l), [arg1])
+ else sel_arith_comm Imul args
| (Cmuli, _) -> sel_arith_comm Imul args
| (Cdivi, _) -> sel_arith Idiv args
| (Cmodi, _) -> sel_arith_comm Imod args
@@ -401,7 +404,6 @@ let rec emit_expr env exp seq =
(Arch.offset_addressing Arch.identity_addressing (-Arch.size_int));
rd
| op ->
- if op = Imodify then Proc.contains_calls := true;
let r1 = emit_tuple env new_args seq in
let rd = Reg.newv ty in
begin try