From: Dmitry Antipov <dmantipov@yandex.ru>
To: emacs-devel@gnu.org
Cc: Ken Raeburn <raeburn@gnu.org>
Subject: Re: Redundant type checking in window.c and w32menu.c
Date: Wed, 20 Jun 2007 18:12:26 +0400 [thread overview]
Message-ID: <467935CA.9020808@yandex.ru> (raw)
In-Reply-To: <DB033EB0-A4BC-42DE-889F-0B52DD31081F@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 1310 bytes --]
Ken Raeburn wrote:
> On Jun 19, 2007, at 10:44, Dmitry Antipov wrote:
>> If we pass CHECK_CONS(), we don't need CONSP()s in Fcar() and Fcdr()
>> and may use XCAR()
>> and XCDR() instead.
>
> Makes sense.
Whoops, probably not for GNU C :-). At least with -O1 and -O2, GCC (I've
tested with 4.1.2) emits an almost identical and optimal (i.e. with the
only branch ends with a call of wrong_type_argument ()) code for both cases
CHECK_CONS (obj);
x = CAR (obj);
y = CDR (obj);
and
CHECK_CONS (obj);
x = XCAR (obj);
y = XCDR (obj);
Have no ideas about other compilers.
> You could make Fcar a static inline function in lisp.h (conditional on
> GCC, or maybe C99). If the optimizer's good at its job, it should
> eliminate the redundant CONSP checks. Using an inline function avoids
> having to check all Fcar uses for arguments that have function calls or
> side effects. (A quick grep shows several of those. In fact, if your
> test used the simple macro version, inline functions may result in less
> code size expansion because of this.) And personally, I think inline
> functions are often more readable than macros, if they're not very
> simple macros.
I agree, and here is the stuff I'm trying now. Reordering of data.c
looks ugly, but I have no ideas on how to avoid them :-(.
Dmitry
[-- Attachment #2: inline_cons_fns.patch --]
[-- Type: text/plain, Size: 4317 bytes --]
Index: data.c
===================================================================
RCS file: /sources/emacs/emacs/src/data.c,v
retrieving revision 1.271
diff -u -r1.271 data.c
--- data.c 26 May 2007 17:21:14 -0000 1.271
+++ data.c 20 Jun 2007 14:11:00 -0000
@@ -506,49 +506,6 @@
return Qnil;
}
-\f
-/* Extract and set components of lists */
-
-DEFUN ("car", Fcar, Scar, 1, 1, 0,
- doc: /* Return the car of LIST. If arg is nil, return nil.
-Error if arg is not nil and not a cons cell. See also `car-safe'.
-
-See Info node `(elisp)Cons Cells' for a discussion of related basic
-Lisp concepts such as car, cdr, cons cell and list. */)
- (list)
- register Lisp_Object list;
-{
- return CAR (list);
-}
-
-DEFUN ("car-safe", Fcar_safe, Scar_safe, 1, 1, 0,
- doc: /* Return the car of OBJECT if it is a cons cell, or else nil. */)
- (object)
- Lisp_Object object;
-{
- return CAR_SAFE (object);
-}
-
-DEFUN ("cdr", Fcdr, Scdr, 1, 1, 0,
- doc: /* Return the cdr of LIST. If arg is nil, return nil.
-Error if arg is not nil and not a cons cell. See also `cdr-safe'.
-
-See Info node `(elisp)Cons Cells' for a discussion of related basic
-Lisp concepts such as cdr, car, cons cell and list. */)
- (list)
- register Lisp_Object list;
-{
- return CDR (list);
-}
-
-DEFUN ("cdr-safe", Fcdr_safe, Scdr_safe, 1, 1, 0,
- doc: /* Return the cdr of OBJECT if it is a cons cell, or else nil. */)
- (object)
- Lisp_Object object;
-{
- return CDR_SAFE (object);
-}
-
DEFUN ("setcar", Fsetcar, Ssetcar, 2, 2, 0,
doc: /* Set the car of CELL to be NEWCAR. Returns NEWCAR. */)
(cell, newcar)
@@ -2933,6 +2890,57 @@
return make_number (order);
}
+#if defined (__GNUC__) && defined (__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__)
+/* If we're optimizing, these are macros, and they will conflict with
+ the definitions below. */
+#undef Fcar
+#undef Fcar_safe
+#undef Fcdr
+#undef Fcdr_safe
+#endif
+
+\f
+/* Extract and set components of lists */
+
+DEFUN ("car", Fcar, Scar, 1, 1, 0,
+ doc: /* Return the car of LIST. If arg is nil, return nil.
+Error if arg is not nil and not a cons cell. See also `car-safe'.
+
+See Info node `(elisp)Cons Cells' for a discussion of related basic
+Lisp concepts such as car, cdr, cons cell and list. */)
+ (list)
+ register Lisp_Object list;
+{
+ return CAR (list);
+}
+
+DEFUN ("car-safe", Fcar_safe, Scar_safe, 1, 1, 0,
+ doc: /* Return the car of OBJECT if it is a cons cell, or else nil. */)
+ (object)
+ Lisp_Object object;
+{
+ return CAR_SAFE (object);
+}
+
+DEFUN ("cdr", Fcdr, Scdr, 1, 1, 0,
+ doc: /* Return the cdr of LIST. If arg is nil, return nil.
+Error if arg is not nil and not a cons cell. See also `cdr-safe'.
+
+See Info node `(elisp)Cons Cells' for a discussion of related basic
+Lisp concepts such as cdr, car, cons cell and list. */)
+ (list)
+ register Lisp_Object list;
+{
+ return CDR (list);
+}
+
+DEFUN ("cdr-safe", Fcdr_safe, Scdr_safe, 1, 1, 0,
+ doc: /* Return the cdr of OBJECT if it is a cons cell, or else nil. */)
+ (object)
+ Lisp_Object object;
+{
+ return CDR_SAFE (object);
+}
\f
void
Index: lisp.h
===================================================================
RCS file: /sources/emacs/emacs/src/lisp.h,v
retrieving revision 1.577
diff -u -r1.577 lisp.h
--- lisp.h 8 Jun 2007 19:56:24 -0000 1.577
+++ lisp.h 20 Jun 2007 14:11:00 -0000
@@ -2206,10 +2206,39 @@
EXFUN (Finteger_or_floatp, 1);
EXFUN (Finteger_or_float_or_marker_p, 1);
+/* If using GNU and optimizing for speed,
+ inline the most common cons operations. */
+#if defined (__GNUC__) && defined (__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__)
+
+#define CONSFN(name) \
+ static __inline__ Lisp_Object \
+ _F ## name (obj) \
+ Lisp_Object obj; \
+ { \
+ return name (obj); \
+ }
+
+CONSFN (CAR)
+CONSFN (CAR_SAFE)
+CONSFN (CDR)
+CONSFN (CDR_SAFE)
+
+#define Fcar(c) _FCAR (c)
+#define Fcar_safe(c) _FCAR_SAFE (c)
+#define Fcdr(c) _FCDR (c)
+#define Fcdr_safe(c) _FCDR_SAFE (c)
+
+#undef CONSFN
+
+#else
+
EXFUN (Fcar, 1);
EXFUN (Fcar_safe, 1);
EXFUN (Fcdr, 1);
EXFUN (Fcdr_safe, 1);
+
+#endif /* __GNUC__ && __OPTIMIZE__ && !__OPTIMIZE_SIZE__ */
+
EXFUN (Fsetcar, 2);
EXFUN (Fsetcdr, 2);
EXFUN (Fboundp, 1);
[-- Attachment #3: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
next prev parent reply other threads:[~2007-06-20 14:12 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-19 14:44 Redundant type checking in window.c and w32menu.c Dmitry Antipov
2007-06-19 14:55 ` Stefan Monnier
2007-06-19 18:46 ` Ken Raeburn
2007-06-20 14:12 ` Dmitry Antipov [this message]
2007-06-20 15:20 ` Jason Rumney
2007-06-20 17:55 ` dmantipov
2007-06-20 20:46 ` Jason Rumney
2007-06-21 15:46 ` Dmitry Antipov
2007-06-21 17:38 ` Ken Raeburn
2007-06-20 20:12 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=467935CA.9020808@yandex.ru \
--to=dmantipov@yandex.ru \
--cc=emacs-devel@gnu.org \
--cc=raeburn@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.