Skip to content

Commit d85b27e

Browse files
authored
Improve copy-down-method and io performance (#1752)
Fixes #1749 Fixes #1743 Fixes #1097
2 parents da96846 + 3780c46 commit d85b27e

35 files changed

+493
-576
lines changed

documentation/source/release-notes/2025.2.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,40 @@ Compiler
3232
encountering the situation outlined in `Issue 1377
3333
<https://github.com/dylan-lang/opendylan/issues/1377>`_.
3434

35+
* Repeated optimization involving lifting closures to top level now
36+
properly preserves types of local bindings.
37+
38+
* Optimization of the type estimation of :drm:`if` expressions can now
39+
be repeated multiple times as the function is iteratively improved.
40+
41+
* The compiler now supports an extended version of
42+
``copy-down-method-definer`` allowing a ``specializing`` clause
43+
selecting which of the more-general methods should be selected for
44+
inlining in the case of dispatch ambiguity. Additionally, ambiguous
45+
``copy-down-method`` definitions are now signaled as serious
46+
warnings rather than allowing a random applicable method to be
47+
chosen for inlining.
48+
3549
Tools
3650
=====
3751

3852
Library Updates
3953
===============
4054

55+
Dylan
56+
-----
57+
58+
* A number of ``copy-down-method`` definitions in the :lib:`dylan`
59+
library that were previously marked as ambiguous have been
60+
corrected.
61+
62+
io
63+
---
64+
65+
* Specific versions of the stream functions sealed on
66+
``<byte-char-file-stream>`` and ``<byte-file-stream>`` are provided,
67+
significantly improving the performance of these stream operations.
68+
69+
4170
Contributors
4271
============

sources/dfmc/conversion/define-function.dylan

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,10 @@ end function;
5959
// to the dynamic case, in which case any problems are reported
6060
// as for references in code.
6161

62-
/*
6362
define program-warning <dynamic-specializer-expressions>
64-
slot condition-form,
65-
init-keyword: form:;
66-
slot condition-specializer-expressions,
67-
init-keyword: specializer-expressions:;
6863
format-string
69-
"The specializers %= of %= cannot be computed at compile-time -- optimizations may be missed.";
70-
format-arguments
71-
specializer-expressions, form;
64+
"Specializers cannot be computed at compile-time -- optimizations may be missed.";
7265
end program-warning;
73-
*/
7466

7567
define function compute-variable-specs-types
7668
(form, variable-specs :: <variable-specs>)

sources/dfmc/conversion/define-method.dylan

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,23 @@ define compiler-sideways method compute-form-model-object
240240
end;
241241
end method;
242242

243+
define compiler-sideways method compute-form-model-object
244+
(form :: <copy-down-method-definition>, name :: <variable-name-fragment>)
245+
=> (model :: false-or(<&method>));
246+
let method-object = next-method();
247+
if (form.form-specializing-signature)
248+
let (specializing-sig-object, static?)
249+
= compute-signature(form, form.form-specializing-signature);
250+
if (static?)
251+
method-object.specializing-signature := specializing-sig-object;
252+
else
253+
note(<dynamic-specializer-expressions>,
254+
source-location: form-source-location(form));
255+
end if;
256+
end if;
257+
method-object
258+
end method;
259+
243260
define compiler-sideways method form-top-level-methods
244261
(form :: <method-definition>) => (methods :: <sequence>)
245262
let inits = next-method();

sources/dfmc/debug-back-end/print-object.dylan

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ define compiler-sideways method print-object
1212
(o :: <named-object>, stream :: <stream>) => ()
1313
if (o.named?)
1414
if (*verbose-objects?*)
15-
format(stream, "{%s %s}", o.object-class, o.name);
15+
format(stream, "{%s %s/%=}", o.object-class, o.name, o.node-id);
1616
else
17-
format(stream, "{%s}", o.name);
17+
format(stream, "{%s/%=}", o.name, o.node-id);
1818
end if;
1919
else
2020
next-method();

sources/dfmc/definitions/define-copy-down.dylan

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,18 @@ Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc.
66
License: See License.txt in this distribution for details.
77
Warranty: Distributed WITHOUT WARRANTY OF ANY KIND
88

9+
define dood-class <copy-down-method-definition> (<method-definition>)
10+
lazy constant slot form-specializing-signature,
11+
required-init-keyword: specializing-signature:;
12+
end;
913

1014
define &definition copy-down-method-definer
15+
{ define ?mods:* \copy-down-method ?:name ?signature:*
16+
specializing ?specializing-signature:* }
17+
=> do-define-copy-down-method(form, mods, name, signature,
18+
specializing-signature);
1119
{ define ?mods:* \copy-down-method ?:name ?signature:* }
12-
=> do-define-copy-down-method (form, mods, name, signature) ;
20+
=> do-define-copy-down-method(form, mods, name, signature, #f);
1321
{ define ?mods:* \copy-down-method ?other:* }
1422
=> begin
1523
note(<malformed-define-method>,
@@ -18,53 +26,31 @@ define &definition copy-down-method-definer
1826
end;
1927
end;
2028

21-
/*
22-
define function do-define-copy-down-method (fragment, mods, name, signature)
23-
format-out ("in do-define-copy-down-method\n");
24-
// let (options, adjectives) = parse-method-adjectives (name, mods);
25-
format-out ("copy-down-method signature is %s\n", signature) ;
26-
// maybe should check body is empty
27-
// ensure-next-method-binding (signature); // not sure this useful
28-
// let args-list = macro-case (signature) { (?args:*) ?other:* } => args end;
29-
let method-form
30-
= #{ define ?mods \method ?name ?signature end };
31-
let new-fragment = method-form.as-body ;
32-
let expanded-forms = top-level-convert (fragment, new-fragment) ;
33-
format-out ("expanded forms for copy-down method %s\n", expanded-forms) ;
34-
let interesting-form = first (expanded-forms) ;
35-
interesting-form.form-class := #"copy-down-method" ;
36-
expanded-forms
37-
end;
38-
*/
39-
define function do-define-copy-down-method (fragment, mods, name, signature)
40-
// format-out ("in do-define-copy-down-method\n");
29+
define function do-define-copy-down-method
30+
(fragment, mods, name, sig-fragment, specializing-sig-fragment)
4131
let (options, adjectives) = parse-method-adjectives (name, mods);
42-
// let signature-and-body = make (<sequence-fragment>,
43-
// record: signature.fragment-record,
44-
// source-position: signature.fragment-source-position,
45-
// fragments:
46-
// concatenate (signature . fragment-fragments,
47-
// #{ #f }.template-fragments)) ;
48-
let signature-and-body = signature ;
49-
let (signature, body) = parse-method-signature(name, signature-and-body);
50-
// format-out ("copy-down-method signature is %s\n", signature) ;
32+
let (signature, body) = parse-method-signature(name, sig-fragment);
5133
ensure-next-method-binding (signature);
34+
let specializing-signature
35+
= specializing-sig-fragment
36+
& parse-method-signature(name, specializing-sig-fragment);
5237
let method-definition
53-
= apply(make, <method-definition>,
38+
= apply(make, <copy-down-method-definition>,
5439
source-location: fragment-source-location(fragment),
5540
variable-name: name,
5641
adjectives: adjectives,
5742
signature: signature,
43+
specializing-signature: specializing-signature,
5844
body: body,
59-
signature-and-body-fragment: signature,
45+
signature-and-body-fragment: sig-fragment,
6046
options);
61-
method-definition.form-class := #"copy-down-method" ;
47+
method-definition.form-class := #"copy-down-method" ;
6248
if (form-sealed?(method-definition))
6349
let domain-fragment
6450
= generate-implicit-domain-definition-fragment(method-definition);
65-
let expanded-forms = top-level-convert(method-definition, domain-fragment) ;
66-
pair (method-definition, expanded-forms)
51+
let expanded-forms = top-level-convert(method-definition, domain-fragment);
52+
pair(method-definition, expanded-forms)
6753
else
68-
list (method-definition)
54+
list(method-definition)
6955
end
7056
end;

sources/dfmc/definitions/definitions-library.dylan

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ define module dfmc-definitions
161161
form-handled-by-make-when-dynamic?,
162162
ensure-next-method-binding;
163163

164+
export <copy-down-method-definition>,
165+
form-specializing-signature;
166+
164167
export <domain-definition>,
165168
domain-definition?,
166169
form-domain-type-expressions;

sources/dfmc/flow-graph/environment.dylan

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,18 @@ define method extract-lambda (code :: <&code>) => ()
517517
extract-lambda(function(code))
518518
end;
519519

520+
define function lambda-make-closure
521+
(lambda :: <&lambda>) => (res :: false-or(<make-closure>))
522+
block (return)
523+
for (user in users(lambda))
524+
if (instance?(user, <make-closure>))
525+
return(user)
526+
end if;
527+
end for;
528+
#f
529+
end block;
530+
end function;
531+
520532
// Walk the lexical variables of the environment in inside out order.
521533

522534
// define generic do-lexical-variables-in-scope

sources/dfmc/flow-graph/flow-graph-library.dylan

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,7 @@ define module dfmc-flow-graph
3333
use dfmc-reader;
3434

3535
export
36-
ensure-invariants,
37-
<closure-entry-strength>,
38-
$no-closure-entry,
39-
$weak-closure-entry,
40-
$strong-closure-entry,
41-
do-over-lambda-users,
42-
analyze-environments;
36+
ensure-invariants;
4337

4438
export
4539
<inlined-origin>,
@@ -289,6 +283,7 @@ define module dfmc-flow-graph
289283
inners, inners-setter,
290284
lambda, lambda-setter,
291285
closure, closure-setter,
286+
lifture, lifture-setter,
292287
entries, entries-setter,
293288
loops, loops-setter,
294289
lambda-loop, lambda-loop-setter,

sources/dfmc/flow-graph/flow-graph.lid

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ Files: flow-graph-library
88
computation
99
c-computation
1010
utilities
11-
closure
1211
checker
1312
walker
1413
queue-ops

sources/dfmc/modeling/functions.dylan

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,10 @@ end method;
679679
// markt, this represents a copy-down method skeleton.
680680

681681
define &class <copy-down-method> (<method>)
682+
// Compile-time slots.
683+
slot specializing-signature :: false-or(<&signature>),
684+
init-value: #f,
685+
init-keyword: specializing-signature:;
682686
end &class;
683687

684688
define &class <simple-copy-down-method> (<copy-down-method>, <simple-method>)

0 commit comments

Comments
 (0)