123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- ;;; Pass to lower-primcalls CPS for hoot
- ;;; Copyright (C) 2023 Free Software Foundation, Inc.
- ;;;
- ;;; This library is free software: you can redistribute it and/or modify
- ;;; it under the terms of the GNU Lesser General Public License as
- ;;; published by the Free Software Foundation, either version 3 of the
- ;;; License, or (at your option) any later version.
- ;;;
- ;;; This library is distributed in the hope that it will be useful, but
- ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
- ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- ;;; Lesser General Public License for more details.
- ;;;
- ;;; You should have received a copy of the GNU Lesser General Public
- ;;; License along with this program. If not, see
- ;;; <http://www.gnu.org/licenses/>.
- ;;; Commentary:
- ;;;
- ;;; When targetting WebAssembly, we don't have untagged struct fields,
- ;;; so we can fold some vtable predicates.
- ;;;
- ;;; Code:
- (define-module (language cps hoot lower-primcalls)
- #:use-module (ice-9 match)
- #:use-module (language cps)
- #:use-module (language cps intmap)
- #:use-module (language cps utils)
- #:use-module (language cps with-cps)
- #:export (lower-primcalls))
- (define (hoot-fixnum? x) (and (exact-integer? x)
- (<= (ash -1 29) x (1- (ash 1 29)))))
- (define (not-hoot-fixnum? x) (not (hoot-fixnum? x)))
- (define (lower-primcalls cps)
- (with-fresh-name-state cps
- (intmap-fold
- (lambda (label cont out)
- (match cont
- (($ $kargs names vars
- ($ $branch kf kt src 'vtable-has-unboxed-fields? nfields (vtable)))
- (intmap-replace out label
- (build-cont
- ($kargs names vars
- ($continue kf src ($values ()))))))
- (($ $kargs names vars
- ($ $branch kf kt src 'vtable-field-boxed? idx (vtable)))
- (intmap-replace out label
- (build-cont
- ($kargs names vars
- ($continue kt src ($values ()))))))
- (($ $kargs names vars
- ($ $branch kf kt src (or 'number? 'complex?) #f (x)))
- (with-cps out
- (letk kheap ($kargs () ()
- ($branch kf kt src 'heap-number? #f (x))))
- (setk label ($kargs names vars
- ($branch kheap kt src 'fixnum? #f (x))))))
- (($ $kargs names vars
- ($ $branch kf kt src 'real? #f (x)))
- (with-cps out
- (letk kfix? ($kargs () ()
- ($branch kf kt src 'fixnum? #f (x))))
- (letk kcomplex? ($kargs () ()
- ($branch kt kf src 'compnum? #f (x))))
- (setk label
- ($kargs names vars
- ($branch kfix? kcomplex? src 'heap-number? #f (x))))))
- (($ $kargs names vars
- ($ $branch kf kt src 'rational? #f (x)))
- (with-cps out
- (letv real imag)
- (letk kreal-finite? ($kargs ('real) (real)
- ($branch kf kt src 'f64-finite? #f (real))))
- (letk kflo ($kargs () ()
- ($continue kreal-finite? src
- ($primcall 'flonum->f64 #f (x)))))
- (letk kcomp-real ($kargs () ()
- ($continue kreal-finite? src
- ($primcall 'compnum-real #f (x)))))
- (letk kimag-finite? ($kargs ('imag) (imag)
- ($branch kf kcomp-real src 'f64-finite? #f (imag))))
- (letk kcomp ($kargs () ()
- ($continue kimag-finite? src
- ($primcall 'compnum-imag #f (x)))))
- (letk knum? ($kargs () ()
- ($branch kf kt src 'heap-number? #f (x))))
- (letk kcomp? ($kargs () ()
- ($branch knum? kcomp src 'compnum? #f (x))))
- (letk kflo? ($kargs () ()
- ($branch kcomp? kflo src 'flonum? #f (x))))
- (setk label ($kargs names vars
- ($branch kflo? kt src 'fixnum? #f (x))))))
- (($ $kargs names vars
- ($ $branch kf kt src 'integer? #f (x)))
- (with-cps out
- (letv real imag)
- (letk kreal-int? ($kargs ('real) (real)
- ($branch kf kt src 'f64-int? #f (real))))
- (letk kflo ($kargs () ()
- ($continue kreal-int? src
- ($primcall 'flonum->f64 #f (x)))))
- (letk kcomp-real ($kargs () ()
- ($continue kreal-int? src
- ($primcall 'compnum-real #f (x)))))
- (letk kimag-int? ($kargs ('imag) (imag)
- ($branch kf kcomp-real src 'f64-int? #f (imag))))
- (letk kcomp ($kargs () ()
- ($continue kimag-int? src
- ($primcall 'compnum-imag #f (x)))))
- (letk kcomp? ($kargs () ()
- ($branch kf kcomp src 'compnum? #f (x))))
- (letk kflo? ($kargs () ()
- ($branch kcomp? kflo src 'flonum? #f (x))))
- (letk kbig? ($kargs () ()
- ($branch kflo? kt src 'bignum? #f (x))))
- (setk label ($kargs names vars
- ($branch kbig? kt src 'fixnum? #f (x))))))
- (($ $kargs names vars
- ($ $branch kf kt src 'exact-integer? #f (x)))
- (with-cps out
- (letk kbig? ($kargs () ()
- ($branch kf kt src 'bignum? #f (x))))
- (setk label ($kargs names vars
- ($branch kbig? kt src 'fixnum? #f (x))))))
- (($ $kargs names vars
- ($ $branch kf kt src 'exact? #f (x)))
- (with-cps out
- (letk kfrac? ($kargs () ()
- ($branch kf kt src 'fracnum? #f (x))))
- (letk kbig? ($kargs () ()
- ($branch kfrac? kt src 'bignum? #f (x))))
- (setk label ($kargs names vars
- ($branch kbig? kt src 'fixnum? #f (x))))))
- (($ $kargs names vars
- ($ $branch kf kt src 'inexact? #f (x)))
- (with-cps out
- (letk kcomp? ($kargs () ()
- ($branch kf kt src 'compnum? #f (x))))
- (setk label ($kargs names vars
- ($branch kcomp? kt src 'flonum? #f (x))))))
- (($ $kargs names vars
- ($ $continue k src ($ $primcall 'call-thunk/no-inline #f (thunk))))
- (intmap-replace out label
- (build-cont
- ($kargs names vars
- ($continue k src ($call thunk ()))))))
- (($ $kargs names vars
- ($ $continue k src ($ $primcall 'load-const/unlikely val ())))
- (with-cps out
- (setk label ($kargs names vars ($continue k src ($const val))))))
- (($ $kargs names vars
- ($ $continue k src ($ $primcall 'tag-fixnum/unlikely #f (val))))
- (with-cps out
- (setk label ($kargs names vars
- ($continue k src
- ($primcall 'tag-fixnum #f (val)))))))
- (($ $kargs names vars
- ($ $continue k src ($ $primcall 'u64->scm/unlikely #f (val))))
- (with-cps out
- (setk label ($kargs names vars
- ($continue k src ($primcall 'u64->scm #f (val)))))))
- (($ $kargs names vars
- ($ $continue k src ($ $primcall 's64->scm/unlikely #f (val))))
- (with-cps out
- (setk label ($kargs names vars
- ($continue k src ($primcall 's64->scm #f (val)))))))
- (($ $kargs names vars
- ($ $continue k src
- ($ $primcall (or 'assume-u64 'assume-s64) (lo . hi) (val))))
- (with-cps out
- (setk label ($kargs names vars
- ($continue k src ($values (val)))))))
- (($ $kargs names vars
- ($ $continue k src
- ($ $primcall 'add/immediate (? not-hoot-fixnum? y) (x))))
- (with-cps out
- (letv y*)
- (letk k* ($kargs ('y) (y*)
- ($continue k src ($primcall 'add #f (x y*)))))
- (setk label ($kargs names vars
- ($continue k* src ($const y))))))
- (($ $kargs names vars
- ($ $continue k src
- ($ $primcall 'sub/immediate (? not-hoot-fixnum? y) (x))))
- (with-cps out
- (letv y*)
- (letk k* ($kargs ('y) (y*)
- ($continue k src ($primcall 'sub #f (x y*)))))
- (setk label ($kargs names vars
- ($continue k* src ($const y))))))
- (($ $kargs names vars
- ($ $continue k src
- ($ $primcall 'mul/immediate (? not-hoot-fixnum? y) (x))))
- (with-cps out
- (letv y*)
- (letk k* ($kargs ('y) (y*)
- ($continue k src ($primcall 'mul #f (x y*)))))
- (setk label ($kargs names vars
- ($continue k* src ($const y))))))
- (($ $kargs names vars
- ($ $continue k src
- ($ $primcall 'logand/immediate (? not-hoot-fixnum? y) (x))))
- (with-cps out
- (letv y*)
- (letk k* ($kargs ('y) (y*)
- ($continue k src ($primcall 'logand #f (x y*)))))
- (setk label ($kargs names vars
- ($continue k* src ($const y))))))
- (($ $kargs names vars ($ $throw src op param args))
- (match op
- ((or 'raise-type-error
- 'raise-range-error
- 'raise-arity-error
- 'raise-exception) out)
- (_ (error "unexpected throw; fix to use raise-exception" op))))
- (_ out)))
- cps
- cps)))
|