From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id 5A21FBC37 for ; Fri, 29 Jan 2010 01:31:39 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApkBAKK7YUvRVdveimdsb2JhbACbDD0BAQEKCQwHEQWtaQqBO4UriGgBAQMFhDgEixQ X-IronPort-AV: E=Sophos;i="4.49,363,1262559600"; d="scan'208";a="42669308" Received: from mail-ew0-f222.google.com ([209.85.219.222]) by mail3-smtp-sop.national.inria.fr with ESMTP; 29 Jan 2010 01:31:34 +0100 Received: by ewy22 with SMTP id 22so1439659ewy.17 for ; Thu, 28 Jan 2010 16:31:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:reply-to:date:message-id :subject:from:to:content-type; bh=4hEMSI5Fdc9jpysQ3N7K88WGUJE5E3Wq/Libko/JHCw=; b=SKnTwp7zXYiiNNrkQIMh3OnhMdiKIMgoCnv1vSTHWS62JnAKBd0O006Mt5+GWasiy/ +oa4zIP9GgCQouD2mYZMEgmc83gJZOzlDpaXVDQ3VHVyUQa5EE/LKNJm5bt3tLGR896G FCoDIZAj2Aumve5jliJyR28ionidEOBxNtBQc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:reply-to:date:message-id:subject:from:to:content-type; b=HDRXKIBuZXx3lp44tgOwze4qiRsrp6n8DOY7L4D0ww9ekgvjayhsHQdu2bKE5Xs0k5 1DkvEbbWf4cEs/p0DQeQ5T5MIu10xx1JDQEqioezoYeA9he8sKfJij7iE0o0xoXx1/7t ElJtJR2QVfiN9N7GDilAMTMCh4iZVPN/xEYd4= MIME-Version: 1.0 Received: by 10.216.157.1 with SMTP id n1mr26375wek.188.1264725093402; Thu, 28 Jan 2010 16:31:33 -0800 (PST) Reply-To: yminsky@gmail.com Date: Thu, 28 Jan 2010 19:31:33 -0500 Message-ID: <891bd3391001281631j5bee86e1h501aae874d06c1bc@mail.gmail.com> Subject: Inside the mind of the inliner From: Yaron Minsky To: caml-list@inria.fr Content-Type: multipart/alternative; boundary=0016367fb6c1ee4945047e42c10b X-Spam: no; 0.00; yaron:01 minsky:01 yminsky:01 ocaml:01 inlining:01 trivial:01 inlining:01 ocamlopt:01 -inline:01 variants:01 inlined:01 inlined:01 foo:01 infix:01 ocaml:01 --0016367fb6c1ee4945047e42c10b Content-Type: text/plain; charset=ISO-8859-1 I've been doing some experiments with the OCaml inliner, and have walked away from the process very confused. It seems like inlining can be prevented by very simple changes to the code of a function. The main surprise for me is that adding a quite trivial allocation of a list or a string literal defeats the inliner. Does anyone have a better understanding of what's going on here? I feel like my intuition for this stuff is terrible. I checked inlining using the following command line: ocamlopt -S -inline 10000 z.ml ; egrep 'call.*camlZ__f' z.s And here are the different variants of z.ml I tried. (* Simple arithmetic. f is inlined *) let f x = x + x let g x = f x + f x (* Add in allocation of a list, not inlined *) let f x = ignore [1]; x + x let g x = f x + f x (* allocate a string, not inlined *) let f x = ignore "foo"; x + x let g x = f x + f x (* reference to the empty list, inlined *) let f x = ignore []; x + x let g x = f x + f x (* call a function that iterates over a list, inlined *) let list = [1;2;3] let plus x y = x + y let f x = x * List.fold_left plus 0 list let g x = f x + f x (* Call a function that includes an infix operator in prefix form, not inlined. *) let list = [1;2;3] let f x = x * List.fold_left (+) 0 list let g x = f x + f x (* Allocate the list in the function, not inlined *) let plus x y = x + y let f x = x * List.fold_left plus 0 [1;2;3] let g x = f x + f x (* call a function to allocate your list, inlined *) let plus x y = x + y let create_list x = x :: x + 1 :: x + 2 :: [] let f x = x * List.fold_left plus 0 (create_list 1) let g x = f x + f x I've tried these experiments with ocaml 3.10.1 and 3.11.1, with similar results. y --0016367fb6c1ee4945047e42c10b Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable I've been doing some experiments with the OCaml inliner, and have
wa= lked away from the process very confused.=A0 It seems like inlining
can = be prevented by very simple changes to the code of a function.
The main = surprise for me is that adding a quite trivial allocation of
a list or a string literal defeats the inliner.

Does anyone have a b= etter understanding of what's going on here?=A0 I
feel like my intui= tion for this stuff is terrible.

I checked inlining using the follow= ing command line:

=A0 ocamlopt -S -in= line 10000 z.ml ; egrep 'call.*camlZ__f'= ; z.s

And here are the different variants of z.ml I tried.

(* Simple arithmeti= c.=A0 f is inlined *)
let f x =3D x + x
let g x =3D f x + f x

(* Add in allocation of a list, not inlined *)
let f x =3D ignore [1];= x + x
let g x =3D f x + f x

(* allocate a string, not inlined *)
let f x =3D ignore "foo"; x + x
let g x =3D f x + f x

(* reference to the empty list, inlined *)
let f x =3D ignore []; = x + x
let g x =3D f x + f x

(* call a function that iterates over a list, in= lined *)
let list =3D [1;2;3]
let plus x y =3D x + y<= /span>
let f x =3D x * List.fold_left plus 0 list=
let g x =3D f x + f x

(* Call a function that includes an infix operator in prefix form, <= /span>
=A0=A0 not inlined. *) =
let list =3D [1;2;3]
let f x =3D x * List.fo= ld_left (+) 0 list
= let g x =3D f x + f x
=A0
(* Allocate the list in the function, not inlined *)<= br style=3D"font-family: courier new,monospace;"> let plus x y =3D x + y<= /span>
let f x =3D x * List.fold_left plus 0 [1;2= ;3]
let g x =3D f x + f x

(* call a function to allocate your list, inlined *)
let plus x y =3D x + y<= /span>
let create_list x =3D x :: x + 1 :: x + 2 = :: []
let f x =3D x * List.fo= ld_left plus 0 (create_list 1)
let g x =3D= f x + f x

I've tried these experiments with ocaml 3.10.1 and 3.11.1, with sim= ilar results.

y
--0016367fb6c1ee4945047e42c10b--