On Sun, Mar 07, 2021 at 05:32:11PM +0100, Waldek Hebisch wrote:
>
> I will look if I can quickly change Spad compiler to produce
> something that causes no trouble to sbcl. If chaging Spad
> compiler requires too much work, I would go with string
> version.
I have now a patch that seem to work well. I am still testing
it, but on TMFORM sbcl reports 64M memory consed, which means
we should have no memory use prolems compiling TMFORM.
The patch "optimizes" constant coercion, if integer constant
is safely in SingleInteger ranges this constant is used as-is
(saving call to "coerce"). Similar thing is done for
coercion from Float to DoubleFloat: if Float is constant
it is converted to DoubleFloat at compile time. There
is extra twist: in context expecting DoubleFloat floating
point constant should now produce DoubleFloat (up to now
this was an error).
Anyway, I am attaching it if somebody wants to comment or
test it.
Note1: Size of SingleInteger is known only at Lisp compile
time, which may be later than Spad compilation and may
use different Lisp than Spad compilation, so we know if
integer fits into SingleInteger only at Lisp compile time
and in principle Lisp compiler may produce nonsense for out-of
range constants. That is why coercion was postponed to
runtime.
BTW: For TMFORM there is workaround at Spad level, namely
instead of code like
60::SI
one could use
qconvert(60)@SI
That skip call to 'coerce' (and corresponding size check).
--
Waldek Hebisch
--
You received this message because you are subscribed to the Google Groups
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/fricas-devel/20210307221025.GA11807%40math.uni.wroc.pl.
diff --git a/src/interp/compiler.boot b/src/interp/compiler.boot
index 29461224..9c4a2393 100644
--- a/src/interp/compiler.boot
+++ b/src/interp/compiler.boot
@@ -426,6 +426,9 @@ compSel1(domain, op, argl, m, e) ==
op := "One"
-- Next clause added JHD 8/Feb/94: the clause after doesn't work
-- since addDomain refuses to add modemaps from Mapping
+ domain=$Float and op="float" and m=$DoubleFloat =>
+ argl is [mant, exp, 10] => try_constant_DF(mant, exp, m, e)
+ nil
e :=
domain is ['Mapping, :.] =>
augModemapsFromDomain1(domain, domain, e)
@@ -438,6 +441,14 @@ compSel1(domain, op, argl, m, e) ==
coerce(T, m)
nil
+try_constant_DF(mant, exp, m, e) ==
+ if mant = ["Zero"] then mant := 0
+ if mant = ["One"] then mant := 1
+ if exp = ["Zero"] then exp := 0
+ if exp = ["One"] then exp := 1
+ INTEGERP(mant) and INTEGERP(exp) => [["mk_DF", mant, exp], m, e]
+ nil
+
compForm1(form is [op,:argl],m,e) ==
op="error" =>
#argl = 1 =>
@@ -1086,6 +1097,7 @@ coerce(T,m) ==
'"function coerce called from the interpreter."])
rplac(CADR T,substitute("$",$Rep,CADR T))
T':= coerceEasy(T,m) => T'
+ T' := constant_coerce(T, m) => T'
T':= coerceSubset(T,m) => T'
T':= coerceHard(T,m) => T'
T.expr = "$fromCoerceable$" or isSomeDomainVariable m => nil
@@ -1185,6 +1197,7 @@ compCoerce1(x,m',e) ==
m1:=
STRINGP T.mode => $String
T.mode
+ T1 := constant_coerce(T, m') => T1
m':=resolve(m1,m')
T:=[T.expr,m1,T.env]
T':= coerce(T,m') => T'
@@ -1196,6 +1209,22 @@ compCoerce1(x,m',e) ==
['check_subtype2, pred, MKQ m', MKQ T.mode, gg]]
[code,m',T.env]
+constant_coerce([x, m, e], m') ==
+ m' = $SingleInteger =>
+ if x = ["Zero"] then x = 0
+ if x = ["One"] then x = 1
+ not(INTEGERP(x)) => nil
+ -- Check if in range of FIXNUM on all supported implementations
+ x > 8000000 or x < -8000000 => nil
+ m = $Integer or m = $PositiveInteger or $NonNegativeInteger =>
+ [x, m', e]
+ nil
+ m' = $DoubleFloat and m = $Float =>
+ x is [["Sel", ["Float"], "float"], mant, exp, 10] =>
+ try_constant_DF(mant, exp, m, e)
+ nil
+ nil
+
coerceByModemap([x,m,e],m') ==
--+ modified 6/27 for new runtime system
u:=
diff --git a/src/lisp/primitives.lisp b/src/lisp/primitives.lisp
index dcc7141c..572572b2 100644
--- a/src/lisp/primitives.lisp
+++ b/src/lisp/primitives.lisp
@@ -1,5 +1,13 @@
(in-package "BOOT")
+;;; Making constant doubles
+(defun |make_DF|(x e)
+ (let ((res (read-from-string (format nil "~D.0d~D" x e))))
+ res)
+)
+
+(defmacro |mk_DF|(x e) (|make_DF| x e))
+
;;; Fast array accessors
(defmacro QAREF1(v i)