ref: d45810bfe48e161fd44f057763feef8b0ae471d6
parent: 829833bcfdb0f780537568a12041c83533401220
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Nov 4 05:24:54 EDT 2021
cc2/qbe: Change rhs() to return Node Receiving a pointer to the struct were we want to store the result needs a lot of temporary variables in the code. If we make that rhs() returns a struct instead of a pointer to struct we can remove a lot of these temporaries and simplify the code. The code generated is pretty similar because returning structs usually mean passing an additional pointer to the function rhsed where it can write the results.
--- a/src/cmd/cc/cc2/target/qbe/cgen.c
+++ b/src/cmd/cc/cc2/target/qbe/cgen.c
@@ -159,7 +159,7 @@
return new;
}
-static Node *rhs(Node *np, Node *new);
+static Node *rhs(Node *np);
static Node *
cast(Type *td, Node *np)
@@ -244,7 +244,7 @@
Node **q, *tmp, *p, *pars[NR_FUNPARAM];
for (n = 0, p = np->right; p; p = p->right)
- pars[n++] = rhs(p->left, node(OTMP));
+ pars[n++] = rhs(p->left);
tp = &np->type;
tmp = tmpnode(NULL, tp);
@@ -318,17 +318,17 @@
static Node *
field(Node *np, int islhs)
{
- Node base, node, off, add, *addr;
+ Node *tmp, *addr;
TUINT offset = np->right->u.sym->u.off;
- addr = rhs(np->left, &base);
+ addr = rhs(np->left);
if (offset != 0) {
- node.op = OADD;
- node.type = ptrtype;
- node.left = addr;
- node.right = constnode(&off, offset, &ptrtype);
- addr = rhs(&node, &add);
+ tmp = node(OADD);
+ tmp->type = ptrtype;
+ tmp->left = addr;
+ tmp->right = constnode(NULL, offset, &ptrtype);
+ addr = rhs(tmp);
}
if (islhs)
@@ -346,7 +346,7 @@
case OAUTO:
return np;
case OPTR:
- return rhs(np->left, node(OTMP));
+ return rhs(np->left);
case OFIELD:
return field(np, 1);
default:
@@ -380,7 +380,7 @@
default:
label2node(&ifyes, true);
label2node(&ifno, false);
- code(ASBRANCH, rhs(np, &ret), &ifyes, &ifno);
+ code(ASBRANCH, rhs(np), &ifyes, &ifno);
break;
}
}
@@ -396,14 +396,14 @@
label2node(&phi, NULL);
colon = np->right;
- code(ASBRANCH, rhs(np->left, node(OTMP)), &ifyes, &ifno);
+ code(ASBRANCH, rhs(np->left), &ifyes, &ifno);
setlabel(ifyes.u.sym);
- copy(&tmp->type, tmp, rhs(colon->left, node(OTMP)));
+ copy(&tmp->type, tmp, rhs(colon->left));
code(ASJMP, NULL, &phi, NULL);
setlabel(ifno.u.sym);
- copy(&tmp->type, tmp, rhs(colon->right, node(OTMP)));
+ copy(&tmp->type, tmp, rhs(colon->right));
setlabel(phi.u.sym);
return tmp;
@@ -476,9 +476,9 @@
}
static Node *
-rhs(Node *np, Node *ret)
+rhs(Node *np)
{
- Node aux1, aux2, aux3;
+ Node *tmp, aux1, aux2, aux3;
Node *phi, *l = np->left, *r = np->right;
Type *tp;
int off, op;
@@ -497,13 +497,11 @@
return NULL;
case OTMP:
case OCONST:
- *ret = *np;
return np;
case OMEM:
case OREG:
case OAUTO:
- *ret = *load(tp, np);
- return ret;
+ return load(tp, np);
case ONEG:
case OAND:
case OOR:
@@ -510,19 +508,19 @@
true = newlabel();
false = newlabel();
phi = label2node(&aux1, NULL);
- tmpnode(ret, &int32type);
+ tmp = tmpnode(NULL, &int32type);
bool(np, true, false);
setlabel(true);
- code(ASCOPYW, ret, constnode(&aux2, 1, &int32type), NULL);
+ code(ASCOPYW, tmp, constnode(&aux2, 1, &int32type), NULL);
code(ASJMP, NULL, phi, NULL);
setlabel(false);
- code(ASCOPYW, ret, constnode(&aux2, 0, &int32type), NULL);
+ code(ASCOPYW, tmp, constnode(&aux2, 0, &int32type), NULL);
setlabel(phi->u.sym);
- return ret;
+ return tmp;
case OMOD:
case OSHR:
assert(tp->flags & INTF);
@@ -550,11 +548,11 @@
off = 0;
binary:
if (l->complex >= r->complex) {
- rhs(l, &aux1);
- rhs(r, &aux2);
+ l = rhs(l);
+ r = rhs(r);
} else {
- rhs(r, &aux2);
- rhs(l, &aux1);
+ r = rhs(r);
+ l = rhs(l);
}
switch (tp->size) {
@@ -567,19 +565,17 @@
default:
abort();
}
- op = tbl[np->op] + off;
- tmpnode(ret, tp);
- code(op, ret, &aux1, &aux2);
- return ret;
+ op = tbl[np->op] + off;
+ tmp = tmpnode(NULL, tp);
+ code(op, tmp, l, r);
+ return tmp;
case OCALL:
case OCALLE:
if (l->op == OPTR)
- l = rhs(l, &aux1);
- *ret = *call(np, l);
- return ret;
+ l = rhs(l);
+ return call(np, l);
case OCAST:
- *ret = *cast(tp, rhs(l, &aux1));
- return ret;
+ return cast(tp, rhs(l));
case OASSIG:
switch (np->u.subop) {
case OINC:
@@ -588,60 +584,62 @@
case ODEC:
op = OSUB;
post_oper:
+ tmp = rhs(l);
+
aux1.op = op;
- aux1.left = rhs(l, ret);
+ aux1.left = tmp;
aux1.right = r;
aux1.type = np->type;
- rhs(&aux1, &aux2);
- aux1 = *lhs(l);
- assign(tp, &aux1, &aux2);
- break;
+ r = &aux1;
+
+ r = rhs(r);
+ l = lhs(l);
+ assign(tp, l, r);
+
+ return tmp;
default:
aux2.type = np->type;
aux2.op = np->u.subop;
aux2.right = np->right;
aux2.left = np->left;
- r = rhs(&aux2, &aux1);
+ r = rhs(&aux2);
case 0:
if (l->complex >= r->complex) {
- aux2 = *lhs(l);
- rhs(r, ret);
+ l = lhs(l);
+ r = rhs(r);
} else {
- rhs(r, ret);
- aux2 = *lhs(l);
+ r = rhs(r);
+ l = lhs(l);
}
- return assign(tp, &aux2, ret);
+ return assign(tp, l, r);
}
- return ret;
case OASK:
- *ret = *ternary(np);
- return ret;
+ return ternary(np);
case OCOMMA:
- rhs(l, &aux1);
- return rhs(r, ret);
+ rhs(l);
+ return rhs(r);
case OPTR:
- *ret = *load(tp, rhs(l, &aux1));
- return ret;
+ return load(tp, rhs(l));
case OADDR:
- *ret = *lhs(l);
- ret->type = *tp;
- return ret;
+ l = lhs(l);
+ l->type = *tp;
+ return l;
case OFIELD:
- *ret = *field(np, 0);
- return ret;
+ return field(np, 0);
case OBUILTIN:
switch (np->u.subop) {
case BVA_START:
- l = rhs(l, &aux1);
+ l = rhs(l);
code(ASVSTAR, NULL, l, NULL);
return NULL;
case BVA_END:
return NULL;
case BVA_ARG:
- l = rhs(l, &aux1);
- code(ASVARG, tmpnode(ret, tp), l, NULL);
- return ret;
+ l = rhs(l);
+ tmp = tmpnode(NULL, tp);
+ code(ASVARG, tmp, l, NULL);
+ return tmp;
case BVA_COPY:
/* TODO */
default:
@@ -671,15 +669,15 @@
bool(np->left, np->u.sym, next->label);
break;
case ORET:
- p = (np->left) ? rhs(np->left, &aux) : NULL;
+ p = (np->left) ? rhs(np->left) : NULL;
code(ASRET, NULL, p, NULL);
break;
case OBSWITCH:
- p = rhs(np->left, &aux);
+ p = rhs(np->left);
swtch_if(p);
break;
default:
- rhs(np, &aux);
+ rhs(np);
break;
}
return NULL;