From mboxrd@z Thu Jan  1 00:00:00 1970
Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail
From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= <mattiase@acm.org>
Newsgroups: gmane.emacs.bugs
Subject: bug#36139: [PATCH] Make better use of the switch op in cond forms
Date: Sat, 8 Jun 2019 16:40:07 +0200
Message-ID: <68467ACF-DA49-4EBA-BA3B-7339DB22A456@acm.org>
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\))
Content-Type: multipart/mixed;
 boundary="Apple-Mail=_6425368A-6F6F-40E3-9751-3E52F91F6248"
Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226";
	logging-data="30483"; mail-complaints-to="usenet@blaine.gmane.org"
Cc: Stefan Monnier <monnier@iro.umontreal.ca>
To: 36139@debbugs.gnu.org
Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Jun 08 17:16:43 2019
Return-path: <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org>
Envelope-to: geb-bug-gnu-emacs@m.gmane.org
Original-Received: from lists.gnu.org ([209.51.188.17])
	by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
	(Exim 4.89)
	(envelope-from <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org>)
	id 1hZd5G-0007lB-Gy
	for geb-bug-gnu-emacs@m.gmane.org; Sat, 08 Jun 2019 17:16:42 +0200
Original-Received: from localhost ([::1]:58998 helo=lists.gnu.org)
	by lists.gnu.org with esmtp (Exim 4.86_2)
	(envelope-from <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org>)
	id 1hZd5F-0007cM-Hb
	for geb-bug-gnu-emacs@m.gmane.org; Sat, 08 Jun 2019 11:16:41 -0400
Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:49970)
 by lists.gnu.org with esmtp (Exim 4.86_2)
 (envelope-from <Debian-debbugs@debbugs.gnu.org>) id 1hZd4l-0007a7-9g
 for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2019 11:16:13 -0400
Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <Debian-debbugs@debbugs.gnu.org>) id 1hZd4j-0004wA-53
 for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2019 11:16:11 -0400
Original-Received: from debbugs.gnu.org ([209.51.188.43]:39967)
 by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16)
 (Exim 4.71) (envelope-from <Debian-debbugs@debbugs.gnu.org>)
 id 1hZd4c-0004tF-Gk
 for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2019 11:16:03 -0400
Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2)
 (envelope-from <Debian-debbugs@debbugs.gnu.org>) id 1hZd4c-0003Qf-BA
 for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2019 11:16:02 -0400
X-Loop: help-debbugs@gnu.org
Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= <mattiase@acm.org>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces@debbugs.gnu.org>
Resent-CC: bug-gnu-emacs@gnu.org
Resent-Date: Sat, 08 Jun 2019 15:16:02 +0000
Resent-Message-ID: <handler.36139.B.156000695013159@debbugs.gnu.org>
Resent-Sender: help-debbugs@gnu.org
X-GNU-PR-Message: report 36139
X-GNU-PR-Package: emacs
X-GNU-PR-Keywords: patch
X-Debbugs-Original-To: bug-gnu-emacs@gnu.org
Original-Received: via spool by submit@debbugs.gnu.org id=B.156000695013159
 (code B ref -1); Sat, 08 Jun 2019 15:16:02 +0000
Original-Received: (at submit) by debbugs.gnu.org; 8 Jun 2019 15:15:50 +0000
Original-Received: from localhost ([127.0.0.1]:53511 helo=debbugs.gnu.org)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <debbugs-submit-bounces@debbugs.gnu.org>)
 id 1hZd4P-0003QB-Cw
 for submit@debbugs.gnu.org; Sat, 08 Jun 2019 11:15:49 -0400
Original-Received: from lists.gnu.org ([209.51.188.17]:56234)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mattiase@acm.org>) id 1hZd4O-0003Q4-0d
 for submit@debbugs.gnu.org; Sat, 08 Jun 2019 11:15:48 -0400
Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:49805)
 by lists.gnu.org with esmtp (Exim 4.86_2)
 (envelope-from <mattiase@acm.org>) id 1hZd4D-0007UD-GR
 for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2019 11:15:44 -0400
Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <mattiase@acm.org>) id 1hZd43-0004Xq-Pm
 for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2019 11:15:33 -0400
Original-Received: from mail1423c50.megamailservers.eu ([91.136.14.23]:58010
 helo=mail102c50.megamailservers.eu)
 by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)
 (Exim 4.71) (envelope-from <mattiase@acm.org>) id 1hZd3u-0004Ru-PT
 for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2019 11:15:21 -0400
X-Authenticated-User: mattiase@bredband.net
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu;
 s=maildub; t=1560004810;
 bh=q7jFxCHF7YGiYJ2CX4fZBdTgsgWfSDK80UCY2jKuCwY=;
 h=From:Subject:Date:Cc:To:From;
 b=ICZlOMpNjru7eAhjAW1n/sL+87zypGBstm0GJu0kegpjCv/+HEXsgnL0TYbfs9mrx
 2nAojpCqecINUzHH1t3bnrF23rrWSSV5Tvs/n9eT4CtITp/fXug8tbPiOW3jUk9ORQ
 Y4lHDHvVtEV96pnVio9f8fVDJYUc6jypHvCK341k=
Feedback-ID: mattiase@acm.or
Original-Received: from [192.168.0.4] ([188.150.171.71]) (authenticated bits=0)
 by mail102c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x58Ee737011987; 
 Sat, 8 Jun 2019 14:40:09 +0000
X-Mailer: Apple Mail (2.3445.104.11)
X-CTCH-RefID: str=0001.0A0B0213.5CFBC8CA.0011, 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=F7x5iJpN c=1 sm=1 tr=0 a=SF+I6pRkHZhrawxbOkkvaA==:117
 a=SF+I6pRkHZhrawxbOkkvaA==:17 a=6To3NTLLAc8gFo8t5NcA:9
 a=7Zwj6sZBwVKJAoWSPKxL6X1jA+E=:19 a=CjuIK1q_8ugA:10
 a=E_EwgWnIFQbYCWLjBlUA:9 a=B2y7HmGcmWMA:10 a=mTj2RzUfRsJlQHX1IeMA:9
 a=KPFwjdhr0wLR6wY-cI4A:9 a=J5JVcn0FUx--a41e-UEA:9 a=hcRNxtQ6DiqpJ61ql5UA:9
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no
 timestamps) [generic]
X-BeenThere: debbugs-submit@debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Received-From: 209.51.188.43
X-BeenThere: bug-gnu-emacs@gnu.org
List-Id: "Bug reports for GNU Emacs,
 the Swiss army knife of text editors" <bug-gnu-emacs.gnu.org>
List-Unsubscribe: <https://lists.gnu.org/mailman/options/bug-gnu-emacs>,
 <mailto:bug-gnu-emacs-request@gnu.org?subject=unsubscribe>
List-Archive: <https://lists.gnu.org/archive/html/bug-gnu-emacs>
List-Post: <mailto:bug-gnu-emacs@gnu.org>
List-Help: <mailto:bug-gnu-emacs-request@gnu.org?subject=help>
List-Subscribe: <https://lists.gnu.org/mailman/listinfo/bug-gnu-emacs>,
 <mailto:bug-gnu-emacs-request@gnu.org?subject=subscribe>
Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org
Original-Sender: "bug-gnu-emacs"
 <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org>
Xref: news.gmane.org gmane.emacs.bugs:160240
Archived-At: <http://permalink.gmane.org/gmane.emacs.bugs/160240>


--Apple-Mail=_6425368A-6F6F-40E3-9751-3E52F91F6248
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=us-ascii

Currently, `cond' forms will only use a switch op under very specific =
circumstances, which limits their potential utility: every condition =
must be a scalar comparison (eq, eql or equal) between a variable and a =
constant; the same variable and the same test function must be used =
everywhere. These restrictions also limit the generation of switch ops =
from `pcase' and `cl-case' constructs.

In actual `cond' forms, scalar comparisons are mixed with multi-value =
ones (memq, memql, member); different comparisons are mixed, since the =
type of values can vary at runtime. There are also non-switch =
comparisons thrown into the same `cond' for convenience, typically at =
the beginning or end. Occasionally, there are even multiple switch-like =
sequences against different variables in the same cond.

Attached is a set of patches which gradually eliminate many of these =
restrictions. Each patch makes a fixed and hopefully easily-reviewed =
improvement. Short overview:

* 0001-Compile-list-member-functions-in-cond-to-switch.patch

Allow memq, memql and member to be used in switch generation, since =
these are idiomatically used for multiple values with the same body. =
They are also used by `pcase' and `cl-case'. For example,

 (cond ((eq x 'a) 11)
       ((memq x '(b c d)) 22))

will generate a single switch as if the code had been

 (cond ((eq x 'a) 11)
       ((eq x 'b) 22)
       ((eq x 'c) 22)
       ((eq x 'd) 22))

- that is, the byte code for the body (22) will be generated thrice.

* 0002-Share-identical-switch-clause-bodies.patch

An improvement of the above to share the body byte code between all =
values of the same `cond' clause. This means that the switch jump table =
is no longer an injective mapping.

* 0003-Tighter-pcase-or-pattern-member-function-selection.patch

Make `pcase' use the most specific comparison function (memq instead of =
memql, etc) in each case, depending on the values.
This patch is technically independent of the other ones, but improves =
code generation for `pcase'.

* 0004-Compile-cond-with-heterogeneous-tests-into-switch.patch

Allow switch generation with a mixture of eq, eql, equal, memq, memql =
and member.

* 0005-Compile-any-subsequence-of-cond-clauses-to-switch.patch

Generalise the code to produce switch ops for any switch-like part of a =
`cond' form. These switches can use different variables, and there can =
be any number of non-switch clauses before, after and between the switch =
clauses.

Performance: The patch set is loosely monotonous with the assumptions =
already present, in the sense that if the current code generator does =
not produce slower code in any case, nor is it expected to do so after =
the patches have been applied. In practice, micro-benchmarks naturally =
show the expected gains, but I haven't found much real-world code that =
is easy enough to benchmark. Some unpublished tree-traversal code =
improved about 7 %.


--Apple-Mail=_6425368A-6F6F-40E3-9751-3E52F91F6248
Content-Disposition: attachment;
	filename=0001-Compile-list-member-functions-in-cond-to-switch.patch
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="0001-Compile-list-member-functions-in-cond-to-switch.patch"
Content-Transfer-Encoding: quoted-printable

=46rom=207ddfbaf4e50f96d0feb05983c4f1d144af774052=20Mon=20Sep=2017=20=
00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20=
<mattiase@acm.org>=0ADate:=20Tue,=2021=20May=202019=2011:56:14=20+0200=0A=
Subject:=20[PATCH=201/5]=20Compile=20list=20member=20functions=20in=20=
cond=20to=20switch=0A=0A*=20lisp/emacs-lisp/bytecomp.el=20=
(byte-compile-cond-jump-table-info):=0AExpand=20`memq',=20`memql'=20and=20=
`member'=20to=20their=20corresponding=0Aequality=20tests.=0A---=0A=20=
lisp/emacs-lisp/bytecomp.el=20|=2046=20=
+++++++++++++++++++++++++------------=0A=201=20file=20changed,=2031=20=
insertions(+),=2015=20deletions(-)=0A=0Adiff=20--git=20=
a/lisp/emacs-lisp/bytecomp.el=20b/lisp/emacs-lisp/bytecomp.el=0Aindex=20=
38cce14fd6..8f089119de=20100644=0A---=20a/lisp/emacs-lisp/bytecomp.el=0A=
+++=20b/lisp/emacs-lisp/bytecomp.el=0A@@=20-4117,23=20+4117,39=20@@=20=
byte-compile-cond-jump-table-info=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-compile-cond-vars=20=
(cadr=20condition)=20(cl-caddr=20condition))))=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(obj1=20(car-safe=20vars))=0A=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(obj2=20=
(cdr-safe=20vars))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(body=20(cdr-safe=20clause)))=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(body=20(cdr-safe=20clause))=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20equality)=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(unless=20prev-var=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(setq=20prev-var=20obj1))=0A-=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(unless=20prev-test=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(setq=20prev-test=20test))=0A-=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(if=20(and=20obj1=20(memq=20test=20'(eq=20=
eql=20equal))=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(eq=20test=20prev-test)=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(eq=20obj1=20prev-var))=0A-=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20discard=20duplicate=20=
clauses=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(unless=20(assoc=20obj2=20cases=20test)=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(push=20(list=20obj2=20body)=20cases))=0A=
-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20(and=20=
(macroexp-const-p=20condition)=20condition)=0A-=09=09=20=20=20=20=20=
(progn=20(push=20(list=20byte-compile--default-val=0A-=09=09=09=09=09(or=20=
body=20`(,condition)))=0A-=09=09=09=09=20=20cases)=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(throw=20=
'break=20t))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20ok=20nil)=0A+=20=20=20=20=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=20=20=20=20((and=20obj1=20(memq=20=
test=20'(eq=20eql=20equal))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(eq=20obj1=20prev-var)=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(or=20(not=20prev-test)=20(eq=20=
test=20prev-test)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20prev-test=20test)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20;;=20discard=20duplicate=20clauses=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(unless=20(assoc=20obj2=20cases=20test)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20(list=20obj2=20=
body)=20cases)))=0A+=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
((and=20obj1=20(memq=20test=20'(memq=20memql=20member))=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(eq=20obj1=20=
prev-var)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(listp=20obj2)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(setq=20equality=20(cdr=20(assq=20test=20'((memq=20=20=20=
.=20eq)=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=20=20=20=20=20=20(memql=20=20.=20eql)=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=20=20=20=20=20=20=
(member=20.=20equal)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(or=20(not=20prev-test)=20(eq=20equality=20=
prev-test)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20=
prev-test=20equality)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20;;=20Expand=20to=20individual=20equality=20tests.=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(dolist=20(elem=20obj2)=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(unless=20(assoc=20elem=20=
cases=20equality)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(push=20(list=20elem=20(or=20body=20`(',(funcall=20test=20elem=20=
obj2))))=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=20cases))))=0A+=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20((and=20(macroexp-const-p=20condition)=20condition)=0A+=09=09=20=
(push=20(list=20byte-compile--default-val=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(or=20body=20=
`(,condition)))=0A+=09=09=20=20=20=20=20=20=20cases)=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(throw=20'break=20t))=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(t=20(setq=20ok=20nil)=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(throw=20'break=20nil))))))=0A=
=20=20=20=20=20=20=20=20=20=20(list=20(cons=20prev-test=20prev-var)=20=
(nreverse=20cases)))))=0A=20=0A--=20=0A2.20.1=20(Apple=20Git-117)=0A=0A=

--Apple-Mail=_6425368A-6F6F-40E3-9751-3E52F91F6248
Content-Disposition: attachment;
	filename=0002-Share-identical-switch-clause-bodies.patch
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="0002-Share-identical-switch-clause-bodies.patch"
Content-Transfer-Encoding: quoted-printable

=46rom=208e3a4317488940adfd58a43e2f66acafba2ea11f=20Mon=20Sep=2017=20=
00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20=
<mattiase@acm.org>=0ADate:=20Sun,=2026=20May=202019=2014:04:22=20+0200=0A=
Subject:=20[PATCH=202/5]=20Share=20identical=20switch=20clause=20bodies=0A=
=0A*=20lisp/emacs-lisp/bytecomp.el=20(byte-compile-cond-jump-table-info)=0A=
(byte-compile-cond-jump-table):=0ACases=20now=20have=20multiple=20=
values.=0A*=20lisp/emacs-lisp/byte-opt.el=20(byte-decompile-bytecode-1)=0A=
(byte-optimize-lapcode):=20Don't=20assume=20switch=20hash=20tables=20to=20=
be=20injective.=0A---=0A=20lisp/emacs-lisp/byte-opt.el=20|=2021=20=
+++++++--------=0A=20lisp/emacs-lisp/bytecomp.el=20|=2051=20=
++++++++++++++++++++++---------------=0A=202=20files=20changed,=2042=20=
insertions(+),=2030=20deletions(-)=0A=0Adiff=20--git=20=
a/lisp/emacs-lisp/byte-opt.el=20b/lisp/emacs-lisp/byte-opt.el=0Aindex=20=
44cca6136c..b0aa407c8b=20100644=0A---=20a/lisp/emacs-lisp/byte-opt.el=0A=
+++=20b/lisp/emacs-lisp/byte-opt.el=0A@@=20-1376,11=20+1376,15=20@@=20=
byte-decompile-bytecode-1=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=20do=20(setq=20last-constant=20=
(copy-hash-table=20e))=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=20and=20return=20nil)=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20;;=20Replace=20all=20addresses=20with=20TAGs.=0A=
-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(maphash=20#'(lambda=20=
(value=20tag)=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(let=20(newtag)=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(setq=20=
newtag=20(byte-compile-make-tag))=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(push=20(cons=20=
tag=20newtag)=20tags)=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(puthash=20value=20newtag=20=
last-constant)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(maphash=20#'(lambda=20(value=20offset)=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(let=20((match=20=
(assq=20offset=20tags)))=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(puthash=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=20=20=20=20=20(if=20match=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(cdr=20match)=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(let=20((tag=20(byte-compile-make-tag)))=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(push=20(cons=20offset=20tag)=20=
tags)=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=20tag))=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=20last-constant)))=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=
last-constant)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20=
Replace=20the=20hash=20table=20referenced=20in=20the=20lapcode=20with=20=
our=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20modified=20=
one.=0A@@=20-1722,13=20+1726,10=20@@=20byte-optimize-lapcode=0A=20=09=09=20=
=20=20=20=20keep-going=20t)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20;;=20replace=20references=20to=20tag=20in=20jump=20tables,=20if=20any=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(dolist=20(table=20=
byte-compile-jump-tables)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(catch=20'break=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(maphash=20#'(lambda=20(value=20tag)=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=
(when=20(equal=20tag=20lap0)=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;;=20each=20=
tag=20occurs=20only=20once=20in=20the=20jump=20table=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(puthash=20value=20lap1=20table)=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=
(throw=20'break=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=20table))))=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(puthash=20value=20lap1=20table)))=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=20table)))=0A=20=09=20=
=20=20=20=20=20;;=0A=20=09=20=20=20=20=20=20;;=20unused-TAG:=20-->=20=
<deleted>=0A=20=09=20=20=20=20=20=20;;=0Adiff=20--git=20=
a/lisp/emacs-lisp/bytecomp.el=20b/lisp/emacs-lisp/bytecomp.el=0Aindex=20=
8f089119de..5930386166=20100644=0A---=20a/lisp/emacs-lisp/bytecomp.el=0A=
+++=20b/lisp/emacs-lisp/bytecomp.el=0A@@=20-4105,9=20+4105,10=20@@=20=
byte-compile-cond-jump-table-info=0A=20TEST=20and=20VAR=20are=20the=20=
same=20throughout=20all=20conditions.=0A=20VALUE=20satisfies=20=
`macroexp-const-p'.=0A=20=0A-Return=20a=20list=20of=20the=20form=20=
((TEST=20.=20VAR)=20=20((VALUE=20BODY)=20...))"=0A+Return=20a=20list=20=
of=20the=20form=20((TEST=20.=20VAR)=20=20((VALUES=20BODY)=20...))"=0A=20=20=
=20(let=20((cases=20'())=0A=20=20=20=20=20=20=20=20=20(ok=20t)=0A+=20=20=20=
=20=20=20=20=20(all-keys=20nil)=0A=20=20=20=20=20=20=20=20=20prev-var=20=
prev-test)=0A=20=20=20=20=20(and=20(catch=20'break=0A=20=20=20=20=20=20=20=
=20=20=20=20=20(dolist=20(clause=20(cdr=20clauses)=20ok)=0A@@=20-4126,23=20=
+4127,30=20@@=20byte-compile-cond-jump-table-info=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(eq=20obj1=20prev-var)=0A=
=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=
(not=20prev-test)=20(eq=20test=20prev-test)))=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(setq=20prev-test=20test)=0A-=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20;;=20discard=20duplicate=20clauses=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(unless=20(assoc=20obj2=20=
cases=20test)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(push=20(list=20obj2=20body)=20cases)))=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20;;=20Discard=20values=20already=20tested=20for.=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(unless=20(member=20obj2=20=
all-keys)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(push=20obj2=20all-keys)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(push=20(list=20(list=20obj2)=20body)=20cases)))=0A=20=0A=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((and=20obj1=20(memq=20test=20=
'(memq=20memql=20member))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(eq=20obj1=20prev-var)=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(listp=20obj2)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Require=20a=20=
non-empty=20body,=20since=20the=20member=20function=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20value=20depends=20=
on=20the=20switch=20argument.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20body=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(setq=20equality=20(cdr=20(assq=20test=20=
'((memq=20=20=20.=20eq)=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=20=20=20=20=20=20=20(memql=20=20.=20eql)=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=20=20=20=
=20=20=20=20(member=20.=20equal)))))=0A=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(not=20prev-test)=20(eq=20=
equality=20prev-test)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(setq=20prev-test=20equality)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20;;=20Expand=20to=20individual=20equality=20tests.=0A-=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(dolist=20(elem=20obj2)=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(unless=20(assoc=20=
elem=20cases=20equality)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(push=20(list=20elem=20(or=20body=20`(',(funcall=20=
test=20elem=20obj2))))=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=20cases))))=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((vals=20nil))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20;;=20Discard=20values=20already=20=
tested=20for.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(dolist=20(elem=20obj2)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(unless=20(funcall=20test=20elem=20all-keys)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20elem=20=
vals)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(when=20vals=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(setq=20all-keys=20(append=20vals=20all-keys))=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20(list=20vals=20=
body)=20cases))))=0A=20=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20((and=20(macroexp-const-p=20condition)=20condition)=0A=20=09=09=20=
(push=20(list=20byte-compile--default-val=0A@@=20-4158,18=20+4166,20=20=
@@=20byte-compile-cond-jump-table=0A=20=20=20=20=20=20=20=20=20=20(test=20=
(caar=20table-info))=0A=20=20=20=20=20=20=20=20=20=20(var=20(cdar=20=
table-info))=0A=20=20=20=20=20=20=20=20=20=20(cases=20(cadr=20=
table-info))=0A-=20=20=20=20=20=20=20=20=20jump-table=20test-obj=20body=20=
tag=20donetag=20default-tag=20default-case)=0A+=20=20=20=20=20=20=20=20=20=
jump-table=20test-objects=20body=20tag=20donetag=20default-tag=20=
default-case)=0A=20=20=20=20=20(when=20(and=20cases=20(not=20(=3D=20=
(length=20cases)=201)))=0A=20=20=20=20=20=20=20;;=20TODO:=20Once=20=
:linear-search=20is=20implemented=20for=20`make-hash-table'=0A=20=20=20=20=
=20=20=20;;=20set=20it=20to=20`t'=20for=20cond=20forms=20with=20a=20=
small=20number=20of=20cases.=0A-=20=20=20=20=20=20(setq=20jump-table=20=
(make-hash-table=0A-=09=09=09:test=20test=0A-=09=09=09:purecopy=20t=0A-=09=
=09=09:size=20(if=20(assq=20byte-compile--default-val=20cases)=0A-=09=09=09=
=09=20=20(1-=20(length=20cases))=0A-=09=09=09=09(length=20cases)))=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20default-tag=20(byte-compile-make-tag)=0A=
-=20=20=20=20=20=20=20=20=20=20=20=20donetag=20(byte-compile-make-tag))=0A=
+=20=20=20=20=20=20(let=20((nvalues=20(apply=20#'+=20(mapcar=20(lambda=20=
(case)=20(length=20(car=20case)))=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=20cases))))=0A+=20=20=20=20=20=20=20=20(setq=20jump-table=20=
(make-hash-table=0A+=09=09=09=20=20:test=20test=0A+=09=09=09=20=20=
:purecopy=20t=0A+=09=09=09=20=20:size=20(if=20(assq=20=
byte-compile--default-val=20cases)=0A+=09=09=09=09=20=20=20=20(1-=20=
nvalues)=0A+=09=09=09=09=20=20nvalues))))=0A+=20=20=20=20=20=20(setq=20=
default-tag=20(byte-compile-make-tag))=0A+=20=20=20=20=20=20(setq=20=
donetag=20(byte-compile-make-tag))=0A=20=20=20=20=20=20=20;;=20The=20=
structure=20of=20byte-switch=20code:=0A=20=20=20=20=20=20=20;;=0A=20=20=20=
=20=20=20=20;;=20varref=20var=0A@@=20-4206,10=20+4216,11=20@@=20=
byte-compile-cond-jump-table=0A=20=0A=20=20=20=20=20=20=20(dolist=20=
(case=20cases)=0A=20=20=20=20=20=20=20=20=20(setq=20tag=20=
(byte-compile-make-tag)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
test-obj=20(nth=200=20case)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
test-objects=20(nth=200=20case)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20body=20(nth=201=20case))=0A=20=20=20=20=20=20=20=20=20=
(byte-compile-out-tag=20tag)=0A-=20=20=20=20=20=20=20=20(puthash=20=
test-obj=20tag=20jump-table)=0A+=20=20=20=20=20=20=20=20(dolist=20(value=20=
test-objects)=0A+=20=20=20=20=20=20=20=20=20=20(puthash=20value=20tag=20=
jump-table))=0A=20=0A=20=20=20=20=20=20=20=20=20(let=20=
((byte-compile-depth=20byte-compile-depth)=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(init-depth=20byte-compile-depth))=0A--=20=0A2.20.1=20=
(Apple=20Git-117)=0A=0A=

--Apple-Mail=_6425368A-6F6F-40E3-9751-3E52F91F6248
Content-Disposition: attachment;
	filename=0003-Tighter-pcase-or-pattern-member-function-selection.patch
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="0003-Tighter-pcase-or-pattern-member-function-selection.patch"
Content-Transfer-Encoding: quoted-printable

=46rom=2016e72d20f6a13ff626721ae55b66e1c3848a5813=20Mon=20Sep=2017=20=
00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20=
<mattiase@acm.org>=0ADate:=20Tue,=2021=20May=202019=2012:19:38=20+0200=0A=
Subject:=20[PATCH=203/5]=20Tighter=20pcase=20or-pattern=20member=20=
function=20selection=0A=0A*=20lisp/emacs-lisp/pcase.el=20(pcase--u1):=0A=
Use=20the=20most=20specific=20of=20`memq',=20`memql'=20and=20`member'=20=
in=20or-patterns=0Awith=20constant=20cases.=20=20This=20improves=20=
performance=20and=20may=20help=20the=20byte-code=0Acompiler=20generate=20=
a=20switch.=0A*=20test/lisp/emacs-lisp/pcase-tests.el=20=
(pcase-tests-member):=0AAdd=20mixed-type=20or-pattern=20test=20cases.=0A=
---=0A=20lisp/emacs-lisp/pcase.el=20=20=20=20=20=20=20=20=20=20=20=20|=20=
15=20++++++++-------=0A=20test/lisp/emacs-lisp/pcase-tests.el=20|=20=206=20=
++++--=0A=202=20files=20changed,=2012=20insertions(+),=209=20=
deletions(-)=0A=0Adiff=20--git=20a/lisp/emacs-lisp/pcase.el=20=
b/lisp/emacs-lisp/pcase.el=0Aindex=20a644453a94..ae2cf8eb02=20100644=0A=
---=20a/lisp/emacs-lisp/pcase.el=0A+++=20b/lisp/emacs-lisp/pcase.el=0A@@=20=
-785,25=20+785,26=20@@=20pcase--u1=0A=20=20=20=20((eq=20'or=20(caar=20=
matches))=0A=20=20=20=20=20(let*=20((alts=20(cdar=20matches))=0A=20=20=20=
=20=20=20=20=20=20=20=20=20(var=20(if=20(eq=20(caar=20alts)=20'match)=20=
(cadr=20(car=20alts))))=0A-=20=20=20=20=20=20=20=20=20=20=20(simples=20=
'())=20(others=20'())=20(memql-ok=20t))=0A+=20=20=20=20=20=20=20=20=20=20=
=20(simples=20'())=20(others=20'())=20(mem-fun=20'memq))=0A=20=20=20=20=20=
=20=20(when=20var=0A=20=20=20=20=20=20=20=20=20(dolist=20(alt=20alts)=0A=20=
=20=20=20=20=20=20=20=20=20=20(if=20(and=20(eq=20(car=20alt)=20'match)=20=
(eq=20var=20(cadr=20alt))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((upat=20(cddr=20alt)))=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(eq=20(car-safe=20upat)=20=
'quote)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((val=20=
(cadr=20(cddr=20alt))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(unless=20(or=20(integerp=20val)=20(symbolp=20val))=0A-=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(setq=20memql-ok=20nil))=0A-=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20(cadr=20(cddr=20alt))=20=
simples))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cond=20=
((integerp=20val)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(when=20(eq=20mem-fun=20'memq)=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(setq=20mem-fun=20=
'memql)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20((not=20(symbolp=20val))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(setq=20mem-fun=20'member)))=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(push=20val=20simples))=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20(push=20alt=20others))))=0A=20=20=20=20=20=20=20=
(cond=0A=20=20=20=20=20=20=20=20((null=20alts)=20(error=20"Please=20=
avoid=20it")=20(pcase--u=20rest))=0A=20=20=20=20=20=20=20=20;;=20Yes,=20=
we=20can=20use=20`memql'=20(or=20`member')!=0A=20=20=20=20=20=20=20=20=
((>=20(length=20simples)=201)=0A=20=20=20=20=20=20=20=20=20(pcase--u1=20=
(cons=20`(match=20,var=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(pred=20=
(pcase--flip=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=
,(if=20memql-ok=20#'memql=20#'member)=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',simples)))=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(pred=20=
(pcase--flip=20,mem-fun=20',simples)))=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(cdr=20matches))=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20code=20vars=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20(null=20others)=20=
rest=0Adiff=20--git=20a/test/lisp/emacs-lisp/pcase-tests.el=20=
b/test/lisp/emacs-lisp/pcase-tests.el=0Aindex=20af8c9a3f3c..e8c0b8219c=20=
100644=0A---=20a/test/lisp/emacs-lisp/pcase-tests.el=0A+++=20=
b/test/lisp/emacs-lisp/pcase-tests.el=0A@@=20-51,9=20+51,11=20@@=20=
pcase-tests-grep=0A=20=0A=20(ert-deftest=20pcase-tests-member=20()=0A=20=20=
=20(should=20(pcase-tests-grep=0A-=20=20=20=20=20=20=20=20=20=20=20=
'memql=20(macroexpand-all=20'(pcase=20x=20((or=201=202=203)=20body)))))=0A=
+=20=20=20=20=20=20=20=20=20=20=20'memq=20(macroexpand-all=20'(pcase=20x=20=
((or=20'a=20'b=20'c)=20body)))))=0A=20=20=20(should=20(pcase-tests-grep=0A=
-=20=20=20=20=20=20=20=20=20=20=20'member=20(macroexpand-all=20'(pcase=20=
x=20((or=20"a"=202=203)=20body)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=
'memql=20(macroexpand-all=20'(pcase=20x=20((or=201=202=203=20'a)=20=
body)))))=0A+=20=20(should=20(pcase-tests-grep=0A+=20=20=20=20=20=20=20=20=
=20=20=20'member=20(macroexpand-all=20'(pcase=20x=20((or=20"a"=202=203=20=
'a)=20body)))))=0A=20=20=20(should-not=20(pcase-tests-grep=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20'memq=20(macroexpand-all=20'(pcase=20=
x=20((or=20"a"=202=203)=20body)))))=0A=20=20=20(should-not=20=
(pcase-tests-grep=0A--=20=0A2.20.1=20(Apple=20Git-117)=0A=0A=

--Apple-Mail=_6425368A-6F6F-40E3-9751-3E52F91F6248
Content-Disposition: attachment;
	filename=0004-Compile-cond-with-heterogeneous-tests-into-switch.patch
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="0004-Compile-cond-with-heterogeneous-tests-into-switch.patch"
Content-Transfer-Encoding: quoted-printable

=46rom=20876f73720ef3274352cf707dbeb1cbb02817cd03=20Mon=20Sep=2017=20=
00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20=
<mattiase@acm.org>=0ADate:=20Wed,=2022=20May=202019=2012:36:03=20+0200=0A=
Subject:=20[PATCH=204/5]=20Compile=20cond=20with=20heterogeneous=20tests=20=
into=20switch=0A=0AAllow=20any=20mixture=20of=20`eq',=20`eql'=20and=20=
`equal',=20`memq',=20`memql'=20and=0A`member'=20in=20a=20switch-like=20=
`cond'=20to=20be=20compiled=20into=20a=20single=20switch.=0A=0A*=20=
lisp/emacs-lisp/bytecomp.el=20(byte-compile--common-test):=20New.=0A=
(byte-compile-cond-jump-table-info):=20Use=20most=20specific=20common=20=
test.=0A*=20test/lisp/emacs-lisp/bytecomp-tests.el=20=
(byte-opt-testsuite-arith-data):=0AAdd=20test=20cases=20for=20=
multi-value=20clause=20cond=20forms.=0A---=0A=20=
lisp/emacs-lisp/bytecomp.el=20=20=20=20=20=20=20=20=20=20=20=20|=2029=20=
+++++++++++++++-----------=0A=20test/lisp/emacs-lisp/bytecomp-tests.el=20=
|=2025=20+++++++++++++++++++++-=0A=202=20files=20changed,=2041=20=
insertions(+),=2013=20deletions(-)=0A=0Adiff=20--git=20=
a/lisp/emacs-lisp/bytecomp.el=20b/lisp/emacs-lisp/bytecomp.el=0Aindex=20=
5930386166..5ee5ceac18=20100644=0A---=20a/lisp/emacs-lisp/bytecomp.el=0A=
+++=20b/lisp/emacs-lisp/bytecomp.el=0A@@=20-4098,6=20+4098,12=20@@=20=
byte-compile-cond-vars=0A=20=0A=20(defconst=20byte-compile--default-val=20=
(cons=20nil=20nil)=20"A=20unique=20object.")=0A=20=0A+(defun=20=
byte-compile--common-test=20(test-1=20test-2)=0A+=20=20"Most=20specific=20=
common=20test=20of=20`eq',=20`eql'=20and=20`equal'"=0A+=20=20(cond=20=
((or=20(eq=20test-1=20'equal)=20(eq=20test-2=20'equal))=20'equal)=0A+=20=20=
=20=20=20=20=20=20((or=20(eq=20test-1=20'eql)=20=20=20(eq=20test-2=20=
'eql))=20=20=20'eql)=0A+=20=20=20=20=20=20=20=20(t=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'eq)))=0A+=0A=20(defun=20=
byte-compile-cond-jump-table-info=20(clauses)=0A=20=20=20"If=20CLAUSES=20=
is=20a=20`cond'=20form=20where:=0A=20The=20condition=20for=20each=20=
clause=20is=20of=20the=20form=20(TEST=20VAR=20VALUE).=0A@@=20-4109,7=20=
+4115,8=20@@=20byte-compile-cond-jump-table-info=0A=20=20=20(let=20=
((cases=20'())=0A=20=20=20=20=20=20=20=20=20(ok=20t)=0A=20=20=20=20=20=20=
=20=20=20(all-keys=20nil)=0A-=20=20=20=20=20=20=20=20prev-var=20=
prev-test)=0A+=20=20=20=20=20=20=20=20(prev-test=20'eq)=0A+=20=20=20=20=20=
=20=20=20prev-var)=0A=20=20=20=20=20(and=20(catch=20'break=0A=20=20=20=20=
=20=20=20=20=20=20=20=20(dolist=20(clause=20(cdr=20clauses)=20ok)=0A=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let*=20((condition=20(car=20=
clause))=0A@@=20-4118,15=20+4125,13=20@@=20=
byte-compile-cond-jump-table-info=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-compile-cond-vars=20=
(cadr=20condition)=20(cl-caddr=20condition))))=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(obj1=20(car-safe=20vars))=0A=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(obj2=20=
(cdr-safe=20vars))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(body=20(cdr-safe=20clause))=0A-=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20equality)=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(body=20(cdr-safe=20clause)))=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(unless=20prev-var=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(setq=20prev-var=20obj1))=0A=20=20=20=20=
=20=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=20=20=20=20=20((and=20obj1=20(memq=20test=20'(eq=20eql=20equal))=0A=
-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(eq=20=
obj1=20prev-var)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(or=20(not=20prev-test)=20(eq=20test=20prev-test)))=0A-=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20prev-test=20test)=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(eq=20=
obj1=20prev-var))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20prev-test=20(byte-compile--common-test=20prev-test=20test))=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Discard=20values=20=
already=20tested=20for.=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(unless=20(member=20obj2=20all-keys)=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(push=20obj2=20all-keys)=0A@@=20-4137,12=20=
+4142,12=20@@=20byte-compile-cond-jump-table-info=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(listp=20obj2)=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Require=20=
a=20non-empty=20body,=20since=20the=20member=20function=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20value=20=
depends=20on=20the=20switch=20argument.=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20body=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(setq=20equality=20(cdr=20(assq=20=
test=20'((memq=20=20=20.=20eq)=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=20=20=20=20=20=20(memql=20=20.=20eql)=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=
=20=20=20=20=20=20(member=20.=20equal)))))=0A-=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(or=20(not=20prev-test)=20(eq=20=
equality=20prev-test)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(setq=20prev-test=20equality)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20body)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(setq=20prev-test=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-compile--common-test=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20prev-test=20(cdr=20=
(assq=20test=20'((memq=20=20=20.=20eq)=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=20=20=20(memql=20=20.=20eql)=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=20=20=
=20(member=20.=20equal))))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let=20((vals=20nil))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20;;=20Discard=20values=20already=20tested=20for.=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(dolist=20(elem=20=
obj2)=0Adiff=20--git=20a/test/lisp/emacs-lisp/bytecomp-tests.el=20=
b/test/lisp/emacs-lisp/bytecomp-tests.el=0Aindex=20=
f45c9209c1..87f2c13bf7=20100644=0A---=20=
a/test/lisp/emacs-lisp/bytecomp-tests.el=0A+++=20=
b/test/lisp/emacs-lisp/bytecomp-tests.el=0A@@=20-311,7=20+311,30=20@@=20=
byte-opt-testsuite-arith-data=0A=20=20=20=20=20(let=20((x=20"a"))=20=
(cond=20((equal=20x=20"a")=20'correct)=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((equal=20x=20"b")=20=
'incorrect)=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((equal=20x=20"a")=20'incorrect)=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((equal=20x=20"c")=20=
'incorrect))))=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((equal=20x=20"c")=20'incorrect)))=0A+=20=20=20=20;;=20=
Multi-value=20clauses=0A+=20=20=20=20(mapcar=20(lambda=20(x)=20(cond=20=
((eq=20x=20'a)=2011)=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((memq=20x=20'(b=20a=20c=20d))=20=
22)=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((eq=20x=20'c)=2033)=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((eq=20x=20=
'e)=2044)=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((memq=20x=20'(d=20f=20g))=2055)=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(t=2099)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20'(a=20b=20c=20d=20=
e=20f=20g=20h))=0A+=20=20=20=20(mapcar=20(lambda=20(x)=20(cond=20((eql=20=
x=201)=2011)=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((memq=20x=20'(a=20b=20c))=2022)=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((memql=20x=20'(2=201=204=201e-3))=2033)=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=
((eq=20x=20'd)=2044)=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((eql=20x=20=
#x10000000000000000))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20'(1=202=20=
4=201e-3=20a=20b=20c=20d=201.0=20#x10000000000000000))=0A+=20=20=20=20=
(mapcar=20(lambda=20(x)=20(cond=20((eq=20x=20'a)=2011)=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=
((memq=20x=20'(b=20d))=2022)=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((equal=20x=20'(a=20.=20=
b))=2033)=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((member=20x=20'(b=20c=201.5=202.5=20"X"=20=
(d)))=2044)=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((eql=20x=203.14)=2055)=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=
((memql=20x=20'(9=200.5=201.5=20q))=2066)=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(t=2099)))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20'(a=20b=20c=20d=20(d)=20(a=20.=20b)=20=
"X"=200.5=201.5=203.14=209=209.0))=0A+=20=20=20=20)=0A=20=20=20"List=20=
of=20expression=20for=20test.=0A=20Each=20element=20will=20be=20executed=20=
by=20interpreter=20and=20with=0A=20bytecompiled=20code,=20and=20their=20=
results=20compared.")=0A--=20=0A2.20.1=20(Apple=20Git-117)=0A=0A=

--Apple-Mail=_6425368A-6F6F-40E3-9751-3E52F91F6248
Content-Disposition: attachment;
	filename=0005-Compile-any-subsequence-of-cond-clauses-to-switch.patch
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="0005-Compile-any-subsequence-of-cond-clauses-to-switch.patch"
Content-Transfer-Encoding: quoted-printable

=46rom=209822f95ca1c3c92b2097c01b3f209d0155284be2=20Mon=20Sep=2017=20=
00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20=
<mattiase@acm.org>=0ADate:=20Fri,=207=20Jun=202019=2017:04:10=20+0200=0A=
Subject:=20[PATCH=205/5]=20Compile=20any=20subsequence=20of=20`cond'=20=
clauses=20to=20switch=0A=0AA=20single=20`cond'=20form=20can=20how=20be=20=
compiled=20to=20any=20number=20of=20switch=20ops,=0Ainterspersed=20with=20=
non-switch=20conditions=20in=20arbitrary=20ways.=20=20Previously,=0A=
switch=20ops=20would=20only=20be=20used=20for=20whole=20`cond'=20forms=20=
containing=20no=0Aother=20tests.=0A=0A*=20lisp/emacs-lisp/bytecomp.el=20=
(byte-compile--cond-vars):=0ARename=20from=20`byte-compile-cond-vars'.=0A=
(byte-compile--default-val):=20Remove.=0A=
(byte-compile--cond-switch-prefix):=0AReplace=20=
`byte-compile-cond-jump-table-info';=20now=20also=20returns=0Atrailing=20=
non-switch=20clauses.=0A(byte-compile-cond-jump-table):=20New=20=
arguments;=20no=20longer=20compiles=0Athe=20default=20case.=0A=
(byte-compile-cond):=20Look=20for=20and=20compile=20switches=20at=20any=20=
place=20in=20the=0Alist=20of=20clauses.=0A*=20=
test/lisp/emacs-lisp/bytecomp-tests.el=20=
(byte-opt-testsuite-arith-data):=0AAdd=20test=20expression.=0A---=0A=20=
lisp/emacs-lisp/bytecomp.el=20=20=20=20=20=20=20=20=20=20=20=20|=20339=20=
++++++++++++-------------=0A=20test/lisp/emacs-lisp/bytecomp-tests.el=20=
|=20=2015=20+-=0A=202=20files=20changed,=20173=20insertions(+),=20181=20=
deletions(-)=0A=0Adiff=20--git=20a/lisp/emacs-lisp/bytecomp.el=20=
b/lisp/emacs-lisp/bytecomp.el=0Aindex=205ee5ceac18..82e47794e3=20100644=0A=
---=20a/lisp/emacs-lisp/bytecomp.el=0A+++=20=
b/lisp/emacs-lisp/bytecomp.el=0A@@=20-4088,7=20+4088,7=20@@=20=
byte-compile-if=0A=20=09(byte-compile-out-tag=20donetag))))=0A=20=20=20=
(setq=20byte-compile--for-effect=20nil))=0A=20=0A-(defun=20=
byte-compile-cond-vars=20(obj1=20obj2)=0A+(defun=20=
byte-compile--cond-vars=20(obj1=20obj2)=0A=20=20=20;;=20We=20make=20sure=20=
that=20of=20OBJ1=20and=20OBJ2,=20one=20of=20them=20is=20a=20symbol,=0A=20=
=20=20;;=20and=20the=20other=20is=20a=20constant=20expression=20whose=20=
value=20can=20be=0A=20=20=20;;=20compared=20with=20`eq'=20(with=20=
`macroexp-const-p').=0A@@=20-4096,193=20+4096,172=20@@=20=
byte-compile-cond-vars=0A=20=20=20=20(and=20(symbolp=20obj1)=20=
(macroexp-const-p=20obj2)=20(cons=20obj1=20(eval=20obj2)))=0A=20=20=20=20=
(and=20(symbolp=20obj2)=20(macroexp-const-p=20obj1)=20(cons=20obj2=20=
(eval=20obj1)))))=0A=20=0A-(defconst=20byte-compile--default-val=20(cons=20=
nil=20nil)=20"A=20unique=20object.")=0A-=0A=20(defun=20=
byte-compile--common-test=20(test-1=20test-2)=0A=20=20=20"Most=20=
specific=20common=20test=20of=20`eq',=20`eql'=20and=20`equal'"=0A=20=20=20=
(cond=20((or=20(eq=20test-1=20'equal)=20(eq=20test-2=20'equal))=20=
'equal)=0A=20=20=20=20=20=20=20=20=20((or=20(eq=20test-1=20'eql)=20=20=20=
(eq=20test-2=20'eql))=20=20=20'eql)=0A=20=20=20=20=20=20=20=20=20(t=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'eq)))=0A=20=0A-(defun=20=
byte-compile-cond-jump-table-info=20(clauses)=0A-=20=20"If=20CLAUSES=20=
is=20a=20`cond'=20form=20where:=0A-The=20condition=20for=20each=20clause=20=
is=20of=20the=20form=20(TEST=20VAR=20VALUE).=0A-VAR=20is=20a=20variable.=0A=
-TEST=20and=20VAR=20are=20the=20same=20throughout=20all=20conditions.=0A=
-VALUE=20satisfies=20`macroexp-const-p'.=0A-=0A-Return=20a=20list=20of=20=
the=20form=20((TEST=20.=20VAR)=20=20((VALUES=20BODY)=20...))"=0A-=20=20=
(let=20((cases=20'())=0A-=20=20=20=20=20=20=20=20(ok=20t)=0A-=20=20=20=20=
=20=20=20=20(all-keys=20nil)=0A-=20=20=20=20=20=20=20=20(prev-test=20=
'eq)=0A-=20=20=20=20=20=20=20=20prev-var)=0A-=20=20=20=20(and=20(catch=20=
'break=0A-=20=20=20=20=20=20=20=20=20=20=20(dolist=20(clause=20(cdr=20=
clauses)=20ok)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20=
((condition=20(car=20clause))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(test=20(car-safe=20condition))=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(vars=20(when=20(consp=20=
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=20=20(byte-compile-cond-vars=20(cadr=20condition)=20=
(cl-caddr=20condition))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(obj1=20(car-safe=20vars))=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(obj2=20(cdr-safe=20vars))=0A-=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(body=20(cdr-safe=20=
clause)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(unless=20=
prev-var=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20=
prev-var=20obj1))=0A-=20=20=20=20=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=20=20=20=20((and=20obj1=20(memq=20=
test=20'(eq=20eql=20equal))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(eq=20obj1=20prev-var))=0A-=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(setq=20prev-test=20=
(byte-compile--common-test=20prev-test=20test))=0A-=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20;;=20Discard=20values=20already=20tested=20=
for.=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(unless=20=
(member=20obj2=20all-keys)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(push=20obj2=20all-keys)=0A-=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(push=20(list=20(list=20obj2)=20body)=20cases)))=0A=
-=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((and=20obj1=20=
(memq=20test=20'(memq=20memql=20member))=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(eq=20obj1=20prev-var)=0A-=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(listp=20obj2)=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20=
Require=20a=20non-empty=20body,=20since=20the=20member=20function=0A-=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20value=20=
depends=20on=20the=20switch=20argument.=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20body)=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(setq=20prev-test=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-compile--common-test=0A-=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20prev-test=20=
(cdr=20(assq=20test=20'((memq=20=20=20.=20eq)=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=20=20=20(memql=20=20.=20=
eql)=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=20=20=20(member=20.=20equal))))))=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((vals=20nil))=0A-=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20;;=20Discard=20values=20already=20tested=20=
for.=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(dolist=20=
(elem=20obj2)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(unless=20(funcall=20test=20elem=20all-keys)=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20elem=20vals)))=0A=
-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(when=20vals=0A=
-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20=
all-keys=20(append=20vals=20all-keys))=0A-=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(push=20(list=20vals=20body)=20cases))))=0A=
-=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((and=20=
(macroexp-const-p=20condition)=20condition)=0A-=09=09=20(push=20(list=20=
byte-compile--default-val=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(or=20body=20`(,condition)))=0A=
-=09=09=20=20=20=20=20=20=20cases)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(throw=20'break=20t))=0A-=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(t=20(setq=20ok=20nil)=0A-=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(throw=20'break=20nil))))))=0A-=20=20=20=20=20=20=
=20=20=20(list=20(cons=20prev-test=20prev-var)=20(nreverse=20cases)))))=0A=
-=0A-(defun=20byte-compile-cond-jump-table=20(clauses)=0A-=20=20(let*=20=
((table-info=20(byte-compile-cond-jump-table-info=20clauses))=0A-=20=20=20=
=20=20=20=20=20=20(test=20(caar=20table-info))=0A-=20=20=20=20=20=20=20=20=
=20(var=20(cdar=20table-info))=0A-=20=20=20=20=20=20=20=20=20(cases=20=
(cadr=20table-info))=0A-=20=20=20=20=20=20=20=20=20jump-table=20=
test-objects=20body=20tag=20donetag=20default-tag=20default-case)=0A-=20=20=
=20=20(when=20(and=20cases=20(not=20(=3D=20(length=20cases)=201)))=0A-=20=
=20=20=20=20=20;;=20TODO:=20Once=20:linear-search=20is=20implemented=20=
for=20`make-hash-table'=0A-=20=20=20=20=20=20;;=20set=20it=20to=20`t'=20=
for=20cond=20forms=20with=20a=20small=20number=20of=20cases.=0A-=20=20=20=
=20=20=20(let=20((nvalues=20(apply=20#'+=20(mapcar=20(lambda=20(case)=20=
(length=20(car=20case)))=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=
cases))))=0A-=20=20=20=20=20=20=20=20(setq=20jump-table=20=
(make-hash-table=0A-=09=09=09=20=20:test=20test=0A-=09=09=09=20=20=
:purecopy=20t=0A-=09=09=09=20=20:size=20(if=20(assq=20=
byte-compile--default-val=20cases)=0A-=09=09=09=09=20=20=20=20(1-=20=
nvalues)=0A-=09=09=09=09=20=20nvalues))))=0A-=20=20=20=20=20=20(setq=20=
default-tag=20(byte-compile-make-tag))=0A-=20=20=20=20=20=20(setq=20=
donetag=20(byte-compile-make-tag))=0A-=20=20=20=20=20=20;;=20The=20=
structure=20of=20byte-switch=20code:=0A-=20=20=20=20=20=20;;=0A-=20=20=20=
=20=20=20;;=20varref=20var=0A-=20=20=20=20=20=20;;=20constant=20=
#s(hash-table=20purecopy=20t=20data=20(val1=20(TAG1)=20val2=20(TAG2)))=0A=
-=20=20=20=20=20=20;;=20switch=0A-=20=20=20=20=20=20;;=20goto=20=
DEFAULT-TAG=0A-=20=20=20=20=20=20;;=20TAG1=0A-=20=20=20=20=20=20;;=20=
<clause=20body>=0A-=20=20=20=20=20=20;;=20goto=20DONETAG=0A-=20=20=20=20=20=
=20;;=20TAG2=0A-=20=20=20=20=20=20;;=20<clause=20body>=0A-=20=20=20=20=20=
=20;;=20goto=20DONETAG=0A-=20=20=20=20=20=20;;=20DEFAULT-TAG=0A-=20=20=20=
=20=20=20;;=20<body=20for=20`t'=20clause,=20if=20any=20(else=20`constant=20=
nil')>=0A-=20=20=20=20=20=20;;=20DONETAG=0A-=0A-=20=20=20=20=20=20=
(byte-compile-variable-ref=20var)=0A-=20=20=20=20=20=20=
(byte-compile-push-constant=20jump-table)=0A-=20=20=20=20=20=20=
(byte-compile-out=20'byte-switch)=0A-=0A-=20=20=20=20=20=20;;=20When=20=
the=20opcode=20argument=20is=20`byte-goto',=20`byte-compile-goto'=20sets=0A=
-=20=20=20=20=20=20;;=20`byte-compile-depth'=20to=20`nil'.=20However,=20=
we=20need=20`byte-compile-depth'=0A-=20=20=20=20=20=20;;=20to=20be=20=
non-nil=20for=20generating=20tags=20for=20all=20cases.=20Since=0A-=20=20=20=
=20=20=20;;=20`byte-compile-depth'=20will=20increase=20by=20at=20most=20=
1=20after=20compiling=0A-=20=20=20=20=20=20;;=20all=20of=20the=20clause=20=
(which=20is=20further=20enforced=20by=20cl-assert=20below)=0A-=20=20=20=20=
=20=20;;=20it=20should=20be=20safe=20to=20preserve=20its=20value.=0A-=20=20=
=20=20=20=20(let=20((byte-compile-depth=20byte-compile-depth))=0A-=20=20=20=
=20=20=20=20=20(byte-compile-goto=20'byte-goto=20default-tag))=0A-=0A-=20=
=20=20=20=20=20(let=20((default-match=20(assq=20=
byte-compile--default-val=20cases)))=0A-=20=20=20=20=20=20=20=20(when=20=
default-match=0A-=09=20=20(setq=20default-case=20(cadr=20default-match)=0A=
-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20cases=20(butlast=20=
cases))))=0A-=0A-=20=20=20=20=20=20(dolist=20(case=20cases)=0A-=20=20=20=20=
=20=20=20=20(setq=20tag=20(byte-compile-make-tag)=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20test-objects=20(nth=200=20case)=0A-=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20body=20(nth=201=20case))=0A-=20=20=20=20=20=20=20=
=20(byte-compile-out-tag=20tag)=0A-=20=20=20=20=20=20=20=20(dolist=20=
(value=20test-objects)=0A-=20=20=20=20=20=20=20=20=20=20(puthash=20value=20=
tag=20jump-table))=0A-=0A-=20=20=20=20=20=20=20=20(let=20=
((byte-compile-depth=20byte-compile-depth)=0A-=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(init-depth=20byte-compile-depth))=0A-=20=20=20=20=20=20=20=
=20=20=20;;=20Since=20`byte-compile-body'=20might=20increase=20=
`byte-compile-depth'=0A-=20=20=20=20=20=20=20=20=20=20;;=20by=201,=20not=20=
preserving=20its=20value=20will=20cause=20it=20to=20potentially=0A-=20=20=
=20=20=20=20=20=20=20=20;;=20increase=20by=20one=20for=20every=20clause=20=
body=20compiled,=20causing=0A-=20=20=20=20=20=20=20=20=20=20;;=20=
depth/tag=20conflicts=20or=20violating=20asserts=20down=20the=20road.=0A=
-=20=20=20=20=20=20=20=20=20=20;;=20To=20make=20sure=20=
`byte-compile-body'=20itself=20doesn't=20violate=20this,=0A-=20=20=20=20=20=
=20=20=20=20=20;;=20we=20use=20`cl-assert'.=0A-=20=20=20=20=20=20=20=20=20=
=20(if=20(null=20body)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(byte-compile-form=20t=20byte-compile--for-effect)=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20(byte-compile-body=20body=20byte-compile--for-effect))=0A=
-=20=20=20=20=20=20=20=20=20=20(cl-assert=20(or=20(=3D=20=
byte-compile-depth=20init-depth)=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(=3D=20byte-compile-depth=20(1+=20=
init-depth))))=0A-=20=20=20=20=20=20=20=20=20=20(byte-compile-goto=20=
'byte-goto=20donetag)=0A-=20=20=20=20=20=20=20=20=20=20(setcdr=20(cdr=20=
donetag)=20nil)))=0A-=0A-=20=20=20=20=20=20(byte-compile-out-tag=20=
default-tag)=0A-=20=20=20=20=20=20(if=20default-case=0A-=20=20=20=20=20=20=
=20=20=20=20(byte-compile-body-do-effect=20default-case)=0A-=20=20=20=20=20=
=20=20=20(byte-compile-constant=20nil))=0A-=20=20=20=20=20=20=
(byte-compile-out-tag=20donetag)=0A-=20=20=20=20=20=20(push=20jump-table=20=
byte-compile-jump-tables))))=0A+(defun=20=
byte-compile--cond-switch-prefix=20(clauses)=0A+=20=20"Find=20a=20switch=20=
corresponding=20to=20a=20prefix=20of=20CLAUSES,=20or=20nil=20if=20none.=0A=
+Return=20(TAIL=20VAR=20TEST=20CASES),=20where:=0A+=20=20TAIL=20is=20the=20=
remaining=20part=20of=20CLAUSES=20after=20the=20switch,=20including=0A+=20=
=20any=20default=20clause,=0A+=20=20VAR=20is=20the=20variable=20being=20=
switched=20on,=0A+=20=20TEST=20is=20the=20equality=20test=20(`eq',=20=
`eql'=20or=20`equal'),=0A+=20=20CASES=20is=20a=20list=20of=20(VALUES=20.=20=
BODY)=20where=20VALUES=20is=20a=20list=20of=20values=0A+=20=20=20=20=
corresponding=20to=20BODY=20(always=20non-empty)."=0A+=20=20(let=20=
((cases=20nil)=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=20=
Reversed=20list=20of=20(VALUES=20BODY).=0A+=20=20=20=20=20=20=20=20(keys=20=
nil)=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=20Switch=20=
keys=20seen=20so=20far.=0A+=20=20=20=20=20=20=20=20(switch-var=20nil)=0A=
+=20=20=20=20=20=20=20=20(switch-test=20'eq))=0A+=20=20=20=20(while=20=
(pcase=20(car=20clauses)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
(`((,fn=20,expr1=20,expr2)=20.=20,body)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(let*=20((vars=20(byte-compile--cond-vars=20expr1=20expr2))=0A=
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(var=20=
(car=20vars))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(value=20(cdr=20vars)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(and=20var=20(or=20(eq=20var=20switch-var)=20(not=20switch-var))=0A=
+=20=20=20=20=20=20=20=20=20=20=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=20=20=20=20=20=20=20=20=20=20=
((memq=20fn=20'(eq=20eql=20equal))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(setq=20switch-var=20var)=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20=
switch-test=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-compile--common-test=20switch-test=20=
fn))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(unless=20(member=20value=20keys)=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(push=20value=20keys)=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=
(push=20(cons=20(list=20value)=20(or=20body=20'(t)))=20cases))=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20t)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((and=20(memq=20=
fn=20'(memq=20memql=20member))=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(listp=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=
;;=20Require=20a=20non-empty=20body,=20since=20the=20member=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=
;;=20function=20value=20depends=20on=20the=20switch=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=
argument.=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=20body)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(setq=20switch-var=20var)=0A+=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20switch-test=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-compile--common-test=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=20switch-test=20=
(cdr=20(assq=20fn=20'((memq=20=20=20.=20eq)=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=20=20=20=20=20=20=20=20=20=
(memql=20=20.=20eql)=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=20=20=20=20=20=20=20=20=20(member=20.=20=
equal))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let=20((vals=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(dolist=20(elem=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=
(unless=20(funcall=20fn=20elem=20keys)=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(push=20elem=20=
vals)))=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(when=20vals=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(setq=20keys=20(append=20vals=20=
keys))=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(push=20(cons=20(nreverse=20vals)=20body)=20cases)))=0A=
+=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+=20=20=20=20=20=20(setq=20clauses=20(cdr=20clauses)))=0A+=20=20=
=20=20(and=20(>=20(length=20cases)=201)=0A+=20=20=20=20=20=20=20=20=20=
(list=20clauses=20switch-var=20switch-test=20(nreverse=20cases)))))=0A+=0A=
+(defun=20byte-compile-cond-jump-table=20(switch=20donetag)=0A+=20=20=
"Generate=20code=20for=20SWITCH,=20ending=20at=20DONETAG."=0A+=20=20=
(let*=20((var=20(car=20switch))=0A+=20=20=20=20=20=20=20=20=20(test=20=
(nth=201=20switch))=0A+=20=20=20=20=20=20=20=20=20(cases=20(nth=202=20=
switch))=0A+=20=20=20=20=20=20=20=20=20jump-table=20test-objects=20body=20=
tag=20default-tag)=0A+=20=20=20=20;;=20TODO:=20Once=20:linear-search=20=
is=20implemented=20for=20`make-hash-table'=0A+=20=20=20=20;;=20set=20it=20=
to=20`t'=20for=20cond=20forms=20with=20a=20small=20number=20of=20cases.=0A=
+=20=20=20=20(let=20((nvalues=20(apply=20#'+=20(mapcar=20(lambda=20=
(case)=20(length=20(car=20case)))=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=
=20cases))))=0A+=20=20=20=20=20=20(setq=20jump-table=20(make-hash-table=0A=
+=09=09=09:test=20test=0A+=09=09=09:purecopy=20t=0A+=09=09=09:size=20=
nvalues)))=0A+=20=20=20=20(setq=20default-tag=20(byte-compile-make-tag))=0A=
+=20=20=20=20;;=20The=20structure=20of=20byte-switch=20code:=0A+=20=20=20=
=20;;=0A+=20=20=20=20;;=20varref=20var=0A+=20=20=20=20;;=20constant=20=
#s(hash-table=20purecopy=20t=20data=20(val1=20(TAG1)=20val2=20(TAG2)))=0A=
+=20=20=20=20;;=20switch=0A+=20=20=20=20;;=20goto=20DEFAULT-TAG=0A+=20=20=
=20=20;;=20TAG1=0A+=20=20=20=20;;=20<clause=20body>=0A+=20=20=20=20;;=20=
goto=20DONETAG=0A+=20=20=20=20;;=20TAG2=0A+=20=20=20=20;;=20<clause=20=
body>=0A+=20=20=20=20;;=20goto=20DONETAG=0A+=20=20=20=20;;=20DEFAULT-TAG=0A=
+=20=20=20=20;;=20<body=20for=20remaining=20(non-switch)=20clauses>=0A+=20=
=20=20=20;;=20DONETAG=0A+=0A+=20=20=20=20(byte-compile-variable-ref=20=
var)=0A+=20=20=20=20(byte-compile-push-constant=20jump-table)=0A+=20=20=20=
=20(byte-compile-out=20'byte-switch)=0A+=0A+=20=20=20=20;;=20When=20the=20=
opcode=20argument=20is=20`byte-goto',=20`byte-compile-goto'=20sets=0A+=20=
=20=20=20;;=20`byte-compile-depth'=20to=20`nil'.=20However,=20we=20need=20=
`byte-compile-depth'=0A+=20=20=20=20;;=20to=20be=20non-nil=20for=20=
generating=20tags=20for=20all=20cases.=20Since=0A+=20=20=20=20;;=20=
`byte-compile-depth'=20will=20increase=20by=20at=20most=201=20after=20=
compiling=0A+=20=20=20=20;;=20all=20of=20the=20clause=20(which=20is=20=
further=20enforced=20by=20cl-assert=20below)=0A+=20=20=20=20;;=20it=20=
should=20be=20safe=20to=20preserve=20its=20value.=0A+=20=20=20=20(let=20=
((byte-compile-depth=20byte-compile-depth))=0A+=20=20=20=20=20=20=
(byte-compile-goto=20'byte-goto=20default-tag))=0A+=0A+=20=20=20=20=
(dolist=20(case=20cases)=0A+=20=20=20=20=20=20(setq=20tag=20=
(byte-compile-make-tag)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
test-objects=20(car=20case)=0A+=20=20=20=20=20=20=20=20=20=20=20=20body=20=
(cdr=20case))=0A+=20=20=20=20=20=20(byte-compile-out-tag=20tag)=0A+=20=20=
=20=20=20=20(dolist=20(value=20test-objects)=0A+=20=20=20=20=20=20=20=20=
(puthash=20value=20tag=20jump-table))=0A+=0A+=20=20=20=20=20=20(let=20=
((byte-compile-depth=20byte-compile-depth)=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20(init-depth=20byte-compile-depth))=0A+=20=20=20=20=20=20=20=20=
;;=20Since=20`byte-compile-body'=20might=20increase=20=
`byte-compile-depth'=0A+=20=20=20=20=20=20=20=20;;=20by=201,=20not=20=
preserving=20its=20value=20will=20cause=20it=20to=20potentially=0A+=20=20=
=20=20=20=20=20=20;;=20increase=20by=20one=20for=20every=20clause=20body=20=
compiled,=20causing=0A+=20=20=20=20=20=20=20=20;;=20depth/tag=20=
conflicts=20or=20violating=20asserts=20down=20the=20road.=0A+=20=20=20=20=
=20=20=20=20;;=20To=20make=20sure=20`byte-compile-body'=20itself=20=
doesn't=20violate=20this,=0A+=20=20=20=20=20=20=20=20;;=20we=20use=20=
`cl-assert'.=0A+=20=20=20=20=20=20=20=20(byte-compile-body=20body=20=
byte-compile--for-effect)=0A+=20=20=20=20=20=20=20=20(cl-assert=20(or=20=
(=3D=20byte-compile-depth=20init-depth)=0A+=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(=3D=20byte-compile-depth=20(1+=20=
init-depth))))=0A+=20=20=20=20=20=20=20=20(byte-compile-goto=20=
'byte-goto=20donetag)=0A+=20=20=20=20=20=20=20=20(setcdr=20(cdr=20=
donetag)=20nil)))=0A+=0A+=20=20=20=20(byte-compile-out-tag=20=
default-tag)=0A+=20=20=20=20(push=20jump-table=20=
byte-compile-jump-tables)))=0A=20=0A=20(defun=20byte-compile-cond=20=
(clauses)=0A-=20=20(or=20(and=20byte-compile-cond-use-jump-table=0A-=20=20=
=20=20=20=20=20=20=20=20=20(byte-compile-cond-jump-table=20clauses))=0A-=20=
=20=20=20(let=20((donetag=20(byte-compile-make-tag))=0A-=20=20=20=20=20=20=
=20=20=20=20nexttag=20clause)=0A-=20=20=20=20=20=20(while=20(setq=20=
clauses=20(cdr=20clauses))=0A-=20=20=20=20=20=20=20=20(setq=20clause=20=
(car=20clauses))=0A-=20=20=20=20=20=20=20=20(cond=20((or=20(eq=20(car=20=
clause)=20t)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(and=20(eq=20(car-safe=20(car=20clause))=20'quote)=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(car-safe=20(cdr-safe=20=
(car=20clause)))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20=
Unconditional=20clause=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20clause=20(cons=20t=20clause)=0A-=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20clauses=20nil))=0A-=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20((cdr=20clauses)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(byte-compile-form=20(car=20clause))=0A-=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(if=20(null=20(cdr=20clause))=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20;;=20First=20clause=20is=20a=20=
singleton.=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(byte-compile-goto-if=20t=20byte-compile--for-effect=20donetag)=0A-=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20nexttag=20=
(byte-compile-make-tag))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(byte-compile-goto=20'byte-goto-if-nil=20nexttag)=0A-=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(byte-compile-maybe-guarded=20(car=20=
clause)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(byte-compile-body=20(cdr=20clause)=20byte-compile--for-effect))=0A-=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(byte-compile-goto=20=
'byte-goto=20donetag)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(byte-compile-out-tag=20nexttag)))))=0A-=20=20=20=20=20=20;;=20Last=20=
clause=0A-=20=20=20=20=20=20(let=20((guard=20(car=20clause)))=0A-=20=20=20=
=20=20=20=20=20(and=20(cdr=20clause)=20(not=20(eq=20guard=20t))=0A-=20=20=
=20=20=20=20=20=20=20=20=20=20=20(progn=20(byte-compile-form=20guard)=0A=
-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(byte-compile-goto-if=20nil=20byte-compile--for-effect=20donetag)=0A-=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20clause=20=
(cdr=20clause))))=0A-=20=20=20=20=20=20=20=20(byte-compile-maybe-guarded=20=
guard=0A-=20=20=20=20=20=20=20=20=20=20(byte-compile-body-do-effect=20=
clause)))=0A-=20=20=20=20=20=20(byte-compile-out-tag=20donetag))))=0A+=20=
=20(let=20((donetag=20(byte-compile-make-tag))=0A+=20=20=20=20=20=20=20=20=
nexttag=20clause)=0A+=20=20=20=20(setq=20clauses=20(cdr=20clauses))=0A+=20=
=20=20=20(while=20clauses=0A+=20=20=20=20=20=20(let=20((switch-prefix=20=
(and=20byte-compile-cond-use-jump-table=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=
(byte-compile--cond-switch-prefix=20clauses))))=0A+=20=20=20=20=20=20=20=20=
(if=20switch-prefix=0A+=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(byte-compile-cond-jump-table=20(cdr=20=
switch-prefix)=20donetag)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20clauses=20(car=20switch-prefix)))=0A+=20=20=20=20=20=20=20=20=20=20=
(setq=20clause=20(car=20clauses))=0A+=20=20=20=20=20=20=20=20=20=20(cond=20=
((or=20(eq=20(car=20clause)=20t)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(and=20(eq=20(car-safe=20(car=20clause))=20=
'quote)=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-safe=20(cdr-safe=20(car=20clause)))))=0A+=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Unconditional=20clause=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20clause=20(cons=20=
t=20clause)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20clauses=20nil))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20((cdr=20clauses)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(byte-compile-form=20(car=20clause))=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(if=20(null=20(cdr=20clause))=0A+=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20First=20clause=20is=20a=20=
singleton.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(byte-compile-goto-if=20t=20byte-compile--for-effect=20donetag)=0A+=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20nexttag=20=
(byte-compile-make-tag))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(byte-compile-goto=20'byte-goto-if-nil=20nexttag)=0A+=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(byte-compile-maybe-guarded=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(byte-compile-body=20(cdr=20clause)=20=
byte-compile--for-effect))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(byte-compile-goto=20'byte-goto=20donetag)=0A+=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(byte-compile-out-tag=20=
nexttag))))=0A+=20=20=20=20=20=20=20=20=20=20(setq=20clauses=20(cdr=20=
clauses)))))=0A+=20=20=20=20;;=20Last=20clause=0A+=20=20=20=20(let=20=
((guard=20(car=20clause)))=0A+=20=20=20=20=20=20(and=20(cdr=20clause)=20=
(not=20(eq=20guard=20t))=0A+=20=20=20=20=20=20=20=20=20=20=20(progn=20=
(byte-compile-form=20guard)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(byte-compile-goto-if=20nil=20byte-compile--for-effect=20=
donetag)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20=
clause=20(cdr=20clause))))=0A+=20=20=20=20=20=20=
(byte-compile-maybe-guarded=20guard=0A+=20=20=20=20=20=20=20=20=
(byte-compile-body-do-effect=20clause)))=0A+=20=20=20=20=
(byte-compile-out-tag=20donetag)))=0A=20=0A=20(defun=20byte-compile-and=20=
(form)=0A=20=20=20(let=20((failtag=20(byte-compile-make-tag))=0Adiff=20=
--git=20a/test/lisp/emacs-lisp/bytecomp-tests.el=20=
b/test/lisp/emacs-lisp/bytecomp-tests.el=0Aindex=20=
87f2c13bf7..b2a47af63b=20100644=0A---=20=
a/test/lisp/emacs-lisp/bytecomp-tests.el=0A+++=20=
b/test/lisp/emacs-lisp/bytecomp-tests.el=0A@@=20-334,7=20+334,20=20@@=20=
byte-opt-testsuite-arith-data=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((memql=20x=20'(9=20=
0.5=201.5=20q))=2066)=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(t=2099)))=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20'(a=20b=20c=20d=20(d)=20(a=20.=20b)=20"X"=200.5=20=
1.5=203.14=209=209.0))=0A-=20=20=20=20)=0A+=20=20=20=20;;=20Multi-switch=20=
cond=20form=0A+=20=20=20=20(mapcar=20(lambda=20(p)=20(let=20((x=20(car=20=
p))=20(y=20(cadr=20p)))=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(cond=20((consp=20x)=2011)=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((eq=20x=20'a)=2022)=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((memql=20x=20'(b=207=20=
a=20-3))=2033)=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((equal=20y=20"a")=2044)=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((memq=20y=20'(c=20d=20e))=2055)=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=
((booleanp=20x)=2066)=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((eq=20x=20'q)=2077)=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((memq=20x=20'(r=20s))=2088)=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=
((eq=20x=20't)=2099)=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(t=20999))))=0A+=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=20=
nil)=20(t=20c)=20(q=20c)=20(r=20c)=20(s=20c)=0A+=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(t=20c)=20(x=20"a")=20(x=20"c")=20(x=20c)=20(x=20d)=20(x=20=
e))))=0A=20=20=20"List=20of=20expression=20for=20test.=0A=20Each=20=
element=20will=20be=20executed=20by=20interpreter=20and=20with=0A=20=
bytecompiled=20code,=20and=20their=20results=20compared.")=0A--=20=0A=
2.20.1=20(Apple=20Git-117)=0A=0A=

--Apple-Mail=_6425368A-6F6F-40E3-9751-3E52F91F6248--