shithub: scc

Download patch

ref: 83bd84e42a0dd0d049e1c8a8dbb7ee52cdfa0b9d
parent: fe758342bf28b59036dad71051e347aaf5017d49
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Aug 18 08:47:21 EDT 2016

[cc2-qbe] Avoid dynamic allocation for temporal nodes

These nodes can be built in nodes allocated in the stack.
In this way we avoid some memory leaks that we are having
(well, we have an arena, so at the end of the function
we do not have memory leaks but we are having them inside
of the function).

--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
@@ -247,9 +247,8 @@
 
 	for (q = pars; q < &pars[n]; ++q) {
 		op = (q == &pars[n-1]) ? ASPARE : ASPAR;
-		p = tmpnode(NULL, &(*q)->type);
-		code(op, NULL, *q, p);
-		deltree(p);
+		tmpnode(&aux, &(*q)->type);
+		code(op, NULL, *q, &aux);
 	}
 	code(ASCALL, NULL, NULL, NULL);
 
@@ -313,7 +312,7 @@
 bool(Node *np, Symbol *true, Symbol *false)
 {
 	Node *l = np->left, *r = np->right;
-	Node ret, *ifyes, *ifno;
+	Node ret, ifyes, ifno;
 	Symbol *label;
 
 	switch (np->op) {
@@ -333,12 +332,9 @@
 		bool(r, true, false);
 		break;
 	default:
-		ifyes = label2node(true);
-		ifno = label2node(false);
-		rhs(l, &ret);
-		code(ASBRANCH, &ret, ifyes, ifno);
-		deltree(ifyes);
-		deltree(ifno);
+		label2node(&ifyes, true);
+		label2node(&ifno, false);
+		code(ASBRANCH, rhs(l, &ret), &ifyes, &ifno);
 		break;
 	}
 }
@@ -346,28 +342,24 @@
 static Node *
 ternary(Node *np, Node *ret)
 {
-	Node *yes, *no, *phi, *colon, aux1, aux2, aux3;
+	Node ifyes, ifno, phi, *colon, aux1, aux2, aux3;
 
 	tmpnode(ret, &np->type);
-	yes = label2node(NULL);
-	no = label2node(NULL);
-	phi = label2node(NULL);
+	label2node(&ifyes, NULL);
+	label2node(&ifno, NULL);
+	label2node(&phi, NULL);
 
 	colon = np->right;
-	code(ASBRANCH, rhs(np->left, &aux1), yes, no);
+	code(ASBRANCH, rhs(np->left, &aux1), &ifyes, &ifno);
 
-	setlabel(yes->u.sym);
+	setlabel(ifyes.u.sym);
 	assign(ret, rhs(colon->left, &aux2));
-	code(ASJMP, NULL, phi, NULL);
+	code(ASJMP, NULL, &phi, NULL);
 
-	setlabel(no->u.sym);
+	setlabel(ifno.u.sym);
 	assign(ret, rhs(colon->right, &aux3));
-	setlabel(phi->u.sym);
+	setlabel(phi.u.sym);
 
-	deltree(yes);
-	deltree(no);
-	deltree(phi);
-
 	return ret;
 }
 
@@ -374,23 +366,24 @@
 static Node *
 function(void)
 {
+	Node aux;
 	Symbol *p;
 
 	/* allocate stack space for parameters */
 	for (p = locals; p && (p->type.flags & PARF) != 0; p = p->next)
-		code(ASALLOC, label2node(p), NULL, NULL);
+		code(ASALLOC, label2node(&aux, p), NULL, NULL);
 
 	/* allocate stack space for local variables) */
 	for ( ; p && p->id != TMPSYM; p = p->next) {
 		if (p->kind != SAUTO)
 			continue;
-		code(ASALLOC, label2node(p), NULL, NULL);
+		code(ASALLOC, label2node(&aux, p), NULL, NULL);
 	}
 	/* store formal parameters in parameters */
 	for (p = locals; p; p = p->next) {
 		if ((p->type.flags & PARF) == 0)
 			break;
-		code(ASFORM, label2node(p), NULL, NULL);
+		code(ASFORM, label2node(&aux, p), NULL, NULL);
 	}
 	return NULL;
 }
@@ -425,7 +418,7 @@
 	case OOR:
 		true = newlabel();
 		false = newlabel();
-		phi = label2node(newlabel());
+		phi = label2node(&aux1, newlabel());
 		tmpnode(ret, &int32type);
 
 		bool(np, true, false);
@@ -438,7 +431,6 @@
 		assign(ret, constnode(0, &int32type));
 
 		setlabel(phi->u.sym);
-		deltree(phi);
 		return ret;
         case OSHR:
         case OMOD:
@@ -523,14 +515,13 @@
 Node *
 cgen(Node *np)
 {
-	Node ret, *aux, *next, *ifyes, *ifno;
+	Node ret, aux1, aux2, *p, *next, ifyes, ifno;
 
 	setlabel(np->label);
 	switch (np->op) {
 	case OJMP:
-		ifyes = label2node(np->u.sym);
-		code(ASJMP, NULL, ifyes, NULL);
-		deltree(ifyes);
+		label2node(&ifyes, np->u.sym);
+		code(ASJMP, NULL, &ifyes, NULL);
 		break;
         case OBRANCH:
                 next = np->next;
@@ -537,16 +528,14 @@
                 if (!next->label)
                         next->label = newlabel();
 
-                ifyes = label2node(np->u.sym);
-                ifno = label2node(next->label);
+                label2node(&ifyes, np->u.sym);
+                label2node(&ifno, next->label);
 		rhs(np->left, &ret);
-		code(ASBRANCH, &ret, ifyes, ifno);
-                deltree(ifyes);
-                deltree(ifno);
+		code(ASBRANCH, &ret, &ifyes, &ifno);
                 break;
 	case ORET:
-		aux = (np->left) ? rhs(np->left, &ret) : NULL;
-		code(ASRET, NULL, aux, NULL);
+		p = (np->left) ? rhs(np->left, &ret) : NULL;
+		code(ASRET, NULL, p, NULL);
 		break;
 	default:
 		rhs(np, &ret);
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -216,7 +216,7 @@
 extern void code(int op, Node *to, Node *from1, Node *from2);
 extern void defvar(Symbol *), defpar(Symbol *), defglobal(Symbol *);
 extern void setlabel(Symbol *sym), getbblocks(void);
-extern Node *label2node(Symbol *sym), *constnode(TUINT n, Type *tp);
+extern Node *label2node(Node *np, Symbol *sym), *constnode(TUINT n, Type *tp);
 extern Symbol *newlabel(void);
 
 /* node.c */
--- a/cc2/code.c
+++ b/cc2/code.c
@@ -1,5 +1,6 @@
 /* See LICENSE file for copyright and license details. */
 #include <stdlib.h>
+#include <string.h>
 
 #include "../inc/cc.h"
 #include "arch.h"
@@ -67,13 +68,15 @@
 }
 
 Node *
-label2node(Symbol *sym)
+label2node(Node *np, Symbol *sym)
 {
-	Node *np;
-
 	if(!sym)
 		sym = newlabel();
-	np = newnode(OLABEL);
+	if (!np)
+		np = newnode(OLABEL);
+	else
+		memset(np, 0, sizeof(np));
+	np->op = OLABEL;
 	np->u.sym = sym;
 
 	return np;