* Compiler bug with bigarray
@ 2009-11-05 2:00 Goswin von Brederlow
0 siblings, 0 replies; only message in thread
From: Goswin von Brederlow @ 2009-11-05 2:00 UTC (permalink / raw)
To: caml-list
Hi,
I just finished adding a (int, int31_elt) Bigarray.kind for 4 byte
taged integers independent of the architecture to Bigarray. While
testing it I noticed that the generated assembler consists of this:
open Bigarray
let get_foo (a : (int, int31_elt, c_layout) Array1.t) x = Array1.unsafe_get a x
let get_bar (a : (int, int, c_layout) Array1.t) x = Array1.unsafe_get a x
0000000000404aa0 <camlTest__get_foo_127>:
404aa0: 48 d1 fb sar %rbx
404aa3: 48 8b 40 08 mov 0x8(%rax),%rax
404aa7: 48 63 04 98 movslq (%rax,%rbx,4),%rax
404aab: 48 d1 e0 shl %rax
404aae: 48 83 c8 01 or $0x1,%rax
404ab2: c3 retq
404ab3: 66 66 66 66 2e 0f 1f nopw %cs:0x0(%rax,%rax,1)
404aba: 84 00 00 00 00 00
0000000000404ac0 <camlTest__get_bar_130>:
404ac0: 48 83 ec 08 sub $0x8,%rsp
404ac4: 48 89 c7 mov %rax,%rdi
404ac7: 48 89 de mov %rbx,%rsi
404aca: 48 8b 05 bf af 21 00 mov 0x21afbf(%rip),%rax # 61fa90 <_DYNAMIC+0x790>
404ad1: e8 7a 27 01 00 callq 417250 <caml_c_call>
404ad6: 48 83 c4 08 add $0x8,%rsp
404ada: c3 retq
404adb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
As you can see in get_foo the compiler optimizes and inlines the
memory access directly. In get_bar on the other hand this optimization
fails and the generic bigarray get function is invoked as caml_c_call.
Looking at my patch for int31 I could not figure out any difference
that would explain this behaviour of the compiler. So I added a few
Printf.printf to see what the compiler does.
In the (int, int31) case the compiler ends up in cmmgen.ml: transl in the
case for
| (Pbigarrayref(unsafe, num_dims, elt_kind, layout), arg1 ::
argl) ->
let elt =
bigarray_get unsafe elt_kind layout
(transl arg1) (List.map transl argl) dbg in
begin match elt_kind with
| Pbigarray_int31 -> Printf.printf "Pbigarray_int31\n"; force_tag_int elt
| Pbigarray_caml_int -> Printf.printf "Pbigarray_caml_int\n"; force_tag_int elt
In the (int, int) case the compiler never reaches that point. Instead
it ends up in cmmgen.ml: simplif_primitive
let simplif_primitive p =
match p with
| Pbigarrayref(unsafe, n, Pbigarray_unknown, layout) ->
Printf.printf "caml_ba_get_ for Pbigarray_unknown\n";
Pccall (default_prim ("caml_ba_get_" ^ string_of_int n))
So something is horribly wrong here. This should contain
Pbigarrayref(unsafe, n, Pbigarray_caml_int, layout)
Somewhere during compilation the wrong Pbigarrayref gets created for
an (int, int, c_layout) Bigarray.Array1.t. It is created as unknown /
polymorphic ('a, 'b, 'c) Bigarray.Array1.t. The knowledge that it is
(int, int, c_layout) Bigarray.Array1.t is lost or never added to the
type and I am at a loss where that type is created at all. I tried
adding some more Printf.printf lines in places where Pbigarrayref gets
created but none of them get triggered.
So does anyone know where the Pbigarrayref gets created during
compilation and why it remains Pbigarray_unknown? The same problem
arises for Pbigarray_int32, Pbigarray_int64 and Pbigarray_native_int.
All three of which look like they should get optimized on 64bit or at
least keep their type information.
MfG
Goswin
PS: This is debians ocaml 3.11.1-3
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-11-05 2:01 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-05 2:00 Compiler bug with bigarray Goswin von Brederlow
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox