6 #define den(i,j) ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1))
8 struct code codehead = { Start };
9 Code codelist = &codehead;
13 static int foldcond(Tree e1, Tree e2);
14 static void caselabel(Swtch, long, int);
15 static void cmp(int, Symbol, long, int);
16 static Tree conditional(int);
17 static void dostmt(int, Swtch, int);
18 static int equal(Symbol, Symbol);
19 static void forstmt(int, Swtch, int);
20 static void ifstmt(int, int, Swtch, int);
21 static Symbol localaddr(Tree);
22 static void stmtlabel(void);
23 static void swstmt(int, int, int);
24 static void whilestmt(int, Swtch, int);
29 warning("unreachable code\n");
39 int reachable(int kind) {
43 for (cp = codelist; cp->kind < Label; )
45 if (cp->kind == Jump || cp->kind == Switch)
50 void addlocal(Symbol p) {
52 code(Local)->u.var = p;
57 void definept(Coordinate *p) {
58 Code cp = code(Defpoint);
60 cp->u.point.src = p ? *p : src;
61 cp->u.point.point = npoints;
63 int n = findcount(cp->u.point.src.file,
64 cp->u.point.src.x, cp->u.point.src.y);
66 refinc = (float)n/ncalled;
68 if (glevel > 2) locus(identifiers, &cp->u.point.src);
69 if (events.points && reachable(Gen))
72 apply(events.points, &cp->u.point.src, &e);
77 void statement(int loop, Swtch swp, int lev) {
80 if (Aflag >= 2 && lev == 15)
81 warning("more than 15 levels of nested statements\n");
83 case IF: ifstmt(genlabel(2), loop, swp, lev + 1);
85 case WHILE: whilestmt(genlabel(3), swp, lev + 1); break;
86 case DO: dostmt(genlabel(3), swp, lev + 1); expect(';');
89 case FOR: forstmt(genlabel(4), swp, lev + 1);
91 case BREAK: walk(NULL, 0, 0);
93 if (swp && swp->lab > loop)
98 error("illegal break statement\n");
99 t = gettok(); expect(';');
102 case CONTINUE: walk(NULL, 0, 0);
107 error("illegal continue statement\n");
108 t = gettok(); expect(';');
111 case SWITCH: swstmt(loop, genlabel(2), lev + 1);
114 int lab = genlabel(1);
116 error("illegal case label\n");
119 static char stop[] = { IF, ID, 0 };
123 if (generic(p->op) == CNST && isint(p->type)) {
126 p = cast(p, swp->sym->type);
127 if (p->type->op == UNSIGNED)
128 p->u.v.i = extend(p->u.v.u, p->type);
130 caselabel(swp, p->u.v.i, lab);
133 error("case label must be a constant integer expression\n");
137 statement(loop, swp, lev);
139 case DEFAULT: if (swp == NULL)
140 error("illegal default label\n");
141 else if (swp->deflab)
142 error("extra default label\n");
144 swp->deflab = findlabel(swp->lab);
145 definelab(swp->deflab->u.l.label);
149 statement(loop, swp, lev); break;
151 Type rty = freturn(cfunc->type);
155 if (rty == voidtype) {
156 error("extraneous return value\n");
163 warning("missing return value\n");
166 branch(cfunc->u.f.label);
170 case '{': compound(loop, swp, lev + 1); break;
171 case ';': definept(NULL); t = gettok(); break;
172 case GOTO: walk(NULL, 0, 0);
176 Symbol p = lookup(token, stmtlabs);
178 p = install(token, &stmtlabs, 0, FUNC);
180 p->u.l.label = genlabel(1);
184 branch(p->u.l.label);
187 error("missing label in goto\n"); expect(';');
190 case ID: if (getchr() == ':') {
192 statement(loop, swp, lev);
195 default: definept(NULL);
197 error("unrecognized statement\n");
202 if (nodecount == 0 || nodecount > 200)
204 else if (glevel) walk(NULL, 0, 0);
210 if (kind[t] != IF && kind[t] != ID
211 && t != '}' && t != EOI) {
212 static char stop[] = { IF, ID, '}', 0 };
213 error("illegal statement termination\n");
219 static void ifstmt(int lab, int loop, Swtch swp, int lev) {
223 walk(conditional(')'), 0, lab);
225 statement(loop, swp, lev);
230 statement(loop, swp, lev);
231 if (findlabel(lab + 1)->ref)
236 static Tree conditional(int tok) {
239 if (Aflag > 1 && isfunc(p->type))
240 warning("%s used in a conditional expression\n",
244 static void stmtlabel(void) {
245 Symbol p = lookup(token, stmtlabs);
248 p = install(token, &stmtlabs, 0, FUNC);
250 p->u.l.label = genlabel(1);
254 error("redefinition of label `%s' previously defined at %w\n", p->name, &p->src);
257 definelab(p->u.l.label);
261 static void forstmt(int lab, Swtch swp, int lev) {
263 Tree e1 = NULL, e2 = NULL, e3 = NULL;
270 e1 = texpr(expr0, ';', FUNC);
277 e2 = texpr(conditional, ';', FUNC);
282 e3 = texpr(expr0, ')', FUNC);
284 static char stop[] = { IF, ID, '}', 0 };
288 once = foldcond(e1, e2);
293 statement(lab, swp, lev);
307 if (findlabel(lab + 2)->ref)
310 static void swstmt(int loop, int lab, int lev) {
319 if (!isint(e->type)) {
320 error("illegal type `%t' in switch expression\n",
322 e = retype(e, inttype);
324 e = cast(e, promote(e->type));
325 if (generic(e->op) == INDIR && isaddrop(e->kids[0]->op)
326 && e->kids[0]->u.sym->type == e->type
327 && !isvolatile(e->kids[0]->u.sym->type)) {
328 sw.sym = e->kids[0]->u.sym;
331 sw.sym = genident(REGISTER, e->type, level);
333 walk(asgn(sw.sym, e), 0, 0);
340 sw.values = newarray(SWSIZE, sizeof *sw.values, FUNC);
341 sw.labels = newarray(SWSIZE, sizeof *sw.labels, FUNC);
343 statement(loop, &sw, lev);
344 if (sw.deflab == NULL) {
345 sw.deflab = findlabel(lab);
348 warning("switch statement with no cases\n");
350 if (findlabel(lab + 1)->ref)
353 codelist = head->prev;
354 codelist->next = head->prev = NULL;
358 head->next->prev = codelist;
359 codelist->next = head->next;
362 static void caselabel(Swtch swp, long val, int lab) {
365 if (swp->ncases >= swp->size)
367 long *vals = swp->values;
368 Symbol *labs = swp->labels;
370 swp->values = newarray(swp->size, sizeof *swp->values, FUNC);
371 swp->labels = newarray(swp->size, sizeof *swp->labels, FUNC);
372 for (k = 0; k < swp->ncases; k++) {
373 swp->values[k] = vals[k];
374 swp->labels[k] = labs[k];
378 for ( ; k > 0 && swp->values[k-1] >= val; k--) {
379 swp->values[k] = swp->values[k-1];
380 swp->labels[k] = swp->labels[k-1];
382 if (k < swp->ncases && swp->values[k] == val)
383 error("duplicate case label `%d'\n", val);
384 swp->values[k] = val;
385 swp->labels[k] = findlabel(lab);
387 if (Aflag >= 2 && swp->ncases == 258)
388 warning("more than 257 cases in a switch\n");
390 void swgen(Swtch swp) {
392 long *v = swp->values;
394 buckets = newarray(swp->ncases + 1,
395 sizeof *buckets, FUNC);
396 for (n = k = 0; k < swp->ncases; k++, n++) {
398 while (n > 0 && den(n-1, k) >= density)
401 buckets[n] = swp->ncases;
402 swcode(swp, buckets, 0, n - 1);
404 void swcode(Swtch swp, int b[], int lb, int ub) {
405 int hilab, lolab, l, u, k = (lb + ub)/2;
406 long *v = swp->values;
408 if (k > lb && k < ub) {
413 hilab = swp->deflab->u.l.label;
415 lolab = swp->deflab->u.l.label;
418 lolab = hilab = swp->deflab->u.l.label;
424 for (i = l; i <= u; i++)
425 cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label);
426 if (k > lb && k < ub)
427 cmp(GT, swp->sym, v[u], hilab);
429 cmp(GT, swp->sym, v[u], hilab);
431 cmp(LT, swp->sym, v[l], lolab);
433 assert(lolab == hilab),
439 Type ty = signedint(swp->sym->type);
440 Symbol table = genident(STATIC,
441 array(voidptype, u - l + 1, 0), GLOBAL);
442 (*IR->defsymbol)(table);
443 if (!isunsigned(swp->sym->type) || v[l] != 0)
444 cmp(LT, swp->sym, v[l], lolab);
445 cmp(GT, swp->sym, v[u], hilab);
446 e = (*optree['-'])(SUB, cast(idtree(swp->sym), ty), cnsttree(ty, v[l]));
447 if (e->type->size < unsignedptr->size)
448 e = cast(e, unsignedlong);
449 walk(tree(JUMP, voidtype,
450 rvalue((*optree['+'])(ADD, pointer(idtree(table)), e)), NULL),
453 codelist->u.swtch.table = table;
454 codelist->u.swtch.sym = swp->sym;
455 codelist->u.swtch.deflab = swp->deflab;
456 codelist->u.swtch.size = u - l + 1;
457 codelist->u.swtch.values = &v[l];
458 codelist->u.swtch.labels = &swp->labels[l];
459 if (v[u] - v[l] + 1 >= 10000)
460 warning("switch generates a huge table\n");
463 assert(lolab != swp->deflab->u.l.label);
465 swcode(swp, b, lb, k - 1);
468 assert(hilab != swp->deflab->u.l.label);
470 swcode(swp, b, k + 1, ub);
473 static void cmp(int op, Symbol p, long n, int lab) {
474 Type ty = signedint(p->type);
481 void retcode(Tree p) {
486 apply(events.returns, cfunc, NULL);
490 ty = assign(freturn(cfunc->type), p);
492 error("illegal return type; found `%t' expected `%t'\n",
493 p->type, freturn(cfunc->type));
500 p = tree(RIGHT, p->type,
501 tree(CALL+B, p->type,
502 p->kids[0]->kids[0], idtree(retv)),
503 rvalue(idtree(retv)));
505 p = asgntree(ASGN, rvalue(idtree(retv)), p);
508 apply(events.returns, cfunc, rvalue(idtree(retv)));
513 Symbol t1 = genident(AUTO, p->type, level);
515 walk(asgn(t1, p), 0, 0);
516 apply(events.returns, cfunc, idtree(t1));
519 if (!isfloat(p->type))
520 p = cast(p, promote(p->type));
523 Symbol q = localaddr(p);
524 if (q && (q->computed || q->generated))
525 warning("pointer to a %s is an illegal return value\n",
526 q->scope == PARAM ? "parameter" : "local");
528 warning("pointer to %s `%s' is an illegal return value\n",
529 q->scope == PARAM ? "parameter" : "local", q->name);
531 walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0);
533 void definelab(int lab) {
535 Symbol p = findlabel(lab);
539 code(Label)->u.forest = newnode(LABEL+V, NULL, NULL, p);
540 for (cp = codelist->prev; cp->kind <= Label; )
542 while ( cp->kind == Jump
543 && cp->u.forest->kids[0]
544 && specific(cp->u.forest->kids[0]->op) == ADDRG+P
545 && cp->u.forest->kids[0]->syms[0] == p) {
546 assert(cp->u.forest->kids[0]->syms[0]->u.l.label == lab);
550 cp->prev->next = cp->next;
551 cp->next->prev = cp->prev;
553 while (cp->kind <= Label)
558 Symbol p = findlabel(lab);
561 return newnode(JUMP+V, newnode(ADDRG+ttob(voidptype), NULL, NULL, p),
564 void branch(int lab) {
566 Symbol p = findlabel(lab);
570 code(Label)->u.forest = jump(lab);
571 for (cp = codelist->prev; cp->kind < Label; )
573 while ( cp->kind == Label
574 && cp->u.forest->op == LABEL+V
575 && !equal(cp->u.forest->syms[0], p)) {
576 equatelab(cp->u.forest->syms[0], p);
579 cp->prev->next = cp->next;
580 cp->next->prev = cp->prev;
582 while (cp->kind < Label)
585 if (cp->kind == Jump || cp->kind == Switch) {
587 codelist->prev->next = NULL;
588 codelist = codelist->prev;
590 codelist->kind = Jump;
591 if (cp->kind == Label
592 && cp->u.forest->op == LABEL+V
593 && equal(cp->u.forest->syms[0], p))
594 warning("source code specifies an infinite loop");
597 void equatelab(Symbol old, Symbol new) {
598 assert(old->u.l.equatedto == NULL);
599 old->u.l.equatedto = new;
602 static int equal(Symbol lprime, Symbol dst) {
603 assert(dst && lprime);
604 for ( ; dst; dst = dst->u.l.equatedto)
609 /* dostmt - do statement while ( expression ) */
610 static void dostmt(int lab, Swtch swp, int lev) {
614 statement(lab, swp, lev);
619 walk(conditional(')'), lab, 0);
620 if (findlabel(lab + 2)->ref)
624 /* foldcond - check if initial test in for(e1;e2;e3) S is necessary */
625 static int foldcond(Tree e1, Tree e2) {
626 int op = generic(e2->op);
629 if (e1 == 0 || e2 == 0)
631 if (generic(e1->op) == ASGN && isaddrop(e1->kids[0]->op)
632 && generic(e1->kids[1]->op) == CNST) {
633 v = e1->kids[0]->u.sym;
637 if ((op==LE || op==LT || op==EQ || op==NE || op==GT || op==GE)
638 && generic(e2->kids[0]->op) == INDIR
639 && e2->kids[0]->kids[0]->u.sym == v
640 && e2->kids[1]->op == e1->op) {
641 e1 = simplify(op, e2->type, e1, e2->kids[1]);
642 if (e1->op == CNST+I)
648 /* localaddr - returns q if p yields the address of local/parameter q; otherwise returns 0 */
649 static Symbol localaddr(Tree p) {
652 switch (generic(p->op)) {
653 case INDIR: case CALL: case ARG:
655 case ADDRL: case ADDRF:
657 case RIGHT: case ASGN:
659 return localaddr(p->kids[1]);
660 return localaddr(p->kids[0]);
663 assert(p->kids[1] && p->kids[1]->op == RIGHT);
664 if ((q = localaddr(p->kids[1]->kids[0])) != NULL)
666 return localaddr(p->kids[1]->kids[1]);
670 if (p->kids[0] && (q = localaddr(p->kids[0])) != NULL)
672 return localaddr(p->kids[1]);
677 /* whilestmt - while ( expression ) statement */
678 static void whilestmt(int lab, Swtch swp, int lev) {
687 e = texpr(conditional, ')', FUNC);
690 statement(lab, swp, lev);
694 if (findlabel(lab + 2)->ref)