1#include <stdlib.h>2#include <string.h>34#include <scc/scc.h>56#include "cc2.h"78#define NNODES 32910Symbol *curfun;1112static Alloc *arena;13static Node *curstmt;1415Node *16node(int op)17{18 Node *np;1920 if (!arena)21 arena = alloc(sizeof(Node), NNODES);22 np = memset(new(arena), 0, sizeof(*np));23 np->op = op;2425 return np;26}2728#ifndef NDEBUG29#include <stdio.h>3031static void32prnode(Node *np)33{34 if (!np)35 return;36 prnode(np->left);37 prnode(np->right);3839 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}6869void70prtree(Node *np)71{72 Block *bb;7374 bb = np->bb;7576 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);8485 prnode(np);86 putc('\n', stderr);87}8889void90prforest(char *msg)91{92 Node *np;9394 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#endif100101Node *102insstmt(Node *np, Node *at)103{104 Node *next;105106 next = at->next;107 if (next)108 next->prev = np;109 at->next = np;110111 np->next = next;112 np->prev = at;113114 return np;115}116117Node *118unlinkstmt(Node *np)119{120 Node *next, *prev;121122 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;129130 return np;131}132133Node *134prestmt(Node *np)135{136 return insstmt(np, curstmt->prev);137}138139Node *140savelabel(void)141{142 Symbol *label = curstmt->label;143144 if (label) {145 prestmt(labelstmt(NULL, label));146 curstmt->label = NULL;147 }148 return curstmt;149}150151Node *152addstmt(Node *np)153{154 insstmt(np, curstmt);155 return curstmt = np;156}157158Node *159delstmt(Node *np)160{161 Node *next;162163 next = np->next;164 deltree(unlinkstmt(np));165 return next;166}167168void169delnode(Node *np)170{171 delete(arena, np);172}173174void175deltree(Node *np)176{177 if (!np)178 return;179 deltree(np->left);180 deltree(np->right);181 delnode(np);182}183184void185cleannodes(void)186{187 if (arena) {188 dealloc(arena);189 arena = NULL;190 }191 curfun = NULL;192}193194void195newfun(Symbol *sym, Node *np)196{197 curfun = sym;198 curstmt = curfun->u.stmt = np;199}200201void202delrange(Node *begin, Node *end)203{204 Node *lprev, *rnext, *next, *np;205206 lprev = begin->prev;207 rnext = end->next;208209 if (lprev)210 lprev->next = rnext;211 if (rnext)212 rnext->prev = lprev;213214 for (np = begin; np != rnext; np = next) {215 next = np->next;216 deltree(np);217 }218}219220void221apply(Node *(*fun)(Node *))222{223 Node *np, *ocurstmt;224225 for (curstmt = curfun->u.stmt; curstmt; curstmt = np) {226 ocurstmt = curstmt;227 np = (*fun)(curstmt);228 np = (np) ? np->next : delstmt(ocurstmt);229 }230}