From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Andreas Rottmann Newsgroups: gmane.lisp.guile.devel Subject: Re: [PATCH 3/3] Add `fixnum?' VM primitive Date: Tue, 05 Apr 2011 02:14:07 +0200 Message-ID: <87pqp1zh9s.fsf@gmx.at> References: <87wrjglvsq.fsf@gmx.at> <1301766148-20242-1-git-send-email-a.rottmann@gmx.at> <1301766148-20242-4-git-send-email-a.rottmann@gmx.at> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: dough.gmane.org 1301962484 2507 80.91.229.12 (5 Apr 2011 00:14:44 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 5 Apr 2011 00:14:44 +0000 (UTC) Cc: guile-devel@gnu.org To: Andy Wingo Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Tue Apr 05 02:14:35 2011 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.69) (envelope-from ) id 1Q6tuk-00088f-H4 for guile-devel@m.gmane.org; Tue, 05 Apr 2011 02:14:35 +0200 Original-Received: from localhost ([127.0.0.1]:58614 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q6tuj-0003BE-ME for guile-devel@m.gmane.org; Mon, 04 Apr 2011 20:14:33 -0400 Original-Received: from [140.186.70.92] (port=38009 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q6tua-0003Am-CY for guile-devel@gnu.org; Mon, 04 Apr 2011 20:14:26 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q6tuY-0006QG-G3 for guile-devel@gnu.org; Mon, 04 Apr 2011 20:14:24 -0400 Original-Received: from mailout-de.gmx.net ([213.165.64.22]:50884) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1Q6tuY-0006PV-1x for guile-devel@gnu.org; Mon, 04 Apr 2011 20:14:22 -0400 Original-Received: (qmail invoked by alias); 05 Apr 2011 00:14:19 -0000 Original-Received: from 83-215-154-5.hage.dyn.salzburg-online.at (EHLO nathot.lan) [83.215.154.5] by mail.gmx.net (mp002) with SMTP; 05 Apr 2011 02:14:19 +0200 X-Authenticated: #3102804 X-Provags-ID: V01U2FsdGVkX1/BSzdAtgzBs3uRBQqsrA4FGeCvN9Svi7kJ21+Ba6 NP2f9fGxg4JLeR Original-Received: from localhost (localhost.localdomain [127.0.0.1]) by nathot.lan (Postfix) with ESMTP id 126363A696; Tue, 5 Apr 2011 02:14:18 +0200 (CEST) Original-Received: from nathot.lan ([127.0.0.1]) by localhost (nathot.lan [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SsdfWOHgQKLO; Tue, 5 Apr 2011 02:14:08 +0200 (CEST) Original-Received: from delenn.lan (delenn.lan [192.168.3.11]) by nathot.lan (Postfix) with ESMTP id 50B733A691; Tue, 5 Apr 2011 02:14:08 +0200 (CEST) Original-Received: by delenn.lan (Postfix, from userid 1000) id 0D5812C00BE; Tue, 5 Apr 2011 02:14:07 +0200 (CEST) In-Reply-To: (Andy Wingo's message of "Mon, 04 Apr 2011 23:53:51 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) X-Y-GMX-Trusted: 0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 213.165.64.22 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:12163 Archived-At: --=-=-= Content-Type: text/plain Andy Wingo writes: > Hi Andreas, > > I applied the first two, thanks. > > I am hesitant about this one for three reasons: > > 1) I don't want the compiler to import (rnrs arithmetic fixnums). > Rather, if we were to do this, I would have that module register its > primitives, as GOOPS does. > > 2) Something about this sounds wrong to me. If fixnum? is important, > I don't hold the opinion that `fixnum?' per se is important; it's just that to achieve better performance for R6RS' fixnum operations (while still remaining within R6RS spec territory), it needs to be fast, due to the abundance of calls to it. If, for example, we'd make fixnum operations VM primitives, we wouldn't need to care about `fixnum?'s speed so much. > why not have it in Guile's default environment directly? > Well, this was what my original patch did [0], but Ludovic objected [1]. [0] http://lists.gnu.org/archive/html/guile-devel/2011-03/msg00223.html [1] http://lists.gnu.org/archive/html/guile-devel/2011-03/msg00234.html If you guys can reach an agreement that it should/could live in Guile's default namespace, either named `fixnum?', or by some other name, I'll happily re-do the patch accordingly. My personal feeling is that having an extension for `fixnum?' alone is clumsy, and I did this just due to Ludovic's response. > Or some other non-R6RS namespace. > Suggestions? > What about, for example, `exact-integer?'? And why for fixnums and > not flonums? > Well, the intention behind naming the files r6rs-arithmetic.{c,h} is that similiar performance hacks for flonums could go in there as well, but ATM I don't really care about flonum operations, so I didn't include that in the patch. > 3) Are there no alternatives, like exposing Guile's tags to Scheme > directly? (ice-9 tags) for example. Then we could inline tc3?, > tc8?, and tc16? ops. Some other predicates would become > unnecessary; char? for example. Perhaps this is a bad idea though. > I don't like this idea. It sounds like exposing what is a _really_ low-level implementation detail to Scheme for not a very good reason. Granted, `fixnum?' exposes also an implementation detail, but one that is probably common to all non-toy implementations of Scheme, and if hardware architectures do not change fundamentally, will probably remain to be so. This is also my response to Ludovic's response that "this fixnum thing is a breach in the numerical tower": Yes, it is, but one that can potentially provide performance gains by having the user explicitly stating (commonly found, in some areas) invariants about the numerical range of certain expressions. A compiler can then leverage this additional information to give better performance on such code. IMO, it's a performance hack, but a potentially useful one. > Apologies for being crabby here after you've done all this work :) It > could well be that something close to this is the right thing. > Well, I've attached my Plan-B solution. We can come back to the `fixnum?' VM primitive when it's clear where its corresponding Scheme binding should go. --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=refactor-define-inlinable.diff From: Andreas Rottmann Subject: Move `define-inlinable' into the default namespace * module/ice-9/boot-9.scm (define-inlineable): Moved here from SRFI-9. * module/srfi/srfi-9 (define-inlinable): Removed here. * doc/ref/api-procedures.texi (Inlinable Procedures): Add subsection about `define-inlinable'. --- doc/ref/api-procedures.texi | 27 ++++++++++++++++++++++++++- module/ice-9/boot-9.scm | 36 ++++++++++++++++++++++++++++++++++++ module/srfi/srfi-9.scm | 32 -------------------------------- 3 files changed, 62 insertions(+), 33 deletions(-) diff --git a/doc/ref/api-procedures.texi b/doc/ref/api-procedures.texi index 02889c4..4b4870d 100644 --- a/doc/ref/api-procedures.texi +++ b/doc/ref/api-procedures.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -16,6 +16,7 @@ * Higher-Order Functions:: Function that take or return functions. * Procedure Properties:: Procedure properties and meta-information. * Procedures with Setters:: Procedures with setters. +* Inlinable Procedures:: Procedures that can be inlined. @end menu @@ -797,6 +798,30 @@ Return the setter of @var{proc}, which must be either a procedure with setter or an operator struct. @end deffn +@node Inlinable Procedures +@subsection Inlinable Procedures + +You can define an ``inlinable procedure'' by using +@code{define-inlinable} instead of @code{define}. An inlinable procedure +behaves the same as a regular procedure, but direct calls will result in +the procedure body being inlined into the caller. + +Making a procedure inlinable eliminates the overhead of the call, but at +the same time means that the caller will not transparently use the new +definition if the inline procedure is redefined. Inlinable procedures +will also not deal nicely with debugging and tracing. Therefore, you +should not make a procedure inlinable unless it demonstrably improves +performance in a crucial way. + +In general, only small procedures should be considered for inlining, as +making large procedures inlinable will probably result in an increase in +code size. Additionally, the elimination of the call overhead rarely +matters for for large procedures. + +@deffn {Scheme Syntax} define-inlinable (name parameter ...) . body +Define @var{name} as a procedure with parameters @var{parameter}s and +body @var{body}. +@end deffn @c Local Variables: @c TeX-master: "guile.texi" diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm index 33aa333..327e3fa 100644 --- a/module/ice-9/boot-9.scm +++ b/module/ice-9/boot-9.scm @@ -3497,6 +3497,42 @@ module '(ice-9 q) '(make-q q-length))}." x))))) +;;; Defining transparently inlinable procedures +;;; + +(define-syntax define-inlinable + ;; Define a macro and a procedure such that direct calls are inlined, via + ;; the macro expansion, whereas references in non-call contexts refer to + ;; the procedure. Inspired by the `define-integrable' macro by Dybvig et al. + (lambda (x) + ;; Use a space in the prefix to avoid potential -Wunused-toplevel + ;; warning + (define prefix (string->symbol "% ")) + (define (make-procedure-name name) + (datum->syntax name + (symbol-append prefix (syntax->datum name) + '-procedure))) + + (syntax-case x () + ((_ (name formals ...) body ...) + (identifier? #'name) + (with-syntax ((proc-name (make-procedure-name #'name)) + ((args ...) (generate-temporaries #'(formals ...)))) + #`(begin + (define (proc-name formals ...) + body ...) + (define-syntax name + (lambda (x) + (syntax-case x () + ((_ args ...) + #'((lambda (formals ...) + body ...) + args ...)) + (_ + (identifier? x) + #'proc-name)))))))))) + + (define using-readline? (let ((using-readline? (make-fluid))) diff --git a/module/srfi/srfi-9.scm b/module/srfi/srfi-9.scm index f9449a6..ad9e95d 100644 --- a/module/srfi/srfi-9.scm +++ b/module/srfi/srfi-9.scm @@ -64,38 +64,6 @@ (cond-expand-provide (current-module) '(srfi-9)) -(define-syntax define-inlinable - ;; Define a macro and a procedure such that direct calls are inlined, via - ;; the macro expansion, whereas references in non-call contexts refer to - ;; the procedure. Inspired by the `define-integrable' macro by Dybvig et al. - (lambda (x) - ;; Use a space in the prefix to avoid potential -Wunused-toplevel - ;; warning - (define prefix (string->symbol "% ")) - (define (make-procedure-name name) - (datum->syntax name - (symbol-append prefix (syntax->datum name) - '-procedure))) - - (syntax-case x () - ((_ (name formals ...) body ...) - (identifier? #'name) - (with-syntax ((proc-name (make-procedure-name #'name)) - ((args ...) (generate-temporaries #'(formals ...)))) - #`(begin - (define (proc-name formals ...) - body ...) - (define-syntax name - (lambda (x) - (syntax-case x () - ((_ args ...) - #'((lambda (formals ...) - body ...) - args ...)) - (_ - (identifier? x) - #'proc-name)))))))))) - (define-syntax define-record-type (lambda (x) (define (field-identifiers field-specs) -- tg: (78d1be4..) t/refactor-define-inlinable (depends on: stable-2.0) --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=smart-fixnum-p.diff From: Andreas Rottmann Subject: Implement R6RS' `fixnum?' in a smarter way * module/rnrs/arithmetic/fixnums.scm (fixnum?): Implemented using bit-twiddling, and using `define-inlinable'. --- module/rnrs/arithmetic/fixnums.scm | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) diff --git a/module/rnrs/arithmetic/fixnums.scm b/module/rnrs/arithmetic/fixnums.scm index 03511ed..0ce2458 100644 --- a/module/rnrs/arithmetic/fixnums.scm +++ b/module/rnrs/arithmetic/fixnums.scm @@ -76,6 +76,7 @@ fxreverse-bit-field) (import (only (guile) ash cons* + define-inlinable inexact->exact logand logbit? @@ -84,7 +85,8 @@ lognot logxor most-positive-fixnum - most-negative-fixnum) + most-negative-fixnum + object-address) (ice-9 optargs) (rnrs base (6)) (rnrs control (6)) @@ -99,12 +101,9 @@ (define (greatest-fixnum) most-positive-fixnum) (define (least-fixnum) most-negative-fixnum) - - (define (fixnum? obj) - (and (integer? obj) - (exact? obj) - (>= obj most-negative-fixnum) - (<= obj most-positive-fixnum))) + + (define-inlinable (fixnum? obj) + (not (= 0 (logand 2 (object-address obj))))) (define-syntax assert-fixnum (syntax-rules () -- tg: (dfabfe2..) t/smart-fixnum-p (depends on: t/rnrs-arithmetic-benchmark t/refactor-define-inlinable) --=-=-= Content-Type: text/plain Regards, Rotty -- Andreas Rottmann -- --=-=-=--