From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.devel Subject: Re: truth of %nil Date: Sat, 4 Jul 2009 22:41:35 -0400 Message-ID: <20090705024135.GA2363@fibril.netris.org> References: <87k52uvhnt.fsf@arudy.ossau.uklinux.net> <20090702142823.GA1401@fibril.netris.org> <877hyqk8bx.fsf@arudy.ossau.uklinux.net> <20090703153218.GA1382@fibril.netris.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1246761721 6795 80.91.229.12 (5 Jul 2009 02:42:01 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 5 Jul 2009 02:42:01 +0000 (UTC) Cc: guile-devel To: Neil Jerram Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sun Jul 05 04:41:54 2009 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1MNHfu-0003IV-GR for guile-devel@m.gmane.org; Sun, 05 Jul 2009 04:41:54 +0200 Original-Received: from localhost ([127.0.0.1]:59731 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MNHft-0001U3-Se for guile-devel@m.gmane.org; Sat, 04 Jul 2009 22:41:53 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MNHfn-0001Pd-Bq for guile-devel@gnu.org; Sat, 04 Jul 2009 22:41:47 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MNHfi-0001H2-Om for guile-devel@gnu.org; Sat, 04 Jul 2009 22:41:46 -0400 Original-Received: from [199.232.76.173] (port=39857 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MNHfi-0001Gz-Ka for guile-devel@gnu.org; Sat, 04 Jul 2009 22:41:42 -0400 Original-Received: from world.peace.net ([204.107.200.8]:47244) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MNHfi-0005Pw-4i for guile-devel@gnu.org; Sat, 04 Jul 2009 22:41:42 -0400 Original-Received: from localhost ([127.0.0.1] helo=fibril.netris.org ident=hope8) by world.peace.net with esmtp (Exim 4.69) (envelope-from ) id 1MNHfc-0004x1-Oa; Sat, 04 Jul 2009 22:41:36 -0400 Content-Disposition: inline In-Reply-To: <20090703153218.GA1382@fibril.netris.org> X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:8832 Archived-At: Below is a proposal for how to make boolean tests and end-of-list tests faster and more compact, by renumbering the representations for SCM_ELISP_NIL, SCM_EOL, SCM_UNDEFINED, and SCM_EOF_VAL. But first, I decided to quantify the increase in code size testing against two constants instead of one, by compiling the following short test program with gcc -Os on three architectures: x86-32, arm, and sparc: (specifically, I did "gcc -Os -S foo.c" and then "as -a foo.s") loop1(int *p) { while (*p != 0x004) p++; } loop2(int *p) { while ((*p & ~0x200) != 0x004) p++; } The size of the resulting loop bodies, in bytes, are as follows: arch loop1 loop2 -------------------- x86-32 8 13 arm 12 16 sparc 16 20 -------------------- I guess this is not too bad. The constants chosen above are based on the following proposal on how best to make SCM_BOOL_F and SCM_ELISP_NIL differ by only one bit, and the same for SCM_EOL and SCM_ELISP_NIL. This can be accomplished by making: SCM_ELISP_NIL equal to SCM_MAKIFLAG (2) i.e. 0x204, and SCM_EOL equal to SCM_MAKIFLAG (3) i.e. 0x304. These values are currently used by SCM_UNDEFINED and SCM_EOF_VAL, but I'm hoping it won't be too disruptive to renumber those, especially if it's done before the release of 2.0. Then, testing for boolean truth becomes: if ((x & ~0x200) != 0x004) and testing for end-of-list becomes: if ((x & ~0x100) == 0x204) These should of course be written differently, perhaps as follows: if ((x & ~(SCM_ELISP_NIL ^ SCM_BOOL_F)) != (SCM_ELISP_NIL & SCM_BOOL_F)) and for end-of-list: if ((x & ~(SCM_ELISP_NIL ^ SCM_EOL)) == (SCM_ELISP_NIL & SCM_EOL)) along with a regression test somewhere to complain unless both of the XOR subexpressions above are powers of two: #define IS_POWER_OF_TWO(x) ((x) & ((x)-1) == 0) #define DIFFER_BY_ONLY_ONE_BIT(x, y) IS_POWER_OF_TWO((x)^(y)) if ( ! DIFFER_BY_ONLY_ONE_BIT(SCM_ELISP_NIL, SCM_BOOL_F) ) complain(); if ( ! DIFFER_BY_ONLY_ONE_BIT(SCM_ELISP_NIL, SCM_EOL) ) complain(); What do you think? Mark