summaryrefslogtreecommitdiff
path: root/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/ir.c b/ir.c
index 255d578..4e7f84e 100644
--- a/ir.c
+++ b/ir.c
@@ -95,8 +95,8 @@ const char *node_type_name(NodeType t) {
}
void node_die(Node *n, Proc *p) {
- /*n->prev_free = p->free_list;
- p->free_list = n;*/
+ n->prev_free = p->free_list;
+ p->free_list = n;
}
void node_del_out(Node *n, Node *p) {
@@ -334,18 +334,29 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
/* transformations to help encourage constant folding */
/* the overall trend is to move them rightwards */
- if ((in[0]->type == N_LIT && in[1]->type != N_LIT)
- || (in[1]->type == n->type && in[0]->type != n->type)) {
-
- if (in[1]->type == n->type) {
- fprintf(stderr, "op(X, op(Y, Z)) -> op(op(Y, Z), X)\n");
- } else {
- fprintf(stderr, "op(lit, X) -> op(X, lit)\n");
- }
+ if (in[0]->type == N_LIT && in[1]->type != N_LIT) {
+ fprintf(stderr, "op(lit, X) -> op(X, lit)\n");
+ return NODE(n->type, in[1], in[0]);
+ }
+ if (in[1]->type == n->type && in[0]->type != n->type) {
+ fprintf(stderr, "op(X, op(Y, Z)) -> op(op(Y, Z), X)\n");
return NODE(n->type, in[1], in[0]);
}
+ if (in[0]->type == n->type
+ && in[1]->type == n->type
+ && in[1]->in.data[1]->type == N_LIT) {
+ fprintf(stderr, "op(op(X, Y), op(Z, lit)) -> op(op(X, op(Y, Z)), lit)\n");
+ return NODE(n->type,
+ NODE(n->type,
+ in[0]->in.data[0],
+ NODE(n->type,
+ in[0]->in.data[1],
+ in[1]->in.data[0])),
+ in[1]->in.data[1]);
+ }
+
if (in[1]->type == N_LIT
&& in[0]->type == n->type
&& in[0]->in.data[0]->type != N_LIT