#include "optimise.h" #include "blocks.h" #include "flow.h" static void removeRedundantLabels(Block b) { Node p, end; int notJump; end = block_lastNode(b)->x.next; p = block_firstNode(b); notJump = (p->op != JUMP + V); for (p = p->x.next; p != end; p = p->x.next) { if ((p->op == LABEL + V) && notJump) { p->op = NOOP; } notJump = (p->op != JUMP + V); } } /* static Node profilerNode(int id) { static Symbol func; static Symbol address; Node icnst, arg, call; if (func == NULL) { func = NEW0(func, PERM); func->type = ftype(voidtype, inttype); address = mksymbol(EXTERN, "_trace_i", func->type); func->defined = 0; } icnst = newnode(CNST + I + sizeop(4), NULL, NULL, intconst(id)); arg = newnode(ARG + I + sizeop(inttype->size), icnst, NULL, intconst(inttype->size)); arg->syms[1] = intconst(inttype->align); call = newnode(CALL + V, newnode(ADDRG + P + sizeop(4), NULL, NULL, address), NULL, func); arg->link = call; return arg; } static void profileLabel(Block b) { Node p, profiler; int id; p = block_firstNode(b); while (p->op != LABEL + V) p = p->x.next; id = p->syms[0]->u.l.label; profiler = profilerNode(id); block_insertAtHead(b, profiler); } */ static void ensureLabel(Block b) { Node p, end; p = block_firstNode(b); if (p->op == LABEL + V) return; if (p->op == NOOP) if (p->x.next && p->x.next->op == LABEL + V) return; else { p->op = LABEL + V; p->syms[0] = findlabel(genlabel(1)); return; } block_insertAtHead(b, newnode(LABEL + V, NULL, NULL, findlabel(genlabel(1)))); } /* static char* _prof(void) { flow_applyToBlocks(removeRedundantLabels); flow_applyToBlocks(ensureLabel); flow_applyToBlocks(profileLabel); // Need to add space for profiling... return NULL; } */ static char* _delabel(void) { flow_applyToBlocks(removeRedundantLabels); return NULL; } static char* _label(void) { flow_applyToBlocks(removeRedundantLabels); flow_applyToBlocks(ensureLabel); return NULL; } optimiser delabel = { "delabel", "Removes redundant labels, makes peep-hole optimiser's job easier.", 0, &_delabel }; optimiser label = { "label", "Ensures that all blocks start with a label and that no other labels exist.", 0, &_label }; /* optimiser profile = { "profile", "Adds block level profiling information.", 0, &_prof }; */