Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inlining with getter-with-setter #1076

Open
shirok opened this issue Oct 24, 2024 · 2 comments
Open

Inlining with getter-with-setter #1076

shirok opened this issue Oct 24, 2024 · 2 comments

Comments

@shirok
Copy link
Owner

shirok commented Oct 24, 2024

If we use getter-with-setter as follows:

(define-inline (foo x) (car x))
(define-inline (foo-set! x v) (set-car! x v))
(define-inline Foo (getter-with-setter foo foo-set!))

Foo is fully inlined:

gosh> (disasm (lambda (x) (Foo x)))
CLOSURE #<closure (#f x)>
=== main_code (name=#f, cc=0x77d9bede3780, codevec=0x77d9bef2e9f0, size=2, const=0 stack=0):
signatureInfo: ((#f x))
     0 LREF0-CAR                ; (car x)
     1 RET 

But if we do this:

(define-inline Foo (getter-with-setter
                    (lambda (x) (car x))
                    (lambda (x v) (set-car! x v))))

It doesn't:

gosh> (disasm (lambda (x) (Foo x)))
CLOSURE #<closure (#f x)>
=== main_code (name=#f, cc=0x77d9bede30c0, codevec=0x77d9be7bb2a0, size=4, const=1 stack=4):
signatureInfo: ((#f x))
     0 LREF0-PUSH               ; x
     1 GREF-TAIL-CALL(1) #<identifier user#Foo.be622100>; (Foo x)
     3 RET 

It's because defining inlinable procedure involves two distinct operations; (1) inset a global binding with 'inlinable' flag, and (2) attach packed IForm to the procedure object, so that the later reference can replace procedure call to its body. With the second example, the compiler failed to do (2).

@shirok
Copy link
Owner Author

shirok commented Oct 26, 2024

Inlining globally bound one is addressed in ebcbd53 .

However, locally bound one isn't optimized yet.

(define (foo x)
   (define bar (getter-with-setter (^y (car y)) (^[y v] (set-car y v))))
  ...)

This is uncommon case, but a macro may produce this kind of local definition and it is better to be optimized.

@shirok
Copy link
Owner Author

shirok commented Oct 26, 2024

Another, completely different approach that can solve both global and local binding cases.

  • Enhance $LAMBDA node to hold setter information (setter's IForm).
  • For such $LAMBDA forms, the compiler emits code to attach setter to the resulting closure. In this case we don't need to copy the closure.
  • Attach custom inliner to getter-with-setter that translates (getter-with-setter (lambda ...) <setter>) into ($LAMBDA ... (setter <setter-iform>)).
  • Then, the existing mechanics of the compiler takes care of the rest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant