scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

optm.c (1226B)


      1 static char sccsid[] = "@(#) ./cc2/arch/qbe/optm.c";
      2 
      3 #include <stddef.h>
      4 
      5 #include <scc/scc.h>
      6 
      7 #include "../../cc2.h"
      8 
      9 Node *
     10 optm_dep(Node *np)
     11 {
     12 	int op = np->op;
     13 	Node *p, *dst, *next = np->next;
     14 	Symbol *sym, *osym;
     15 
     16 	switch (op) {
     17 	case OEFUN:
     18 		/*
     19 		 * In QBE we need at the end of a basic block
     20 		 * a jump, so we have to ensure that the last
     21 		 * statement of the function is a ret, a jmp
     22 		 * or a branch. In the same way, QBE does
     23 		 * not accept labels at the end of a function
     24 		 * (ONOP is used for labels) so we have to add
     25 		 * a ret there, and in the case of branches
     26 		 * we need a label for the next statement
     27 		 */
     28 		op = (np->prev) ? np->prev->op : 0;
     29 		if (!op || op == ONOP || op == OBRANCH || (op != ORET && op != OJMP))
     30 			addstmt(node(ORET), KEEPCUR);
     31 		break;
     32 	case OBRANCH:
     33 		if (!next->label) {
     34 			sym = getsym(TMPSYM);
     35 			sym->kind = SLABEL;
     36 			next->label = sym;
     37 		}
     38 	case OJMP:
     39 		for (;;) {
     40 			dst = np->u.sym->u.stmt;
     41 			if (dst->op != OJMP)
     42 				break;
     43 			np->u.sym = dst->u.sym;
     44 		}
     45 		for (p = np->next; p; p = p->next) {
     46 			if (p == dst)
     47 				return NULL;
     48 			if (p->op == ONOP ||
     49 			    p->op == OBLOOP ||
     50 			    p->op == OELOOP) {
     51 				continue;
     52 			}
     53 			break;
     54 		}
     55 		break;
     56 	}
     57 	return np;
     58 }