shithub: scc

Download patch

ref: 79ccb978a8d4f8c9c9700bb16d2b97625f3f1dd4
parent: 101edd9a3b5d71aecd5ed30c70b2ad011e27a66d
author: Roberto E. Vargas Caballero <[email protected]>
date: Wed Aug 26 18:25:35 EDT 2015

Simplify expression like *& or &*

This kind of expressions are common in array expressions
and the can simplify a lot the IR generated.

--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -358,6 +358,12 @@
 	switch (tp->op) {
 	case ARY:
 		tp = tp->type;
+		if (np->op == OPTR) {
+			Node *new = np->left;
+			free(np);
+			new->type = mktype(tp, PTR, 0, NULL);
+			return new;
+		}
 	case FTN:
 		break;
 	default:
@@ -539,14 +545,16 @@
 	}
 	if (BTYPE(rp) != INT)
 		goto incorrect;
+
 	rp = convert(promote(rp), sizettype, 0);
-	rp = node(OMUL, sizettype, rp, size);
-	rp = node(OCAST, tp, rp, NULL);
+	rp = simplify(OMUL, sizettype, rp, size);
+	rp = convert(rp, tp, 1);
 
-	return node(OADD, tp, lp, rp);
+	return simplify(OADD, tp, lp, rp);
 
 incorrect:
-	error("incorrect arithmetic operands");
+	errorp("incorrect arithmetic operands");
+	return node(OADD, tp, lp, rp);
 }
 
 static Node *
@@ -752,6 +760,11 @@
 		error("lvalue required in unary expression");
 	if (np->symbol && (np->sym->flags & ISREGISTER))
 		error("address of register variable '%s' requested", yytext);
+	if (np->op == OPTR) {
+		Node *new = np->left;
+		free(np);
+		return new;
+	}
 	return node(op, mktype(np->type, PTR, 0, NULL), np, NULL);
 }
 
@@ -761,8 +774,12 @@
 	switch (BTYPE(np)) {
 	case ARY:
 	case FTN:
-		np = decay(np);
 	case PTR:
+		if (np->op == OADDR) {
+			Node *new = np->left;
+			free(np);
+			return new;
+		}
 		np = node(op, np->type->type, np, NULL);
 		np->lvalue = 1;
 		return np;