Opened 6 months ago

Last modified 8 weeks ago

#1611 new enhancement

Restructure checks for inlinable intrinsics

Reported by: sjamaan Owned by: sjamaan
Priority: major Milestone: 5.3
Component: compiler Version:
Keywords: inlining, intrinsics, performance, lfa2, code duplication Cc:
Estimated difficulty: medium

Description (last modified by sjamaan)

Currently, we have a lot of intrinsics which are inlinable. Sometimes the safe inlineable versions are missing, sometimes the unsafe ones are missing. It also means there is a *lot* of handwritten C code with duplications.

There would be less duplication if the compiler knew that the safe version is actually (roughly) an argument check followed by an unsafe call.

For example:

  • C_a_i_log is just C_check_real followed by C_flonum(a, log(f))
  • C_a_i_flonum_log is C_flonum(a, C_log(C_flonum_magnitude(x))) (it should actually have a _u_ in its name)

Same is true for all the arithmetic operators in (chicken flonum). At least for flonums, I think it's quite doable to have just the unsafe version and have some sort of "rewrite" in the compiler which will do the check followed by a call to the unsafe one.

This can be done for a lot of other intrinsics too; think all the char=, char<, char-upcase, etc.

This would give us a lot of faster implementations of safe operations "for free" by rewriting them to the unsafe ones, and if I'm not mistaken, we'd end up with a lot of calls to the "check" procedures, which ties in nicely with lfa2, which means all but the first can be eliminated.

I'm thinking something like this:

(define-intrinsic (chicken.flonum#fp+ x y)
  (check-flonum x)
  (check-flonum y)
  (##core#inline_allocate ("C_a_i_flonum_plus" 4) x y) ;; to be renamed to C_a_u_i_flonum_plus?
)

(define-intrinsic (scheme#integer->char n)
  (check-fixnum n 'integer->char)
  (##core#inline "C_make_character" (##core#inline "C_unfix" n))
)

This could even replace the definitions in library.scm; then when we are compiling, we could process this code to generate an intrinsics database file, which the compiler can use like types.db. The above define-intrinsic would collapse to a simple define while generating library.so.

When the compiler is compiling with an intrinsics database, it can replace all calls with the inlinable versions.

Perhaps this is simply a more controlled way of doing -emit-inline-file?

This isn't difficult but a lot of work and some care needs to be taken with regards to backwards C API/binary compatibility.

Change History (2)

comment:1 Changed 6 months ago by sjamaan

Description: modified (diff)

comment:2 Changed 8 weeks ago by felix winkelmann

Milestone: 5.25.3
Note: See TracTickets for help on using tickets.