scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit 6a7fb9b9a0a08b584646222fdc7cd1ec03a7230c
parent 37ffac184537c284e94c6384c630236f13db972b
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 19 Mar 2015 17:46:35 +0000

Add peephole infrastructure

The peephole will be necessary in some moment, so it is a good
idea to build it now. This small demo of peephole also allow
to simplify add(), and make it more suitable for other operations,
so maybe the code will be much clearer due to this change.

Diffstat:
cc2/Makefile | 2+-
cc2/cc2.h | 5+++++
cc2/cgen.c | 12+-----------
cc2/code.c | 56++++++++++++++++++++++++++++++++++++++++++--------------
cc2/main.c | 1+
cc2/peep.c | 32++++++++++++++++++++++++++++++++
6 files changed, 82 insertions(+), 26 deletions(-)

diff --git a/cc2/Makefile b/cc2/Makefile @@ -1,5 +1,5 @@ -OBJS = main.o parser.o cgen.o code.o optm.o +OBJS = main.o parser.o cgen.o code.o optm.o peep.o LIBS = -lcc diff --git a/cc2/cc2.h b/cc2/cc2.h @@ -157,8 +157,13 @@ extern void prtree(Node *np); /* code.c */ extern void code(uint8_t op, Node *to, Node *from); +extern void inscode(uint8_t op, Addr *to, Addr *from); extern void writeout(void); +extern void delcode(void); /* optm.c */ extern void optimize(void); extern Node *imm(TINT i); + +/* peep.c */ +extern void peephole(void); diff --git a/cc2/cgen.c b/cc2/cgen.c @@ -7,7 +7,7 @@ #include "cc2.h" -static Node *reguse[NREGS]; +static Node *reguse[NPAIRS]; static uint8_t upper[] = {[DE] = D, [HL] = H, [BC] = B, [IY] = IYH}; static uint8_t lower[] = {[DE] = E, [HL] = L, [BC] = C, [IY] = IYL}; static uint8_t pair[] = { @@ -301,17 +301,7 @@ add(Node *np) abort(); } add_A: - if (rp->op == CONST) { - if ((i = rp->sym->u.imm) == 0) - goto update_A; - if (i < 4) { - while (i--) - code(INC, lp, NULL); - goto update_A; - } - } code(ADD, lp, rp); - update_A: np->op = REG; np->reg = A; break; diff --git a/cc2/code.c b/cc2/code.c @@ -50,24 +50,25 @@ static char *insttext[] = { Inst *pc, *prog; -Inst * +static void nextpc(void) { Inst *new; new = xmalloc(sizeof(*new)); - new->prev = pc; - if (!pc) + if (!pc) { + new->next = NULL; prog = new; - else + } else { + new->next = pc->next; pc->next = new; + } + + new->prev = pc; + new->to.kind = NONE; + new->from.kind = NONE; pc = new; - pc->op = NOP; - pc->to.kind = NONE; - pc->from.kind = NONE; - pc->next = NULL; - return pc; } void @@ -96,14 +97,41 @@ addr(char op, Node *np, Addr *addr) void code(uint8_t op, Node *to, Node *from) { - Inst *ip; - ip = nextpc(); + nextpc(); + if (from) + addr(op, from, &pc->from); + if (to) + addr(op, to, &pc->to); + pc->op = op; +} + +void +inscode(uint8_t op, Addr *to, Addr *from) +{ + nextpc(); if (from) - addr(op, from, &ip->from); + pc->from = *from; if (to) - addr(op, to, &ip->to); - ip->op = op; + pc->to = *to; + pc->op = op; +} + +void +delcode(void) +{ + Inst *prev = pc->prev, *next = pc->next; + + free(pc); + if (!prev) { + pc = next; + prog = NULL; + } else { + pc = prev; + prev->next = next; + if (next) + next->prev = prev; + } } void diff --git a/cc2/main.c b/cc2/main.c @@ -47,6 +47,7 @@ main(void) optimize(); addable(); generate(); + peephole(); writeout(); } return 0; diff --git a/cc2/peep.c b/cc2/peep.c @@ -0,0 +1,32 @@ + +#include <inttypes.h> +#include <stddef.h> + +#include "../inc/cc.h" +#include "cc2.h" + +void +peephole(void) +{ + Addr to, from; + TINT i; + + for (pc = prog; pc; pc = pc->next) { + to = pc->to; + from = pc->from; + + switch (pc->op) { + case ADD: + if (from.kind == CONST) { + if ((i = from.u.i) == 0 || i < 4) { + delcode(); + + while (i--) + inscode(INC, &to, NULL); + } + /* TODO: More optimizations (ex: -1) */ + } + break; + } + } +}