Changeset 16453


Ignore:
Timestamp:
Jul 8, 2015, 7:30:40 AM (4 years ago)
Author:
gb
Message:

lose the explict handling of callee-save live intervals; spill-and-split
those intervals instead. spill after first def, so we can tranfer control into the split child.
expire intervals without retaining them on an "expired" list as was done
until a few weeks ago.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/lscan/source/compiler/vinsn.lisp

    r16448 r16453  
    11281128  (let* ((target-seq (vinsn-sequence target))
    11291129         (pred-seq (1- target-seq))
    1130          (pred (vinsn-pred target)))
     1130         (pred (vinsn-pred target))
     1131         (target-fgn (vinsn-fgn target)))
    11311132    (declare (fixnum target-seq pred-seq))
    11321133    (if (and (typep pred 'vinsn)
     
    11351136      (progn
    11361137        (insert-dll-node-before vinsn target)
    1137         (setf (vinsn-sequence vinsn) pred-seq)))))
     1138        (setf (vinsn-sequence vinsn) pred-seq
     1139             (vinsn-fgn vinsn) target-fgn)))))
    11381140
    11391141(defun insert-vinsn-after (vinsn target)
    11401142  (let* ((target-seq (vinsn-sequence target))
    11411143         (succ-seq (1+ target-seq))
    1142          (succ (vinsn-succ target)))
     1144         (succ (vinsn-succ target))
     1145         (target-fgn (vinsn-fgn target)))
    11431146    (declare (fixnum target-seq succ-seq))
    11441147    (if (and (typep succ 'vinsn)
     
    11471150      (progn
    11481151        (insert-dll-node-after vinsn target)
    1149         (setf (vinsn-sequence vinsn) succ-seq)))))
     1152        (setf (vinsn-sequence vinsn) succ-seq
     1153              (vinsn-fgn vinsn) target-fgn)))))
    11501154         
    11511155;;; treat incoming stack arguments as if they had
     
    12291233                                       (setf (vinsn-list-max-nfp-spill-depth seg)
    12301234                                             (vinsn-list-nfp-spill-offset seg)))))))))
    1231                                    
    1232           (let* ((spill-point (find-vinsn seg new-end))
    1233                  (spill-vinsn (select-vinsn (spill-vinsn-for-interval parent) templates (list lreg offset))))
    1234             ;;(push spill-vinsn (lreg-refs lreg))
    1235             (format t "~&spill ~s before ~a" spill-vinsn spill-point)
    1236             (insert-vinsn-before spill-vinsn spill-point)
     1235          (dolist (def (lreg-defs lreg))
     1236            (let* ((spill-vinsn (select-vinsn (spill-vinsn-for-interval parent) templates (list lreg offset))))
     1237
     1238
     1239              (insert-vinsn-after spill-vinsn def)))
    12371240            (let* ((min (vinsn-list-max-seq seg))
    12381241                   (max (interval-end parent))
    1239                    (reloads ())
     1242                   (reloads ()))
    12401243                     
    1241                    )
     1244             
    12421245             
    12431246              (dolist (ref (lreg-refs lreg))
     
    12781281
    12791282                ;; Ready to expire
    1280                 (setf (interval-end parent) (1-  new-end))))))))))
     1283                (setf (interval-end parent) (1-  new-end)))))))))
    12811284
    12821285(defun assign-interval-indices (vector)
     
    13301333            (setf (svref v i) new)))))))
    13311334
    1332 (defun expire-interval (seg interval expired)
     1335(defun expire-interval (seg interval)
    13331336  (let* ((avail (vinsn-list-available-physical-registers seg))
    13341337         (used (vinsn-list-spill-area-used seg))
     
    13461349    ;; child expires.
    13471350    )
    1348   (remove-dll-node interval)
    1349   (append-dll-node interval expired))
     1351  (postprocess-interval interval)
     1352  )
    13501353       
    13511354(defun postprocess-interval (interval)
     
    13631366                       
    13641367 
    1365 
    1366 (defun find-spill-candidate (intervals at)
    1367   (declare (ignorable at))
    1368   (let*  ((max at) (best nil))
    1369     (declare (ignorable max best))
    1370   (do-dll-nodes (x intervals (or best (error "no interval to spill")))
    1371     (let* ((lreg (interval-lreg x)))
    1372       (unless (or (lreg-wired lreg) (lreg-local-p lreg))
    1373        (return x)
     1368;;; try to pick an interval whose next use is farthest away.
     1369(defun find-spill-candidate (intervals regtype  at)
     1370  (let* ((max at) (best nil))
     1371    (do-dll-nodes (x intervals (or best (error "no interval to spill")))
     1372      (let* ((lreg (interval-lreg x)))
     1373        (unless (or (lreg-wired lreg) (lreg-local-p lreg) (not (eql regtype (interval-regtype x))))
     1374
    13741375       
    1375        '(let* ((all (append (lreg-refs lreg) (lreg-refs lreg))))
    1376           (dolist (use all)
    1377             (let* ((seq (vinsn-sequence use)))
    1378               (when (>= seq at)
    1379                 (when (> seq max)
    1380                   (setq max seq best x)))))))))))
     1376          (let* ((all (append (lreg-refs lreg) (lreg-refs lreg))))
     1377            (when (> (vinsn-sequence (car (sort  (copy-list all) #'< :key (lambda (vinsn) (let* ((seq (vinsn-sequence vinsn))) (if (>= seq at) seq most-positive-fixnum)))))) max) (setq best x))))))))
     1378
    13811379
    13821380(defun linear-scan (seg )
     
    14041402        (declare (type (vector t) intervals))
    14051403        (let* ((active (make-dll-header))
    1406                (unhandled (make-dll-header))
    1407                (expired (make-dll-header))
     1404               (unhandled (make-dll-header)
     1405)              ;;(expired (make-dll-header))
    14081406               (limit (vinsn-list-max-seq seg)))
    14091407          (assign-interval-indices intervals)
     
    14131411          (do* ((i (pop-dll-node unhandled) (pop-dll-node unhandled))
    14141412                (begin (if i (interval-begin I) limit) (if i (interval-begin I) limit)))
    1415                ((= begin limit) (progn (do-dll-nodes (a active ) (expire-interval seg a expired))   (do-dll-nodes (x expired t) (postprocess-interval x))))
     1413               ((= begin limit) (progn (do-dll-nodes (a active ) (expire-interval seg a )) t   ))
    14161414            (ls-format t  "~&i=~s" i)
    1417            
     1415
     1416
    14181417            (do-dll-nodes (other active)
    1419 
     1418              (format t  "other = ~s, begin = ~s" other begin)
    14201419              (let* ((other-end (interval-end other)))
    14211420                (when (< other-end begin)
    1422                   (expire-interval seg other expired))))
     1421                  (remove-dll-node other)
     1422                  (expire-interval seg other ))))
    14231423
    14241424            (if (null (interval-lreg i))
    14251425              (let* ((caller-save ())
    1426                      (call-vinsn (find-vinsn seg begin))
    1427                      (end-vinsn (if (vinsn-attribute-p call-vinsn :extended-call) (find-vinsn seg (interval-end i)) call-vinsn))
    1428                      (templates (backend-p2-vinsn-templates *target-backend*)))
     1426                     )
    14291427                (do-dll-nodes (a active)
    14301428                  (when (>= (interval-end a) (interval-end i))
    14311429                    ;; should see if preg is in the killed set
    14321430                    (push a caller-save)))
    1433                 (warn "caller-save = ~s, call = ~s" caller-save call-vinsn)
     1431                ;;(break "caller-save = ~s, call = ~s" caller-save call-vinsn)
    14341432                (dolist (cs caller-save)
    1435                   (let* ((offset (spill-offset-for-interval seg cs))
    1436                          (cs-lreg (interval-lreg cs))
    1437                          (spill-vinsn (select-vinsn (spill-vinsn-for-interval cs) templates (list cs-lreg offset)))
    1438                          (reload-vinsn (select-vinsn (reload-vinsn-for-interval cs) templates (list cs-lreg offset))))
    1439                     (when (lreg-wired cs-lreg) )
    1440                     (insert-vinsn-before spill-vinsn call-vinsn)
    1441                     (insert-vinsn-after reload-vinsn end-vinsn)))
     1433                  (spill-and-split-interval    seg 'call cs begin intervals unhandled)
     1434                  )
    14421435                 
    14431436                         
     
    14491442                (setf (interval-avail i) mask)
    14501443                (when (eql 0 mask)
    1451                   (do-dll-nodes (victim active)
    1452                     (when (and (eql regtype (interval-regtype victim))
    1453                                (interval-lreg victim)
    1454                                (> (interval-end victim) begin))
    1455                       (return (progn (spill-and-split-interval   seg 'pressure victim begin intervals unhandled) (expire-interval seg victim expired) (setq mask (svref avail regtype)) (when (eql mask 0) (break "mask is still 0 after spilling ~s" victim)))))))
     1444                  (let* ((victim (find-spill-candidate active regtype begin)))
     1445                    (progn (spill-and-split-interval   seg 'pressure victim begin intervals unhandled) (expire-interval seg victim ) (setq mask (svref avail regtype)) (when (eql mask 0) (break "mask is still 0 after spilling ~s" victim)))))
    14561446                                 
    14571447
Note: See TracChangeset for help on using the changeset viewer.