shithub: scc

Download patch

ref: c9538a1cb5279a7a70695c86ad31ea9f85436d59
parent: 19e83e69aa412cea8f41a28506cc9bfcc84525c4
author: Roberto E. Vargas Caballero <[email protected]>
date: Wed Sep 2 10:57:54 EDT 2015

Add more algebraic identities

--- a/cc1/fold.c
+++ b/cc1/fold.c
@@ -376,36 +376,81 @@
 	return v;
 }
 
+/*
+ * i || 0 => i,0
+ * i || 1 => i
+ * i && 0 => i,0
+ * i && 1 => i
+ * i >> 0 => i
+ * i << 0 => i
+ * i + 0  => i
+ * i - 0  => i
+ * i | 0  => i
+ * i ^ 0  => i
+ * i * 0  => i,0
+ * i * 1  => i
+ * i / 1  => i
+ * i & ~0 => i
+ * i % 1  => i,1
+ */
 static Node *
-identity(int op, Node *lp, Node *rp)
+identity(int *op, Node *lp, Node *rp)
 {
-	int val;
+	int iszero, isone, istrue;
 
-	switch (op) {
+	if (!rp)
+		return NULL;
+
+	iszero = cmpnode(rp, 0);
+	isone = cmpnode(rp, 1),
+	istrue = !iszero && rp->constant;
+
+	switch (*op) {
+	case OOR:
+		if (istrue)
+			goto change_to_comma;
+		if (iszero)
+			break;
+		return NULL;
+	case OAND:
+		if (iszero)
+			goto change_to_comma;
+		if (istrue)
+			break;
+		return NULL;
 	case OSHL:
 	case OSHR:
 	case OBXOR:
 	case OADD:
+	case OBOR:
 	case OSUB:
-		val = 0;
-		break;
-	case ODIV:
-	case OMOD:
+		if (iszero)
+			break;
+		return NULL;
 	case OMUL:
-	case OBOR:
-		val = 1;
-		break;
+		if (iszero)
+			goto change_to_comma;
+	case ODIV:
+		if (isone)
+			break;
+		return NULL;
 	case OBAND:
-		if (cmpnode(lp, ones(lp->type->size * 8)))
-			goto free_right;
+		if (cmpnode(rp, ones(lp->type->size * 8)))
+			break;
+		return NULL;
+	case OMOD:
+		if (isone)
+			goto change_to_comma;
 	default:
 		return NULL;
 	}
-	if (!cmpnode(rp, val))
-		return NULL;
-free_right:
+
 	freetree(rp);
 	return lp;
+
+change_to_comma:
+	*op = OCOMMA;
+	return NULL;
 }
 
 Node *
@@ -416,7 +461,7 @@
 	commutative(&op, &lp, &rp);
 	if ((np = fold(op, tp, lp, rp)) != NULL)
 		return np;
-	if ((np = identity(op, lp, rp)) != NULL)
+	if ((np = identity(&op, lp, rp)) != NULL)
 		return np;
 	return node(op, tp, lp, rp);
 }