Match pointer dereferences with pointer assignements.

Having the source operand of a pointer assignment available to later
instrctions can make for more efficient code as the value does not need to
be dereferenced later. For this purpose, pointer dereference dag nodes now
store the source operand as their value, and dagnode_match will match x=a.b
with *(a+b)=y so long as both a and b are the same in both nodes. x and y
are irrelevant to the match. The resulting code will be the equivalent of:
    *(a+b) = y;
    x = y;
This commit is contained in:
Bill Currie 2012-11-20 15:22:05 +09:00
parent 36e359e2ee
commit 22d72f33d2

View file

@ -234,6 +234,19 @@ node (operand_t *op)
return node;
}
static int
dagnode_deref_match (const dagnode_t *n, const daglabel_t *op,
dagnode_t *operands[3])
{
int i;
for (i = 0; i < 2; i++) {
if (n->children[i + 1] != operands[i])
return 0;
}
return 1;
}
static int
dagnode_match (const dagnode_t *n, const daglabel_t *op,
dagnode_t *operands[3])
@ -242,6 +255,9 @@ dagnode_match (const dagnode_t *n, const daglabel_t *op,
if (n->killed)
return 0;
if (!strcmp (op->opcode, ".")
&& n->label->opcode && !strcmp (n->label->opcode, ".="))
return dagnode_deref_match (n, op, operands);
if (n->label->opcode != op->opcode)
return 0;
for (i = 0; i < 3; i++) {
@ -624,6 +640,8 @@ dag_gencode (dag_t *dag, sblock_t *block, dagnode_t *dagnode)
st = build_statement (dagnode->label->opcode, operands,
dagnode->label->expr);
sblock_add_statement (block, st);
// the source location is suitable for use in other nodes
dst = operands[0];
break;
case st_move:
case st_state: