scc

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

node.c (3067B)


      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 savelabel(void)
    141 {
    142 	Symbol *label = curstmt->label;
    143 
    144 	if (label) {
    145 		prestmt(labelstmt(NULL, label));
    146 		curstmt->label = NULL;
    147 	}
    148 	return curstmt;
    149 }
    150 
    151 Node *
    152 addstmt(Node *np)
    153 {
    154 	insstmt(np, curstmt);
    155 	return curstmt = np;
    156 }
    157 
    158 Node *
    159 delstmt(Node *np)
    160 {
    161 	Node *next;
    162 
    163 	next = np->next;
    164 	deltree(unlinkstmt(np));
    165 	return next;
    166 }
    167 
    168 void
    169 delnode(Node *np)
    170 {
    171 	delete(arena, np);
    172 }
    173 
    174 void
    175 deltree(Node *np)
    176 {
    177 	if (!np)
    178 		return;
    179 	deltree(np->left);
    180 	deltree(np->right);
    181 	delnode(np);
    182 }
    183 
    184 void
    185 cleannodes(void)
    186 {
    187 	if (arena) {
    188 		dealloc(arena);
    189 		arena = NULL;
    190 	}
    191 	curfun = NULL;
    192 }
    193 
    194 void
    195 newfun(Symbol *sym, Node *np)
    196 {
    197 	curfun = sym;
    198 	curstmt = curfun->u.stmt = np;
    199 }
    200 
    201 void
    202 delrange(Node *begin, Node *end)
    203 {
    204 	Node *lprev, *rnext, *next, *np;
    205 
    206 	lprev = begin->prev;
    207 	rnext = end->next;
    208 
    209 	if (lprev)
    210 		lprev->next = rnext;
    211 	if (rnext)
    212 		rnext->prev = lprev;
    213 
    214 	for (np = begin; np != rnext; np = next) {
    215 		next = np->next;
    216 		deltree(np);
    217 	}
    218 }
    219 
    220 void
    221 apply(Node *(*fun)(Node *))
    222 {
    223 	Node *np, *ocurstmt;
    224 
    225 	for (curstmt = curfun->u.stmt; curstmt; curstmt = np) {
    226 		ocurstmt = curstmt;
    227 		np = (*fun)(curstmt);
    228 		np = (np) ? np->next : delstmt(ocurstmt);
    229 	}
    230 }