123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* V A L U E N U M B E R I N G M E T H O D */
- #include <em_mnem.h>
- #include "../share/types.h"
- #include "../share/global.h"
- #include "../share/debug.h"
- #include "../share/aux.h"
- #include "cs.h"
- #include "cs_alloc.h"
- #include "cs_aux.h"
- #include "cs_entity.h"
- #include "cs_avail.h"
- #include "cs_stack.h"
- #include "cs_kill.h"
- #include "cs_partit.h"
- #include "cs_getent.h"
- STATIC push_entity(enp, lfirst)
- entity_p enp;
- line_p lfirst;
- {
- /* Build token and Push it. */
- struct token tk;
- tk.tk_vn = enp->en_vn;
- tk.tk_size = enp->en_size;
- tk.tk_lfirst = lfirst;
- Push(&tk);
- }
- STATIC put_expensive_load(bp, lnp, lfirst, enp)
- bblock_p bp;
- line_p lnp, lfirst;
- entity_p enp;
- {
- struct avail av;
- occur_p ocp;
- av.av_instr = INSTR(lnp);
- av.av_size = enp->en_size;
- av.av_operand = enp->en_vn;
- ocp = newoccur(lfirst, lnp, bp);
- av_enter(&av, ocp, EXPENSIVE_LOAD);
- }
- STATIC put_aar(bp, lnp, lfirst, enp)
- bblock_p bp;
- line_p lnp, lfirst;
- entity_p enp;
- {
- /* Enp points to an ENARRELEM. We do as if its address was computed. */
- struct avail av;
- occur_p ocp;
- assert(enp->en_kind == ENARRELEM);
- av.av_instr = op_aar;
- av.av_size = ps;
- av.av_ofirst = enp->en_arbase;
- av.av_osecond = enp->en_index;
- av.av_othird = enp->en_adesc;
- ocp = newoccur(lfirst, lnp, bp);
- av_enter(&av, ocp, TERNAIR_OP);
- }
- STATIC push_avail(avp, lfirst)
- avail_p avp;
- line_p lfirst;
- {
- struct token tk;
- tk.tk_vn = avp->av_result;
- tk.tk_size = avp->av_size;
- tk.tk_lfirst = lfirst;
- Push(&tk);
- }
- STATIC push_unair_op(bp, lnp, tkp1)
- bblock_p bp;
- line_p lnp;
- token_p tkp1;
- {
- struct avail av;
- occur_p ocp;
- av.av_instr = INSTR(lnp);
- av.av_size = avsize(lnp);
- av.av_operand = tkp1->tk_vn;
- ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
- push_avail(av_enter(&av, ocp, UNAIR_OP), tkp1->tk_lfirst);
- }
- STATIC push_binair_op(bp, lnp, tkp1, tkp2)
- bblock_p bp;
- line_p lnp;
- token_p tkp1, tkp2;
- {
- struct avail av;
- occur_p ocp;
- av.av_instr = INSTR(lnp);
- av.av_size = avsize(lnp);
- av.av_oleft = tkp1->tk_vn;
- av.av_oright = tkp2->tk_vn;
- ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
- push_avail(av_enter(&av, ocp, BINAIR_OP), tkp1->tk_lfirst);
- }
- STATIC push_ternair_op(bp, lnp, tkp1, tkp2, tkp3)
- bblock_p bp;
- line_p lnp;
- token_p tkp1, tkp2, tkp3;
- {
- struct avail av;
- occur_p ocp;
- av.av_instr = INSTR(lnp);
- av.av_size = avsize(lnp);
- av.av_ofirst = tkp1->tk_vn;
- av.av_osecond = tkp2->tk_vn;
- av.av_othird = tkp3->tk_vn;
- ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
- push_avail(av_enter(&av, ocp, TERNAIR_OP), tkp1->tk_lfirst);
- }
- STATIC fiddle_stack(lnp)
- line_p lnp;
- {
- /* The instruction in lnp does something to the valuenumber-stack. */
- struct token dummy;
- offset size;
- /* Partly initialize dummy. */
- dummy.tk_lfirst = lnp;
- switch (INSTR(lnp)) {
- default:
- assert(FALSE);
- break;
- case op_lor:
- dummy.tk_vn = newvalnum(); dummy.tk_size = ps;
- Push(&dummy);
- break;
- case op_asp:
- if ((size = off_set(lnp)) > 0) {
- Pop(&dummy, size);
- } else {
- dummy.tk_vn = newvalnum();
- dummy.tk_size = size;
- Push(&dummy);
- }
- break;
- case op_dup:
- Dup(lnp);
- break;
- case op_ass:
- case op_dus:
- case op_exg:
- case op_los:
- /* Don't waste effort. */
- clr_stack();
- break;
- case op_sig:
- Pop(&dummy, (offset) ps);
- break;
- case op_lfr:
- dummy.tk_vn = newvalnum();
- dummy.tk_size = off_set(lnp);
- Push(&dummy);
- break;
- case op_beq:
- case op_bge:
- case op_bgt:
- case op_bne:
- case op_ble:
- case op_blt:
- Pop(&dummy, (offset) ws);
- Pop(&dummy, (offset) ws);
- break;
- case op_bra:
- case op_csa:/* ??? */
- case op_csb:/* ??? */
- case op_gto:/* ??? */
- case op_ret:/* ??? */
- case op_rtt:/* ??? */
- break;
- case op_zeq:
- case op_zge:
- case op_zgt:
- case op_zne:
- case op_zle:
- case op_zlt:
- case op_trp:
- Pop(&dummy, (offset) ws);
- break;
- case op_rck:
- Pop(&dummy, (offset) ps);
- break;
- }
- }
- STATIC proc_p find_proc(vn)
- valnum vn;
- {
- /* Find the procedure-identifier with valuenumber vn. */
- entity_p enp;
- enp = find_entity(vn);
- if (enp != (entity_p) 0 && enp->en_kind == ENPROC)
- return enp->en_pro;
- return (proc_p) 0;
- }
- STATIC side_effects(lnp)
- line_p lnp;
- {
- /* Lnp contains a cai or cal instruction. We try to find the callee
- * and see what side-effects it has.
- */
- struct token tk;
- proc_p pp;
- if (INSTR(lnp) == op_cai) {
- Pop(&tk, (offset) ps);
- pp = find_proc(tk.tk_vn);
- } else {
- assert(INSTR(lnp) == op_cal);
- pp = PROC(lnp);
- }
- if (pp != (proc_p) 0) {
- kill_call(pp);
- } else {
- kill_much();
- }
- }
- hopeless(instr)
- int instr;
- {
- /* The effect of `instr' is too difficult to
- * compute. We assume worst case behaviour.
- */
- switch (instr) {
- default:
- assert(FALSE);
- break;
- case op_mon:
- case op_str:
- case op_nop: /* for volatiles */
- /* We can't even trust "static" entities. */
- kill_all();
- clr_stack();
- break;
- case op_blm:
- case op_bls:
- case op_sts:
- kill_much();
- clr_stack();
- break;
- }
- }
- vnm(bp)
- bblock_p bp;
- {
- register line_p lnp;
- register entity_p rep;
- line_p lfirst;
- struct token tk, tk1, tk2, tk3;
- for (lnp = bp->b_start; lnp != (line_p) 0; lnp = lnp->l_next) {
- rep = getentity(lnp, &lfirst);
- switch (instrgroup(lnp)) {
- case SIMPLE_LOAD:
- push_entity(rep, lfirst);
- break;
- case LOAD_ARRAY:
- put_aar(bp, lnp, lfirst, rep);
- /* Fall through ... */
- case EXPENSIVE_LOAD:
- push_entity(rep, lfirst);
- put_expensive_load(bp, lnp, lfirst, rep);
- break;
- case STORE_DIRECT:
- kill_direct(rep);
- Pop(&tk, rep->en_size);
- rep->en_vn = tk.tk_vn;
- break;
- case STORE_ARRAY:
- put_aar(bp, lnp, lfirst, rep);
- /* Fall through ... */
- case STORE_INDIR:
- kill_indir(rep);
- Pop(&tk, rep->en_size);
- rep->en_vn = tk.tk_vn;
- break;
- case UNAIR_OP:
- Pop(&tk1, op11size(lnp));
- push_unair_op(bp, lnp, &tk1);
- break;
- case BINAIR_OP:
- Pop(&tk2, op22size(lnp));
- Pop(&tk1, op12size(lnp));
- push_binair_op(bp, lnp, &tk1, &tk2);
- break;
- case TERNAIR_OP:
- Pop(&tk3, op33size(lnp));
- Pop(&tk2, op23size(lnp));
- Pop(&tk1, op13size(lnp));
- push_ternair_op(bp, lnp, &tk1, &tk2, &tk3);
- break;
- case KILL_ENTITY:
- kill_direct(rep);
- break;
- case SIDE_EFFECTS:
- side_effects(lnp);
- break;
- case FIDDLE_STACK:
- fiddle_stack(lnp);
- break;
- case IGNORE:
- break;
- case HOPELESS:
- hopeless(INSTR(lnp));
- break;
- case BBLOCK_END:
- fiddle_stack(lnp);
- break;
- default:
- assert(FALSE);
- break;
- }
- }
- }
|