scc

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

node.c (2911B)


      1 #include <stdlib.h>
      2 #include <string.h>
      3 
      4 #include <scc/scc.h>
      5 
      6 #include "cc2.h"
      7 
      8 #define NNODES   32
      9 
     10 Symbol *curfun;
     11 
     12 static Alloc *arena;
     13 static Node *curstmt;
     14 
     15 Node *
     16 node(int op)
     17 {
     18 	Node *np;
     19 
     20 	if (!arena)
     21 		arena = alloc(sizeof(Node), NNODES);
     22 	np = memset(new(arena), 0, sizeof(*np));
     23 	np->op = op;
     24 
     25 	return np;
     26 }
     27 
     28 #ifndef NDEBUG
     29 #include <stdio.h>
     30 
     31 static void
     32 prnode(Node *np)
     33 {
     34 	if (!np)
     35 		return;
     36 	prnode(np->left);
     37 	prnode(np->right);
     38 
     39 	switch (np->op) {
     40 	case OBRANCH:
     41 	case OJMP:
     42 		fprintf(stderr,
     43 		        "\t%c -> L%u",
     44 		        np->op, np->u.sym->numid);
     45 		break;
     46 	case OCONST:
     47 		fprintf(stderr,
     48 		        "\t%c%lu{%llu}",
     49 		        np->op, np->type.size, np->u.i);
     50 		break;
     51 	case OAUTO:
     52 	case OREG:
     53 	case OMEM:
     54 	case OLABEL:
     55 	case OTMP:
     56 		fprintf(stderr,
     57 		        "\t%c%lu[%u]",
     58 		        np->op, np->type.size, np->u.sym->numid);
     59 		break;
     60 	default:
     61 		fprintf(stderr,
     62 		        "\t%c%lu",
     63 		        np->op, np->type.size);
     64 		break;
     65 	}
     66 	fprintf(stderr,"(%d,%d)", np->complex, np->address);
     67 }
     68 
     69 void
     70 prtree(Node *np)
     71 {
     72 	Block *bb;
     73 
     74 	bb = np->bb;
     75 
     76 	if (np->flags & BBENTRY)
     77 		putc('>', stderr);
     78 	fprintf(stderr, "(%d)",  bb ? bb->id : 0);
     79 	if (np->flags & BBEXIT)
     80 		putc('>', stderr);
     81 	putc('\t', stderr);
     82 	if (np->label)
     83 		fprintf(stderr, "L%u:", np->label->numid);
     84 
     85 	prnode(np);
     86 	putc('\n', stderr);
     87 }
     88 
     89 void
     90 prforest(char *msg)
     91 {
     92 	Node *np;
     93 
     94 	fprintf(stderr, "tree %s {\n", msg);
     95 	for (np = curfun->u.stmt; np; np = np->next)
     96 		prtree(np);
     97 	fputs("}\n", stderr);
     98 }
     99 #endif
    100 
    101 Node *
    102 insstmt(Node *np, Node *at)
    103 {
    104 	Node *next;
    105 
    106 	next = at->next;
    107 	if (next)
    108 		next->prev = np;
    109 	at->next = np;
    110 
    111 	np->next = next;
    112 	np->prev = at;
    113 
    114 	return np;
    115 }
    116 
    117 Node *
    118 unlinkstmt(Node *np)
    119 {
    120 	Node *next, *prev;
    121 
    122 	next = np->next;
    123 	prev = np->prev;
    124 	if (next)
    125 		next->prev = prev;
    126 	if (prev)
    127 		prev->next = next;
    128 	np->next = np->prev = NULL;
    129 
    130 	return np;
    131 }
    132 
    133 Node *
    134 prestmt(Node *np)
    135 {
    136 	return insstmt(np, curstmt->prev);
    137 }
    138 
    139 Node *
    140 addstmt(Node *np)
    141 {
    142 	insstmt(np, curstmt);
    143 	return curstmt = np;
    144 }
    145 
    146 Node *
    147 delstmt(Node *np)
    148 {
    149 	Node *next;
    150 
    151 	next = np->next;
    152 	deltree(unlinkstmt(np));
    153 	return next;
    154 }
    155 
    156 void
    157 delnode(Node *np)
    158 {
    159 	delete(arena, np);
    160 }
    161 
    162 void
    163 deltree(Node *np)
    164 {
    165 	if (!np)
    166 		return;
    167 	deltree(np->left);
    168 	deltree(np->right);
    169 	delnode(np);
    170 }
    171 
    172 void
    173 cleannodes(void)
    174 {
    175 	if (arena) {
    176 		dealloc(arena);
    177 		arena = NULL;
    178 	}
    179 	curfun = NULL;
    180 }
    181 
    182 void
    183 newfun(Symbol *sym, Node *np)
    184 {
    185 	curfun = sym;
    186 	curstmt = curfun->u.stmt = np;
    187 }
    188 
    189 void
    190 delrange(Node *begin, Node *end)
    191 {
    192 	Node *lprev, *rnext, *next, *np;
    193 
    194 	lprev = begin->prev;
    195 	rnext = end->next;
    196 
    197 	if (lprev)
    198 		lprev->next = rnext;
    199 	if (rnext)
    200 		rnext->prev = lprev;
    201 
    202 	for (np = begin; np != rnext; np = next) {
    203 		next = np->next;
    204 		deltree(np);
    205 	}
    206 }
    207 
    208 void
    209 apply(Node *(*fun)(Node *))
    210 {
    211 	Node *np, *ocurstmt;
    212 
    213 	for (curstmt = curfun->u.stmt; curstmt; curstmt = np) {
    214 		ocurstmt = curstmt;
    215 		np = (*fun)(curstmt);
    216 		np = (np) ? np->next : delstmt(ocurstmt);
    217 	}
    218 }