123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* S H A R E D F I L E
- *
- * A U X I L I A R Y R O U T I N E S
- *
- */
- #include <em_mes.h>
- #include <em_pseu.h>
- #include "types.h"
- #include "debug.h"
- #include "global.h"
- #include "alloc.h"
- #include "aux.h"
- #include "map.h"
- #include "lset.h"
- offset off_set(line_p lnp)
- {
- switch(lnp->l_optype) {
- case OPSHORT:
- return (offset) SHORT(lnp);
- case OPOFFSET:
- return OFFSET(lnp);
- default:
- assert(FALSE);
- }
- /* NOTREACHED */
- return 0;
- }
- offset aoff(arg_p ap, int n)
- {
- while (n>0) {
- if (ap != (arg_p) 0)
- ap = ap->a_next;
- n--;
- }
- if (ap == (arg_p) 0)
- error("too few parameters");
- if (ap->a_type != ARGOFF)
- error("offset expected");
- return(ap->a_a.a_offset);
- }
- offset tmplocal(proc_p p, offset size)
- {
- /* Allocate a new local variable in the stack frame of p */
- p->p_localbytes += size;
- return -(p->p_localbytes);
- }
- line_p int_line(offset off)
- {
- /* Allocate a line struct of type OPSHORT or OPOFFSET,
- * whichever one fits best.
- */
- line_p lnp;
- if ((short) off == off) {
- /* fits in a short */
- lnp = newline(OPSHORT);
- SHORT(lnp) = (short) off;
- } else {
- lnp = newline(OPOFFSET);
- OFFSET(lnp) = off;
- }
- return lnp;
- }
- line_p reg_mes(offset tmp, short size, int typ, int score)
- {
- /* Generate a register message */
- line_p l;
- arg_p a;
- #define NEXTARG(a,val) a->a_next = newarg(ARGOFF); a = a->a_next; \
- a->a_a.a_offset = val
- l = newline(OPLIST);
- l->l_instr = ps_mes;
- a = ARG(l) = newarg(ARGOFF);
- a->a_a.a_offset = ms_reg;
- NEXTARG(a,tmp);
- NEXTARG(a,size);
- NEXTARG(a,typ);
- NEXTARG(a,score);
- return l;
- }
- bool dom(bblock_p b1, bblock_p b2)
- {
- /* See if b1 dominates b2. Note that a block always
- * dominates itself.
- */
- register bblock_p b;
- for (b = b2; b != (bblock_p) 0; b = b->b_idom) {
- /* See if b1 is a (not necessarily proper) ancestor
- * of b2 in the immediate dominator tree.
- */
- if (b == b1) return TRUE;
- }
- return FALSE;
- }
- bblock_p common_dom(bblock_p a, bblock_p b)
- {
- /* find a basic block that dominates a as well as b;
- * note that a basic block also dominates itself.
- */
- assert (a != (bblock_p) 0);
- assert (b != (bblock_p) 0);
- if (dom(a,b)) {
- return a;
- } else {
- if (dom(b,a)) {
- return b;
- } else {
- return common_dom(a->b_idom,b->b_idom);
- }
- }
- }
- #define R time_space_ratio
- short add_timespace(short time, short space)
- {
- /* Add together a time and space, using the time_space_ratio
- * parameter that may be set by the user, indicating the need
- * to optimize for time, space or something in between.
- */
- return (R * time + (100 - R) * space) / 100;
- }
- void rm_line(line_p l, bblock_p b)
- {
- if (b->b_start == l) {
- b->b_start = l->l_next;
- } else {
- PREV(l)->l_next = l->l_next;
- }
- if (l->l_next != (line_p) 0) {
- PREV(l->l_next) = PREV(l);
- }
- oldline(l);
- }
- void appnd_line(line_p l1, line_p l2)
- {
- /* Put l1 after l2 */
- PREV(l1) = l2;
- l1->l_next = l2->l_next;
- l2->l_next = l1;
- if (l1->l_next != (line_p) 0) {
- PREV(l1->l_next) = l1;
- }
- }
- line_p last_instr(bblock_p b)
- {
- /* Determine the last line of a list */
- register line_p l = b->b_start;
- if (l == (line_p) 0) return (line_p) 0;
- while (l->l_next != (line_p) 0) l = l->l_next;
- return l;
- }
- line_p find_mesreg(offset off)
- {
- /* Find the register message for the local with the given offset */
- Lindex li;
- line_p l;
- for (li = Lfirst(mesregs); li != (Lindex) 0; li = Lnext(li,mesregs)) {
- l = (line_p) Lelem(li);
- if (aoff(ARG(l),1) == off) return l;
- }
- return (line_p) 0;
- }
- bool is_regvar(offset off)
- {
- return find_mesreg(off) != (line_p) 0;
- }
- offset regv_arg(offset off, int n)
- {
- /* fetch the n'th argument of the register message of the
- * local variable at offset off;
- */
- line_p x = find_mesreg(off);
- assert (x != (line_p) 0);
- return aoff(ARG(x),n);
- }
|