From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Newsgroups: gmane.emacs.bugs Subject: bug#42147: 28.0.50; pure vs side-effect-free, missing optimizations? Date: Tue, 7 Jul 2020 18:55:39 +0200 Message-ID: References: <3A9CC2A3-8307-47B2-8D80-795C0AF020E1@acm.org> <0433A879-C98D-4B1A-B85C-A15DA9289099@acm.org> <1621669100.2102667.1593639091621@mail.yahoo.com> <775819003.2516724.1593687594435@mail.yahoo.com> <5F2B4684-34D1-4474-8909-9F435369FE54@acm.org> <705260433.2731607.1593698199171@mail.yahoo.com> <6CF8EE58-9A49-40E7-AA86-48AB39BF94BA@acm.org> <28B19D86-343C-4126-B95F-1F38735F73F2@acm.org> <1288c6a5-545b-f68c-ff6b-7683db3e54c1@cs.ucla.edu> <1690361185.4397117.1593879228865@mail.yahoo.com> <374F2E9C-E8C2-4362-8BEF-E6AA5EEE5C79@acm.org> <68F4CFD4-17BF-4ADA-B2EF-55281ACD2373@acm.org> <926674413.6042347.1594070583586@mail.yahoo.com> <475381031.6812910.1594139070322@mail.yahoo.com> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.14\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_088E5902-3449-4CC0-9EEA-22F13BAFCEEE" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="18002"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 42147-done@debbugs.gnu.org, Paul Eggert , Stefan Monnier , Andrea Corallo To: Andrea Corallo Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Jul 07 19:02:40 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jsqzP-0004XX-SK for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 07 Jul 2020 19:02:40 +0200 Original-Received: from localhost ([::1]:46780 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jsqzO-00084w-T8 for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 07 Jul 2020 13:02:38 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:44782) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jsqty-0006Wi-7H for bug-gnu-emacs@gnu.org; Tue, 07 Jul 2020 12:57:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:53330) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jsqtx-0007Zw-TZ for bug-gnu-emacs@gnu.org; Tue, 07 Jul 2020 12:57:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1jsqtx-0002Ru-Ss for bug-gnu-emacs@gnu.org; Tue, 07 Jul 2020 12:57:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 07 Jul 2020 16:57:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 42147 X-GNU-PR-Package: emacs Original-Received: via spool by 42147-done@debbugs.gnu.org id=D42147.15941409679345 (code D ref 42147); Tue, 07 Jul 2020 16:57:01 +0000 Original-Received: (at 42147-done) by debbugs.gnu.org; 7 Jul 2020 16:56:07 +0000 Original-Received: from localhost ([127.0.0.1]:36643 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jsqt5-0002Qf-GK for submit@debbugs.gnu.org; Tue, 07 Jul 2020 12:56:07 -0400 Original-Received: from mail80c50.megamailservers.eu ([91.136.10.90]:57500 helo=mail70c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jsqt2-0002QU-Hq for 42147-done@debbugs.gnu.org; Tue, 07 Jul 2020 12:56:06 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1594140952; bh=/OribfoKMMxTj8DjXKc8dJGWLCHp44aZqFTrE7y1xro=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=koU7MMqntjUvIb0lgnZj/9YAstQd/wUNKEZYrfa4SkXO/H7qfKPgrBF1nYvZVF3TJ gqvzqTr15064gTzkw3a+n8jUbX0GuYE+kiVc60sNKJk4drSHLA8EbSAgCkBUCnzii+ M4GkA7BkRssVbM9jXW4D1dxL+r112QV2LhxvgnLE= Feedback-ID: mattiase@acm.or Original-Received: from [192.168.0.4] (c188-150-171-71.bredband.comhem.se [188.150.171.71]) (authenticated bits=0) by mail70c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 067GtdOj006811; Tue, 7 Jul 2020 16:55:41 +0000 In-Reply-To: <475381031.6812910.1594139070322@mail.yahoo.com> X-Mailer: Apple Mail (2.3445.104.14) X-CTCH-RefID: str=0001.0A782F21.5F04A917.0076, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=OKBZIhSB c=1 sm=1 tr=0 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17 a=M51BFTxLslgA:10 a=zPQN9lk3ysA_GdDB1ogA:9 a=CjuIK1q_8ugA:10 a=Q2kcLhgP3hmHiaRPxBUA:9 a=B2y7HmGcmWMA:10 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:182809 Archived-At: --Apple-Mail=_088E5902-3449-4CC0-9EEA-22F13BAFCEEE Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii 7 juli 2020 kl. 18.24 skrev Andrea Corallo : > Sure I'm. The native compiler does it already but I'm curious to see > how you do it at source level and how generic it is. Not very, but doing it at source level has some advantages since it can = enable other source-level transformations. It's mainly a proof of concept -- for simplicity, it doesn't attempt to = be overly clever in the face of loops or setq. One snag is that because Emacs inline functions (defsubst) are inlined = as bytecode, they are usually not amenable to source optimisations. It = is only when a defsubst is imported from a different .el file that has = not yet been byte-compiled that it is integrated as source, and then the = machinery in this patch will nicely propagate constant arguments into = the body. --Apple-Mail=_088E5902-3449-4CC0-9EEA-22F13BAFCEEE Content-Disposition: attachment; filename=0001-Constprop-of-lexical-variables.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Constprop-of-lexical-variables.patch" Content-Transfer-Encoding: quoted-printable =46rom=206ba3ec19de923250394f86fbbdb843f43f2f519a=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Sat,=2028=20Dec=202019=2021:11:56=20+0100=0A= Subject:=20[PATCH]=20Constprop=20of=20lexical=20variables=0A=0ALexical=20= variables=20bound=20to=20a=20constant=20value=20(symbol,=20number=20or=20= string)=0Aare=20substituted=20at=20their=20point=20of=20use=20and=20the=20= variable=20then=20eliminated=0Aif=20possible.=20=20Example:=0A=0A=20=20= (let=20((x=20(+=202=203)))=20(f=20x))=20=20=3D>=20=20(f=205)=0A=0AThis=20= reduces=20code=20size,=20eliminates=20stack=20operations,=20and=20= enables=0Afurther=20optimisations.=20=20The=20constprop=20mechanism=20is=20= generally=20afraid=20of=0Avariable=20mutation,=20conditions=20and=20= loops.=0A=0A*=20lisp/emacs-lisp/byte-opt.el=20= (byte-optimize-enable-constprop):=0AMaster=20switch=20for=20constprop=20= optimisations.=0A(byte-optimize--lexvars,=20= byte-optimize--vars-outside-condition)=0A= (byte-optimize--vars-outside-loop,=20byte-optimize--constprop-mode)=0A= (byte-optimize--dynamic-vars):=20New=20dynamic=20variables.=0A= (byte-optimize--substitutable-p,=20byte-optimize-let-form):=20New.=0A= (byte-optimize-form-code-walker):=20Adapt=20several=20clauses=20for=20= constprop,=0Aand=20add=20clauses=20for=20'setq'=20and=20'defvar'.=0A*=20= test/lisp/emacs-lisp/bytecomp-tests.el=20(bytecomp-test-var)=0A= (bytecomp-test-get-var,=20bytecomp-test-identity)=0A= (byte-opt-testsuite-arith-data):=20Add=20constprop=20test=20cases.=0A---=0A= =20lisp/emacs-lisp/byte-opt.el=20=20=20=20=20=20=20=20=20=20=20=20|=20= 299=20+++++++++++++++++++------=0A=20= test/lisp/emacs-lisp/bytecomp-tests.el=20|=20=2059=20+++++=0A=202=20= files=20changed,=20290=20insertions(+),=2068=20deletions(-)=0A=0Adiff=20= --git=20a/lisp/emacs-lisp/byte-opt.el=20b/lisp/emacs-lisp/byte-opt.el=0A= index=20194ceee176..a4a14410b9=20100644=0A---=20= a/lisp/emacs-lisp/byte-opt.el=0A+++=20b/lisp/emacs-lisp/byte-opt.el=0A@@=20= -366,6=20+366,48=20@@=20byte-compile-unfold-lambda=0A=20=0C=0A=20;;;=20= implementing=20source-level=20optimizers=0A=20=0A+(defconst=20= byte-optimize-enable-constprop=20t=0A+=20=20"If=20non-nil,=20enable=20= constant=20propagation=20optimisations.")=0A+=0A+(defvar=20= byte-optimize--lexvars=20nil=0A+=20=20"Lexical=20variables=20in=20scope,=20= in=20reverse=20order=20of=20declaration.=0A+Each=20element=20is=20on=20= the=20form=20(NAME=20CHANGED=20[VALUE]),=20where:=0A+=20=20NAME=20is=20= the=20variable=20name,=0A+=20=20CHANGED=20is=20a=20boolean=20indicating=20= whether=20it's=20been=20changed=20(with=20setq),=0A+=20=20VALUE,=20if=20= present,=20is=20a=20substitutable=20expression.=0A+Earlier=20variables=20= shadow=20later=20ones=20with=20the=20same=20name.=0A+Only=20lexical=20= variables=20are=20included.")=0A+=0A+(defvar=20= byte-optimize--vars-outside-condition=20nil=0A+=20=20"Alist=20of=20= variables=20lexically=20bound=20outside=20conditionally=20executed=20= code.")=0A+=0A+(defvar=20byte-optimize--vars-outside-loop=20nil=0A+=20=20= "Alist=20of=20variables=20lexically=20bound=20outside=20the=20innermost=20= `while'=20loop.")=0A+=0A+(defvar=20byte-optimize--constprop-mode=20t=0A+=20= =20"Constant-propagation=20mode:=20When=20t,=20constprop=20is=20always=0A= +enabled;=20when=20nil,=20disabled=20for=20variables=20bound=20outside=20= the=0A+innermost=20loop;=20when=20`loop',=20disabled=20for=20changed=20= variables=20bound=0A+outside=20the=20innermost=20loop.")=0A+=0A+(defvar=20= byte-optimize--dynamic-vars=20nil=0A+=20=20"List=20of=20variables=20= declared=20as=20dynamic=20during=20optimisation.")=0A+=0A+(defun=20= byte-optimize--substitutable-p=20(expr)=0A+=20=20"Whether=20EXPR=20is=20= a=20constant=20that=20can=20be=20propagated."=0A+=20=20;;=20Only=20= consider=20numbers,=20symbols=20and=20strings=20to=20be=20values=20for=20= substitution=0A+=20=20;;=20purposes.=20=20Numbers=20and=20symbols=20are=20= immutable,=20and=20mutating=20string=0A+=20=20;;=20literals=20(or=20= results=20from=20constant-evaluated=20string-returning=20functions)=0A+=20= =20;;=20can=20be=20considered=20undefined.=0A+=20=20;;=20(What=20about=20= other=20quoted=20values,=20like=20conses?)=0A+=20=20(or=20(booleanp=20= expr)=0A+=20=20=20=20=20=20(numberp=20expr)=0A+=20=20=20=20=20=20= (stringp=20expr)=0A+=20=20=20=20=20=20(and=20(consp=20expr)=0A+=20=20=20=20= =20=20=20=20=20=20=20(eq=20(car=20expr)=20'quote)=0A+=20=20=20=20=20=20=20= =20=20=20=20(symbolp=20(cadr=20expr)))=0A+=20=20=20=20=20=20(keywordp=20= expr)))=0A+=0A=20(defun=20byte-optimize-form-code-walker=20(form=20= for-effect)=0A=20=20=20;;=0A=20=20=20;;=20For=20normal=20function=20= calls,=20We=20can=20just=20mapcar=20the=20optimizer=20the=20cdr.=20=20= But=0A@@=20-377,11=20+419,22=20@@=20byte-optimize-form-code-walker=0A=20=20= =20(let=20((fn=20(car-safe=20form))=0A=20=09tmp)=0A=20=20=20=20=20(cond=20= ((not=20(consp=20form))=0A-=09=20=20=20(if=20(not=20(and=20for-effect=0A= -=09=09=09=20(or=20byte-compile-delete-errors=0A-=09=09=09=20=20=20=20=20= (not=20(symbolp=20form))=0A-=09=09=09=20=20=20=20=20(eq=20form=20t))))=0A= -=09=20=20=20=20=20form))=0A+=20=20=20=20=20=20=20=20=20=20=20(cond=0A+=20= =20=20=20=20=20=20=20=20=20=20=20((and=20for-effect=0A+=09=09=20=20(or=20= byte-compile-delete-errors=0A+=09=09=20=20=20=20=20=20(not=20(symbolp=20= form))=0A+=09=09=20=20=20=20=20=20(eq=20form=20t)))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20nil)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= ((symbolp=20form)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20= ((lexvar=20(assq=20form=20byte-optimize--lexvars)))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(if=20(and=20(cddr=20lexvar)=20=20=20=20=20=20= ;=20Value=20available?=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(or=20(eq=20byte-optimize--constprop-mode=20t)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(not=20(assq=20form=20byte-optimize--vars-outside-loop))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(and=20(eq=20byte-optimize--constprop-mode=20'loop)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(not=20(cadr=20lexvar)))))=20=20;=20Variable=20unchanged?=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(caddr=20= lexvar)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20form)))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20(t=20form)))=0A=20=09=20=20((eq=20= fn=20'quote)=0A=20=09=20=20=20(if=20(cdr=20(cdr=20form))=0A=20=09=20=20=20= =20=20=20=20(byte-compile-warn=20"malformed=20quote=20form:=20`%s'"=0A@@=20= -402,29=20+455,19=20@@=20byte-optimize-form-code-walker=0A=20=09=20=20=20= ;;=20recursively=20enter=20the=20optimizer=20for=20the=20bindings=20and=20= body=0A=20=09=20=20=20;;=20of=20a=20let=20or=20let*.=20=20This=20for=20= depth-firstness:=20forms=20that=0A=20=09=20=20=20;;=20are=20more=20= deeply=20nested=20are=20optimized=20first.=0A-=09=20=20=20(cons=20fn=0A-=09= =20=20=20=20=20(cons=0A-=09=20=20=20=20=20=20(mapcar=20(lambda=20= (binding)=0A-=09=09=09=20(if=20(symbolp=20binding)=0A-=09=09=09=20=20=20=20= =20binding=0A-=09=09=09=20=20=20(if=20(cdr=20(cdr=20binding))=0A-=09=09=09= =20=20=20=20=20=20=20(byte-compile-warn=20"malformed=20let=20binding:=20= `%s'"=0A-=09=09=09=09=09=09=20=20(prin1-to-string=20binding)))=0A-=09=09=09= =20=20=20(list=20(car=20binding)=0A-=09=09=09=09=20(byte-optimize-form=20= (nth=201=20binding)=20nil))))=0A-=09=09=20=20=20=20=20=20(nth=201=20= form))=0A-=09=20=20=20=20=20=20(byte-optimize-body=20(cdr=20(cdr=20= form))=20for-effect))))=0A+=20=20=20=20=20=20=20=20=20=20=20(cons=20fn=20= (byte-optimize-let-form=20fn=20(cdr=20form)=20for-effect)))=0A=20=09=20=20= ((eq=20fn=20'cond)=0A-=09=20=20=20(cons=20fn=0A-=09=09=20(mapcar=20= (lambda=20(clause)=0A-=09=09=09=20=20=20=20(if=20(consp=20clause)=0A-=09=09= =09=09(cons=0A-=09=09=09=09=20(byte-optimize-form=20(car=20clause)=20= nil)=0A-=09=09=09=09=20(byte-optimize-body=20(cdr=20clause)=20= for-effect))=0A-=09=09=09=20=20=20=20=20=20(byte-compile-warn=20= "malformed=20cond=20form:=20`%s'"=0A-=09=09=09=09=09=09=20= (prin1-to-string=20clause))=0A-=09=09=09=20=20=20=20=20=20clause))=0A-=09= =09=09=20(cdr=20form))))=0A+=20=20=20=20=20=20=20=20=20=20=20(let=20= ((byte-optimize--vars-outside-condition=20byte-optimize--lexvars))=0A+=09= =20=20=20=20=20(cons=20fn=0A+=09=09=20=20=20(mapcar=20(lambda=20(clause)=0A= +=09=09=09=20=20=20=20=20(if=20(consp=20clause)=0A+=09=09=09=09=20(cons=0A= +=09=09=09=09=20=20(byte-optimize-form=20(car=20clause)=20nil)=0A+=09=09=09= =09=20=20(byte-optimize-body=20(cdr=20clause)=20for-effect))=0A+=09=09=09= =20=20=20=20=20=20=20(byte-compile-warn=20"malformed=20cond=20form:=20= `%s'"=0A+=09=09=09=09=09=09=20=20(prin1-to-string=20clause))=0A+=09=09=09= =20=20=20=20=20=20=20clause))=0A+=09=09=09=20=20=20(cdr=20form)))))=0A=20= =09=20=20((eq=20fn=20'progn)=0A=20=09=20=20=20;;=20As=20an=20extra=20= added=20bonus,=20this=20simplifies=20(progn=20)=20-->=20.=0A=20=09=20= =20=20(if=20(cdr=20(cdr=20form))=0A@@=20-456,36=20+499,54=20@@=20= byte-optimize-form-code-walker=0A=20=09=20=20=20=20=20(byte-compile-warn=20= "too=20few=20arguments=20for=20`if'"))=0A=20=09=20=20=20(cons=20fn=0A=20=09= =20=20=20=20=20(cons=20(byte-optimize-form=20(nth=201=20form)=20nil)=0A-=09= =20=20=20=20=20=20=20(cons=0A-=09=09(byte-optimize-form=20(nth=202=20= form)=20for-effect)=0A-=09=09(byte-optimize-body=20(nthcdr=203=20form)=20= for-effect)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(let=20((byte-optimize--vars-outside-condition=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= byte-optimize--lexvars))=0A+=09=20=20=20=20=20=20=20=20=20=20=20=20=20= (cons=0A+=09=09=20=20=20=20=20=20(byte-optimize-form=20(nth=202=20form)=20= for-effect)=0A+=09=09=20=20=20=20=20=20(byte-optimize-body=20(nthcdr=203=20= form)=20for-effect))))))=0A=20=0A=20=09=20=20((memq=20fn=20'(and=20or))=20= =20;=20Remember,=20and/or=20are=20control=20structures.=0A-=09=20=20=20= ;;=20Take=20forms=20off=20the=20back=20until=20we=20can't=20any=20more.=0A= -=09=20=20=20;;=20In=20the=20future=20it=20could=20conceivably=20be=20a=20= problem=20that=20the=0A-=09=20=20=20;;=20subexpressions=20of=20these=20= forms=20are=20optimized=20in=20the=20reverse=0A-=09=20=20=20;;=20order,=20= but=20it's=20ok=20for=20now.=0A-=09=20=20=20(if=20for-effect=0A-=09=20=20= =20=20=20=20=20(let=20((backwards=20(reverse=20(cdr=20form))))=0A-=09=09=20= (while=20(and=20backwards=0A-=09=09=09=20=20=20=20=20(null=20(setcar=20= backwards=0A-=09=09=09=09=09=20=20=20(byte-optimize-form=20(car=20= backwards)=0A-=09=09=09=09=09=09=09=20=20=20=20=20=20=20for-effect))))=0A= -=09=09=20=20=20(setq=20backwards=20(cdr=20backwards)))=0A-=09=09=20(if=20= (and=20(cdr=20form)=20(null=20backwards))=0A-=09=09=20=20=20=20=20= (byte-compile-log=0A-=09=09=20=20=20=20=20=20"=20=20all=20subforms=20of=20= %s=20called=20for=20effect;=20deleted"=20form))=0A-=09=09=20(and=20= backwards=0A-=09=09=20=20=20=20=20=20(cons=20fn=20(nreverse=20(mapcar=20= 'byte-optimize-form=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20backwards)))))=0A-=09=20=20=20=20=20(cons=20fn=20= (mapcar=20'byte-optimize-form=20(cdr=20form)))))=0A-=0A-=09=20=20((eq=20= fn=20'while)=0A-=20=20=20=20=20=20=20=20=20=20=20(unless=20(consp=20(cdr=20= form))=0A-=09=20=20=20=20=20(byte-compile-warn=20"too=20few=20arguments=20= for=20`while'"))=0A-=20=20=20=20=20=20=20=20=20=20=20(cons=20fn=0A-=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cons=20(byte-optimize-form=20= (cadr=20form)=20nil)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(byte-optimize-body=20(cddr=20form)=20t))))=0A+=20=20=20= =20=20=20=20=20=20=20=20;;=20We=20have=20to=20optimise=20in=20= left-to-right=20order,=20but=20doing=20so=0A+=20=20=20=20=20=20=20=20=20=20= =20;;=20we=20miss=20some=20optimisation=20opportunities:=20consider=0A+=20= =20=20=20=20=20=20=20=20=20=20;;=20(and=20A=20B)=20in=20a=20for-effect=20= context,=20where=20B=20=3D>=20nil.=0A+=20=20=20=20=20=20=20=20=20=20=20= ;;=20Then=20A=20could=20be=20optimised=20in=20a=20for-effect=20context=20= too.=0A+=20=20=20=20=20=20=20=20=20=20=20(let=20((tail=20(cdr=20form))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(args=20nil))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20(when=20tail=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20;;=20The=20first=20argument=20is=20always=20= unconditional.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20= (byte-optimize-form=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(car=20tail)=20(and=20for-effect=20(null=20(cdr=20= tail))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= args)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20tail=20= (cdr=20tail))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20= Remaining=20arguments=20are=20conditional.=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(let=20((byte-optimize--vars-outside-condition=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= byte-optimize--lexvars))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(while=20tail=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(push=20(byte-optimize-form=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(car=20tail)=20(and=20= for-effect=20(null=20(cdr=20tail))))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20args)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(setq=20tail=20(cdr=20tail)))))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20(cons=20fn=20(nreverse=20args))))=0A+=0A= +=20=20=20=20=20=20=20=20=20=20((eq=20fn=20'while)=0A+=20=20=20=20=20=20=20= =20=20=20=20(let=20((byte-optimize--vars-outside-condition=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20byte-optimize--lexvars)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (byte-optimize--vars-outside-loop=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20byte-optimize--lexvars))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20;;=20Traverse=20the=20loop=20twice:=20first=20without=20any=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20constprop,=20to=20detect=20= setq=20forms...=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((opt=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20= ((byte-optimize--constprop-mode=20nil))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(cons=20(byte-optimize-form=20(nth=20= 1=20form)=20nil)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(byte-optimize-body=20(nthcdr=202=20form)=20= t)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20...=20then=20= in=20loop=20mode,=20allowing=20substitution=20of=20variables=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20;;=20bound=20inside=20all=20loops=20= or=20not=20changed=20anywhere.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20;;=20This=20is=20a=20bit=20slow=20(exponential=20in=20the=20number=20= of=20nested=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20loops).=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20= ((byte-optimize--constprop-mode=20'loop))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(cons=20fn=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(cons=20(byte-optimize-form=20(car=20opt)=20= nil)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(byte-optimize-body=20(cdr=20opt)=20t)))))))=0A=20=0A= =20=09=20=20((eq=20fn=20'interactive)=0A=20=09=20=20=20= (byte-compile-warn=20"misplaced=20interactive=20spec:=20`%s'"=0A@@=20= -498,12=20+559,14=20@@=20byte-optimize-form-code-walker=0A=20=09=20=20=20= form)=0A=20=0A=20=09=20=20((eq=20fn=20'condition-case)=0A-=20=20=20=20=20= =20=20=20=20=20=20`(condition-case=20,(nth=201=20form)=20;Not=20= evaluated.=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ,(byte-optimize-form=20(nth=202=20form)=20for-effect)=0A-=20=20=20=20=20=20= =20=20=20=20=20=20=20=20,@(mapcar=20(lambda=20(clause)=0A-=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20`(,(car=20= clause)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20,@(byte-optimize-body=20(cdr=20clause)=20= for-effect)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(nthcdr=203=20form))))=0A+=20=20=20=20=20=20=20=20=20=20=20= (let=20((byte-optimize--vars-outside-condition=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20byte-optimize--lexvars))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20`(condition-case=20,(nth=201=20form)=20;Not=20= evaluated.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ,(byte-optimize-form=20(nth=202=20form)=20for-effect)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20,@(mapcar=20(lambda=20(clause)=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= `(,(car=20clause)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20,@(byte-optimize-body=20(cdr=20= clause)=20for-effect)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(nthcdr=203=20form)))))=0A=20=0A=20=09=20=20= ((eq=20fn=20'unwind-protect)=0A=20=09=20=20=20;;=20the=20"protected"=20= part=20of=20an=20unwind-protect=20is=20compiled=20(and=20thus=0A@@=20= -511,14=20+574,21=20@@=20byte-optimize-form-code-walker=0A=20=09=20=20=20= ;;=20non-protected=20part=20has=20the=20same=20for-effect=20status=20as=20= the=0A=20=09=20=20=20;;=20unwind-protect=20itself.=20=20(The=20protected=20= part=20is=20always=20for=20effect,=0A=20=09=20=20=20;;=20but=20that=20= isn't=20handled=20properly=20yet.)=0A-=09=20=20=20(cons=20fn=0A-=09=09=20= (cons=20(byte-optimize-form=20(nth=201=20form)=20for-effect)=0A-=09=09=20= =20=20=20=20=20=20(cdr=20(cdr=20form)))))=0A+=20=20=20=20=20=20=20=20=20=20= =20(let*=20((byte-optimize--vars-outside-condition=20= byte-optimize--lexvars)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(bodyform=20(byte-optimize-form=20(nth=201=20form)=20for-effect)))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20(cons=20fn=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(cons=20bodyform=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(pcase=20(cddr=20= form)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(`(:fun-body=20,f)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20:fun-body=20= (byte-optimize-form=20f=20nil)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(unwindforms=20= unwindforms))))))=0A=20=0A=20=09=20=20((eq=20fn=20'catch)=0A-=09=20=20=20= (cons=20fn=0A-=09=09=20(cons=20(byte-optimize-form=20(nth=201=20form)=20= nil)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(byte-optimize-body=20(cdr=20form)=20for-effect))))=0A+=20=20=20=20=20= =20=20=20=20=20=20(let=20((byte-optimize--vars-outside-condition=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20byte-optimize--lexvars))=0A= +=09=20=20=20=20=20(cons=20fn=0A+=09=09=20=20=20(cons=20= (byte-optimize-form=20(nth=201=20form)=20nil)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(byte-optimize-body=20= (cdr=20form)=20for-effect)))))=0A=20=0A=20=09=20=20((eq=20fn=20'ignore)=0A= =20=09=20=20=20;;=20Don't=20treat=20the=20args=20to=20`ignore'=20as=20= being=0A@@=20-528,7=20+598,45=20@@=20byte-optimize-form-code-walker=0A=20= =09=20=20=20`(prog1=20nil=20.=20,(mapcar=20'byte-optimize-form=20(cdr=20= form))))=0A=20=0A=20=20=20=20=20=20=20=20=20=20=20;;=20Needed=20as=20= long=20as=20we=20run=20byte-optimize-form=20after=20cconv.=0A-=20=20=20=20= =20=20=20=20=20=20((eq=20fn=20'internal-make-closure)=20form)=0A+=20=20=20= =20=20=20=20=20=20=20((eq=20fn=20'internal-make-closure)=0A+=20=20=20=20=20= =20=20=20=20=20=20;;=20Look=20up=20free=20vars=20and=20mark=20them=20as=20= changed,=20so=20that=20they=0A+=20=20=20=20=20=20=20=20=20=20=20;;=20= won't=20be=20optimised=20away.=0A+=20=20=20=20=20=20=20=20=20=20=20= (dolist=20(var=20(caddr=20form))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= (let=20((lexvar=20(assq=20var=20byte-optimize--lexvars)))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(when=20lexvar=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(setcar=20(cdr=20lexvar)=20t))))=0A+=20=20=20=20= =20=20=20=20=20=20=20form)=0A+=0A+=20=20=20=20=20=20=20=20=20=20((eq=20= fn=20'setq)=0A+=20=20=20=20=20=20=20=20=20=20=20(let=20((args=20(cdr=20= form))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (var-expr-list=20nil))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(while=20= args=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(unless=20(and=20= (consp=20args)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(symbolp=20(car=20args))=20(consp=20(cdr=20= args)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (byte-compile-warn=20"malformed=20setq=20form:=20%S"=20form))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(let*=20((var=20(car=20args))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(expr=20= (cadr=20args))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(lexvar=20(assq=20var=20byte-optimize--lexvars))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(value=20= (byte-optimize-form=20expr=20nil)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(when=20lexvar=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20;;=20If=20it's=20bound=20outside=20conditional,=20= invalidate.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (if=20(assq=20var=20byte-optimize--vars-outside-condition)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20We=20are=20= in=20conditional=20code=20and=20the=20variable=20was=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20bound=20outside:=20= cancel=20substitutions.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(setcdr=20(cdr=20lexvar)=20nil)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setcdr=20(cdr=20lexvar)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(and=20(byte-optimize--substitutable-p=20value)=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(list=20value))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(setcar=20(cdr=20lexvar)=20t))=20=20=20;=20Mark=20= variable=20as=20changed.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(push=20var=20var-expr-list)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(push=20value=20var-expr-list))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(setq=20args=20(cddr=20args)))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20(cons=20fn=20(nreverse=20var-expr-list))))=0A+=0A+=20= =20=20=20=20=20=20=20=20=20((eq=20fn=20'defvar)=0A+=20=20=20=20=20=20=20=20= =20=20=20(when=20(and=20(>=3D=20(length=20form)=202)=20(symbolp=20(cadr=20= form)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20(cadr=20form)=20= byte-optimize--dynamic-vars))=0A+=20=20=20=20=20=20=20=20=20=20=20form)=0A= =20=0A=20=20=20=20=20=20=20=20=20=20=20((byte-code-function-p=20fn)=0A=20= =20=20=20=20=20=20=20=20=20=20=20(cons=20fn=20(mapcar=20= #'byte-optimize-form=20(cdr=20form))))=0A@@=20-563,6=20+671,60=20@@=20= byte-optimize-form-code-walker=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(error=20(cons=20fn=20args))))=0A=20=09=20=20=20=20= =20=20=20(cons=20fn=20args)))))))=0A=20=0A+(defun=20= byte-optimize-let-form=20(head=20form=20for-effect)=0A+=20=20(if=20(and=20= lexical-binding=20byte-optimize-enable-constprop)=0A+=20=20=20=20=20=20= (let*=20((byte-optimize--lexvars=20byte-optimize--lexvars)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20(new-lexvars=20nil)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20(let-vars=20nil))=0A+=20=20=20=20=20=20=20=20(dolist=20= (binding=20(car=20form))=0A+=20=20=20=20=20=20=20=20=20=20(let*=20((name=20= (cond=20((consp=20binding)=20(car=20binding))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((symbolp=20= binding)=20binding)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(t=0A+=09=09=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(byte-compile-warn=20"malformed=20let=20binding:=20`%S'"=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= binding))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(expr=20= (and=20(consp=20binding)=20(consp=20(cdr=20binding))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (byte-optimize-form=20(cadr=20binding)=20nil)))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(value=20(and=20= (byte-optimize--substitutable-p=20expr)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20expr)))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(lexical=20(not=20= (or=20(special-variable-p=20name)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (memq=20name=20byte-compile-bound-variables)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(memq=20name=20byte-optimize--dynamic-vars))))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(lexinfo=20(and=20lexical=20(cons=20name=20= (cons=20nil=20value)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20(push=20= (cons=20name=20(cons=20expr=20(cdr=20lexinfo)))=20let-vars)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20(when=20lexinfo=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(push=20lexinfo=20(if=20(eq=20head=20'let*)=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20byte-optimize--lexvars=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20new-lexvars)))))=0A+=20=20= =20=20=20=20=20=20(setq=20byte-optimize--lexvars=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(append=20new-lexvars=20byte-optimize--lexvars))=0A= +=20=20=20=20=20=20=20=20;;=20Walk=20the=20body=20expressions,=20which=20= may=20mutate=20some=20of=20the=20records,=0A+=20=20=20=20=20=20=20=20;;=20= and=20generate=20new=20bindings=20that=20exlude=20unused=20variables.=0A= +=20=20=20=20=20=20=20=20(let*=20((opt-body=20(byte-optimize-body=20(cdr=20= form)=20for-effect))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (bindings=20nil))=0A+=20=20=20=20=20=20=20=20=20=20(dolist=20(var=20= let-vars)=0A+=20=20=20=20=20=20=20=20=20=20=20=20;;=20VAR=20is=20(NAME=20= EXPR=20[CHANGED=20[VALUE]])=0A+=20=20=20=20=20=20=20=20=20=20=20=20(if=20= (and=20(nthcdr=203=20var)=20(not=20(nth=202=20var))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= byte-optimize--constprop-mode)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(when=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20;;=20This=20warning=20makes=20the=20compiler=20very=20chatty,=20but=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20it=20does=20= find=20the=20occasional=20mistake.=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(byte-compile-warn=20"eliminating=20local=20variable=20= %S"=20(car=20var)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20= (list=20(nth=200=20var)=20(nth=201=20var))=20bindings)))=0A+=20=20=20=20=20= =20=20=20=20=20(cons=20bindings=20opt-body)))=0A+=0A+=20=20=20=20;;=20= With=20dynamic=20binding,=20no=20substitutions=20are=20in=20effect.=0A+=20= =20=20=20(let=20((byte-optimize--lexvars=20nil))=0A+=20=20=20=20=20=20= (cons=0A+=20=20=20=20=20=20=20(mapcar=20(lambda=20(binding)=0A+=09=20=20=20= =20=20=20=20=20=20(if=20(symbolp=20binding)=0A+=09=09=20=20=20=20=20= binding=0A+=09=20=20=20=20=20=20=20=20=20=20=20(when=20(or=20(atom=20= binding)=20(cddr=20binding))=0A+=09=09=20=20=20=20=20(byte-compile-warn=20= "malformed=20let=20binding:=20`%S'"=20binding))=0A+=09=20=20=20=20=20=20=20= =20=20=20=20(list=20(car=20binding)=0A+=09=09=20=20=20=20=20=20=20=20=20= (byte-optimize-form=20(nth=201=20binding)=20nil))))=0A+=09=20=20=20=20=20= =20=20(car=20form))=0A+=20=20=20=20=20=20=20(byte-optimize-body=20(cdr=20= form)=20for-effect)))))=0A+=0A=20(defun=20byte-optimize-all-constp=20= (list)=0A=20=20=20"Non-nil=20if=20all=20elements=20of=20LIST=20satisfy=20= `macroexp-const-p'."=0A=20=20=20(let=20((constant=20t))=0A@@=20-607,6=20= +769,7=20@@=20byte-optimize-body=0A=20=20=20;;=20all-for-effect=20is=20= true.=20=20returns=20a=20new=20list=20of=20forms.=0A=20=20=20(let=20= ((rest=20forms)=0A=20=09(result=20nil)=0A+=20=20=20=20=20=20=20=20= (byte-optimize--dynamic-vars=20byte-optimize--dynamic-vars)=0A=20=09fe=20= new)=0A=20=20=20=20=20(while=20rest=0A=20=20=20=20=20=20=20(setq=20fe=20= (or=20all-for-effect=20(cdr=20rest)))=0Adiff=20--git=20= a/test/lisp/emacs-lisp/bytecomp-tests.el=20= b/test/lisp/emacs-lisp/bytecomp-tests.el=0Aindex=20= c235dd43fc..07320cf921=20100644=0A---=20= a/test/lisp/emacs-lisp/bytecomp-tests.el=0A+++=20= b/test/lisp/emacs-lisp/bytecomp-tests.el=0A@@=20-31,6=20+31,15=20@@=0A=20= (require=20'bytecomp)=0A=20=0A=20;;;=20Code:=0A+(defvar=20= bytecomp-test-var=20nil)=0A+=0A+(defun=20bytecomp-test-get-var=20()=0A+=20= =20bytecomp-test-var)=0A+=0A+(defun=20bytecomp-test-identity=20(x)=0A+=20= =20"Identity,=20but=20hidden=20from=20some=20optimisations."=0A+=20=20x)=0A= +=0A=20(defconst=20byte-opt-testsuite-arith-data=0A=20=20=20'(=0A=20=20=20= =20=20;;=20some=20functional=20tests=0A@@=20-349,6=20+358,56=20@@=20= byte-opt-testsuite-arith-data=0A=20=20=20=20=20=20=20=20=20=20=20=20=20= '((a=20c)=20(b=20c)=20(7=20c)=20(-3=20c)=20(nil=20nil)=20(t=20c)=20(q=20= c)=20(r=20c)=20(s=20c)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(t=20= c)=20(x=20"a")=20(x=20"c")=20(x=20c)=20(x=20d)=20(x=20e)))=0A=20=0A+=20=20= =20=20;;=20Constprop=20test=20cases=0A+=20=20=20=20(let=20((a=20'alpha)=20= (b=20(concat=20"be"=20"ta"))=20(c=20nil)=20(d=20t)=20(e=20:gamma)=0A+=20=20= =20=20=20=20=20=20=20=20(f=20'(delta=20epsilon)))=0A+=20=20=20=20=20=20= (list=20a=20b=20c=20d=20e=20f))=0A+=0A+=20=20=20=20(let=20((x=201)=20(y=20= (+=203=204)))=0A+=20=20=20=20=20=20(list=0A+=20=20=20=20=20=20=20(let=20= (q=20(y=20x)=20(z=20y))=0A+=20=20=20=20=20=20=20=20=20(if=20q=20x=20= (list=20x=20y=20z)))))=0A+=0A+=20=20=20=20(let*=20((x=203)=20(y=20(*=20x=20= 2))=20(x=20(1+=20y)))=0A+=20=20=20=20=20=20x)=0A+=0A+=20=20=20=20(let=20= ((x=201)=20(bytecomp-test-var=202)=20(y=203))=0A+=20=20=20=20=20=20(list=20= x=20bytecomp-test-var=20(bytecomp-get-test-var)=20y))=0A+=0A+=20=20=20=20= (progn=0A+=20=20=20=20=20=20(defvar=20d)=0A+=20=20=20=20=20=20(let=20((x=20= 'a)=20(y=20'b))=20(list=20x=20y)))=0A+=0A+=20=20=20=20(let=20((x=202))=0A= +=20=20=20=20=20=20(list=20x=20(setq=20x=2013)=20(setq=20x=20(*=20x=20= 2))=20x))=0A+=0A+=20=20=20=20(let=20((x=20'a)=20(y=20'b))=0A+=20=20=20=20= =20=20(setq=20y=20x=0A+=20=20=20=20=20=20=20=20=20=20=20=20x=20(cons=20= 'c=20y)=0A+=20=20=20=20=20=20=20=20=20=20=20=20y=20x)=0A+=20=20=20=20=20=20= (list=20x=20y))=0A+=0A+=20=20=20=20(let=20((x=203))=0A+=20=20=20=20=20=20= (let=20((y=20x)=20z)=0A+=20=20=20=20=20=20=20=20(setq=20x=205)=0A+=20=20=20= =20=20=20=20=20(setq=20y=20(+=20y=208))=0A+=20=20=20=20=20=20=20=20(setq=20= z=20(if=20(bytecomp-test-identity=20t)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(progn=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(setq=20x=20(+=20x=201))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20y))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20x=20(+=20x=20= 2))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20x=20= y)))=0A+=20=20=20=20=20=20=20=20(list=20x=20y=20z)))=0A+=0A+=20=20=20=20= (let=20((i=201)=20(s=200)=20(x=2013))=0A+=20=20=20=20=20=20(while=20(<=20= i=205)=0A+=20=20=20=20=20=20=20=20(setq=20s=20(+=20s=20i))=0A+=20=20=20=20= =20=20=20=20(setq=20i=20(1+=20i)))=0A+=20=20=20=20=20=20(list=20s=20x=20= i))=0A+=0A+=20=20=20=20(let=20((x=202))=0A+=20=20=20=20=20=20(list=20(or=20= (bytecomp-identity=20'a)=20(setq=20x=203))=20x))=0A+=0A=20=20=20=20=20;;=20= `substring'=20bytecode=20generation=20(bug#39709).=0A=20=20=20=20=20= (substring=20"abcdef")=0A=20=20=20=20=20(substring=20"abcdef"=202)=0A--=20= =0A2.21.1=20(Apple=20Git-122.3)=0A=0A= --Apple-Mail=_088E5902-3449-4CC0-9EEA-22F13BAFCEEE--