Skip to content

Commit 304c44d

Browse files
committed
0.8.9.10:
DYNAMIC-EXTENT &REST lists. ... much as per CSR sbcl-devel 2004-03-29; ... alter listify-rest-args VOPs on non-x86 to meet the new use (don't do anything yet with the DX parameter) ... note concerns over stack manipulation in x86 DX allocation This version compiles and passes tests on x86 and alpha (modulo one unrelated bugfix, coming soon)
1 parent 4fa6bd7 commit 304c44d

17 files changed

+232
-94
lines changed

Diff for: NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -2364,6 +2364,9 @@ changes in sbcl-0.8.9 relative to sbcl-0.8.8:
23642364
the readtable currently in effect.
23652365

23662366
changes in sbcl-0.8.10 relative to sbcl-0.8.9:
2367+
* [placeholder for DX summary]
2368+
** user code with &REST lists declared dynamic-extent, under high
2369+
speed or space and low safety and debug optimization policy.
23672370
* bug fix: compiler emitted division in optimized DEREF. (thanks for
23682371
the test case to Dave Roberts)
23692372
* bug fix: multidimensional simple arrays loaded from FASLs had fill

Diff for: TLA

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Some of these already were used pretty consistently in CMU CL.
1919
Others not so much, but in sbcl-0.7.0 I put some effort into
2020
making them more consistent.
2121
ARG argument
22+
DX dynamic-extent
2223
FUN function
2324
GC garbage collect(ion)
2425
N new: number, as in e.g. N-PASSES or N-WORD-BITS

Diff for: src/compiler/alpha/call.lisp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,9 @@ default-value-8
11041104
(define-vop (listify-rest-args)
11051105
(:args (context-arg :target context :scs (descriptor-reg))
11061106
(count-arg :target count :scs (any-reg)))
1107-
(:arg-types * tagged-num)
1107+
(:info dx)
1108+
(:ignore dx)
1109+
(:arg-types * tagged-num (:constant t))
11081110
(:temporary (:scs (any-reg) :from (:argument 0)) context)
11091111
(:temporary (:scs (any-reg) :from (:argument 1)) count)
11101112
(:temporary (:scs (descriptor-reg) :from :eval) temp dst)

Diff for: src/compiler/fndb.lisp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1362,7 +1362,9 @@
13621362
(defknown %cleanup-point () t)
13631363
(defknown %special-bind (t t) t)
13641364
(defknown %special-unbind (t) t)
1365-
(defknown %listify-rest-args (t index) list (flushable))
1365+
(defknown %dynamic-extent-start () t)
1366+
(defknown %dynamic-extent-end () t)
1367+
(defknown %listify-rest-args (t index t) list (flushable))
13661368
(defknown %more-arg-context (t t) (values t index) (flushable))
13671369
(defknown %more-arg (t index) t)
13681370
(defknown %more-arg-values (t index index) * (flushable))

Diff for: src/compiler/hppa/call.lisp

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1-
(in-package "SB!VM")
1+
;;;; the VM definition of function call for the HPPA
2+
3+
;;;; This software is part of the SBCL system. See the README file for
4+
;;;; more information.
5+
;;;;
6+
;;;; This software is derived from the CMU CL system, which was
7+
;;;; written at Carnegie Mellon University and released into the
8+
;;;; public domain. The software is in the public domain and is
9+
;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10+
;;;; files for more information.
211

12+
(in-package "SB!VM")
313

414
;;;; Interfaces to IR2 conversion:
515

@@ -1068,7 +1078,9 @@ default-value-8
10681078
(define-vop (listify-rest-args)
10691079
(:args (context-arg :target context :scs (descriptor-reg))
10701080
(count-arg :target count :scs (any-reg)))
1071-
(:arg-types * tagged-num)
1081+
(:info dx)
1082+
(:ignore dx)
1083+
(:arg-types * tagged-num (:constant t))
10721084
(:temporary (:scs (any-reg) :from (:argument 0)) context)
10731085
(:temporary (:scs (any-reg) :from (:argument 1)) count)
10741086
(:temporary (:scs (descriptor-reg) :from :eval) temp)

Diff for: src/compiler/ir1tran-lambda.lisp

+37-7
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,24 @@
255255
(rest svars))))))
256256
(values))
257257

258+
;;; FIXME: this is the interface of the CMUCL WITH-DYNAMIC-EXTENT
259+
;;; macro. It is slightly confusing, in that START and BODY-START are
260+
;;; already-existing CTRANs (and FIXME: probably deserve a ONCE-ONLY),
261+
;;; whereas NEXT is a variable naming a CTRAN in the body. -- CSR,
262+
;;; 2004-03-30.
263+
(defmacro with-dynamic-extent ((start body-start next kind) &body body)
264+
(with-unique-names (cleanup next-ctran)
265+
`(progn
266+
(ctran-starts-block ,body-start)
267+
(let ((,cleanup (make-cleanup :kind :dynamic-extent))
268+
(,next-ctran (make-ctran))
269+
(,next (make-ctran)))
270+
(ir1-convert ,start ,next-ctran nil '(%dynamic-extent-start))
271+
(setf (cleanup-mess-up ,cleanup) (ctran-use ,next-ctran))
272+
(let ((*lexenv* (make-lexenv :cleanup ,cleanup)))
273+
(ir1-convert ,next-ctran ,next nil '(%cleanup-point))
274+
(locally ,@body))))))
275+
258276
;;; Create a lambda node out of some code, returning the result. The
259277
;;; bindings are specified by the list of VAR structures VARS. We deal
260278
;;; with adding the names to the LEXENV-VARS for the conversion. The
@@ -267,7 +285,7 @@
267285
;;; the special binding code.
268286
;;;
269287
;;; We ignore any ARG-INFO in the VARS, trusting that someone else is
270-
;;; dealing with &nonsense.
288+
;;; dealing with &NONSENSE, except for &REST vars with DYNAMIC-EXTENT.
271289
;;;
272290
;;; AUX-VARS is a list of VAR structures for variables that are to be
273291
;;; sequentially bound. Each AUX-VAL is a form that is to be evaluated
@@ -291,7 +309,8 @@
291309
:%source-name source-name
292310
:%debug-name debug-name))
293311
(result-ctran (make-ctran))
294-
(result-lvar (make-lvar)))
312+
(result-lvar (make-lvar))
313+
(dx-rest nil))
295314

296315
(awhen (lexenv-lambda *lexenv*)
297316
(push lambda (lambda-children it))
@@ -321,7 +340,12 @@
321340
(t
322341
(when note-lexical-bindings
323342
(note-lexical-binding (leaf-source-name var)))
324-
(new-venv (cons (leaf-source-name var) var))))))
343+
(new-venv (cons (leaf-source-name var) var)))))
344+
(let ((info (lambda-var-arg-info var)))
345+
(when (and info
346+
(eq (arg-info-kind info) :rest)
347+
(leaf-dynamic-extent var))
348+
(setq dx-rest t))))
325349

326350
(let ((*lexenv* (make-lexenv :vars (new-venv)
327351
:lambda lambda
@@ -346,9 +370,14 @@
346370
(ctran-starts-block prebind-ctran)
347371
(link-node-to-previous-ctran bind prebind-ctran)
348372
(use-ctran bind postbind-ctran)
349-
(ir1-convert-special-bindings postbind-ctran result-ctran result-lvar
350-
body
351-
aux-vars aux-vals (svars))))))
373+
(if dx-rest
374+
(with-dynamic-extent (postbind-ctran result-ctran dx :rest)
375+
(ir1-convert-special-bindings dx result-ctran result-lvar
376+
body aux-vars aux-vals
377+
(svars)))
378+
(ir1-convert-special-bindings postbind-ctran result-ctran
379+
result-lvar body
380+
aux-vars aux-vals (svars)))))))
352381

353382
(link-blocks (component-head *current-component*) (node-block bind))
354383
(push lambda (component-new-functionals *current-component*))
@@ -514,7 +543,8 @@
514543
(arg-vars context-temp count-temp)
515544

516545
(when rest
517-
(arg-vals `(%listify-rest-args ,n-context ,n-count)))
546+
(arg-vals `(%listify-rest-args
547+
,n-context ,n-count ,(leaf-dynamic-extent rest))))
518548
(when morep
519549
(arg-vals n-context)
520550
(arg-vals n-count))

Diff for: src/compiler/ir1tran.lisp

+33-4
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,38 @@
11041104
(setf (lambda-var-ignorep var) t)))))
11051105
(values))
11061106

1107+
(defun process-dx-decl (names vars)
1108+
(flet ((maybe-notify (control &rest args)
1109+
(when (policy *lexenv* (> speed inhibit-warnings))
1110+
(apply #'compiler-notify control args))))
1111+
(if (policy *lexenv* (= stack-allocate-dynamic-extent 3))
1112+
(dolist (name names)
1113+
(cond
1114+
((symbolp name)
1115+
(let* ((bound-var (find-in-bindings vars name))
1116+
(var (or bound-var
1117+
(lexenv-find name vars)
1118+
(find-free-var name))))
1119+
(etypecase var
1120+
(leaf
1121+
(if bound-var
1122+
(setf (leaf-dynamic-extent var) t)
1123+
(maybe-notify
1124+
"ignoring DYNAMIC-EXTENT declaration for free ~S"
1125+
name)))
1126+
(cons
1127+
(compiler-error "DYNAMIC-EXTENT on symbol-macro: ~S" name))
1128+
(heap-alien-info
1129+
(compiler-error "DYNAMIC-EXTENT on heap-alien-info: ~S"
1130+
name)))))
1131+
((and (consp name)
1132+
(eq (car name) 'function)
1133+
(null (cddr name))
1134+
(valid-function-name-p (cadr name)))
1135+
(maybe-notify "ignoring DYNAMIC-EXTENT declaration for ~S" name))
1136+
(t (compiler-error "DYNAMIC-EXTENT on a weird thing: ~S" name))))
1137+
(maybe-notify "ignoring DYNAMIC-EXTENT declarations for ~S" names))))
1138+
11071139
;;; FIXME: This is non-ANSI, so the default should be T, or it should
11081140
;;; go away, I think.
11091141
(defvar *suppress-values-declaration* nil
@@ -1146,10 +1178,7 @@
11461178
`(values ,@types)))))
11471179
res))
11481180
(dynamic-extent
1149-
(when (policy *lexenv* (> speed inhibit-warnings))
1150-
(compiler-notify
1151-
"compiler limitation: ~
1152-
~% There's no special support for DYNAMIC-EXTENT (so it's ignored)."))
1181+
(process-dx-decl (cdr spec) vars)
11531182
res)
11541183
(t
11551184
(unless (info :declaration :recognized (first spec))

Diff for: src/compiler/ir2tran.lisp

+3
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,9 @@
13311331
(defoptimizer (%special-unbind ir2-convert) ((var) node block)
13321332
(vop unbind node block))
13331333

1334+
(defoptimizer (%dynamic-extent-start ir2-convert) (() node block) node block)
1335+
(defoptimizer (%dynamic-extent-end ir2-convert) (() node block) node block)
1336+
13341337
;;; ### It's not clear that this really belongs in this file, or
13351338
;;; should really be done this way, but this is the least violation of
13361339
;;; abstraction in the current setup. We don't want to wire

Diff for: src/compiler/mips/call.lisp

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1-
(in-package "SB!VM")
1+
;;;; the VM definition of function call for MIPS
2+
3+
;;;; This software is part of the SBCL system. See the README file for
4+
;;;; more information.
5+
;;;;
6+
;;;; This software is derived from the CMU CL system, which was
7+
;;;; written at Carnegie Mellon University and released into the
8+
;;;; public domain. The software is in the public domain and is
9+
;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10+
;;;; files for more information.
211

12+
(in-package "SB!VM")
313

414
;;;; Interfaces to IR2 conversion:
515

@@ -1099,7 +1109,9 @@ default-value-8
10991109
(define-vop (listify-rest-args)
11001110
(:args (context-arg :target context :scs (descriptor-reg))
11011111
(count-arg :target count :scs (any-reg)))
1102-
(:arg-types * tagged-num)
1112+
(:info dx)
1113+
(:ignore dx)
1114+
(:arg-types * tagged-num (:constant t))
11031115
(:temporary (:scs (any-reg) :from (:argument 0)) context)
11041116
(:temporary (:scs (any-reg) :from (:argument 1)) count)
11051117
(:temporary (:scs (descriptor-reg) :from :eval) temp dst)

Diff for: src/compiler/node.lisp

+4-1
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,8 @@
423423
(defstruct (cleanup (:copier nil))
424424
;; the kind of thing that has to be cleaned up
425425
(kind (missing-arg)
426-
:type (member :special-bind :catch :unwind-protect :block :tagbody))
426+
:type (member :special-bind :catch :unwind-protect
427+
:block :tagbody :dynamic-extent))
427428
;; the node that messes things up. This is the last node in the
428429
;; non-messed-up environment. Null only temporarily. This could be
429430
;; deleted due to unreachability.
@@ -593,6 +594,8 @@
593594
;; true if there was ever a REF or SET node for this leaf. This may
594595
;; be true when REFS and SETS are null, since code can be deleted.
595596
(ever-used nil :type boolean)
597+
;; is it declared dynamic-extent?
598+
(dynamic-extent nil :type boolean)
596599
;; some kind of info used by the back end
597600
(info nil))
598601

Diff for: src/compiler/physenvanal.lisp

+3-1
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,9 @@
364364
(code `(%funcall ,fun))))
365365
((:block :tagbody)
366366
(dolist (nlx (cleanup-nlx-info cleanup))
367-
(code `(%lexical-exit-breakup ',nlx)))))))
367+
(code `(%lexical-exit-breakup ',nlx))))
368+
(:dynamic-extent
369+
(code `(%dynamic-extent-end))))))
368370

369371
(when (code)
370372
(aver (not (node-tail-p (block-last block1))))

Diff for: src/compiler/policies.lisp

+7
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,10 @@
4949
3
5050
0)
5151
("no" "maybe" "yes" "yes"))
52+
53+
(define-optimization-quality stack-allocate-dynamic-extent
54+
(if (and (> (max speed space) (max debug safety))
55+
(< safety 3))
56+
3
57+
0)
58+
("no" "maybe" "yes" "yes"))

Diff for: src/compiler/ppc/call.lisp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,9 @@ default-value-8
11001100
(define-vop (listify-rest-args)
11011101
(:args (context-arg :target context :scs (descriptor-reg))
11021102
(count-arg :target count :scs (any-reg)))
1103-
(:arg-types * tagged-num)
1103+
(:info dx)
1104+
(:ignore dx)
1105+
(:arg-types * tagged-num (:constant t))
11041106
(:temporary (:scs (any-reg) :from (:argument 0)) context)
11051107
(:temporary (:scs (any-reg) :from (:argument 1)) count)
11061108
(:temporary (:scs (descriptor-reg) :from :eval) temp)

Diff for: src/compiler/sparc/call.lisp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,9 @@ default-value-8
10731073
(define-vop (listify-rest-args)
10741074
(:args (context-arg :target context :scs (descriptor-reg))
10751075
(count-arg :target count :scs (any-reg)))
1076-
(:arg-types * tagged-num)
1076+
(:info dx)
1077+
(:ignore dx)
1078+
(:arg-types * tagged-num (:constant t))
10771079
(:temporary (:scs (any-reg) :from (:argument 0)) context)
10781080
(:temporary (:scs (any-reg) :from (:argument 1)) count)
10791081
(:temporary (:scs (descriptor-reg) :from :eval) temp)

Diff for: src/compiler/x86/call.lisp

+3-2
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,8 @@
12651265
(:policy :safe)
12661266
(:args (context :scs (descriptor-reg) :target src)
12671267
(count :scs (any-reg) :target ecx))
1268-
(:arg-types * tagged-num)
1268+
(:info *dynamic-extent*)
1269+
(:arg-types * tagged-num (:constant t))
12691270
(:temporary (:sc unsigned-reg :offset esi-offset :from (:argument 0)) src)
12701271
(:temporary (:sc unsigned-reg :offset ecx-offset :from (:argument 1)) ecx)
12711272
(:temporary (:sc unsigned-reg :offset eax-offset) eax)
@@ -1283,7 +1284,7 @@
12831284
(inst jecxz done)
12841285
(inst lea dst (make-ea :dword :index ecx :scale 2))
12851286
(pseudo-atomic
1286-
(allocation dst dst node)
1287+
(allocation dst dst node *dynamic-extent*)
12871288
(inst lea dst (make-ea :byte :base dst :disp list-pointer-lowtag))
12881289
;; Convert the count into a raw value, so that we can use the
12891290
;; LOOP instruction.

0 commit comments

Comments
 (0)