@@ -139,6 +139,23 @@ define method emit-local-tmp-definition
139
139
end if ;
140
140
end if ;
141
141
temporary-value(tmp) := alloca;
142
+ else
143
+ let c = tmp.generator;
144
+ if (instance? (c, <make-closure>))
145
+ let o = function (c.computation-closure-method);
146
+ if (closure?(o) & c.closure-has-dynamic-extent?)
147
+ let class
148
+ = if (instance? (o, <&keyword-method>))
149
+ dylan-value(# "<keyword-closure-method>" )
150
+ else
151
+ dylan-value(# "<simple-closure-method>" );
152
+ end if ;
153
+ let closure-size = closure-size(o.environment);
154
+ let closure = op--stack-allocate-closure(back-end, class , closure-size);
155
+ let result = ins--bitcast(back-end, closure, $llvm-object-pointer-type);
156
+ temporary-value(tmp) := result;
157
+ end if ;
158
+ end if ;
142
159
end if ;
143
160
end method ;
144
161
@@ -481,142 +498,148 @@ end method;
481
498
define method emit-computation
482
499
(back-end :: <llvm-back-end>, m :: <llvm-module>, c :: <make-closure>)
483
500
=> ();
501
+ let temp = c.temporary;
484
502
let o = function (c.computation-closure-method);
485
503
let sigtmp = c.computation-signature-value;
486
504
let key? = instance? (o, <&keyword-method>);
487
- if (closure?(o))
488
- let init? = computation-init-closure?(c);
489
- let top-level? = computation-top-level-closure?(c);
490
- let env = o.environment;
491
- let closure-inits
492
- = if (init? & ~top-level?) env.closure else #() end if ;
493
- if (c.closure-has-dynamic-extent?)
494
- // Stack-allocated closure
495
- let class
496
- = if (key?)
497
- dylan-value(# "<keyword-closure-method>" )
498
- else
499
- dylan-value(# "<simple-closure-method>" );
500
- end if ;
501
-
502
- let template = emit-reference(back-end, m, o);
503
- let closure-size = closure-size(env);
504
- let closure
505
- = op--stack-allocate-closure(back-end, class , template, closure-size);
506
-
507
- for (index from 0 , init in closure-inits)
508
- let value = emit-reference(back-end, m, init);
509
- let ptr
510
- = op--getslotptr(back-end, closure, class , # "environment-element" ,
511
- index);
512
- ins--store(back-end, value, ptr);
513
- end for ;
505
+ if (temp.used?)
506
+ if (closure?(o))
507
+ let init? = computation-init-closure?(c);
508
+ let top-level? = computation-top-level-closure?(c);
509
+ let env = o.environment;
510
+ let closure-inits
511
+ = if (init? & ~top-level?) env.closure else #() end if ;
512
+ if (c.closure-has-dynamic-extent?)
513
+ // Stack-allocated closure
514
+ let class
515
+ = if (key?)
516
+ dylan-value(# "<keyword-closure-method>" )
517
+ else
518
+ dylan-value(# "<simple-closure-method>" );
519
+ end if ;
514
520
515
- if (sigtmp)
516
- // Dynamic signature
517
- let signature = emit-reference(back-end, m, sigtmp);
518
- let signature-ptr
519
- = op--getslotptr(back-end, closure, class , # "function-signature" );
520
- ins--store(back-end, signature, signature-ptr);
521
- end if ;
521
+ let template = emit-reference(back-end, m, o);
522
+ let closure-size = closure-size(env);
523
+ let class-type
524
+ = llvm-class-type(back-end, class , repeated-size: closure-size);
525
+ let closure
526
+ = ins--bitcast(back-end, temporary-value(temp),
527
+ llvm-pointer-to(back-end, class-type));
528
+ op--initialize-stack-allocated-closure
529
+ (back-end, class , template, closure, closure-size);
530
+
531
+ for (index from 0 , init in closure-inits)
532
+ let value = emit-reference(back-end, m, init);
533
+ let ptr
534
+ = op--getslotptr(back-end, closure, class , # "environment-element" ,
535
+ index);
536
+ ins--store(back-end, value, ptr);
537
+ end for ;
522
538
523
- let result = ins--bitcast(back-end, closure, $llvm-object-pointer-type);
524
- computation-result(back-end, c, result);
525
- else
526
- if (sigtmp)
527
- if (top-level?)
528
- // Top-level method with a dynamic signature
539
+ if (sigtmp)
540
+ // Dynamic signature
529
541
let signature = emit-reference(back-end, m, sigtmp);
530
- let name = emit-name(back-end, m, o);
531
- let global = llvm-builder-global(back-end, name);
532
- let class = o.^object-class;
533
- llvm-constrain-type
534
- (global.llvm-value-type,
535
- llvm-pointer-to(back-end, llvm-class-type(back-end, class )));
536
542
let signature-ptr
537
- = op--getslotptr(back-end, global , class , # "function-signature" );
543
+ = op--getslotptr(back-end, closure , class , # "function-signature" );
538
544
ins--store(back-end, signature, signature-ptr);
539
-
540
- let result = ins--bitcast(back-end, global, $llvm-object-pointer-type);
541
- computation-result(back-end, c, result);
545
+ end if ;
546
+ else
547
+ if (sigtmp)
548
+ if (top-level?)
549
+ // Top-level method with a dynamic signature
550
+ let signature = emit-reference(back-end, m, sigtmp);
551
+ let name = emit-name(back-end, m, o);
552
+ let global = llvm-builder-global(back-end, name);
553
+ let class = o.^object-class;
554
+ llvm-constrain-type
555
+ (global.llvm-value-type,
556
+ llvm-pointer-to(back-end, llvm-class-type(back-end, class )));
557
+ let signature-ptr
558
+ = op--getslotptr(back-end, global, class , # "function-signature" );
559
+ ins--store(back-end, signature, signature-ptr);
560
+
561
+ let result
562
+ = ins--bitcast(back-end, global, $llvm-object-pointer-type);
563
+ computation-result(back-end, c, result);
564
+ else
565
+ let result
566
+ = if (init?)
567
+ // Initialized closure
568
+ let primitive
569
+ = if (key?)
570
+ primitive-make-keyword-closure-with-environment-signature-descriptor
571
+ else
572
+ primitive-make-closure-with-environment-signature-descriptor
573
+ end if ;
574
+ apply (call-primitive, back-end, primitive,
575
+ emit-reference(back-end, m, o),
576
+ emit-reference(back-end, m, sigtmp),
577
+ closure-size(env),
578
+ map (curry (emit-reference, back-end, m), closure-inits))
579
+ else
580
+ // Uninitialized closure
581
+ let primitive
582
+ = if (key?)
583
+ primitive-make-keyword-closure-signature-descriptor
584
+ else
585
+ primitive-make-closure-signature-descriptor
586
+ end if ;
587
+ call-primitive(back-end, primitive,
588
+ emit-reference(back-end, m, o),
589
+ emit-reference(back-end, m, sigtmp),
590
+ closure-size(env));
591
+ end if ;
592
+ computation-result(back-end, c, result);
593
+ end if ;
542
594
else
543
595
let result
544
596
= if (init?)
545
597
// Initialized closure
546
598
let primitive
547
599
= if (key?)
548
- primitive-make-keyword-closure-with-environment-signature- descriptor
600
+ primitive-make-keyword-closure-with-environment-descriptor
549
601
else
550
- primitive-make-closure-with-environment-signature- descriptor
602
+ primitive-make-closure-with-environment-descriptor
551
603
end if ;
552
604
apply (call-primitive, back-end, primitive,
553
605
emit-reference(back-end, m, o),
554
- emit-reference(back-end, m, sigtmp),
555
606
closure-size(env),
556
607
map (curry (emit-reference, back-end, m), closure-inits))
557
608
else
558
609
// Uninitialized closure
559
610
let primitive
560
611
= if (key?)
561
- primitive-make-keyword-closure-signature- descriptor
612
+ primitive-make-keyword-closure-descriptor
562
613
else
563
- primitive-make-closure-signature- descriptor
614
+ primitive-make-closure-descriptor
564
615
end if ;
565
616
call-primitive(back-end, primitive,
566
617
emit-reference(back-end, m, o),
567
- emit-reference(back-end, m, sigtmp),
568
618
closure-size(env));
569
619
end if ;
570
620
computation-result(back-end, c, result);
571
621
end if ;
572
- else
573
- let result
574
- = if (init?)
575
- // Initialized closure
576
- let primitive
577
- = if (key?)
578
- primitive-make-keyword-closure-with-environment-descriptor
579
- else
580
- primitive-make-closure-with-environment-descriptor
581
- end if ;
582
- apply (call-primitive, back-end, primitive,
583
- emit-reference(back-end, m, o),
584
- closure-size(env),
585
- map (curry (emit-reference, back-end, m), closure-inits))
622
+ end if ;
623
+ else
624
+ // Not a closure
625
+ if (sigtmp)
626
+ // Dynamic method signature
627
+ let primitive
628
+ = if (key?)
629
+ primitive-make-keyword-method-with-signature-descriptor
586
630
else
587
- // Uninitialized closure
588
- let primitive
589
- = if (key?)
590
- primitive-make-keyword-closure-descriptor
591
- else
592
- primitive-make-closure-descriptor
593
- end if ;
594
- call-primitive(back-end, primitive,
595
- emit-reference(back-end, m, o),
596
- closure-size(env));
631
+ primitive-make-method-with-signature-descriptor
597
632
end if ;
633
+ let result
634
+ = call-primitive(back-end, primitive,
635
+ emit-reference(back-end, m, o),
636
+ emit-reference(back-end, m, sigtmp));
598
637
computation-result(back-end, c, result);
599
- end if ;
638
+ else
639
+ // Ordinary compile-time method signature
640
+ computation-result(back-end, c, emit-reference(back-end, m, o));
641
+ end if
600
642
end if ;
601
- else
602
- // Not a closure
603
- if (sigtmp)
604
- // Dynamic method signature
605
- let primitive
606
- = if (key?)
607
- primitive-make-keyword-method-with-signature-descriptor
608
- else
609
- primitive-make-method-with-signature-descriptor
610
- end if ;
611
- let result
612
- = call-primitive(back-end, primitive,
613
- emit-reference(back-end, m, o),
614
- emit-reference(back-end, m, sigtmp));
615
- computation-result(back-end, c, result);
616
- else
617
- // Ordinary compile-time method signature
618
- computation-result(back-end, c, emit-reference(back-end, m, o));
619
- end if
620
643
end if ;
621
644
end method ;
622
645
0 commit comments