routine getbblocks (plus its auxiliary routines) moved from get.c
to this file; core allocation macros newcfbx() and oldcfbx() added.
This commit is contained in:
parent
edcb838b98
commit
f3e35f5432
180
util/ego/cf/cf.c
180
util/ego/cf/cf.c
|
@ -20,10 +20,190 @@
|
|||
#include "cf_idom.h"
|
||||
#include "cf_loop.h"
|
||||
|
||||
#define nexcfbx() (bext_p) newstruct(bext_cf)
|
||||
#define oldcfbx(x) oldstruct(bext_cf,x)
|
||||
|
||||
STATIC cset lpi_set; /* set of procedures used in LPI instruction */
|
||||
STATIC cset cai_set; /* set of all procedures doing a CAI */
|
||||
|
||||
|
||||
/* The procedure getbblocks reads the EM textfile and
|
||||
* partitions every procedure into a number of basic blocks.
|
||||
*/
|
||||
|
||||
#define LABEL0 0
|
||||
#define LABEL 1
|
||||
#define NORMAL 2
|
||||
#define JUMP 3
|
||||
#define END 4
|
||||
#define AFTERPRO 5
|
||||
#define INIT 6
|
||||
|
||||
|
||||
/* These global variables are used by getbblocks and nextblock. */
|
||||
|
||||
STATIC bblock_p b, *bp; /* b is the current basic block, bp is
|
||||
* the address where the next block has
|
||||
* to be linked.
|
||||
*/
|
||||
STATIC line_p lnp, *lp; /* lnp is the current line, lp is
|
||||
* the address where the next line
|
||||
* has to be linked.
|
||||
*/
|
||||
STATIC short state; /* We use a finite state machine with the
|
||||
* following states:
|
||||
* LABEL0: after the first (successive)
|
||||
* instruction label.
|
||||
* LABEL1: after at least two successive
|
||||
* instruction labels.
|
||||
* NORMAL: after a normal instruction.
|
||||
* JUMP: after a branch (conditional,
|
||||
* unconditional or CSA/CSB).
|
||||
* END: after an END pseudo
|
||||
* AFTERPRO: after we've read a PRO pseudo
|
||||
* INIT: initial state
|
||||
*/
|
||||
|
||||
|
||||
STATIC nextblock()
|
||||
{
|
||||
/* allocate a new basic block structure and
|
||||
* set b, bp and lp.
|
||||
*/
|
||||
|
||||
b = *bp = freshblock();
|
||||
bp = &b->b_next;
|
||||
b->b_start = lnp;
|
||||
b->b_succ = Lempty_set();
|
||||
b->b_pred = Lempty_set();
|
||||
b->b_extend = newcfbx(); /* basic block extension for CF */
|
||||
b->b_extend->bx_cf.bx_bucket = Lempty_set();
|
||||
b->b_extend->bx_cf.bx_semi = 0;
|
||||
lp = &lnp->l_next;
|
||||
#ifdef TRACE
|
||||
fprintf(stderr,"new basic block, id = %d\n",lastbid);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
STATIC short kind(lnp)
|
||||
line_p lnp;
|
||||
{
|
||||
/* determine if lnp is a label, branch, end or otherwise */
|
||||
|
||||
short instr;
|
||||
byte flow;
|
||||
|
||||
if ((instr = INSTR(lnp)) == op_lab) return (short) LABEL;
|
||||
if (instr == ps_end) return (short) END;
|
||||
if (instr > sp_lmnem) return (short) NORMAL; /* pseudo */
|
||||
if ((flow = (em_flag[instr-sp_fmnem] & EM_FLO)) == FLO_C ||
|
||||
flow == FLO_T) return (short) JUMP; /* conditional/uncond. jump */
|
||||
return (short) NORMAL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC bool getbblocks(fp,kind_out,n_out,g_out,l_out)
|
||||
FILE *fp;
|
||||
short *kind_out;
|
||||
short *n_out;
|
||||
bblock_p *g_out;
|
||||
line_p *l_out;
|
||||
{
|
||||
bblock_p head = (bblock_p) 0;
|
||||
line_p headl = (line_p) 0;
|
||||
|
||||
curproc = (proc_p) 0;
|
||||
/* curproc will get a value when we encounter a PRO pseudo.
|
||||
* If there is no such pseudo, we're reading only data
|
||||
* declarations or messages (outside any proc.).
|
||||
*/
|
||||
curinp = fp;
|
||||
lastbid = (block_id) 0; /* block identier */
|
||||
state = INIT; /* initial state */
|
||||
bp = &head;
|
||||
|
||||
for (;;) {
|
||||
#ifdef TRACE
|
||||
fprintf(stderr,"state = %d\n",state);
|
||||
#endif
|
||||
switch(state) {
|
||||
case LABEL0:
|
||||
nextblock();
|
||||
/* Fall through !! */
|
||||
case LABEL:
|
||||
lbmap[INSTRLAB(lnp)] = b;
|
||||
/* The lbmap table contains for each
|
||||
* label_id the basic block of that label.
|
||||
*/
|
||||
lnp = read_line(&curproc);
|
||||
state = kind(lnp);
|
||||
if (state != END) {
|
||||
*lp = lnp;
|
||||
lp = &lnp->l_next;
|
||||
}
|
||||
break;
|
||||
case NORMAL:
|
||||
lnp = read_line(&curproc);
|
||||
if ( (state = kind(lnp)) == LABEL) {
|
||||
/* If we come accross a label
|
||||
* here, it must be the beginning
|
||||
* of a new basic block.
|
||||
*/
|
||||
state = LABEL0;
|
||||
} else {
|
||||
if (state != END) {
|
||||
*lp = lnp;
|
||||
lp = &lnp->l_next;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case JUMP:
|
||||
lnp = read_line(&curproc);
|
||||
/* fall through ... */
|
||||
case AFTERPRO:
|
||||
switch(state = kind(lnp)) {
|
||||
case LABEL:
|
||||
state = LABEL0;
|
||||
break;
|
||||
case JUMP:
|
||||
case NORMAL:
|
||||
nextblock();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case END:
|
||||
*lp = lnp;
|
||||
#ifdef TRACE
|
||||
fprintf(stderr,"at end of proc, %d blocks\n",lastbid);
|
||||
#endif
|
||||
if (head == (bblock_p) 0) {
|
||||
*kind_out = LDATA;
|
||||
*l_out = headl;
|
||||
} else {
|
||||
*kind_out = LTEXT;
|
||||
*g_out = head;
|
||||
*n_out = (short) lastbid;
|
||||
/* number of basic blocks */
|
||||
}
|
||||
return TRUE;
|
||||
case INIT:
|
||||
lnp = read_line(&curproc);
|
||||
if (feof(curinp)) return FALSE;
|
||||
if (INSTR(lnp) == ps_pro) {
|
||||
state = AFTERPRO;
|
||||
} else {
|
||||
state = NORMAL;
|
||||
headl = lnp;
|
||||
lp = &lnp->l_next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC interproc_analysis(p)
|
||||
proc_p p;
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue