Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
#include "config.h"
32
#include "extern_adds.h"
33
#include "common_types.h"
34
#include "tags.h"
35
#include "exp.h"
36
#include "expmacs.h"
37
#include "shapemacs.h"
38
#include "externs.h"
39
 
40
 
41
extern exp * ptr_position PROTO_S ((exp e));
42
 
43
/* replaces uses of extern in procs by local identification of address;
44
 
45
   initially replace usage chain by
46
     name:0; pt: usage chain in proc P; son: P; props: !=0 if in loop
47
	no: no of usages in proc; bro: last in usage chain;
48
    in usages[no of procs]
49
    Use this to determine if and where to identify global to a proc local	
50
 
51
*/
52
 
53
exp * usages;
54
 
55
static bool enter_parents
56
    PROTO_N ( ( e ) )
57
    PROTO_T ( exp e )
58
{
59
  exp dad =e;
60
  bool inloop = 0;
61
  Assert(name(e)==name_tag);
62
  for(;;) {
63
    dad = father(dad);
64
    if (name(dad)==rep_tag) {
65
      inloop=1;
66
    }
67
    else if (name(dad)==proc_tag) {
68
      exp nu = usages[no(dad)];
69
      if (nu == nilexp) {
70
	nu = getexp(sh(e), e, 1, dad, nilexp, 0,0, 0);
71
	usages[no(dad)] = nu;
72
      }
73
      props(nu) |= inloop;
74
      pt(e) = pt(nu); 
75
				/* remember pt(e) before entry */
76
      pt(nu) = e;
77
      no(nu)++;
78
      return 1;
79
    }
80
    else if (name(dad)== ident_tag && isglob(dad)) {
81
      return 0;
82
    }
83
    else if (name(dad) == 102 || name(dad) == hold_tag) {
84
      /* thou shalt use descriptive names for constants (102 ?) */
85
 
86
      /* could be leftover from exp token expansion with no pars */
87
      return 0;
88
    }
89
  }
90
}
91
 
92
 
93
 
94
void global_usages
95
    PROTO_N ( ( id, nop ) )
96
    PROTO_T ( exp id X int nop )
97
{
98
  exp plist, nextpl;
99
  int i;
100
  Assert(name(id)==ident_tag && isglob(id) && son(id)==nilexp);
101
  if (no(id)==0) return;
102
  for(i=0; i<nop; i++) {
103
    usages[i] = nilexp;
104
  }
105
  plist = pt(id);
106
  nextpl = pt(plist);
107
  pt(id) = nilexp;
108
  no(id) = 0;
109
  for(;;) {
110
    if (!enter_parents(plist)) {
111
      pt(plist) = pt(id);
112
      pt(id) = plist;
113
      no(id)++;
114
    }
115
    if ((plist = nextpl) == nilexp) break;
116
    nextpl = pt(plist);
117
  }
118
  for(i=0; i<nop; i++) {
119
    exp ui = usages[i];
120
    if (ui != nilexp) {
121
      if (props(ui) != 0  ) {
122
	/* id is used enough in proc i - 
123
	   so identify it locally */		
124
	exp * pi;
125
	shape sname = f_pointer(f_alignment(sh(id)));
126
	for(pi= &son(son(ui));;) {
127
	  if (name(*pi)== ident_tag && isparam(*pi)) {
128
	    pi = &bro(son(*pi));
129
	  }
130
	  else if (name(*pi) == diagnose_tag || name(*pi) == prof_tag) {
131
	    pi = &son(*pi);
132
	  }	
133
	  else {
134
	    /* invent new def to identify global ... */	
135
	    exp nl = getexp(sname,
136
			    *pi, 0, id, pt(id), 0, 0, name_tag);
137
	    exp ndef = getexp(sh(*pi), bro(*pi),last(*pi),
138
			      nl, nilexp, 0x10/*don't defer */, 
139
			      0, ident_tag);
140
	    exp lu = pt(ui);
141
	    setlast(*pi); bro(*pi) = ndef;
142
	    pt(id) = nl; no(id)++;
143
	    setcaonly(ndef);
144
	    *pi = ndef;
145
	    /*... and replace uses of global by ndef */
146
	    while(lu != nilexp) {
147
	      exp nlu = pt(lu);
148
	      if (no(lu)!=0) {
149
		exp * plu = ptr_position(lu);
150
		exp nrf = getexp(sh(lu), bro(lu), last(lu),
151
				 lu, nilexp, 0, no(lu), reff_tag);
152
		sh(lu) = sname;
153
		no(lu) = 0;
154
		bro(lu) = nrf; setlast(lu);
155
		*plu = nrf;
156
	      }
157
	      son(lu) = ndef;
158
	      pt(lu) = pt(ndef);
159
	      pt(ndef)= lu; no(ndef)++;				
160
	      lu = nlu;
161
	    }
162
	    break;
163
	  }
164
	}
165
      }
166
      else {
167
	/* restore normal usage chain */
168
	pt(bro(ui)) = pt(id);
169
	pt(id) = pt(ui);
170
	no(id)+= no(ui);
171
      }
172
      retcell(ui);
173
    }
174
  }
175
}		
176
 
177
 
178
 
179