home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mitsch75.zip / scheme-7_5_17-src.zip / scheme-7.5.17 / src / compiler / rtlopt / ralloc.scm next >
Encoding:
Text File  |  1999-01-02  |  4.7 KB  |  135 lines

  1. #| -*-Scheme-*-
  2.  
  3. $Id: ralloc.scm,v 1.18 1999/01/02 06:06:43 cph Exp $
  4.  
  5. Copyright (c) 1988-1999 Massachusetts Institute of Technology
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. |#
  21.  
  22. ;;;; Register Allocation
  23. ;;;  Based on the GNU C Compiler
  24.  
  25. (declare (usual-integrations))
  26.  
  27. (package (register-allocation)
  28.  
  29. (define-export (register-allocation rgraphs)
  30.   (for-each (lambda (rgraph)
  31.           (let ((n-temporaries (walk-rgraph rgraph)))
  32.         (if (> n-temporaries number-of-temporary-registers)
  33.             (error "Too many temporary quantities" n-temporaries))))
  34.         rgraphs))
  35.  
  36. (define (walk-rgraph rgraph)
  37.   (let ((n-registers (rgraph-n-registers rgraph)))
  38.     (set-rgraph-register-renumber!
  39.      rgraph
  40.      (make-vector n-registers false))
  41.     (fluid-let ((*current-rgraph* rgraph))
  42.       (walk-bblocks n-registers (rgraph-bblocks rgraph)))))
  43.  
  44. (define (walk-bblocks n-registers bblocks)
  45.   ;; First, renumber all the registers remaining to be allocated.
  46.   (let ((next-renumber 0)
  47.     (register->renumber (make-vector n-registers false)))
  48.     (define (renumbered-registers n)
  49.       (if (< n n-registers)
  50.       (if (vector-ref register->renumber n)
  51.           (cons n (renumbered-registers (1+ n)))
  52.           (renumbered-registers (1+ n)))
  53.       '()))
  54.     (for-each-pseudo-register
  55.      (lambda (register)
  56.        (if (positive? (register-n-refs register))
  57.        (begin (vector-set! register->renumber register next-renumber)
  58.           (set! next-renumber (1+ next-renumber))))))
  59.     ;; Now create a conflict matrix for those registers and fill it.
  60.     (let ((conflict-matrix
  61.        (make-initialized-vector next-renumber
  62.          (lambda (i)
  63.            i
  64.            (make-regset next-renumber)))))
  65.       (for-each (lambda (bblock)
  66.           (let ((live (make-regset next-renumber)))
  67.             (for-each-regset-member (bblock-live-at-entry bblock)
  68.               (lambda (register)
  69.             (let ((renumber
  70.                    (vector-ref register->renumber register)))
  71.               (if renumber
  72.                   (regset-adjoin! live renumber)))))
  73.             (bblock-walk-forward bblock
  74.               (lambda (rinst)
  75.             (for-each-regset-member live
  76.               (lambda (renumber)
  77.                 (regset-union! (vector-ref conflict-matrix
  78.                                renumber)
  79.                        live)))
  80.             (for-each (lambda (register)
  81.                     (let ((renumber
  82.                        (vector-ref register->renumber
  83.                                register)))
  84.                       (if renumber
  85.                       (regset-delete! live renumber))))
  86.                   (rinst-dead-registers rinst))
  87.             (mark-births! live
  88.                       (rinst-rtl rinst)
  89.                       register->renumber)))))
  90.         bblocks)
  91.  
  92.       ;; Finally, sort the renumbered registers into an allocation
  93.       ;; order, and then allocate them into registers one at a time.
  94.       ;; Return the number of required real registers as a value.
  95.       (let ((next-allocation 0)
  96.         (allocated (make-vector next-renumber 0)))
  97.     (for-each (lambda (register)
  98.             (let ((renumber (vector-ref register->renumber register)))
  99.               (define (loop allocation)
  100.             (if (< allocation next-allocation)
  101.                 (if (regset-disjoint?
  102.                  (vector-ref conflict-matrix renumber)
  103.                  (vector-ref allocated allocation))
  104.                 allocation
  105.                 (loop (1+ allocation)))
  106.                 (let ((allocation next-allocation))
  107.                   (set! next-allocation (1+ next-allocation))
  108.                   (vector-set! allocated allocation
  109.                        (make-regset next-renumber))
  110.                   allocation)))
  111.               (let ((allocation (loop 0)))
  112.             (set-register-renumber! register allocation)
  113.             (regset-adjoin! (vector-ref allocated allocation)
  114.                     renumber))))
  115.           (sort (renumbered-registers number-of-machine-registers)
  116.             allocate<?))
  117.     next-allocation))))
  118.  
  119. (define (allocate<? x y)
  120.   (and (not (= (register-live-length x) 0))
  121.        (or (= (register-live-length y) 0)
  122.        (< (/ (register-n-refs x) (register-live-length x))
  123.           (/ (register-n-refs y) (register-live-length y))))))
  124.  
  125. (define (mark-births! live rtl register->renumber)
  126.   (if (rtl:assign? rtl)
  127.       (let ((address (rtl:assign-address rtl)))
  128.     (if (rtl:register? address)
  129.         (let ((register (rtl:register-number address)))
  130.           (if (pseudo-register? register)
  131.           (regset-adjoin! live
  132.                   (vector-ref register->renumber
  133.                           register))))))))
  134.  
  135. )