Quick Search:

Mode

Context

Displaying 3 lines of context. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.44
 
1.45
 
MAIN:ragge:20070930193207
 
optim2.c
_>247247 void
 248248 deljumps(struct interpass *ipole)
 249249 {
<>250 -        struct interpass *ip, *n, *ip2;
  250+        struct interpass *ip, *n, *ip2, *start;
251251         int gotone,low, high;
<>252 -        int *lblary, sz, o, i;
  252+        int *lblary, *jmpary, sz, o, i, j, lab1, lab2;
  253+        int del;
253254 
 254255         low = ipp->ip_lblnum;
 255256         high = epp->ip_lblnum;
     
 !
260261 
 261262         sz = (high-low) * sizeof(int);
 262263         lblary = tmpalloc(sz);
<> 264+        jmpary = tmpalloc(sz);
263265 
<> 266+        /*
  267+         * XXX: Find the first two labels. They may not be deleted,
  268+         * because the register allocator expects them to be there.
  269+         * These will not be coalesced with any other label.
  270+         */
  271+        lab1 = lab2 = -1;
  272+        start = NULL;
  273+        DLIST_FOREACH(ip, ipole, qelem) {
  274+                if (ip->type != IP_DEFLAB)
  275+                        continue;
  276+                if (lab1 < 0)
  277+                        lab1 = ip->ip_lbl;
  278+                else if (lab2 < 0) {
  279+                        lab2 = ip->ip_lbl;
  280+                        start = ip;
  281+                } else  /* lab1 >= 0 && lab2 >= 0, we're done. */
  282+                        break;
  283+        }
  284+        if (lab1 < 0 || lab2 < 0)
  285+                comperr("deljumps");
  286+
264287 again:  gotone = 0;
 265288         memset(lblary, 0, sz);
<> 289+        lblary[lab1 - low] = lblary[lab2 - low] = 1;
  290+        memset(jmpary, 0, sz);
266291 
 267292         /* refcount and coalesce all labels */
 268293         DLIST_FOREACH(ip, ipole, qelem) {
<>269 -                if (ip->type == IP_DEFLAB) {
  294+                if (ip->type == IP_DEFLAB && ip->ip_lbl != lab1 &&
  295+                    ip->ip_lbl != lab2) {
270296                         n = DLIST_NEXT(ip, qelem);
<> 297+
  298+                        /*
  299+                         * Find unconditional jumps directly following a
  300+                         * label.
  301+                         */
  302+                        if (n->type == IP_NODE && n->ip_node->n_op == GOTO) {
  303+                                i = n->ip_node->n_left->n_lval;
  304+                                jmpary[ip->ip_lbl - low] = i;
  305+                        }
  306+
271307                         while (n->type == IP_DEFLAB) {
<>272 -                                if (n->type == IP_DEFLAB &&
 273 -                                    lblary[n->ip_lbl-low] >= 0)
 274 -                                        lblary[n->ip_lbl-low] = -ip->ip_lbl;
  308+                                if (n->ip_lbl != lab1 && n->ip_lbl != lab2 &&
  309+                                    lblary[n->ip_lbl-low] >= 0) {
  310+                                        /*
  311+                                         * If the label is used, mark the
  312+                                         * label to be coalesced with as
  313+                                         * used, too.
  314+                                         */
  315+                                        if (lblary[n->ip_lbl - low] > 0 &&
  316+                                            lblary[ip->ip_lbl - low] == 0)
  317+                                                lblary[ip->ip_lbl - low] = 1;
  318+                                        lblary[n->ip_lbl - low] = -ip->ip_lbl;
  319+                                }
275320                                 n = DLIST_NEXT(n, qelem);
 276321                         }
 277322                 }
     
 !
284329                         i = ip->ip_node->n_right->n_lval;
 285330                 else
 286331                         continue;
<>287 -                lblary[i-low] |= 1;
  332+
  333+                /*
  334+                 * Mark destination label i as used, if it is not already.
  335+                 * If i is to be merged with label j, mark j as used, too.
  336+                 */
  337+                if (lblary[i - low] == 0)
  338+                        lblary[i-low] = 1;
  339+                else if ((j = lblary[i - low]) < 0 && lblary[-j - low] == 0)
  340+                        lblary[-j - low] = 1;
288341         }
 289342 
 290343         /* delete coalesced/unused labels and rename gotos */
     
 !
295348                                 DLIST_REMOVE(n, qelem);
 296349                                 gotone = 1;
 297350                         }
<>298 -                        continue;
299351                 }
<>300 -                if (n->type != IP_NODE)
  352+                if (ip->type != IP_NODE)
301353                         continue;
<>302 -                o = n->ip_node->n_op;
  354+                o = ip->ip_node->n_op;
303355                 if (o == GOTO)
<>304 -                        i = n->ip_node->n_left->n_lval;
  356+                        i = ip->ip_node->n_left->n_lval;
305357                 else if (o == CBRANCH)
<>306 -                        i = n->ip_node->n_right->n_lval;
  358+                        i = ip->ip_node->n_right->n_lval;
307359                 else
 308360                         continue;
<> 361+
  362+                /* Simplify (un-)conditional jumps to unconditional jumps. */
  363+                if (jmpary[i - low] > 0) {
  364+                        gotone = 1;
  365+                        i = jmpary[i - low];
  366+                        if (o == GOTO)
  367+                                ip->ip_node->n_left->n_lval = i;
  368+                        else
  369+                                ip->ip_node->n_right->n_lval = i;
  370+                }
  371+
  372+                /* Fixup for coalesced labels. */
309373                 if (lblary[i-low] < 0) {
 310374                         if (o == GOTO)
<>311 -                                n->ip_node->n_left->n_lval = -lblary[i-low];
  375+                                ip->ip_node->n_left->n_lval = -lblary[i-low];
312376                         else
<>313 -                                n->ip_node->n_right->n_lval = -lblary[i-low];
  377+                                ip->ip_node->n_right->n_lval = -lblary[i-low];
314378                 }
 315379         }
 316380 
     
 !
332396 
 333397                 if (ip2->type != IP_DEFLAB)
 334398                         continue;
<>335 -                if (ip2->ip_lbl == i) {
  399+                if (ip2->ip_lbl == i && i != lab1 && i != lab2) {
336400                         tfree(n->ip_node);
 337401                         DLIST_REMOVE(n, qelem);
 338402                         gotone = 1;
 339403                 }
 340404         }
 341405 
<> 406+        /*
  407+         * Transform cbranch cond, 1; goto 2; 1: ... into
  408+         * cbranch !cond, 2; 1: ...
  409+         */
  410+        DLIST_FOREACH(ip, ipole, qelem) {
  411+                n = DLIST_NEXT(ip, qelem);
  412+                ip2 = DLIST_NEXT(n, qelem);
  413+                if (ip->type != IP_NODE || ip->ip_node->n_op != CBRANCH)
  414+                        continue;
  415+                if (n->type != IP_NODE || n->ip_node->n_op != GOTO)
  416+                        continue;
  417+                if (ip2->type != IP_DEFLAB)
  418+                        continue;
  419+                i = ip->ip_node->n_right->n_lval;
  420+                j = n->ip_node->n_left->n_lval;
  421+                if (j == lab1 || j == lab2)
  422+                        continue;
  423+                if (i != ip2->ip_lbl || i == lab1 || i == lab2)
  424+                        continue;
  425+                ip->ip_node->n_right->n_lval = j;
  426+                switch (ip->ip_node->n_left->n_op) {
  427+                case EQ:
  428+                        j = NE;
  429+                        break;
  430+                case NE:
  431+                        j = EQ;
  432+                        break;
  433+                case LE:
  434+                        j = GT;
  435+                        break;
  436+                case LT:
  437+                        j = GE;
  438+                        break;
  439+                case GE:
  440+                        j = LT;
  441+                        break;
  442+                case GT:
  443+                        j = LE;
  444+                        break;
  445+                case ULE:
  446+                        j = UGT;
  447+                        break;
  448+                case ULT:
  449+                        j = UGE;
  450+                        break;
  451+                case UGE:
  452+                        j = ULT;
  453+                        break;
  454+                case UGT:
  455+                        j = ULE;
  456+                        break;
  457+                default:
  458+                        comperr("deljumps: unexpected op");
  459+                }
  460+                ip->ip_node->n_left->n_op = j;
  461+                tfree(n->ip_node);
  462+                DLIST_REMOVE(n, qelem);
  463+                gotone = 1;
  464+        }
  465+
  466+        /* Delete everything after a goto up to the next label. */
  467+        for (ip = start, del = 0; ip != DLIST_ENDMARK(ipole);
  468+             ip = DLIST_NEXT(ip, qelem)) {
  469+loop:
  470+                if ((n = DLIST_NEXT(ip, qelem)) == DLIST_ENDMARK(ipole))
  471+                        break;
  472+                if (n->type != IP_NODE) {
  473+                        del = 0;
  474+                        continue;
  475+                }
  476+                if (del) {
  477+                        tfree(n->ip_node);
  478+                        DLIST_REMOVE(n, qelem);
  479+                        gotone = 1;
  480+                        goto loop;
  481+                } else if (n->ip_node->n_op == GOTO)
  482+                        del = 1;
  483+        }
  484+
<_342485         if (gotone)
 343486                 goto again;
 344487 
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-21 17:34 +0100