From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by sympa.inria.fr (Postfix) with ESMTPS id 8ED047EDC2 for ; Tue, 20 Nov 2012 17:20:17 +0100 (CET) Received-SPF: None (mail4-smtp-sop.national.inria.fr: no sender authenticity information available from domain of gabriel.scherer@gmail.com) identity=pra; client-ip=209.85.223.182; receiver=mail4-smtp-sop.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="gabriel.scherer@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail4-smtp-sop.national.inria.fr: domain of gabriel.scherer@gmail.com designates 209.85.223.182 as permitted sender) identity=mailfrom; client-ip=209.85.223.182; receiver=mail4-smtp-sop.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="gabriel.scherer@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail4-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-ie0-f182.google.com) identity=helo; client-ip=209.85.223.182; receiver=mail4-smtp-sop.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="postmaster@mail-ie0-f182.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AuoBANGsq1DRVd+2kWdsb2JhbAA8CbAUkj0IFg4BAQEBCQkNBxIpgh4BAQUnGQEbEgsBAwwGBQsNDSEiAREBBQEKEgYTEodoAQMPC6FyjDGBboEKhRYKGScDClmIdQEFDItAaRGEZAOULYFRgRyKFoMvFimEEQ X-IronPort-AV: E=Sophos;i="4.83,286,1352070000"; d="scan'208";a="163166383" Received: from mail-ie0-f182.google.com ([209.85.223.182]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 20 Nov 2012 17:20:16 +0100 Received: by mail-ie0-f182.google.com with SMTP id s9so3891139iec.27 for ; Tue, 20 Nov 2012 08:20:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=lj98wpWYS/N24iahlMzITrKKGLlp/pPN7L2S1EIo7Tc=; b=BNgD0TuQ3GRBFo0oVopSwn3763A7t8LhrEM4hSR+sIFXbpy2mqKDodCIo0hRjbcEmO /keacaR5ThEwt4MHBtC4QjWxUo9ivUvJCy7PGoC+MKx6RIouMATu8uu45Q7RYvx0WDgX Sn3gpfYRWOQXrlLV1NpnwuZUCIInZvIMUvbpwsnnAGqLmKgWQ/77UTGsNVX3rGfyLUri qJSM21ILjjdE9amOJ9x4mj5ZK1OdqE+/grJSy/tn7UfGuu/MJD3TmCDtDb6gWSCiSiyy 5AszLco0izmkDTrBNhUYtxyVNFCdyM0sOe4NkkOxa5VwkWY3m6YGxZmJX21Pe1mOI5oY xlbg== Received: by 10.50.1.200 with SMTP id 8mr10620149igo.51.1353428415221; Tue, 20 Nov 2012 08:20:15 -0800 (PST) MIME-Version: 1.0 Received: by 10.50.184.199 with HTTP; Tue, 20 Nov 2012 08:19:34 -0800 (PST) In-Reply-To: <20121120112519.2e155a09@crans.org> References: <1353347369.78785.YahooMailNeo@web111510.mail.gq1.yahoo.com> <50AA7427.5080104@etorok.net> <1353349126.4420.YahooMailNeo@web111512.mail.gq1.yahoo.com> <20121120112519.2e155a09@crans.org> From: Gabriel Scherer Date: Tue, 20 Nov 2012 17:19:34 +0100 Message-ID: To: Pierre Chambart Cc: caml-list@inria.fr Content-Type: text/plain; charset=ISO-8859-1 Subject: Re: [Caml-list] The verdict on "%identity" This is good advice in general, and using ocamlobjinfo to get inlining information from the .cmx is indeed a very good idea. Regarding -dcmm vs. -S, I generally use -dcmm myself (much more readable), but it is not the right tool in this case. The cmm produced for my test.ml code does make a difference between the three styles: (let testA/1046 (let x/1075 "camlTest__3" x/1075) (store (+a "camlTest" 20) testA/1046)) (let testB/1047 (let prim/1076 "camlTest__2" prim/1076) (store (+a "camlTest" 24) testB/1047)) (let testD/1048 "camlTest__1" (store (+a "camlTest" 28) testD/1048)) In fact, the removal of the trivial (let x = foo in x) does not happen during the inlining passes in closure.ml, but much later at the register allocation phase, where there is indeed a strong preference for eg. testA/1046 and x/1705 to be given the same register, and the useless move is erased. I make no claim of how robust this behavior will be in a different case (eg. with higher register pressure), but I'm not sure I really care. I'd rather have people study the behavior on the compiler the real performance-critical applications and suggest potential style changes in the program (or optimization changes in the compiler) in cases where this really make a performance difference. Writing code in a certain way because "the generated code is nicer" is usually not worth the trouble. On Tue, Nov 20, 2012 at 11:25 AM, Pierre Chambart wrote: > To know what will be generated after inlining I prefer to use -dcmm, > which is closer to the original code than the assembly and still show > show inlining result (and if you are using the svn trunk, you can use > -dclambda which show a higher level code, without allocations and > boxing). > > Inlining of OCaml functions works the same way inside a module or > cross-module. It looks at the function size and if it smaller than > a certain threshold, it will be inlined. To know if it will happen to > your function, look at the result of ocamlobjinfo. > > for instance: > module.mli: > > type t > external id_prim : string -> t = "%identity" > val id : string -> t > val f : int -> int > val g : int -> int > > module.ml: > > type t = string > external id_prim : 'a -> 'a = "%identity" > let id x = x > let f x = x + x + x + x > let g x = x + x + x + x + x + x + x + x > > ocamlobjinfo module.cmx: > > ... > Approximation: > (0: function camlIdentity__id_1010 arity 1 (closed) (inline) -> _; > 1: function camlIdentity__f_1012 arity 1 (closed) (inline) -> _; > 2: function camlIdentity__g_1014 arity 1 (closed) -> _) > ... > > the function id and f will be inlined whatever the context of the call > is, but g won't be. > > If you want a function to be inlined, you can use the -inline option of > ocamlopt to increase the maximum size of inlined functions in the > module. Notice that recursive functions can't be inlined. > > The usage of private type is different. > When using generic comparison/equality/hash/set in an array, the > compiler generate an optimised code when the type is known to be one of > the fast cases: > > module M1 : sig > type t = private int > end = struct type t = int end > module M2 : sig > type t > end = struct type t = int end > > let a x y = x > y > let b (x:int) y = x > y > let c (x:M1.t) y = x > y > let d (x:M2.t) y = x > y > > the result of ocamlopt -dcmm: > > (function camlCompare__a_1014 (x/1015: addr y/1016: addr) > (extcall "caml_greaterthan" x/1015 y/1016 addr)) > > (function camlCompare__b_1017 (x/1018: addr y/1019: addr) > (+ (<< (> x/1018 y/1019) 1) 1)) > > (function camlCompare__c_1020 (x/1021: addr y/1022: addr) > (+ (<< (> x/1021 y/1022) 1) 1)) > > (function camlCompare__d_1023 (x/1024: addr y/1025: addr) > (extcall "caml_greaterthan" x/1024 y/1025 addr)) > > Here b and c will be a lot faster than a and d. > Using private type allows to keep those informations acros modules. > -- > Pierre > > Le Mon, 19 Nov 2012 18:28:32 +0000, > David House wrote : > >> If you wanted to investigate this yourself, you could compile with -S >> and look at the generated assembly. For such short functions, this is >> generally not very hard. >> >> On Mon, Nov 19, 2012 at 6:18 PM, Dario Teixeira >> wrote: >> > Hi, >> > >> >> Wouldn't 'type t = private string' help the compiler optimize this? >> > >> > >> > Possibly, though the semantics would change: what before was >> > an abstract type is now translucent (ie, not quite transparent). >> > >> > Regards, >> > Dario >> > >> > -- >> > Caml-list mailing list. Subscription management and archives: >> > https://sympa.inria.fr/sympa/arc/caml-list >> > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners >> > Bug reports: http://caml.inria.fr/bin/caml-bugs >> > > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs