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:
bal 1984-11-29 10:51:16 +00:00
parent edcb838b98
commit f3e35f5432

View file

@ -20,10 +20,190 @@
#include "cf_idom.h" #include "cf_idom.h"
#include "cf_loop.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 lpi_set; /* set of procedures used in LPI instruction */
STATIC cset cai_set; /* set of all procedures doing a CAI */ 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) STATIC interproc_analysis(p)
proc_p p; proc_p p;
{ {