From: "Thompson, David" <dthompson2@worcester.edu>
To: Andy Wingo <wingo@pobox.com>
Cc: guile-devel <guile-devel@gnu.org>
Subject: Re: [PATCH] Add unboxed floating point comparison instructions.
Date: Sun, 8 Jan 2017 20:09:41 -0500 [thread overview]
Message-ID: <CAJ=RwfYrVFZPxqXVR4NA3P8j0J1ZL01fHqPyQAoS4v_5YkSk2w@mail.gmail.com> (raw)
In-Reply-To: <87bmvhcil9.fsf@pobox.com>
[-- Attachment #1: Type: text/plain, Size: 137 bytes --]
Hi Andy,
Thanks for the feedback. I believe this new patch addresses everything
you asked me to fix. Am I in time for 2.1.6? ;)
- Dave
[-- Attachment #2: 0001-Add-unboxed-floating-point-comparison-instructions.patch --]
[-- Type: text/x-patch, Size: 13866 bytes --]
From bfd7b4f343c5f5cc8761c8d1fed1f61ba564a5dd Mon Sep 17 00:00:00 2001
From: David Thompson <dthompson2@worcester.edu>
Date: Mon, 12 Dec 2016 22:46:08 -0500
Subject: [PATCH] Add unboxed floating point comparison instructions.
* libguile/vm-engine.c (BR_F64_ARITHMETIC): New preprocessor macro.
(br_if_f64_ee, br_if_f64_lt, br_if_f64_le, br_if_f64_gt, br_if_f64_ge):
New VM instructions.
* doc/ref/vm.texi ("Unboxed Floating-Point Arithmetic"): Document them.
* module/language/cps/compile-bytecode.scm (compile-function): Emit f64
comparison instructions.
* module/language/cps/effects-analysis.scm: Define effects for f64
primcalls.
* module/language/cps/primitives.scm (*branching-primcall-arities*): Add
arities for f64 primcalls.
* module/language/cps/specialize-numbers.scm (specialize-f64-comparison):
New procedure.
(specialize-operations): Specialize f64 comparisons.
* module/system/vm/assembler.scm (emit-br-if-f64-=, emit-br-if-f64-<)
(emit-br-if-f64-<=, emit-br-if-f64->, emit-br-if-f64->=): Export.
* module/system/vm/disassembler.scm (code-annotation): Add annotations
for f64 comparison instructions.
---
doc/ref/vm.texi | 10 ++++
libguile/vm-engine.c | 73 ++++++++++++++++++++++++++++--
module/language/cps/compile-bytecode.scm | 7 ++-
module/language/cps/effects-analysis.scm | 5 ++
module/language/cps/primitives.scm | 7 ++-
module/language/cps/specialize-numbers.scm | 52 +++++++++++++++------
module/language/cps/type-fold.scm | 5 ++
module/system/vm/assembler.scm | 5 ++
module/system/vm/disassembler.scm | 2 +
9 files changed, 145 insertions(+), 21 deletions(-)
diff --git a/doc/ref/vm.texi b/doc/ref/vm.texi
index 1abbbce..4e42bb9 100644
--- a/doc/ref/vm.texi
+++ b/doc/ref/vm.texi
@@ -1674,3 +1674,13 @@ the operands as unboxed IEEE double floating-point numbers, and producing
the same.
@end deftypefn
+@deftypefn Instruction {} br-if-f64-= s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
+@deftypefnx Instruction {} br-if-f64-< s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
+@deftypefnx Instruction {} br-if-f64-<= s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
+@deftypefnx Instruction {} br-if-f64-> s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
+@deftypefnx Instruction {} br-if-f64->= s24:@var{a} x8:@var{_} s24:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset}
+If the unboxed IEEE double value in @var{a} is @code{=}, @code{<},
+@code{<=}, @code{>}, or @code{>=} to the unboxed IEEE double value in
+@var{b}, respectively, add @var{offset} to the current instruction
+pointer.
+@end deftypefn
diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c
index 195237a..e9ec648 100644
--- a/libguile/vm-engine.c
+++ b/libguile/vm-engine.c
@@ -358,6 +358,24 @@
NEXT (3); \
}
+#define BR_F64_ARITHMETIC(crel) \
+ { \
+ scm_t_uint32 a, b; \
+ scm_t_uint64 x, y; \
+ UNPACK_24 (op, a); \
+ UNPACK_24 (ip[1], b); \
+ x = SP_REF_F64 (a); \
+ y = SP_REF_F64 (b); \
+ if ((ip[2] & 0x1) ? !(x crel y) : (x crel y)) \
+ { \
+ scm_t_int32 offset = ip[2]; \
+ offset >>= 8; /* Sign-extending shift. */ \
+ NEXT (offset); \
+ } \
+ NEXT (3); \
+ }
+
+
#define ARGS1(a1) \
scm_t_uint16 dst, src; \
SCM a1; \
@@ -3935,11 +3953,56 @@ VM_NAME (scm_i_thread *thread, struct scm_vm *vp,
NEXT (1);
}
- VM_DEFINE_OP (187, unused_187, NULL, NOP)
- VM_DEFINE_OP (188, unused_188, NULL, NOP)
- VM_DEFINE_OP (189, unused_189, NULL, NOP)
- VM_DEFINE_OP (190, unused_190, NULL, NOP)
- VM_DEFINE_OP (191, unused_191, NULL, NOP)
+ /* br-if-f64= a:12 b:12 invert:1 _:7 offset:24
+ *
+ * If the F64 value in A is = to the F64 value in B, add OFFSET, a
+ * signed 24-bit number, to the current instruction pointer.
+ */
+ VM_DEFINE_OP (187, br_if_f64_ee, "br-if-f64-=", OP3 (X8_S24, X8_S24, B1_X7_L24))
+ {
+ BR_F64_ARITHMETIC (==);
+ }
+
+ /* br-if-f64< a:12 b:12 invert:1 _:7 offset:24
+ *
+ * If the F64 value in A is < to the F64 value in B, add OFFSET, a
+ * signed 24-bit number, to the current instruction pointer.
+ */
+ VM_DEFINE_OP (188, br_if_f64_lt, "br-if-f64-<", OP3 (X8_S24, X8_S24, B1_X7_L24))
+ {
+ BR_F64_ARITHMETIC (<);
+ }
+
+ /* br-if-f64-<= a:24 _:8 b:24 invert:1 _:7 offset:24
+ *
+ * If the F64 value in A is <= than the F64 value in B, add OFFSET, a
+ * signed 24-bit number, to the current instruction pointer.
+ */
+ VM_DEFINE_OP (189, br_if_f64_le, "br-if-f64-<=", OP3 (X8_S24, X8_S24, B1_X7_L24))
+ {
+ BR_F64_ARITHMETIC (<=);
+ }
+
+ /* br-if-f64-> a:24 _:8 b:24 invert:1 _:7 offset:24
+ *
+ * If the F64 value in A is > than the F64 value in B, add OFFSET, a
+ * signed 24-bit number, to the current instruction pointer.
+ */
+ VM_DEFINE_OP (190, br_if_f64_gt, "br-if-f64->", OP3 (X8_S24, X8_S24, B1_X7_L24))
+ {
+ BR_F64_ARITHMETIC (>);
+ }
+
+ /* br-if-uf4->= a:24 _:8 b:24 invert:1 _:7 offset:24
+ *
+ * If the F64 value in A is >= than the F64 value in B, add OFFSET, a
+ * signed 24-bit number, to the current instruction pointer.
+ */
+ VM_DEFINE_OP (191, br_if_f64_ge, "br-if-f64->=", OP3 (X8_S24, X8_S24, B1_X7_L24))
+ {
+ BR_F64_ARITHMETIC (>=);
+ }
+
VM_DEFINE_OP (192, unused_192, NULL, NOP)
VM_DEFINE_OP (193, unused_193, NULL, NOP)
VM_DEFINE_OP (194, unused_194, NULL, NOP)
diff --git a/module/language/cps/compile-bytecode.scm b/module/language/cps/compile-bytecode.scm
index db5b8fa..a3f8ba4 100644
--- a/module/language/cps/compile-bytecode.scm
+++ b/module/language/cps/compile-bytecode.scm
@@ -446,7 +446,12 @@
(($ $primcall 'u64-=-scm (a b)) (binary emit-br-if-u64-=-scm a b))
(($ $primcall 'u64->=-scm (a b)) (binary emit-br-if-u64->=-scm a b))
(($ $primcall 'u64->-scm (a b)) (binary emit-br-if-u64->-scm a b))
- (($ $primcall 'logtest (a b)) (binary emit-br-if-logtest a b))))
+ (($ $primcall 'logtest (a b)) (binary emit-br-if-logtest a b))
+ (($ $primcall 'f64-< (a b)) (binary emit-br-if-f64-< a b))
+ (($ $primcall 'f64-<= (a b)) (binary emit-br-if-f64-<= a b))
+ (($ $primcall 'f64-= (a b)) (binary emit-br-if-f64-= a b))
+ (($ $primcall 'f64->= (a b)) (binary emit-br-if-f64->= a b))
+ (($ $primcall 'f64-> (a b)) (binary emit-br-if-f64-> a b))))
(define (compile-trunc label k exp nreq rest-var)
(define (do-call proc args emit-call)
diff --git a/module/language/cps/effects-analysis.scm b/module/language/cps/effects-analysis.scm
index 9ce6585..f1833bb 100644
--- a/module/language/cps/effects-analysis.scm
+++ b/module/language/cps/effects-analysis.scm
@@ -439,6 +439,11 @@ is or might be a read or a write to the same location as A."
((u64-=-scm . _) &type-check)
((u64->=-scm . _) &type-check)
((u64->-scm . _) &type-check)
+ ((f64-= . _))
+ ((f64-< . _))
+ ((f64-> . _))
+ ((f64-<= . _))
+ ((f64->= . _))
((zero? . _) &type-check)
((add . _) &type-check)
((add/immediate . _) &type-check)
diff --git a/module/language/cps/primitives.scm b/module/language/cps/primitives.scm
index bc03c98..a3e6e38 100644
--- a/module/language/cps/primitives.scm
+++ b/module/language/cps/primitives.scm
@@ -99,7 +99,12 @@
(u64-=-scm . (1 . 2))
(u64->=-scm . (1 . 2))
(u64->-scm . (1 . 2))
- (logtest . (1 . 2))))
+ (logtest . (1 . 2))
+ (f64-= . (1 . 2))
+ (f64-< . (1 . 2))
+ (f64-> . (1 . 2))
+ (f64-<= . (1 . 2))
+ (f64->= . (1 . 2))))
(define (compute-prim-instructions)
(let ((table (make-hash-table)))
diff --git a/module/language/cps/specialize-numbers.scm b/module/language/cps/specialize-numbers.scm
index 8ce3245..808ea67 100644
--- a/module/language/cps/specialize-numbers.scm
+++ b/module/language/cps/specialize-numbers.scm
@@ -144,6 +144,20 @@
($continue kop src
($primcall 'scm->u64 (a-u64)))))))
+(define (specialize-f64-comparison cps kf kt src op a b)
+ (let ((op (symbol-append 'f64- op)))
+ (with-cps cps
+ (letv f64-a f64-b)
+ (letk kop ($kargs ('f64-b) (f64-b)
+ ($continue kf src
+ ($branch kt ($primcall op (f64-a f64-b))))))
+ (letk kunbox-b ($kargs ('f64-a) (f64-a)
+ ($continue kop src
+ ($primcall 'scm->f64 (b)))))
+ (build-term
+ ($continue kunbox-b src
+ ($primcall 'scm->f64 (a)))))))
+
(define (sigbits-union x y)
(and x y (logior x y)))
@@ -287,6 +301,11 @@ BITS indicating the significant bits needed for a variable. BITS may be
(lambda (type min max)
(and (eqv? type &exact-integer)
(<= 0 min max #xffffffffffffffff))))))
+ (define (f64-operand? var)
+ (call-with-values (lambda ()
+ (lookup-pre-type types label var))
+ (lambda (type min max)
+ (and (eqv? type &flonum)))))
(match cont
(($ $kfun)
(let ((types (infer-types cps label)))
@@ -391,20 +410,25 @@ BITS indicating the significant bits needed for a variable. BITS may be
($ $continue k src
($ $branch kt ($ $primcall (and op (or '< '<= '= '>= '>)) (a b)))))
(values
- (if (u64-operand? a)
- (let ((specialize (if (u64-operand? b)
- specialize-u64-comparison
- specialize-u64-scm-comparison)))
- (with-cps cps
- (let$ body (specialize k kt src op a b))
- (setk label ($kargs names vars ,body))))
- (if (u64-operand? b)
- (let ((op (match op
- ('< '>) ('<= '>=) ('= '=) ('>= '<=) ('> '<))))
- (with-cps cps
- (let$ body (specialize-u64-scm-comparison k kt src op b a))
- (setk label ($kargs names vars ,body))))
- cps))
+ (cond
+ ((or (f64-operand? a) (f64-operand? b))
+ (with-cps cps
+ (let$ body (specialize-f64-comparison k kt src op a b))
+ (setk label ($kargs names vars ,body))))
+ ((u64-operand? a)
+ (let ((specialize (if (u64-operand? b)
+ specialize-u64-comparison
+ specialize-u64-scm-comparison)))
+ (with-cps cps
+ (let$ body (specialize k kt src op a b))
+ (setk label ($kargs names vars ,body)))))
+ ((u64-operand? b)
+ (let ((op (match op
+ ('< '>) ('<= '>=) ('= '=) ('>= '<=) ('> '<))))
+ (with-cps cps
+ (let$ body (specialize-u64-scm-comparison k kt src op b a))
+ (setk label ($kargs names vars ,body)))))
+ (else cps))
types
sigbits))
(_ (values cps types sigbits))))
diff --git a/module/language/cps/type-fold.scm b/module/language/cps/type-fold.scm
index 9459e31..fc37fac 100644
--- a/module/language/cps/type-fold.scm
+++ b/module/language/cps/type-fold.scm
@@ -110,6 +110,11 @@
(else (values #f #f))))
(define-branch-folder-alias u64-< <)
(define-branch-folder-alias u64-<-scm <)
+;; We currently cannot define branch folders for floating point
+;; comparison ops like the commented one below because we can't prove
+;; there are no nans involved.
+;;
+;; (define-branch-folder-alias f64-< <)
(define-binary-branch-folder (<= type0 min0 max0 type1 min1 max1)
(case (compare-ranges type0 min0 max0 type1 min1 max1)
diff --git a/module/system/vm/assembler.scm b/module/system/vm/assembler.scm
index 2c6bf81..226a223 100644
--- a/module/system/vm/assembler.scm
+++ b/module/system/vm/assembler.scm
@@ -106,6 +106,11 @@
emit-br-if-u64-=-scm
emit-br-if-u64->=-scm
emit-br-if-u64->-scm
+ emit-br-if-f64-=
+ emit-br-if-f64-<
+ emit-br-if-f64-<=
+ emit-br-if-f64->
+ emit-br-if-f64->=
emit-box
emit-box-ref
emit-box-set!
diff --git a/module/system/vm/disassembler.scm b/module/system/vm/disassembler.scm
index b0867e6..b6f4f78 100644
--- a/module/system/vm/disassembler.scm
+++ b/module/system/vm/disassembler.scm
@@ -198,6 +198,8 @@ address of that offset."
'br-if-u64-= 'br-if-u64-< 'br-if-u64-<=
'br-if-u64-<-scm 'br-if-u64-<=-scm 'br-if-u64-=-scm
'br-if-u64->-scm 'br-if-u64->=-scm
+ 'br-if-f64-= 'br-if-f64-< 'br-if-f64-<=
+ 'br-if-f64-> 'br-if-f64->=
'br-if-logtest) _ ... target)
(list "-> ~A" (vector-ref labels (- (+ offset target) start))))
(('br-if-tc7 slot invert? tc7 target)
--
2.10.0
next prev parent reply other threads:[~2017-01-09 1:09 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-14 1:47 [PATCH] Add unboxed floating point comparison instructions David Thompson
2016-12-14 14:51 ` Thompson, David
2016-12-21 19:11 ` Andy Wingo
2016-12-21 21:12 ` Mark H Weaver
2017-01-05 1:41 ` Thompson, David
2017-01-08 22:06 ` Andy Wingo
2017-01-09 1:09 ` Thompson, David [this message]
2017-01-09 21:23 ` Andy Wingo
2017-01-10 0:47 ` Thompson, David
2017-01-12 15:38 ` Thompson, David
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAJ=RwfYrVFZPxqXVR4NA3P8j0J1ZL01fHqPyQAoS4v_5YkSk2w@mail.gmail.com' \
--to=dthompson2@worcester.edu \
--cc=guile-devel@gnu.org \
--cc=wingo@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).