From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Andrea Corallo Newsgroups: gmane.emacs.devel Subject: Inlining policy (was: emacs rendering comparisson between emacs23 and emacs26.3) Date: Sun, 05 Apr 2020 10:23:38 +0000 Message-ID: References: <86tv2h2vww.fsf@gmail.com> <20200326193128.GC14092@ACM> <86d08y4zsx.fsf@gmail.com> <83sghs7qdz.fsf@gnu.org> <83h7y63sjj.fsf@gnu.org> <834ku43c61.fsf@gnu.org> <83k12zz6ds.fsf@gnu.org> <054393f3-3873-ab6e-b325-0eca354d8838@gmx.at> <29a6c120-f260-0ea3-f5e0-1d3dd6323d09@gmx.at> <5752c978-3a13-4e09-18b3-14201eaf1083@gmx.at> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="21159"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) Cc: martin rudalics , Stefan Monnier , emacs-devel@gnu.org To: Paul Eggert Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Apr 05 12:24:52 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jL2SR-0005Ml-AC for ged-emacs-devel@m.gmane-mx.org; Sun, 05 Apr 2020 12:24:51 +0200 Original-Received: from localhost ([::1]:46578 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jL2SQ-0005uP-C1 for ged-emacs-devel@m.gmane-mx.org; Sun, 05 Apr 2020 06:24:50 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:38556) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jL2Rb-0005Mr-Gf for emacs-devel@gnu.org; Sun, 05 Apr 2020 06:24:01 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jL2RZ-0001iJ-D2 for emacs-devel@gnu.org; Sun, 05 Apr 2020 06:23:59 -0400 Original-Received: from mx.sdf.org ([205.166.94.20]:51031) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jL2RZ-0001fX-1J for emacs-devel@gnu.org; Sun, 05 Apr 2020 06:23:57 -0400 Original-Received: from sdf.org (ma.sdf.org [205.166.94.33]) by mx.sdf.org (8.15.2/8.14.5) with ESMTPS id 035ANdX0023375 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits) verified NO); Sun, 5 Apr 2020 10:23:39 GMT Original-Received: (from akrl@localhost) by sdf.org (8.15.2/8.12.8/Submit) id 035ANcEJ001721; Sun, 5 Apr 2020 10:23:38 GMT In-Reply-To: (Paul Eggert's message of "Sat, 4 Apr 2020 17:07:48 -0700") X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 205.166.94.20 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:246445 Archived-At: --=-=-= Content-Type: text/plain Paul Eggert writes: > I looked into this, and although it's no doubt fundamentally due to a > slow algorithm, the slowness is exacerbated if you use -Og (which you > appear to be using). Stefan's recent message hinted at this. I > installed the attached into master to try to fix the -Og issue; please > give it a try. Hi Paul, what about having a new macro to control the key operations we want to always have inlined at -O0 and -Og instead of falling back into defining these as macros? Something like the attached patch. Going further I think we could also use this to take control of the subset of functions we really want to have always inlined also when optimizing. Don't know maybe this solution of the always_inline attribute has been already attempted, in case apologies for the noise. Andrea -- akrl@sdf.org --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Introduce-KEY_OP_INLINE-for-key-operations-inlining.patch >From 902a46835d8c37089de407d847ce1259c477dc00 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sun, 5 Apr 2020 10:09:43 +0100 Subject: [PATCH] Introduce KEY_OP_INLINE for key operations inlining. 2020-04-05 Andrea Corallo * src/lisp.h: (XLI, XIL, XLP, XPL, CHECK_FIXNUM, CHECK_SYMBOL, CHECK_TYPE) (CONSP, EQ, FLOATP, FIXNUMP, NILP, SET_SYMBOL_VAL) (SYMBOL_CONSTANT_P, SYMBOL_TRAPPED_WRITE_P, SYMBOL_VAL, SYMBOLP) (TAGGEDP, VECTORLIKEP, XCAR, XCDR, XCONS, XHASH, make_fixnum) (XFIXNUM_RAW, XTYPE): Do not define these as macro plus use KEY_OP_INLINE in the function definition. * src/conf_post.h (ATTRIBUTE_ALWAYS_INLINE): New macro. (KEY_OP_INLINE): New macro. * src/Makefile.in (DEFINE_KEY_OPS_AS_MACROS): Rename into FORCE_INLINE_KEY_OPS. --- src/Makefile.in | 2 +- src/conf_post.h | 14 +++++++ src/lisp.h | 107 ++++++++++++++---------------------------------- 3 files changed, 45 insertions(+), 78 deletions(-) diff --git a/src/Makefile.in b/src/Makefile.in index dfd322553b..51c200dc9e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -378,7 +378,7 @@ pdmp := NON_OBJC_CFLAGS = -Wignored-attributes -Wignored-qualifiers -Wopenmp-simd # Cajole GCC into inlining key ops even if it wouldn't normally. -KEY_OPS_CFLAGS = $(if $(filter -Og,$(CFLAGS)),-DDEFINE_KEY_OPS_AS_MACROS) +KEY_OPS_CFLAGS = $(if $(filter -Og,$(CFLAGS)),-DFORCE_INLINE_KEY_OPS) # -Demacs makes some files produce the correct version for use in Emacs. # MYCPPFLAGS is for by-hand Emacs-specific overrides, e.g., diff --git a/src/conf_post.h b/src/conf_post.h index eb8fb18c00..441e19d829 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -240,6 +240,8 @@ #define NO_INLINE __attribute__((noinline)) #define NO_INLINE #endif +#define ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) + #if __has_attribute (externally_visible) #define EXTERNALLY_VISIBLE __attribute__((externally_visible)) #else @@ -446,6 +448,18 @@ #define ATTRIBUTE_MALLOC_SIZE(args) ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE (args) #endif +/* Have key operations inlined at -O0 and -Og not to excessively kill + performance. */ +#ifndef KEY_OP_INLINE +# if (! defined __OPTIMIZE__ \ + || (defined FORCE_INLINE_KEY_OPS && ! defined __NO_INLINE__ \ + && ! defined __OPTIMIZE_SIZE__)) +# define KEY_OP_INLINE static inline ATTRIBUTE_UNUSED ATTRIBUTE_ALWAYS_INLINE +# else +# define KEY_OP_INLINE INLINE +# endif +#endif + /* 'int x UNINIT;' is equivalent to 'int x;', except it cajoles GCC into not warning incorrectly about use of an uninitialized variable. */ #if defined GCC_LINT || defined lint diff --git a/src/lisp.h b/src/lisp.h index 23ff89a977..168a496d58 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -411,53 +411,6 @@ #define lisp_h_XHASH(a) XUFIXNUM_RAW (a) # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) #endif -/* When DEFINE_KEY_OPS_AS_MACROS, define key operations as macros to - cajole the compiler into inlining them; otherwise define them as - inline functions as this is cleaner and can be more efficient. - The default is true if the compiler is GCC-like and if function - inlining is disabled because the compiler is not optimizing or is - optimizing for size. Otherwise the default is false. */ -#ifndef DEFINE_KEY_OPS_AS_MACROS -# if (defined __NO_INLINE__ \ - && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__) -# define DEFINE_KEY_OPS_AS_MACROS true -# else -# define DEFINE_KEY_OPS_AS_MACROS false -# endif -#endif - -#if DEFINE_KEY_OPS_AS_MACROS -# define XLI(o) lisp_h_XLI (o) -# define XIL(i) lisp_h_XIL (i) -# define XLP(o) lisp_h_XLP (o) -# define XPL(p) lisp_h_XPL (p) -# define CHECK_FIXNUM(x) lisp_h_CHECK_FIXNUM (x) -# define CHECK_SYMBOL(x) lisp_h_CHECK_SYMBOL (x) -# define CHECK_TYPE(ok, predicate, x) lisp_h_CHECK_TYPE (ok, predicate, x) -# define CONSP(x) lisp_h_CONSP (x) -# define EQ(x, y) lisp_h_EQ (x, y) -# define FLOATP(x) lisp_h_FLOATP (x) -# define FIXNUMP(x) lisp_h_FIXNUMP (x) -# define NILP(x) lisp_h_NILP (x) -# define SET_SYMBOL_VAL(sym, v) lisp_h_SET_SYMBOL_VAL (sym, v) -# define SYMBOL_CONSTANT_P(sym) lisp_h_SYMBOL_CONSTANT_P (sym) -# define SYMBOL_TRAPPED_WRITE_P(sym) lisp_h_SYMBOL_TRAPPED_WRITE_P (sym) -# define SYMBOL_VAL(sym) lisp_h_SYMBOL_VAL (sym) -# define SYMBOLP(x) lisp_h_SYMBOLP (x) -# define TAGGEDP(a, tag) lisp_h_TAGGEDP (a, tag) -# define VECTORLIKEP(x) lisp_h_VECTORLIKEP (x) -# define XCAR(c) lisp_h_XCAR (c) -# define XCDR(c) lisp_h_XCDR (c) -# define XCONS(a) lisp_h_XCONS (a) -# define XHASH(a) lisp_h_XHASH (a) -# if USE_LSB_TAG -# define make_fixnum(n) lisp_h_make_fixnum (n) -# define XFIXNUM_RAW(a) lisp_h_XFIXNUM_RAW (a) -# define XTYPE(a) lisp_h_XTYPE (a) -# endif -#endif - - /* Define the fundamental Lisp data structures. */ /* This is the set of Lisp data types. If you want to define a new @@ -718,25 +671,25 @@ definitely_will_not_unexec_p (void) if pointers differ in width from EMACS_INT; otherwise they are no-ops. */ -INLINE EMACS_INT +KEY_OP_INLINE EMACS_INT (XLI) (Lisp_Object o) { return lisp_h_XLI (o); } -INLINE Lisp_Object +KEY_OP_INLINE Lisp_Object (XIL) (EMACS_INT i) { return lisp_h_XIL (i); } -INLINE void * +KEY_OP_INLINE void * (XLP) (Lisp_Object o) { return lisp_h_XLP (o); } -INLINE Lisp_Object +KEY_OP_INLINE Lisp_Object (XPL) (void *p) { return lisp_h_XPL (p); @@ -744,7 +697,7 @@ definitely_will_not_unexec_p (void) /* Extract A's type. */ -INLINE enum Lisp_Type +KEY_OP_INLINE enum Lisp_Type (XTYPE) (Lisp_Object a) { #if USE_LSB_TAG @@ -758,13 +711,13 @@ definitely_will_not_unexec_p (void) /* True if A has type tag TAG. Equivalent to XTYPE (a) == TAG, but often faster. */ -INLINE bool +KEY_OP_INLINE bool (TAGGEDP) (Lisp_Object a, enum Lisp_Type tag) { return lisp_h_TAGGEDP (a, tag); } -INLINE void +KEY_OP_INLINE void (CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x) { lisp_h_CHECK_TYPE (ok, predicate, x); @@ -991,13 +944,13 @@ #define ROUNDUP(x, y) (POWER_OF_2 (y) \ ptrdiff_t size; }; -INLINE bool +KEY_OP_INLINE bool (SYMBOLP) (Lisp_Object x) { return lisp_h_SYMBOLP (x); } -INLINE struct Lisp_Symbol * ATTRIBUTE_NO_SANITIZE_UNDEFINED +KEY_OP_INLINE struct Lisp_Symbol * ATTRIBUTE_NO_SANITIZE_UNDEFINED XSYMBOL (Lisp_Object a) { eassert (SYMBOLP (a)); @@ -1052,7 +1005,7 @@ c_symbol_p (struct Lisp_Symbol *sym) } } -INLINE void +KEY_OP_INLINE void (CHECK_SYMBOL) (Lisp_Object x) { lisp_h_CHECK_SYMBOL (x); @@ -1146,14 +1099,14 @@ #define FIXNUM_OVERFLOW_P(i) \ #if USE_LSB_TAG -INLINE Lisp_Object +KEY_OP_INLINE Lisp_Object (make_fixnum) (EMACS_INT n) { eassert (!FIXNUM_OVERFLOW_P (n)); return lisp_h_make_fixnum_wrap (n); } -INLINE EMACS_INT +KEY_OP_INLINE EMACS_INT (XFIXNUM_RAW) (Lisp_Object a) { return lisp_h_XFIXNUM_RAW (a); @@ -1173,7 +1126,7 @@ make_ufixnum (EMACS_INT n) the lisp_h_* macros are eventually removed. */ /* Make a fixnum representing the value of the low order bits of N. */ -INLINE Lisp_Object +KEY_OP_INLINE Lisp_Object make_fixnum (EMACS_INT n) { eassert (! FIXNUM_OVERFLOW_P (n)); @@ -1195,7 +1148,7 @@ make_fixnum (EMACS_INT n) /* Extract A's value as a signed integer. Unlike XFIXNUM, this works on any Lisp object, although the resulting integer is useful only for things like hashing when A is not a fixnum. */ -INLINE EMACS_INT +KEY_OP_INLINE EMACS_INT XFIXNUM_RAW (Lisp_Object a) { EMACS_INT i = XLI (a); @@ -1225,13 +1178,13 @@ make_ufixnum (EMACS_INT n) #endif /* ! USE_LSB_TAG */ -INLINE bool +KEY_OP_INLINE bool (FIXNUMP) (Lisp_Object x) { return lisp_h_FIXNUMP (x); } -INLINE EMACS_INT +KEY_OP_INLINE EMACS_INT XFIXNUM (Lisp_Object a) { eassert (FIXNUMP (a)); @@ -1253,7 +1206,7 @@ XUFIXNUM (Lisp_Object a) } /* Return A's hash, which is in the range 0..INTMASK. */ -INLINE EMACS_INT +KEY_OP_INLINE EMACS_INT (XHASH) (Lisp_Object a) { return lisp_h_XHASH (a); @@ -1270,7 +1223,7 @@ make_fixed_natnum (EMACS_INT n) /* Return true if X and Y are the same object. */ -INLINE bool +KEY_OP_INLINE bool (EQ) (Lisp_Object x, Lisp_Object y) { return lisp_h_EQ (x, y); @@ -1399,13 +1352,13 @@ make_pointer_integer (void *p) }; verify (GCALIGNED (struct Lisp_Cons)); -INLINE bool +KEY_OP_INLINE bool (NILP) (Lisp_Object x) { return lisp_h_NILP (x); } -INLINE bool +KEY_OP_INLINE bool (CONSP) (Lisp_Object x) { return lisp_h_CONSP (x); @@ -1417,7 +1370,7 @@ CHECK_CONS (Lisp_Object x) CHECK_TYPE (CONSP (x), Qconsp, x); } -INLINE struct Lisp_Cons * +KEY_OP_INLINE struct Lisp_Cons * (XCONS) (Lisp_Object a) { return lisp_h_XCONS (a); @@ -1443,13 +1396,13 @@ xcdr_addr (Lisp_Object c) /* Use these from normal code. */ -INLINE Lisp_Object +KEY_OP_INLINE Lisp_Object (XCAR) (Lisp_Object c) { return lisp_h_XCAR (c); } -INLINE Lisp_Object +KEY_OP_INLINE Lisp_Object (XCDR) (Lisp_Object c) { return lisp_h_XCDR (c); @@ -1652,7 +1605,7 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize) Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; } GCALIGNED_STRUCT; -INLINE bool +KEY_OP_INLINE bool (VECTORLIKEP) (Lisp_Object x) { return lisp_h_VECTORLIKEP (x); @@ -2174,7 +2127,7 @@ CHAR_TABLE_EXTRA_SLOTS (struct Lisp_Char_Table *ct) /* Value is name of symbol. */ -INLINE Lisp_Object +KEY_OP_INLINE Lisp_Object (SYMBOL_VAL) (struct Lisp_Symbol *sym) { return lisp_h_SYMBOL_VAL (sym); @@ -2199,7 +2152,7 @@ SYMBOL_FWD (struct Lisp_Symbol *sym) return sym->u.s.val.fwd; } -INLINE void +KEY_OP_INLINE void (SET_SYMBOL_VAL) (struct Lisp_Symbol *sym, Lisp_Object v) { lisp_h_SET_SYMBOL_VAL (sym, v); @@ -2250,7 +2203,7 @@ SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) i.e. it's a constant (e.g. nil, t, :keywords), or it has some watching functions. */ -INLINE int +KEY_OP_INLINE int (SYMBOL_TRAPPED_WRITE_P) (Lisp_Object sym) { return lisp_h_SYMBOL_TRAPPED_WRITE_P (sym); @@ -2261,7 +2214,7 @@ SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) write to SYM, should also check whether there are any watching functions. */ -INLINE int +KEY_OP_INLINE int (SYMBOL_CONSTANT_P) (Lisp_Object sym) { return lisp_h_SYMBOL_CONSTANT_P (sym); @@ -2806,7 +2759,7 @@ XBUFFER_OBJFWD (lispfwd a) } u; } GCALIGNED_STRUCT; -INLINE bool +KEY_OP_INLINE bool (FLOATP) (Lisp_Object x) { return lisp_h_FLOATP (x); @@ -2970,7 +2923,7 @@ CHECK_LIST_END (Lisp_Object x, Lisp_Object y) CHECK_TYPE (NILP (x), Qlistp, y); } -INLINE void +KEY_OP_INLINE void (CHECK_FIXNUM) (Lisp_Object x) { lisp_h_CHECK_FIXNUM (x); -- 2.17.1 --=-=-=--