Re: master: Replace mem-reg XADD with load+add+store
Stas Boukarev <[email protected]>
| Newsgroups | gmane.lisp.steel-bank.cvs,gmane.lisp.steel-bank.devel |
|---|---|
| Message-ID | <CAF63=1013KTSgELkf7s-S67wR3U7kmkbyqjvmcF0zmd=eVXSZg@mail.gmail.com> |
or even:
+++ b/src/compiler/x86-64/tls.lisp
@@ -421,10 +421,9 @@ (defun binding-stack-push (node symbol index-temp
bsp val-temp
&aux (value-ea (ea 1 index-temp)))
(inst mov val-temp (ea index-temp thread-tn))
(load-binding-stack-pointer bsp)
- (inst add bsp (* binding-size n-word-bytes))
- (store-binding-stack-pointer bsp)
- (storew val-temp bsp (- binding-value-slot binding-size))
- (inst mov :dword (object-slot-ea bsp (- binding-symbol-slot
binding-size) 0) index-temp)
+ (inst add :qword (thread-slot-ea thread-binding-stack-pointer-slot) 16)
+ (storew val-temp bsp binding-value-slot)
+ (inst mov :dword (object-slot-ea bsp binding-symbol-slot 0) index-temp)
;; (usually) update the indirect pointer
(cond ((not symbol) ; compile-time-unknown if indirection word exists
(assemble ()
it's 1 byte shorter than xadd.
On Sat, Aug 29, 2026 at 1:50 AM Stas Boukarev <[email protected]> wrote:
>
> What will actually break if it's:
> ADD QWORD PTR [R13+16], 16 ; thread.binding-stack-pointer
> MOV RDX, [R13+16] ; thread.binding-stack-pointer
>
> ?
>
> On Sat, Aug 29, 2026 at 1:35 AM Stas Boukarev <[email protected]> wrote:
> >
> > It might theoretically be faster, but the latency might be eaten by
> > something else, making shorter code a net win.
> > Have you observed any improvements empirically?
> >
> > On Sat, Aug 29, 2026 at 1:31 AM snuglas via Sbcl-commits
> > <[email protected]> wrote:
> > >
> > > The branch "master" has been updated in SBCL:
> > > via 33c68e006d3a0a30df0e6e1007743e2a9e58e6d2 (commit)
> > > from db35d456122e0be7795fd50e713ce0b76a8f996d (commit)
> > >
> > > - Log -----------------------------------------------------------------
> > > commit 33c68e006d3a0a30df0e6e1007743e2a9e58e6d2
> > > Author: Douglas Katzman <[email protected]>
> > > Date: Fri Aug 28 17:40:59 2026 -0400
> > >
> > > Replace mem-reg XADD with load+add+store
> > >
> > > llvm-mca confirms that 3 instructions is better than 2 in this case.
> > > XADD is mainly used with :LOCK so if you don't need :LOCK, you don't need XADD
> > > ---
> > > src/compiler/x86-64/tls.lisp | 18 ++++++++++--------
> > > 1 file changed, 10 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/src/compiler/x86-64/tls.lisp b/src/compiler/x86-64/tls.lisp
> > > index a19717654..6824348b9 100644
> > > --- a/src/compiler/x86-64/tls.lisp
> > > +++ b/src/compiler/x86-64/tls.lisp
> > > @@ -369,18 +369,19 @@
> > > (inst mov (thread-tls-ea tls-index) val)))
> > >
> > > (defun bind (bsp symbol tmp)
> > > - (inst mov bsp (* binding-size n-word-bytes))
> > > - (inst xadd (thread-slot-ea thread-binding-stack-pointer-slot) bsp)
> > > + (load-binding-stack-pointer bsp)
> > > + (inst add bsp (* binding-size n-word-bytes))
> > > + (store-binding-stack-pointer bsp)
> > > (let* ((tls-index (load-time-tls-offset symbol))
> > > (tls-cell (thread-tls-ea tls-index)))
> > > ;; Too bad we can't use "XCHG [thread + disp], val" to write new value
> > > ;; and read the old value in one step. It will violate the constraints
> > > ;; prescribed in the internal documentation on special binding.
> > > (inst mov tmp tls-cell)
> > > - (storew tmp bsp binding-value-slot)
> > > + (storew tmp bsp (- binding-value-slot binding-size))
> > > ;; Indices are small enough to be written as :DWORDs which avoids
> > > ;; a REX prefix if 'bsp' happens to be any of the low 8 registers.
> > > - (inst mov :dword (ea (ash binding-symbol-slot word-shift) bsp) tls-index)
> > > + (inst mov :dword (object-slot-ea bsp (- binding-symbol-slot binding-size) 0) tls-index)
> > > (values tls-cell tmp)))
> > >
> > > (define-vop (bind) ; bind a known symbol
> > > @@ -419,10 +420,11 @@
> > > &optional (newval nil newvalp)
> > > &aux (value-ea (ea 1 index-temp)))
> > > (inst mov val-temp (ea index-temp thread-tn))
> > > - (inst mov bsp (* binding-size n-word-bytes))
> > > - (inst xadd (thread-slot-ea thread-binding-stack-pointer-slot) bsp)
> > > - (inst mov (ea (ash binding-value-slot word-shift) bsp) val-temp)
> > > - (inst mov :dword (ea (ash binding-symbol-slot word-shift) bsp) index-temp)
> > > + (load-binding-stack-pointer bsp)
> > > + (inst add bsp (* binding-size n-word-bytes))
> > > + (store-binding-stack-pointer bsp)
> > > + (storew val-temp bsp (- binding-value-slot binding-size))
> > > + (inst mov :dword (object-slot-ea bsp (- binding-symbol-slot binding-size) 0) index-temp)
> > > ;; (usually) update the indirect pointer
> > > (cond ((not symbol) ; compile-time-unknown if indirection word exists
> > > (assemble ()
> > >
> > > -----------------------------------------------------------------------
> > >
> > >
> > > hooks/post-receive
> > > --
> > > SBCL
> > >
> > >
> > > _______________________________________________
> > > Sbcl-commits mailing list
> > > [email protected]
> > > https://lists.sourceforge.net/lists/listinfo/sbcl-commits
_______________________________________________
Sbcl-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sbcl-commits