home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / stmt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  18.5 KB  |  766 lines

  1. #include "c.h"
  2.  
  3. #define SWSIZE 512
  4.  
  5. #define den(i,j) ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1))
  6.  
  7. struct swtch {
  8.     Symbol sym;
  9.     int lab;
  10.     Symbol deflab;
  11.     int ncases;
  12.     int size;
  13.     int *values;
  14.     Symbol *labels;
  15. };
  16. struct code codehead = { Start };
  17. Code codelist = &codehead;
  18. float density = (float)0.5;
  19. Table stmtlabs;
  20.  
  21. static int foldcond ARGS((Tree e1, Tree e2));
  22. static void branch ARGS((int));
  23. static void caselabel ARGS((Swtch, int, int));
  24. static Tree cmp ARGS((int, Symbol, int, int));
  25. static Tree conditional ARGS((int));
  26. static void dostmt ARGS((int, Swtch, int));
  27. static int equal ARGS((Symbol, Symbol));
  28. static void forstmt ARGS((int, Swtch, int));
  29. static void ifstmt ARGS((int, int, Swtch, int));
  30. static Symbol localaddr ARGS((Tree));
  31. static void stmtlabel ARGS((void));
  32. static void swcode ARGS((Swtch, int *, int, int));
  33. static void swgen ARGS((Swtch));
  34. static void swstmt ARGS((int, int, int));
  35. static void whilestmt ARGS((int, Swtch, int));
  36. Code code(int kind)
  37. {
  38.     Code cp;
  39.  
  40.     if (kind > Start) {
  41.         for (cp = codelist; cp->kind < Label; )
  42.             cp = cp->prev;
  43.         if (cp->kind == Jump || cp->kind == Switch)
  44.             warning("unreachable code\n");
  45.     }
  46.     NEW(cp, FUNC);
  47.     cp->kind = kind;
  48.     cp->prev = codelist;
  49.     cp->next = NULL;
  50.     codelist->next = cp;
  51.     codelist = cp;
  52.     return cp;
  53. }
  54. void addlocal(Symbol p)
  55. {
  56.     if (!p->defined) {
  57.         code(Local)->u.var = p;
  58.         p->defined = 1;
  59.         p->scope = level;
  60.     }
  61. }
  62. void definept(Coordinate *p)
  63. {
  64.     Code cp = code(Defpoint);
  65.  
  66.     StatementCount++;
  67.     cp->u.point.src = p ? *p : src;
  68.     cp->u.point.point = npoints;
  69.     if (ncalled > 0) {
  70.         int n = findcount(cp->u.point.src.file,
  71.             cp->u.point.src.x, cp->u.point.src.y);
  72.         if (n >= 0)
  73.             refinc = (float)n/ncalled;
  74.     }
  75.     if (events.points)
  76.         {
  77.             Tree e = NULL;
  78.             apply(events.points, &cp->u.point.src, &e);
  79.             if (e)
  80.                 listnodes(e, 0, 0);
  81.         }
  82.     if (glevel > 2)    locus(identifiers, &cp->u.point.src);
  83. }
  84. void statement(int loop,Swtch swp,int lev)
  85. {
  86.     float ref = refinc;
  87.  
  88.     if (Aflag >= 2 && lev == 15)
  89.         warning("more than 15 levels of nested statements\n");
  90.     switch (t) {
  91.     case IF:       ifstmt(genlabel(2), loop, swp, lev + 1);
  92.  break;
  93.     case WHILE:    whilestmt(genlabel(3), swp, lev + 1); break;
  94.     case DO:       dostmt(genlabel(3), swp, lev + 1); expect(';');
  95.                     break;
  96.  
  97.     case FOR:      forstmt(genlabel(4), swp, lev + 1);
  98.  break;
  99.     case BREAK:    walk(NULL, 0, 0);
  100.                definept(NULL);
  101.                if (swp && swp->lab > loop)
  102.                    branch(swp->lab + 1);
  103.                else if (loop)
  104.                    branch(loop + 2);
  105.                else
  106.                    error("illegal break statement\n");
  107.                t = gettok(); expect(';');
  108.                        break;
  109.  
  110.     case CONTINUE: walk(NULL, 0, 0);
  111.                definept(NULL);
  112.                if (loop)
  113.                    branch(loop + 1);
  114.                else
  115.                    error("illegal continue statement\n");
  116.                t = gettok(); expect(';');
  117.                           break;
  118.  
  119.     case SWITCH:   swstmt(loop, genlabel(2), lev + 1);
  120.  break;
  121.     case CASE:     {
  122.                    int lab = genlabel(1);
  123.                    if (swp == NULL)
  124.                        error("illegal case label\n");
  125.                    definelab(lab);
  126.                    while (t == CASE) {
  127.                        static char stop[] = { IF, ID, 0 };
  128.                        Tree p;
  129.                        t = gettok();
  130.                        p = constexpr(0);
  131.                        if (generic(p->op) == CNST && isint(p->type)) {
  132.                            if (swp) {
  133.                                needconst++;
  134.                                p = cast(p, swp->sym->type);
  135.                                needconst--;
  136.                                caselabel(swp, p->u.v.i, lab);
  137.                            }
  138.                        } else
  139.                            error("case label must be a constant integer expression\n");
  140.  
  141.                        test(':', stop);
  142.                    }
  143.                    statement(loop, swp, lev);
  144.                } break;
  145.     case DEFAULT:  if (swp == NULL)
  146.                    error("illegal default label\n");
  147.                else if (swp->deflab)
  148.                    error("extra default label\n");
  149.                else {
  150.                    swp->deflab = findlabel(swp->lab);
  151.                    definelab(swp->deflab->u.l.label);
  152.                }
  153.                t = gettok();
  154.                expect(':');
  155.                statement(loop, swp, lev); break;
  156.     case RETURN:   {
  157.                    Type rty = freturn(cfunc->type);
  158.                    t = gettok();
  159.                    definept(NULL);
  160.                    if (t != ';')
  161.                        if (rty == voidtype) {
  162.                            error("extraneous return value\n");
  163.                            expr(0);
  164.                            retcode(NULL);
  165.                        } else
  166.                            retcode(expr(0));
  167.                    else {
  168.                        if (rty != voidtype
  169.                        && (rty != inttype || Aflag >= 1))
  170.                            warning("missing return value\n");
  171.                        retcode(NULL);
  172.                    }
  173.                    branch(cfunc->u.f.label);
  174.                } expect(';');
  175.                         break;
  176.  
  177.     case '{':
  178.               compound(loop, swp, lev + 1); 
  179.           break;
  180.     case ';':      definept(NULL); t = gettok(); break;
  181.     case GOTO:     walk(NULL, 0, 0);
  182.                definept(NULL);
  183.                FunctionInfo.hasgotos = 1;
  184.                t = gettok();
  185.                if (t == ID) {
  186.                    Symbol p = lookup(token, stmtlabs);
  187.                    if (p == NULL) {
  188.                 p = install(token, &stmtlabs, 0, FUNC);
  189.                 p->scope = LABELS;
  190.                 p->u.l.label = genlabel(1);
  191.                 p->src = src;
  192.             }
  193.                    use(p, src);
  194.                    branch(p->u.l.label);
  195.                    t = gettok();
  196.                } else
  197.                    error("missing label in goto\n"); expect(';');
  198.                       break;
  199.  
  200.     case ID:       if (getchr() == ':') {
  201.                    stmtlabel();
  202.                    statement(loop, swp, lev);
  203.                    break;
  204.                }
  205.     default:       definept(NULL);
  206.                if (kind[t] != ID) {
  207.                    error("unrecognized statement\n");
  208.                    t = gettok();
  209.                } else {
  210.                    Tree e = expr0(0);
  211.                    listnodes(e, 0, 0);
  212. //                   if (nodecount == 0 || nodecount > 200)
  213. //                       walk(NULL, 0, 0);
  214. //                   else if (glevel) 
  215.                 walk(NULL, 0, 0);
  216.                    deallocate(STMT);
  217.                } expect(';');
  218.                         break;
  219.  
  220.     }
  221.     if (kind[t] != IF && kind[t] != ID
  222.     && t != '}' && t != EOI) {
  223.         static char stop[] = { IF, ID, '}', 0 };
  224.         error("illegal statement termination\n");
  225.         skipto(0, stop);
  226.     }
  227.     refinc = ref;
  228. }
  229.  
  230. static void ifstmt(int lab,int loop,Swtch swp,int lev)
  231. {
  232.     t = gettok();
  233.     expect('(');
  234.     definept(NULL);
  235.     walk(conditional(')'), 0, lab);
  236.     refinc /= (float)2.0;
  237.     statement(loop, swp, lev);
  238.     if (t == ELSE) {
  239.         branch(lab + 1);
  240.         t = gettok();
  241.         definelab(lab);
  242.         statement(loop, swp, lev);
  243.         if (findlabel(lab + 1)->ref)
  244.             definelab(lab + 1);
  245.     } else
  246.         definelab(lab);
  247. }
  248. static Tree conditional(int tok)
  249. {
  250.     Tree p = expr(tok);
  251.  
  252.     if (Aflag > 1 && isfunc(p->type))
  253.         warning("%s used in a conditional expression\n",
  254.             funcname(p));
  255.     return cond(p);
  256. }
  257. static void stmtlabel(void) 
  258. {
  259.     Symbol p = lookup(token, stmtlabs);
  260.  
  261.     if (p == NULL) {
  262.         p = install(token, &stmtlabs, 0, FUNC);
  263.         p->scope = LABELS;
  264.         p->u.l.label = genlabel(1);
  265.         p->src = src;
  266.     }
  267.     if (p->defined)
  268.         error("redefinition of label `%s' previously defined at %w\n", p->name, &p->src);
  269.  
  270.     p->defined = 1;
  271.     definelab(p->u.l.label);
  272.     t = gettok();
  273.     expect(':');
  274. }
  275.  
  276.  
  277. static void forstmt(int lab,Swtch swp,int lev)
  278. {
  279.     int once = 0;
  280.     Tree e1 = NULL, e2 = NULL, e3 = NULL;
  281.     Coordinate pt2, pt3;
  282.     int start;
  283.  
  284.     start = StatementCount;
  285.     t = gettok();
  286.     expect('(');
  287.     definept(NULL);
  288.     if (kind[t] == ID)
  289.         e1 = texpr(expr0, ';', FUNC);
  290.     else
  291.         expect(';');
  292.     walk(e1, 0, 0);
  293.     pt2 = src;
  294.     refinc *= (float)10.0;
  295.     if (kind[t] == ID)
  296.         e2 = texpr(conditional, ';', FUNC);
  297.     else
  298.         expect(';');
  299.     pt3 = src;
  300.     if (kind[t] == ID)
  301.         e3 = texpr(expr0, ')', FUNC);
  302.     else {
  303.         static char stop[] = { IF, ID, '}', 0 };
  304.         test(')', stop);
  305.     }
  306.     if (e2) {
  307.         once = foldcond(e1, e2);
  308.         if (!once)
  309.             branch(lab + 3);
  310.     }
  311.     definelab(lab);
  312.     statement(lab, swp, lev);
  313.     definelab(lab + 1);
  314.     definept(&pt3);
  315.     if (e3)
  316.         walk(e3, 0, 0);
  317.     if (e2) {
  318.         if (!once)
  319.             definelab(lab + 3);
  320.         definept(&pt2);
  321.         walk(e2, lab, 0);
  322.     } else {
  323.         definept(&pt2);
  324.         branch(lab);
  325.     }
  326.     if (OptimizeFlag) {
  327.         ExtendDomain(level,start);
  328.     }
  329.     if (findlabel(lab + 2)->ref)
  330.         definelab(lab + 2);
  331. }
  332. static void swstmt(int loop,int lab,int lev)
  333. {
  334.     Tree e,exprTree;
  335.     struct swtch sw;
  336.     Code head, tail;
  337.  
  338.     t = gettok();
  339.     expect('(');
  340.     definept(NULL);
  341.     e = expr(')');
  342.     if (!isint(e->type)) {
  343.         error("illegal type `%t' in switch expression\n",
  344.             e->type);
  345.         e = retype(e, inttype);
  346.     }
  347.     e = cast(e, promote(e->type));
  348.     if (generic(e->op) == INDIR && isaddrop(e->kids[0]->op)
  349.     && (e->kids[0]->u.sym->type == e->type || 
  350.         isenum(e->kids[0]->u.sym->type))
  351.     && !isvolatile(e->kids[0]->u.sym->type)) {
  352.         sw.sym = e->kids[0]->u.sym;
  353.         walk(NULL, 0, 0);
  354.     } else {
  355.         sw.sym = genident(REGISTER, e->type, level);
  356.         addlocal(sw.sym);
  357.         exprTree = asgn(sw.sym,e);
  358.         walk(exprTree, 0, 0);
  359.     }
  360.     if (OptimizeFlag)
  361.         sw.sym->x.switchSymbol = 1;
  362.     head = code(Switch);
  363.     sw.lab = lab;
  364.     sw.deflab = NULL;
  365.     sw.ncases = 0;
  366.     sw.size = SWSIZE;
  367.     sw.values = newarray(SWSIZE, sizeof *sw.values, FUNC);
  368.     sw.labels = newarray(SWSIZE, sizeof *sw.labels, FUNC);
  369.     refinc /= (float)10.0;
  370.     statement(loop, &sw, lev);
  371.     if (sw.deflab == NULL) {
  372.         sw.deflab = findlabel(lab);
  373.         definelab(lab);
  374.         if (sw.ncases == 0)
  375.             warning("switch statement with no cases\n");
  376.     }
  377.     if (findlabel(lab + 1)->ref)
  378.         definelab(lab + 1);
  379.     tail = codelist;
  380.     codelist = head->prev;
  381.     codelist->next = head->prev = NULL;
  382.     if (sw.ncases > 0)
  383.         swgen(&sw);
  384.     branch(lab);
  385.     head->next->prev = codelist;
  386.     codelist->next = head->next;
  387.     codelist = tail;
  388. }
  389. static void caselabel(Swtch swp,int val,int lab)
  390. {
  391.     int k;
  392.  
  393.     if (swp->ncases >= swp->size)
  394.         {
  395.         int    *vals = swp->values;
  396.         Symbol *labs = swp->labels;
  397.         swp->size *= 2;
  398.         swp->values = newarray(swp->size, sizeof *swp->values, FUNC);
  399.         swp->labels = newarray(swp->size, sizeof *swp->labels, FUNC);
  400.         for (k = 0; k < swp->ncases; k++) {
  401.             swp->values[k] = vals[k];
  402.             swp->labels[k] = labs[k];
  403.         }
  404.         }
  405.     k = swp->ncases;
  406.     for ( ; k > 0 && swp->values[k-1] >= val; k--) {
  407.         swp->values[k] = swp->values[k-1];
  408.         swp->labels[k] = swp->labels[k-1];
  409.     }
  410.     if (k < swp->ncases && swp->values[k] == val)
  411.         error("duplicate case label `%d'\n", val);
  412.     swp->values[k] = val;
  413.     swp->labels[k] = findlabel(lab);
  414.     ++swp->ncases;
  415.     if (Aflag >= 2 && swp->ncases == 258)
  416.         warning("more than 257 cases in a switch\n");
  417. }
  418. static void swgen(Swtch swp)
  419. {
  420.     int *buckets, k, n, *v = swp->values;
  421.  
  422.     buckets = newarray(swp->ncases + 1,
  423.         sizeof *buckets, FUNC);
  424.     for (n = k = 0; k < swp->ncases; k++, n++) {
  425.         buckets[n] = k;
  426.         while (n > 0 && den(n-1, k) >= density)
  427.             n--;
  428.     }
  429.     buckets[n] = swp->ncases;
  430.     swcode(swp, buckets, 0, n - 1);
  431. }
  432. static void swcode(Swtch swp,int b[],int lb,int ub)
  433. {
  434.     int hilab, lolab, l, u, k = (lb + ub)/2;
  435.     int *v = swp->values;
  436.  
  437.     if (k > lb && k < ub) {
  438.         lolab = genlabel(1);
  439.         hilab = genlabel(1);
  440.     } else if (k > lb) {
  441.         lolab = genlabel(1);
  442.         hilab = swp->deflab->u.l.label;
  443.     } else if (k < ub) {
  444.         lolab = swp->deflab->u.l.label;
  445.         hilab = genlabel(1);
  446.     } else
  447.         lolab = hilab = swp->deflab->u.l.label;
  448.     l = b[k];
  449.     u = b[k+1] - 1;
  450.     if (u - l + 1 <= 3)
  451.         {
  452.             int i,lastvalue;
  453.             Tree ResultTree;
  454.             for (i = l; i <= u; i++) {
  455.                 ResultTree = cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label);
  456.                 lastvalue = v[i];
  457.             }
  458.             if (k > lb && k < ub) {
  459.                 ResultTree = cmp(GT, swp->sym, v[u], hilab);
  460.                 if (lastvalue == v[u])
  461.                     SetForestFlags(1);
  462.  
  463.             }
  464.             else if (k > lb) {
  465.                 ResultTree = cmp(GT, swp->sym, v[u], hilab);
  466.                 if (lastvalue == v[u])
  467.                     SetForestFlags(1);
  468.             }
  469.             else if (k < ub) {
  470.                 ResultTree = cmp(LT, swp->sym, v[l], lolab);
  471.                 if (lastvalue == v[l])
  472.                     SetForestFlags(1);
  473.             }
  474.             else
  475. #ifndef NDEBUG
  476.                 assert(lolab == hilab),
  477. #endif
  478.                 branch(lolab);
  479.             walk(NULL, 0, 0);
  480.         }
  481.     else {
  482.         Symbol table = genident(STATIC,
  483.             array(voidptype, u - l + 1, 0), LABELS);
  484.         (*IR->defsymbol)(table);
  485.         cmp(LT, swp->sym, v[l], lolab);
  486.         cmp(GT, swp->sym, v[u], hilab);
  487.         walk(tree(JUMP, voidtype,
  488.             rvalue((*optree['+'])(ADD, pointer(idtree(table)),
  489.                 (*optree['-'])(SUB,
  490.                     cast(idtree(swp->sym), inttype),
  491.                     consttree(v[l], inttype)))), NULL), 0, 0);
  492.         code(Switch);
  493.         codelist->u.swtch.table = table;
  494.         codelist->u.swtch.sym = swp->sym;
  495.         codelist->u.swtch.deflab = swp->deflab;
  496.         codelist->u.swtch.size = u - l + 1;
  497.         codelist->u.swtch.values = &v[l];
  498.         codelist->u.swtch.labels = &swp->labels[l];
  499.         if (v[u] - v[l] + 1 >= 10000)
  500.             warning("switch generates a huge table\n");
  501.     }
  502.     if (k > lb) {
  503.         assert(lolab != swp->deflab->u.l.label);
  504.         definelab(lolab);
  505.         swcode(swp, b, lb, k - 1);
  506.     }
  507.     if (k < ub) {
  508.         assert(hilab != swp->deflab->u.l.label);
  509.         definelab(hilab);
  510.         swcode(swp, b, k + 1, ub);
  511.     }
  512. }
  513. static Tree cmp(int op,Symbol p,int n,int lab)
  514. {
  515.     Tree Result;
  516.  
  517.     Result = eqtree(op,cast(idtree(p), inttype),
  518.             consttree(n, inttype));
  519.     listnodes(Result,lab, 0);
  520.     return Result;
  521. }
  522. void retcode(Tree p)
  523. {
  524.     Type ty;
  525.  
  526.     if (p == NULL) {
  527.         if (events.returns)
  528.             apply(events.returns, cfunc, NULL);
  529.         return;
  530.     }
  531.     /*
  532.     There is no need to do anything if the called function returns
  533.     an integer and the function return type is integer
  534.     */
  535.     if ( (p->op == CALLI && isint(cfunc->type)) ||
  536.          (p->op == CALLL && cfunc->type == longlongtype) ||
  537.          (p->op == CALLD && cfunc->type == doubletype)){
  538.         walk(tree(RET + widen(p->type), p->type, p, NULL), 0, 0);
  539.         return;
  540.     }
  541.  
  542.     p = pointer(p);
  543.     ty = assign(freturn(cfunc->type), p);
  544.     if (ty == NULL) {
  545.         error("illegal return type; found `%t' expected `%t'\n",
  546.             p->type, freturn(cfunc->type));
  547.         return;
  548.     }
  549.     p = cast(p, ty);
  550.     if (retv)
  551.         {
  552.             if (iscallb(p))
  553.                 p = tree(RIGHT, p->type,
  554.                     tree(CALL+B, p->type,
  555.                         p->kids[0]->kids[0], idtree(retv)),
  556.                     rvalue(idtree(retv)));
  557.             else
  558.                 p = asgntree(ASGN, rvalue(idtree(retv)), p);
  559.             walk(p, 0, 0);
  560.             if (events.returns)
  561.                 apply(events.returns, cfunc, rvalue(idtree(retv)));
  562.             return;
  563.         }
  564.     if (events.returns)
  565.         {
  566.             Symbol t1 = genident(AUTO, p->type, level);
  567.             addlocal(t1);
  568.             walk(asgn(t1, p), 0, 0);
  569.             apply(events.returns, cfunc, idtree(t1));
  570.             p = idtree(t1);
  571.         }
  572.     p = cast(p, promote(p->type));
  573.     if (isptr(p->type)) {
  574.         Symbol q = localaddr(p);
  575.         if (q && (q->computed || q->generated))
  576.             warning("pointer to a %s is an illegal return value\n",
  577.                 q->scope == PARAM ? "parameter" : "local");
  578.         else if (q)
  579.             warning("pointer to %s `%s' is an illegal return value\n",
  580.                 q->scope == PARAM ? "parameter" : "local", q->name);
  581.         p = cast(p, unsignedtype);
  582.     }
  583.     walk(tree(RET + widen(p->type), p->type, p, NULL), 0, 0);
  584. }
  585. void definelab(int lab)
  586. {
  587.     Code cp;
  588.     Symbol p = findlabel(lab);
  589.  
  590.     assert(lab);
  591.     walk(NULL, 0, 0);
  592.     code(Label)->u.forest = newnode(LABELV, NULL, NULL, p);
  593.     for (cp = codelist->prev; cp->kind <= Label; )
  594.         cp = cp->prev;
  595.     while (   cp->kind == Jump
  596.            && cp->u.forest->kids[0]
  597.            && cp->u.forest->kids[0]->op == ADDRGP
  598.            && cp->u.forest->kids[0]->syms[0] == p) {
  599.         assert(cp->u.forest->kids[0]->syms[0]->u.l.label == lab);
  600.         p->ref--;
  601.         assert(cp->next);
  602.         assert(cp->prev);
  603.         cp->prev->next = cp->next;
  604.         cp->next->prev = cp->prev;
  605.         cp = cp->prev;
  606.         while (cp->kind <= Label)
  607.             cp = cp->prev;
  608.     }
  609. }
  610. Node jump(int lab)
  611. {
  612.     Symbol p = findlabel(lab);
  613.  
  614.     p->ref++;
  615.     return newnode(JUMPV, newnode(ADDRGP, NULL, NULL, p),
  616.         NULL, NULL);
  617. }
  618. static void branch(int lab)
  619. {
  620.     Code cp;
  621.     Symbol p = findlabel(lab);
  622.  
  623.     assert(lab);
  624.     walk(NULL, 0, 0);
  625.     code(Label)->u.forest = jump(lab);
  626.     for (cp = codelist->prev; cp->kind < Label; )
  627.         cp = cp->prev;
  628.     while (   cp->kind == Label
  629.            && cp->u.forest->op == LABELV
  630.            && !equal(cp->u.forest->syms[0], p)) {
  631.         equatelab(cp->u.forest->syms[0], p);
  632.         assert(cp->next);
  633.         assert(cp->prev);
  634.         cp->prev->next = cp->next;
  635.         cp->next->prev = cp->prev;
  636.         cp = cp->prev;
  637.         while (cp->kind < Label)
  638.             cp = cp->prev;
  639.     }
  640.     if (cp->kind == Jump || cp->kind == Switch) {
  641.         p->ref--;
  642.         codelist->prev->next = NULL;
  643.         codelist = codelist->prev;
  644.     } else {
  645.         codelist->kind = Jump;
  646.         if (cp->kind == Label
  647.         &&  cp->u.forest->op == LABELV
  648.         &&  equal(cp->u.forest->syms[0], p))
  649.             warning("source code specifies an infinite loop");
  650.     }
  651. }
  652. void equatelab(Symbol old,Symbol new)
  653. {
  654.     assert(old->u.l.equatedto == NULL);
  655.     old->u.l.equatedto = new;
  656.     new->ref++;
  657. }
  658. static int equal(Symbol lprime,Symbol dst)
  659. {
  660.     assert(dst && lprime);
  661.     for ( ; dst; dst = dst->u.l.equatedto)
  662.         if (lprime == dst)
  663.             return 1;
  664.     return 0;
  665. }
  666. /* dostmt - do statement while ( expression ) */
  667. static void dostmt(int lab,Swtch swp,int lev)
  668. {
  669.     int start = StatementCount;
  670.     refinc *= (float)10.0;
  671.     t = gettok();
  672.     definelab(lab);
  673.     statement(lab, swp, lev);
  674.     definelab(lab + 1);
  675.     expect(WHILE);
  676.     expect('(');
  677.     definept(NULL);
  678.     walk(conditional(')'), lab, 0);
  679.     if (findlabel(lab + 2)->ref)
  680.         definelab(lab + 2);
  681.     if (OptimizeFlag) {
  682.         ExtendDomain(level,start);
  683.     }
  684. }
  685.  
  686. /* foldcond - check if initial test in for(e1;e2;e3) S is necessary */
  687. static int foldcond(Tree e1,Tree e2)
  688. {
  689.     int op = generic(e2->op);
  690.     Symbol v;
  691.  
  692.     if (e1 == 0 || e2 == 0)
  693.         return 0;
  694.     if (generic(e1->op) == ASGN && isaddrop(e1->kids[0]->op)
  695.     && generic(e1->kids[1]->op) == CNST) {
  696.         v = e1->kids[0]->u.sym;
  697.         e1 = e1->kids[1];
  698.     } else
  699.         return 0;
  700.     if ((op==LE || op==LT || op==EQ || op==NE || op==GT || op==GE)
  701.     && generic(e2->kids[0]->op) == INDIR
  702.     && e2->kids[0]->kids[0]->u.sym == v
  703.     && e2->kids[1]->op == e1->op) {
  704.         e1 = simplify(op, e2->type, e1, e2->kids[1]);
  705.         if (e1->op == CNST+I)
  706.             return e1->u.v.i;
  707.     }
  708.     return 0;
  709. }
  710.  
  711. /* localaddr - returns q if p yields the address of local/parameter q; otherwise returns 0 */
  712. static Symbol localaddr(Tree p)
  713. {
  714.     if (p == NULL)
  715.         return NULL;
  716.     switch (generic(p->op)) {
  717.     case INDIR: case CALL: case ARG:
  718.         return NULL;
  719.     case ADDRL: case ADDRF:
  720.         return p->u.sym;
  721.     case RIGHT: case ASGN:
  722.         if (p->kids[1])
  723.             return localaddr(p->kids[1]);
  724.         return localaddr(p->kids[0]);
  725.     case COND: {
  726.         Symbol q;
  727.         assert(p->kids[1] && p->kids[1]->op == RIGHT);
  728.         if ((q = localaddr(p->kids[1]->kids[0])) != NULL)
  729.             return q;
  730.         return localaddr(p->kids[1]->kids[1]);
  731.         }
  732.     default: {
  733.         Symbol q;
  734.         if (p->kids[0] && (q = localaddr(p->kids[0])) != NULL)
  735.             return q;
  736.         return localaddr(p->kids[1]);
  737.         }
  738.     }
  739. }
  740.  
  741. /* whilestmt - while ( expression ) statement */
  742. static void whilestmt(int lab,Swtch swp,int lev)
  743. {
  744.     Coordinate pt;
  745.     Tree e;
  746.     int start = StatementCount;
  747.  
  748.     refinc *= (float)10.0;
  749.     t = gettok();
  750.     expect('(');
  751.     walk(NULL, 0, 0);
  752.     pt = src;
  753.     e = texpr(conditional, ')', FUNC);
  754.     branch(lab + 1);
  755.     definelab(lab);
  756.     statement(lab, swp, lev);
  757.     definelab(lab + 1);
  758.     definept(&pt);
  759.     walk(e, lab, 0);
  760.     if (findlabel(lab + 2)->ref)
  761.         definelab(lab + 2);
  762.     if (OptimizeFlag) {
  763.         ExtendDomain(level,start);
  764.     }
  765. }
  766.