<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE message PUBLIC
  "-//MLarc//DTD MLarc output files//EN"
  "../../mlarc.dtd"[
  <!ATTLIST message
    listname CDATA #REQUIRED
    title CDATA #REQUIRED
  >
]>

  <?xml-stylesheet href="../../mlarc.xsl" type="text/xsl"?>


<message 
  url="2003/12/1e21db54a184690899c1c313b0a8de85"
  from="Remi Vanicat &lt;remi.vanicat@l...&gt;"
  author="Remi Vanicat"
  date="2003-12-20T16:50:30"
  subject="Re: [Caml-list] ASM code generated by OCAML"
  prev="2003/12/40b3de4cc54ef3b2aa6aed7de32917f8"
  next="2003/12/11aef5a42199a1b25c1d3da01c1e7795"
  prev-in-thread="2003/12/558c3ea8590ceaa0759c13dbe9214a62"
  prev-thread="2003/12/59c29f4d5f2da28e2310ec5d53a052cb"
  next-thread="2003/12/11aef5a42199a1b25c1d3da01c1e7795"
  root="../../"
  period="month"
  listname="caml-list"
  title="Archives of the Caml mailing list">

<thread subject="[Caml-list] ASM code generated by OCAML">
<msg 
  url="2003/12/558c3ea8590ceaa0759c13dbe9214a62"
  from="Francesco Abbate &lt;segfault@e...&gt;"
  author="Francesco Abbate"
  date="2003-12-20T12:44:11"
  subject="[Caml-list] ASM code generated by OCAML">
<msg 
  url="2003/12/1e21db54a184690899c1c313b0a8de85"
  from="Remi Vanicat &lt;remi.vanicat@l...&gt;"
  author="Remi Vanicat"
  date="2003-12-20T16:50:30"
  subject="Re: [Caml-list] ASM code generated by OCAML">
</msg>
</msg>
</thread>

<contents>
Francesco Abbate &lt;segfault@email.it&gt; writes:

&gt; Dear Ocamlers,
&gt;
&gt; ok, I confess that I'm a little bit paranoid and I often
&gt; look to the assembler code generated by Ocaml to get an
&gt; idea of real efficience of the compiler.
&gt;
&gt; While, generally speaking, the ASM code generated by ocaml
&gt; is pretty good, I wonder why the following function
&gt; is not decently assembled by ocaml :
&gt; -----------------------------------------
&gt; let rec conv n =
&gt;   let r = n mod 10
&gt;   and n' = n / 10 in
&gt;   if n' = 0 then r
&gt;   else r + 8 * (conv n')
&gt; -----------------------------------------
&gt; nor the C version is decently assembled by GCC
&gt; -----------------------------------------
&gt; int
&gt; conv (int n)
&gt; {
&gt;   int m = n / 10, r = n % 10;
&gt;   if (m &gt; 0)
&gt;     return r + 8 * conv (m);
&gt;   return m;
&gt; }
&gt; -----------------------------------------

&gt; So my answer is why nor Ocaml nor GCC does generate efficient
&gt; assembler code ?
&gt;
&gt; I will attempt to give a tentative answer
&gt; - for some reason the compiler does not understands the (n mod 10)
&gt;   and (n /10) both can be avaluated with a simgle "idiv"
&gt;   instruction

This require some analysis that isn't needed in general

&gt; - for some reason the compilers does not conceive to have a loop
&gt;   which push something on the stack at each cycle.

Ocaml (and I believe GCC) only optimize code witch is tail recursive,
that is the result of the function is the result of the recursive
case. 

You should transform your code into a tail rec function by hand :
let conv n =
   let rec helper n mult accu =
      if n = 0 then accu
      else
         let r = n mod 10
         and n' = n / 10 in
         helper n' (mult * 8) (accu + r * mult) in
   helper n 1 0

As you can see, the result of the recursive function helper is the
result of the recursive call.

-- 
Rémi Vanicat

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners

</contents>

</message>

