Changeset 16430


Ignore:
Timestamp:
Jun 19, 2015, 8:11:31 AM (4 years ago)
Author:
gb
Message:

Try to avoid conflicts with fixed intervals, but the problems
there remain. Still need to address those problems, but need to
address other things too, and need to try to move forward.
(this is just masking a bug, but the bug remains.)

File:
1 edited

Legend:

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

    r16427 r16430  
    978978        ;; This is probably not the only case where we can't
    979979        ;; avoid removing a COPY instruction.
    980         (unless (or (lreg-wired dest)
     980        (unless (lreg-wired dest)
    981981                    ;(logbitp lreg-spill-bit (lreg-flags src))
    982982                    ;(logbitp lreg-spill-bit (lreg-flags dest)))
     
    12411241    (declare (simple-vector avail) (simple-bit-vector used) (ignorable used)(fixnum start end))
    12421242    (flet ((unuse-reg (regno type)
     1243             (format t "~&unuse ~d/~d for ~s" regno type interval)
    12431244             (setf (svref avail type)
    12441245                   (logior (svref avail type) (ash 1 regno)))
     
    12611262 
    12621263
     1264
    12631265(defun linear-scan (seg )
    12641266  (let* ((avail (vinsn-list-available-physical-registers seg)))
    1265     (flet ((use-reg (regno type)
     1267    (flet ((use-reg (regno type i)
     1268             (declare (ignorable i))
     1269             ;(format t "~& using ~s/~d in ~s" regno type i)
    12661270             (setf (svref avail type)
    12671271                   (logandc2 (svref avail type) (ash 1 regno))))
    1268            )
     1272
     1273           (select-available-register (mask)
     1274             (declare (type (unsigned-byte 16) mask))
     1275             (unless (eql 0 mask)
     1276               (do* ((i 15 (1- i)))
     1277                    ((< i 0))
     1278                 (when (logbitp i mask) (return i))))))
    12691279      (let* ((intervals (vinsn-list-intervals seg)))
    12701280        (declare (type (vector t) intervals))
    12711281        (let* ((active (make-dll-header))
    1272                    (unhandled (make-dll-header))
    1273                    (limit (vinsn-list-max-seq seg)))
    1274               (dotimes (i (length intervals))
    1275                 (let*  ((interval (aref intervals i)))
    1276                   (setf (interval-idx interval ) i)
    1277                   (append-dll-node interval unhandled)))
    1278               (do* ((i (pop-dll-node unhandled) (pop-dll-node unhandled))
    1279                     (begin (if i (interval-begin I) limit) (if i (interval-begin I) limit)))
    1280                    ((= begin limit) (do-dll-nodes (a active  t) (expire-interval seg a)))
    1281                 (let* ((regtype (interval-regtype i))
    1282                        (mask (svref avail regtype)))
    1283                   (setf (interval-avail i) mask)
    1284                   (when (eql 0 mask)
    1285                     (do-dll-nodes (victim active)
    1286                       (when (and (eql regtype (interval-regtype victim))
    1287                                  (> (interval-end victim) begin))
    1288                         (when (eq i victim) (dbg))
    1289                         (return (spill-and-split-interval   seg victim (interval-begin victim) intervals unhandled)))))
     1282               (unhandled (make-dll-header))
     1283               (limit (vinsn-list-max-seq seg)))
     1284          (dotimes (i (length intervals))
     1285            (let*  ((interval (aref intervals i)))
     1286              (setf (interval-idx interval ) i)
     1287              (append-dll-node interval unhandled)))
     1288          (do* ((i (pop-dll-node unhandled) (pop-dll-node unhandled))
     1289                (begin (if i (interval-begin I) limit) (if i (interval-begin I) limit)))
     1290               ((= begin limit) (do-dll-nodes (a active  t) (expire-interval seg a)))
     1291            (let* ((regtype (interval-regtype i))
     1292                   (mask (svref avail regtype)))
     1293              (setf (interval-avail i) mask)
     1294              (when (eql 0 mask)
     1295                (do-dll-nodes (victim active)
     1296                  (when (and (eql regtype (interval-regtype victim))
     1297                             (> (interval-end victim) begin))
     1298                    (when (eq i victim) (dbg))
     1299                    (return (spill-and-split-interval   seg victim (interval-begin victim) intervals unhandled)))))
    12901300                                 
    12911301
    1292                   (do-dll-nodes (other active)
     1302              (do-dll-nodes (other active)
    12931303           
    1294                     (let* ((other-end (interval-end other)))
    1295                       (when (< other-end begin)
    1296 
    1297                        
    1298                         (expire-interval seg other)
    1299                         (remove-dll-node other))))
    1300                   (let* ((lreg (interval-lreg i))
    1301                          (regtype (interval-regtype i))
    1302                          (mask (svref avail regtype)))
    1303 
    1304                       (let* ((fixed (interval-preg i))
    1305                              (targeted (and lreg (or (lreg-wired lreg) (lreg-local-p lreg)) (lreg-value lreg)))
    1306                              (preg (or fixed (if (and targeted (logbitp targeted mask))
    1307                                                       targeted
    1308                                                       (dotimes (i (integer-length mask) (break "huh"))
    1309                                                         (when (logbitp i mask)
    1310                                                           (return i)))))))
    1311 
    1312                         (when (and fixed (not (logbitp fixed mask)))
    1313                           (let* ((other (do-dll-nodes (x active (error "can't find interval with ~d" fixed))
    1314                                           (when (and (eql regtype (interval-regtype x))
    1315                                                      (eql fixed (interval-preg x)))
    1316                                             (return x)))))
    1317                             (spill-and-split-interval seg other begin intervals unhandled)))
    1318 
    1319                         (when (and targeted (not (eql targeted preg)))
    1320                           (let*  ((rival (do-dll-nodes (other active (error "can't find rival on active-list"))
    1321                                            (when (and (eql (interval-preg other) targeted)
    1322                                                       (eql (interval-regtype other) regtype))
    1323                                              (return other))))
    1324                                   (rival-lreg (and rival (interval-lreg rival))))
    1325                             (cond ((null rival-lreg) (break "no lreg for conflicting interval ~s" rival))
    1326                                   ((or (lreg-wired rival-lreg) (lreg-local-p rival-lreg))
    1327                                    (if (eql (interval-end rival) begin)
    1328                                      (setq preg targeted)
    1329                                      (error "conflicting intervals overlap")))
    1330                                   (t
    1331                                    (setf (interval-preg rival) preg)
    1332                                    (use-reg preg regtype)
    1333                                    (setq preg targeted)))))
    1334                         (use-reg preg regtype)
    1335                         (setf (interval-preg i) preg)
    1336                         (append-dll-node i active))))))))))
     1304                (let* ((other-end (interval-end other)))
     1305                  (when (< other-end begin)
     1306
     1307                       
     1308                    (expire-interval seg other)
     1309                    (remove-dll-node other))))
     1310              (let* ((lreg (interval-lreg i))
     1311                     (regtype (interval-regtype i))
     1312                     (mask (svref avail regtype)))
     1313
     1314                   
     1315                (let* ((fixed (interval-preg i))
     1316                       (targeted (and lreg (or (lreg-wired lreg) (lreg-local-p lreg)) (lreg-value lreg)))
     1317                       (preg (or fixed (if (and targeted (logbitp targeted mask))
     1318                                         targeted
     1319                                         (select-available-register mask)))))
     1320                 
     1321
     1322                  (when (and fixed (not (logbitp fixed mask)))
     1323                    (let* ((other (do-dll-nodes (x active (error "can't find interval with ~d" fixed))
     1324                                    (when (and (eql regtype (interval-regtype x))
     1325                                               (eql fixed (interval-preg x)))
     1326                                      (return x)))))
     1327                      (spill-and-split-interval seg other begin intervals unhandled)))
     1328
     1329                  (when (and targeted (not (eql targeted preg)))
     1330                    (let*  ((rival (do-dll-nodes (other active (error "can't find rival on active-list"))
     1331                                     (when (and (eql (interval-preg other) targeted)
     1332                                                (eql (interval-regtype other) regtype))
     1333                                       (return other))))
     1334                            (rival-lreg (and rival (interval-lreg rival)))
     1335                            )
     1336                      (break "want to use reg ~d, for ~s in use by ~s. ~d may be free" targeted lreg rival-lreg preg)
     1337                      (cond ((null rival-lreg) (break "no lreg for conflicting interval ~s" rival))
     1338                            ((or (lreg-wired rival-lreg) (lreg-local-p rival-lreg))
     1339                             (if (eql (interval-end rival) begin)
     1340                               (setq preg targeted)
     1341                               (error "conflicting intervals overlap")))
     1342                            (t
     1343                             ;; We can't easily revert he earlier decision to
     1344                             ;; assign the conflicting preg to the rival interval;
     1345                             ;; that decision affected later decisionsa, and the
     1346                             ;; affected intervals may no longer be on the active
     1347                             ;; list.  An older, hairier scheme tried to review
     1348                             ;; intervening decisions, but interval-splitting
     1349                             ;; complicated that.
     1350
     1351                             ;; the rival interval is still active.  we want
     1352                             ;; to replace any uses of the rival lreg that occur
     1353                             ;; before this point with the "old" preg, insert
     1354                             ;; a copy instruction here, and change the rival'a
     1355                             ;; preg so that aubsequent uses will use the new preg
     1356                             (let* ((copy (select-vinsn 'copy-gpr (backend-p2-vinsn-templates *target-backend*) (list preg targeted))))
     1357                               (insert-vinsn-before copy (find-vinsn seg begin))
     1358                               (dolist (use (append (lreg-defs rival-lreg)
     1359                                                    (lreg-refs rival-lreg)))
     1360                                        ; fencepost ?
     1361                                 (replace-vinsn-operands use rival-lreg targeted (interval-begin rival) (vinsn-sequence copy)))))
     1362                            (setf (interval-preg rival) preg)
     1363                            (use-reg preg)
     1364                            (setq preg targeted))))
     1365                           
     1366                             
     1367                 
     1368                (use-reg preg regtype i)
     1369                (setf (interval-preg i) preg)
     1370                (append-dll-node i active))))))))))
     1371
    13371372
    13381373(defun optimize-vinsns (header)
Note: See TracChangeset for help on using the changeset viewer.