123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* M O D U L E F O R A C C E S S S I N G T H E L I S T
- *
- * O F A V A I L A B L E E X P R E S S I O N S
- */
- #include <em_mnem.h>
- #include "../share/types.h"
- #include "../share/debug.h"
- #include "../share/aux.h"
- #include "../share/lset.h"
- #include "../share/global.h"
- #include "cs.h"
- #include "cs_aux.h"
- #include "cs_debug.h"
- #include "cs_alloc.h"
- #include "cs_getent.h"
- avail_p avails; /* The list of available expressions. */
- static bool commutative(int instr)
- {
- /* Is instr a commutative operator? */
- switch (instr) {
- case op_adf: case op_adi: case op_adu: case op_and:
- case op_cms: case op_ior: case op_mlf: case op_mli:
- case op_mlu:
- return TRUE;
- default:
- return FALSE;
- }
- }
- static bool same_avail(byte kind, avail_p avp1, avail_p avp2)
- {
- /* Two expressions are the same if they have the same operator,
- * the same size, and their operand(s) have the same value.
- * Only if the operator is commutative, the order of the operands
- * does not matter.
- */
- if (avp1->av_instr != avp2->av_instr) return FALSE;
- if (avp1->av_size != avp2->av_size) return FALSE;
- switch (kind) {
- default:
- assert(FALSE);
- break;
- case EXPENSIVE_LOAD:
- case UNAIR_OP:
- return avp1->av_operand == avp2->av_operand;
- case BINAIR_OP:
- if (commutative(avp1->av_instr & BMASK))
- return ( (avp1->av_oleft == avp2->av_oleft) &&
- (avp1->av_oright == avp2->av_oright) )
- ||
- ( (avp1->av_oleft == avp2->av_oright) &&
- (avp1->av_oright == avp2->av_oleft) )
- ;
- else
- return (avp1->av_oleft == avp2->av_oleft) &&
- (avp1->av_oright == avp2->av_oright);
- case TERNAIR_OP:
- return (avp1->av_ofirst == avp2->av_ofirst) &&
- (avp1->av_osecond == avp2->av_osecond) &&
- (avp1->av_othird == avp2->av_othird);
- }
- /* NOTREACHED */
- return 0;
- }
- static void check_local(avail_p avp)
- {
- /* Check if the local in which the result of avp was stored,
- * still holds this result. Update if not.
- */
- if (avp->av_saveloc == (entity_p) 0) return; /* Nothing to check. */
- if (avp->av_saveloc->en_vn != avp->av_result) {
- OUTTRACE("save local changed value", 0);
- avp->av_saveloc = (entity_p) 0;
- }
- }
- static entity_p result_local(offset size, line_p l)
- {
- /* If the result of an expression of size bytes is stored into a
- * local for which a registermessage was generated, return a pointer
- * to this local.
- */
- line_p dummy;
- entity_p enp;
- if (l == (line_p) 0)
- return (entity_p) 0;
- if ( ((INSTR(l)==op_stl) && (size==ws)) || ((INSTR(l)==op_sdl) && (size==2*ws)) ) {
- enp = getentity(l, &dummy);
- if (is_regvar(enp->en_loc)) {
- OUTTRACE("save local found, %ld(LB)", enp->en_loc);
- return enp;
- }
- }
- return (entity_p) 0;
- }
- static void copy_avail(int kind, avail_p src, avail_p dst)
- {
- /* Copy some attributes from src to dst. */
- dst->av_instr = src->av_instr;
- dst->av_size = src->av_size;
- switch (kind) {
- default:
- assert(FALSE);
- break;
- case EXPENSIVE_LOAD:
- case UNAIR_OP:
- dst->av_operand = src->av_operand;
- break;
- case BINAIR_OP:
- dst->av_oleft = src->av_oleft;
- dst->av_oright = src->av_oright;
- break;
- case TERNAIR_OP:
- dst->av_ofirst = src->av_ofirst;
- dst->av_osecond = src->av_osecond;
- dst->av_othird = src->av_othird;
- break;
- }
- }
- avail_p av_enter(avail_p avp, occur_p ocp, int kind)
- {
- /* Put the available expression avp in the list,
- * if it is not already there.
- * Add ocp to the set of occurrences of this expression.
- */
- avail_p ravp;
- line_p last = ocp->oc_llast;
- for (ravp = avails; ravp != (avail_p) 0; ravp = ravp->av_before) {
- if (same_avail(kind, ravp, avp)) { /* It was there. */
- Ladd(ocp, &ravp->av_occurs);
- /* Can we still use the local in which
- * the result was stored?
- */
- check_local(ravp);
- return ravp;
- }
- }
- /* A new available axpression. */
- ravp = newavail();
- /* Remember local, if any, that holds result. */
- if (avp->av_instr != (byte) INSTR(last)) {
- /* Only possible when instr is the implicit AAR in
- * a LAR or SAR.
- */
- ravp->av_saveloc = (entity_p) 0;
- } else {
- ravp->av_saveloc = result_local(avp->av_size, last->l_next);
- }
- ravp->av_found = last;
- ravp->av_result = kind == EXPENSIVE_LOAD? avp->av_operand: newvalnum();
- copy_avail(kind, avp, ravp);
- oldoccur(ocp);
- ravp->av_before = avails;
- avails = ravp;
- return ravp;
- }
- void clr_avails()
- {
- /* Throw away the information about the available expressions. */
- avail_p ravp, next;
- Lindex i;
- lset s;
- for (ravp = avails; ravp != (avail_p) 0; ravp = next) {
- next = ravp->av_before;
- s = ravp->av_occurs;
- for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i, s)) {
- oldoccur(occ_elem(i));
- }
- Ldeleteset(s);
- oldavail(ravp);
- }
- avails = (avail_p) 0;
- }
|