From: bal Date: Tue, 27 Nov 1984 15:40:13 +0000 (+0000) Subject: Initial revision X-Git-Tag: release-5-5~5958 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=165965eadc2fab2a527071b24c92446481b6cfe3;p=ack.git Initial revision --- diff --git a/util/ego/bo/Makefile b/util/ego/bo/Makefile new file mode 100644 index 000000000..c84fe0f36 --- /dev/null +++ b/util/ego/bo/Makefile @@ -0,0 +1,31 @@ +EMH=../../../h +EML=../../../lib +SHARE=../share +CFLAGS=-DVERBOSE +OBJECTS=bo.o +SHOBJECTS=$(SHARE)/get.o $(SHARE)/put.o $(SHARE)/alloc.o $(SHARE)/global.o $(SHARE)/debug.o $(SHARE)/files.o $(SHARE)/map.o $(SHARE)/lset.o $(SHARE)/cset.o $(SHARE)/aux.o $(SHARE)/stack_change.o $(SHARE)/go.o +SRC=bo.c + +all: $(OBJECTS) +bo: \ + $(OBJECTS) $(SHOBJECTS) + $(CC) -o bo -i $(OBJECTS) $(SHOBJECTS) $(EML)/em_data.a +lpr: + pr $(SRC) | lpr +# the next lines are generated automatically +# AUTOAUTOAUTOAUTOAUTOAUTO +bo.o: ../share/alloc.h +bo.o: ../share/aux.h +bo.o: ../share/debug.h +bo.o: ../share/def.h +bo.o: ../share/files.h +bo.o: ../share/get.h +bo.o: ../share/global.h +bo.o: ../share/go.h +bo.o: ../share/lset.h +bo.o: ../share/map.h +bo.o: ../share/put.h +bo.o: ../share/types.h +bo.o: ../../../h/em_mnem.h +bo.o: ../../../h/em_pseu.h +bo.o: ../../../h/em_spec.h diff --git a/util/ego/bo/bo.c b/util/ego/bo/bo.c new file mode 100644 index 000000000..fa9d57c00 --- /dev/null +++ b/util/ego/bo/bo.c @@ -0,0 +1,322 @@ +/* B R A N C H O P T I M I Z A T I O N + * + * B O . C + */ + + +#include +#include "../share/types.h" +#include "../share/debug.h" +#include "../share/global.h" +#include "../share/files.h" +#include "../share/get.h" +#include "../share/put.h" +#include "../share/lset.h" +#include "../share/map.h" +#include "../share/alloc.h" +#include "../share/aux.h" +#include "../share/def.h" +#include "../share/go.h" +#include "../../../h/em_mnem.h" +#include "../../../h/em_pseu.h" +#include "../../../h/em_spec.h" + +#define LP_BLOCKS lp_extend->lpx_ra.lpx_blocks + +STATIC int Sbo; /* #optimizations found */ + +#define DLINK(l1,l2) l1->l_next=l2; l2->l_prev=l1 + +/* This module performs some very simple branch optimizations. + * + * I) Look for pairs of basic blocks (B1,B2), such that + * SUCC(b1) = {B2} and + * PRED(B2) = {B1}. + * In this case B1 and B2 can be combined into one block. + * This optimization is mainly succesful: + * 1) for switch statements in C, as the C compiler generates a branch + * over the entire switch. + * 2) for return statements, if the only way to return from a procedure + * is via a return statement somewhere in the middle of the procedure. + * II) Optimize while statements. Transformations like: + * 1: jmp 2 + * tst cond 1: + * beq 2f S + * S 2: + * jmp 1 tst cond + * 2: bneq 1 + * are done by this optimization. + */ + + + +STATIC line_p last_code(lines,skip_pseu) + line_p lines; + bool skip_pseu; +{ + /* Determine the last line of a list */ + + register line_p l; + + for (l = lines; l->l_next != (line_p) 0; l = l->l_next); + if (skip_pseu) { + while (INSTR(l) < sp_fmnem || INSTR(l) > sp_lmnem) l = PREV(l); + } + return l; +} + +STATIC short cc_tab[12] = + {op_blt,op_zlt,op_ble,op_zle,op_beq,op_zeq, + op_zne,op_bne,op_zgt,op_bgt,op_zge,op_bge}; + + +STATIC short rev_cond(cond) + short cond; +{ + register i; + + for (i = 0; i < 12; i++) { + if (cond == cc_tab[i]) return cc_tab[11-i]; + } + return op_nop; +} + +STATIC bool is_bcc(l) + line_p l; +{ + return rev_cond(INSTR(l)) != op_nop; +} + + +STATIC bo_optloop(p,b,x,bra,bcc) + proc_p p; + bblock_p b,x; + line_p bra,bcc; +{ + bblock_p prevb,n; + line_p l; + + if (b->b_start == bra) { + b->b_start = (line_p) 0; + } else { + PREV(bra)->l_next = (line_p) 0; + } + PREV(bra) = (line_p) 0; + bcc->l_instr = rev_cond(INSTR(bcc)); + n = x->b_next; + l = n->b_start; + if (l == (line_p) 0 || INSTR(l) != op_lab) { + l = newline(OPINSTRLAB); + l->l_instr = op_lab; + INSTRLAB(l) = freshlabel(); + if (n->b_start != (line_p) 0) { + DLINK(l,n->b_start); + } + n->b_start = l; + } + INSTRLAB(bcc) = INSTRLAB(l); + for (prevb = p->p_start; prevb != (bblock_p) 0 && prevb->b_next != x; + prevb = prevb->b_next); + if (prevb == (bblock_p) 0) { + p->p_start = x->b_next; + } else { + prevb->b_next = x->b_next; + l = last_instr(prevb); + if (l == (line_p) 0) { + prevb->b_start = bra; + } else { + if (INSTR(l) == op_bra && + INSTRLAB(l) == INSTRLAB(bra)) { + oldline(bra); + } else { + appnd_line(bra,l); + } + } + } + x->b_next = b->b_next; + b->b_next = x; +} + + + +STATIC bo_tryloop(p,loop) + proc_p p; + lset loop; +{ + Lindex i,j; + bblock_p b,x; + line_p bra,bcc; + + for (i = Lfirst(loop); i != (Lindex) 0; i = Lnext(i,loop)) { + b = (bblock_p) Lelem(i); + if (b->b_next != (bblock_p) 0 && !Lis_elem(b->b_next,loop)) { + j = Lfirst(b->b_succ); + if (j != (Lindex) 0 && + (bra = last_instr(b)) != (line_p) 0 && + INSTR(bra) == op_bra) { + x = (bblock_p) Lelem(j); /* single successor */ + if (Lis_elem(b->b_next,x->b_succ) && + is_bcc((bcc = last_instr(x)))) { +OUTVERBOSE("branch optimization proc %d block %d\n", curproc->p_id,x->b_id); + Sbo++; + bo_optloop(p,b,x,bra,bcc); + return; + } + } + } + } +} + + + +STATIC bo_loops(p) + proc_p p; +{ + Lindex i; + loop_p lp; + + for (i = Lfirst(p->p_loops); i != (Lindex) 0; i = Lnext(i,p->p_loops)) { + lp = (loop_p) (Lelem(i)); + bo_tryloop(p,lp->LP_BLOCKS); + } +} + +STATIC mv_code(b1,b2) + bblock_p b1,b2; +{ + line_p l,x; + + l = last_code(b2->b_start,TRUE); + DLINK(l,b1->b_start); + x = l->l_next; + if (INSTR(l) == op_bra) { + rm_line(l,b2); + } + if (INSTR(x) == op_lab) { + rm_line(x,b2); + } +} + +bo_switch(b) + bblock_p b; +{ + bblock_p s,x; + Lindex i; + line_p l; + + if (Lnrelems(b->b_succ) == 1) { + s = (bblock_p) Lelem(Lfirst(b->b_succ)); + if (b->b_start != (line_p) 0 && + s->b_start != (line_p) 0 && + Lnrelems(s->b_pred) == 1 && + (s->b_next == (bblock_p) 0 || + !Lis_elem(s->b_next,s->b_succ))) { + l = last_code(s->b_start,FALSE); + if (INSTR(l) == ps_end) { + if (PREV(l) == (line_p) 0) return; + PREV(l)->l_next = (line_p) 0; + PREV(l) = (line_p) 0; + } else { + l = (line_p) 0; + } +OUTVERBOSE("branch optimization in proc %d, block %d",curproc->p_id,b->b_id); + Sbo++; + Ldeleteset(b->b_succ); + b->b_succ = s->b_succ; + Ldeleteset(s->b_pred); + s->b_succ = Lempty_set(); + s->b_pred = Lempty_set(); + for (i = Lfirst(b->b_succ); i != (Lindex) 0; + i = Lnext(i,b->b_succ)) { + x = (bblock_p) Lelem(i); + Lremove(s,&x->b_pred); + Ladd(b,&x->b_pred); + if (x->b_idom == s) { + x->b_idom = b; + } + } + mv_code(s,b); + s->b_start = l; + } + } +} + +STATIC bo_extproc(p) + proc_p p; +{ + /* Allocate the extended data structures for procedure p */ + + register loop_p lp; + register Lindex pi; + register bblock_p b; + + for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; + pi = Lnext(pi,p->p_loops)) { + lp = (loop_p) Lelem(pi); + lp->lp_extend = newralpx(); + } + for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { + b->b_extend = newrabx(); + } +} + + +STATIC loop_blocks(p) + proc_p p; +{ + /* Compute the LP_BLOCKS sets for all loops of p */ + + register bblock_p b; + register Lindex i; + + for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { + for (i = Lfirst(b->b_loops); i != (Lindex) 0; + i = Lnext(i,b->b_loops)) { + Ladd(b,&(((loop_p) Lelem(i))->LP_BLOCKS)); + } + } +} + +STATIC bo_cleanproc(p) + proc_p p; +{ + /* Allocate the extended data structures for procedure p */ + + register loop_p lp; + register Lindex pi; + register bblock_p b; + + for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; + pi = Lnext(pi,p->p_loops)) { + lp = (loop_p) Lelem(pi); + oldralpx(lp->lp_extend); + } + for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { + oldrabx(b->b_extend); + } +} + +bo_optimize(p) + proc_p p; +{ + bblock_p b; + + bo_extproc(p); + loop_blocks(p); + bo_loops(p); + for (b = p->p_start; b != 0; b = b->b_next) { + bo_switch(b); + } + bo_cleanproc(p); +} + + + +main(argc,argv) + int argc; + char *argv[]; +{ + go(argc,argv,no_action,bo_optimize,no_action,no_action); + report("branch optimizations", Sbo); + exit(0); +}