blob: 79ad51348c7840959da857dc343ab47c1d590415 [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001/* $VER: vbcc (rd.c) $Revision: 1.16 $ */
2/* reaching definitions and constant propagation */
3
4#include "opt.h"
5
6static char FILE_[]=__FILE__;
7
8unsigned int dcount;
9size_t dsize;
10IC **dlist;
11bvtype *rd_defs;
12bvtype **defs_kill; /* definitions killed */
13bvtype **defs_gen; /* definitions undefined */
14bvtype **var_defs; /* definitions of a variable */
15bvtype **var_undefs; /* definitions which are undefined by writing to this var */
16bvtype *rd_matrix;
17
18int def_overwrites(IC *new,IC *old);
19#define NO_OVERWRITE 0
20#define FULL_OVERWRITE 1
21#define PARTIAL_OVERWRITE 2
22#define EXACT_OVERWRITE 3
23
24/* compares two constants; -1, if q1<q2; 0, if q1==q1; 1 otherwise */
25int compare_const(union atyps *q1,union atyps *q2,int t)
26{
27 zldouble d1,d2;zmax l1,l2;zumax u1,u2;
28 t&=NU;
29 eval_const(q1,t);d1=vldouble;l1=vmax;u1=vumax;
30 eval_const(q2,t);d2=vldouble;l2=vmax;u2=vumax;
31 if(ISFLOAT(t)) return(zldleq(d2,d1)?!zldeqto(d1,d2):-1);
32 if(ISPOINTER(t)||(t&UNSIGNED)) return(zumleq(u2,u1)?!zumeqto(u1,u2):-1);
33 return(zmleq(l2,l1)?!zmeqto(l1,l2):-1);
34}
35
36/* prints definitions in a bitvector */
37void print_rd(bvtype *bitvector)
38{
39 unsigned int i;
40 if(!bitvector) {printf("reaching definitions not available\n");return;}
41 for(i=1;i<=dcount;i++){
42 if(BTST(bitvector,i)) {printf("%3u:",i);pric2(stdout,dlist[i]);}
43 if(BTST(bitvector,UNDEF(i))) {printf("%3u(ud):",i);pric2(stdout,dlist[i]);}
44 }
45}
46
47/* numbers all definitions and creates some bitvectors */
48void num_defs(void)
49{
50 int i,j;IC *p;
51 size_t matrix_size;
52 bvtype *bp;
53 unsigned long heapsize=0;
54 if(DEBUG&1024) printf("numerating definitions\n");
55 i=0;
56 for(p=first_ic;p;p=p->next){
57 if(!(p->z.flags&(VAR|DREFOBJ))&&p->code!=CALL){p->defindex=0;continue;}
58 p->defindex=++i;
59 }
60 dcount=i;
61 /*dsize=(2*dcount+1+CHAR_BIT)/CHAR_BIT; /* +1, da bei 1 anfaengt */
62 dsize=BVSIZE(2*(dcount+1));
63 if(DEBUG&(16384|1024)) printf("%lu definitions, dsize=%lu\n",(unsigned long)dcount,(unsigned long)dsize);
64
65 /* get big memory block to store defs_kill, defs_gen, vars, var_defs and var_undefs */
66 matrix_size=(2*(dcount+vcount)*dsize);
67 rd_matrix=bp=mymalloc(matrix_size);
68 memset(bp,0,matrix_size);
69 heapsize+=matrix_size;
70
71 /* calculate bit-vector which contains all definitions killed or */
72 /* undefined (=partially overwritten) by this definition */
73 defs_kill=mymalloc(sizeof(*defs_kill)*(dcount+1));
74 defs_gen=mymalloc(sizeof(*defs_gen)*(dcount+1));
75 heapsize+=2*sizeof(*defs_kill)*(dcount+1);
76
77 for(i=1;i<=dcount;i++){
78 defs_kill[i]=bp;
79 bp+=dsize/sizeof(bvtype);
80 defs_gen[i]=bp;
81 bp+=dsize/sizeof(bvtype);
82 }
83
84 /* calculate bit vector with all undefined definitions of each variable */
85 var_defs=mymalloc(sizeof(*var_defs)*vcount);
86 heapsize+=sizeof(*var_defs)*vcount;
87 var_undefs=mymalloc(sizeof(*var_undefs)*vcount);
88 heapsize+=sizeof(*var_undefs)*vcount;
89 for(i=0;i<vcount;i++){
90 var_defs[i]=bp;
91 bp+=dsize/sizeof(bvtype);
92 var_undefs[i]=bp;
93 bp+=dsize/sizeof(bvtype);
94 }
95
96 /* calculate pointers to IC for every definition */
97 dlist=mymalloc((dcount+1)*sizeof(*dlist));
98 heapsize+=(dcount+1)*sizeof(*dlist);
99
100 for(p=first_ic;p;p=p->next){
101 if(p->defindex){
102 dlist[p->defindex]=p;
103 if(p->z.flags&VAR){
104 Var *v=p->z.v;
105 i=v->index;
106 if(p->z.flags&DREFOBJ) i+=vcount-rcount;
107 BSET(var_defs[i],p->defindex);
108 BSET(var_defs[i],UNDEF(p->defindex));
109 if(i<rcount){
110 BSET(var_defs[i+vcount-rcount],p->defindex);
111 BSET(var_defs[i+vcount-rcount],UNDEF(p->defindex));
112 }
113 BSET(var_undefs[i],UNDEF(p->defindex));
114 }
115 }
116 }
117
118 for(i=1;i<=dcount;i++){
119 p=dlist[i];
120 for(j=0;j<p->change_cnt;j++){
121 int idx;
122 idx=p->change_list[j].v->index;
123 if(p->change_list[j].flags&DREFOBJ) idx+=vcount-rcount;
124 if(idx>=vcount) continue;
125 BSET(var_defs[idx],i);
126 bvunite(defs_gen[i],var_undefs[idx],dsize);
127 }
128 if(p->z.flags&VAR){
129 for(j=1;j<=dcount;j++){
130 int ow;
131 IC *p2;
132 if(i==j) continue;
133 p2=dlist[j];
134 if(!(p2->z.flags&VAR)||p->z.v!=p2->z.v||p->z.flags!=p2->z.flags)
135 continue;
136 ow=def_overwrites(p,p2);
137 if(ow==FULL_OVERWRITE||ow==EXACT_OVERWRITE){
138 BSET(defs_kill[i],j);
139 BSET(defs_kill[i],UNDEF(j));
140 }
141 if(ow==EXACT_OVERWRITE||ow==NO_OVERWRITE){
142 BCLR(defs_gen[i],j);
143 BCLR(defs_gen[i],UNDEF(j));
144 }
145 }
146 }
147 /* every definition defines itself) */
148 BSET(defs_gen[i],i);
149 BCLR(defs_gen[i],UNDEF(i));
150 BSET(defs_kill[i],UNDEF(i));
151 }
152
153 if(DEBUG&2048){
154 for(i=0;i<vcount;i++){
155 printf("var_defs for var %i %s(%p):\n",i,vilist[i]->identifier,vilist[i]);
156 print_rd(var_defs[i]);
157 }
158
159 for(i=1;i<=dcount;i++){
160 printf("Def%3d: ",i);pric2(stdout,dlist[i]);
161 printf(" kills:\n");
162 for(j=1;j<=dcount;j++){
163 if(BTST(defs_kill[i],j)) {printf(" ");pric2(stdout,dlist[j]);}
164 if(BTST(defs_kill[i],UNDEF(j))) {printf(" (ud)");pric2(stdout,dlist[j]);}
165 }
166 printf(" gens:\n");
167 for(j=1;j<=dcount;j++){
168 if(BTST(defs_gen[i],j)) {printf(" ");pric2(stdout,dlist[j]);}
169 if(BTST(defs_gen[i],UNDEF(j))) {printf(" (ud)");pric2(stdout,dlist[j]);}
170 }
171 }
172 }
173
174 if(DEBUG&16384) printf("num_defs heapsize=%lu\n",heapsize);
175
176 free(var_undefs);
177}
178
179/* returns whether n overwrites the definition p */
180int def_overwrites(IC *n,IC *o)
181{
182 zmax nstart,nend,ostart,oend,nsize,osize;
183 if(!(n->z.flags&VAR)) ierror(0);
184 if(!(o->z.flags&VAR)) ierror(0);
185 if((n->z.flags&DREFOBJ)!=(o->z.flags&DREFOBJ)) ierror(0);
186 if(n->code==ASSIGN){
187 nsize=n->q2.val.vmax;
188 }else{
189 nsize=sizetab[ztyp(n)&NQ];
190 }
191 if(o->code==ASSIGN){
192 osize=o->q2.val.vmax;
193 }else{
194 osize=sizetab[ztyp(o)&NQ];
195 }
196 if(n->z.flags&DREFOBJ)
197 return zmleq(osize,nsize);
198
199 nstart=n->z.val.vmax;
200 nend=zmsub(zmadd(nstart,nsize),l2zm(1L));
201 ostart=o->z.val.vmax;
202 oend=zmsub(zmadd(ostart,osize),l2zm(1L));
203
204 if(zmeqto(nstart,ostart)&&zmeqto(nend,oend))
205 return EXACT_OVERWRITE;
206
207 if(zmleq(nstart,ostart)&&zmleq(oend,nend))
208 return FULL_OVERWRITE;
209
210 if(zmleq(ostart,nstart)&&zmleq(nstart,oend))
211 return PARTIAL_OVERWRITE;
212 if(zmleq(ostart,nend)&&zmleq(nend,oend))
213 return PARTIAL_OVERWRITE;
214
215 return NO_OVERWRITE;
216}
217
218/* performs data flow analysis for reaching definitions */
219void reaching_definitions(flowgraph *fg)
220{
221 flowgraph *g;IC *p;bvtype *tmp,*init;
222 int changed,pass,i,j;
223 unsigned long heapsize=0;
224 /* rd_gen und rd_kill fuer jeden Block berechnen */
225 if(DEBUG&1024) printf("analysing reaching definitions\n");
226 tmp=mymalloc(dsize);
227 init=mymalloc(dsize);
228 heapsize+=2*dsize;
229 memset(init,0,dsize);
230 for(i=1;i<=dcount;i++){
231 p=dlist[i];
232 if(p->z.flags&VAR){
233 Var *v=p->z.v;
234 if(v->storage_class==EXTERN||v->storage_class==STATIC||v->reg!=0||!zmleq(l2zm(0L),v->offset)){
235 BSET(init,UNDEF(i));
236 }
237 }
238 }
239 g=fg;
240 while(g){
241 g->rd_in=mymalloc(dsize);
242 memset(g->rd_in,0,dsize);
243 g->rd_out=mymalloc(dsize);
244 memset(g->rd_out,0,dsize);
245 g->rd_gen=mymalloc(dsize);
246 memset(g->rd_gen,0,dsize);
247 g->rd_kill=mymalloc(dsize);
248 memset(g->rd_kill,0,dsize);
249 heapsize+=4*dsize;
250 p=g->end;
251 while(p){
252 if(p->defindex){
253 bvunite(g->rd_gen,defs_gen[p->defindex],dsize);
254 bvdiff(g->rd_gen,g->rd_kill,dsize);
255 bvunite(g->rd_kill,defs_kill[p->defindex],dsize);
256 bvdiff(g->rd_kill,g->rd_gen,dsize);
257 }
258 if(p==g->start) break;
259 p=p->prev;
260 }
261 memcpy(g->rd_out,g->rd_gen,dsize);
262 g=g->normalout;
263 }
264
265 /* rd_in und rd_out fuer jeden Block berechnen */
266 /* out(b)=gen(B) vorinitialisiert */
267 if(DEBUG&1024) {printf("pass:");pass=0;}
268 do{
269 if(DEBUG&1024) {printf(" %d",++pass);fflush(stdout);}
270 changed=0;
271 g=fg;
272 while(g){
273 flowlist *lp;
274 /* in(B)=U out(C) : C Vorgaenger von B */
275 if(g==fg)
276 memcpy(g->rd_in,init,dsize);
277 else
278 memset(g->rd_in,0,dsize);
279 lp=g->in;
280 while(lp){
281 if(!lp->graph) ierror(0);
282 if(lp->graph->branchout==g||!lp->graph->end||lp->graph->end->code!=BRA)
283 bvunite(g->rd_in,lp->graph->rd_out,dsize);
284 lp=lp->next;
285 }
286 /* out(b)=gen(B) U (in(B)-kill(B) */
287 memcpy(tmp,g->rd_in,dsize);
288 bvdiff(tmp,g->rd_kill,dsize);
289 bvunite(tmp,g->rd_gen,dsize);
290 if(!bvcmp(tmp,g->rd_out,dsize)){changed=1;memcpy(g->rd_out,tmp,dsize);}
291 g=g->normalout;
292 }
293 }while(changed);
294 if(DEBUG&1024) printf("\n");
295 if(DEBUG&16384) printf("reaching_defs heapsize=%lu\n",heapsize);
296 free(tmp);
297 free(init);
298}
299
300/* calculates z:=q1 op q2 with constants */
301/* if p is non-zero q1typ,q2typ from p will be used */
302void calc(int c,int t,union atyps *q1,union atyps *q2,union atyps *z,IC *p)
303{
304 zldouble d1,d2;zmax l1,l2;zumax u1,u2;
305 if(p) t=q1typ(p);
306 eval_const(q1,t);
307 d1=vldouble;l1=vmax;u1=vumax;
308 if(c!=MINUS&&c!=KOMPLEMENT){
309 if(p)
310 eval_const(q2,q2typ(p));
311 else
312 eval_const(q2,t);
313 d2=vldouble;l2=vmax;u2=vumax;
314 }
315 if(c==ADD){ vldouble=zldadd(d1,d2);vmax=zmadd(l1,l2);vumax=zumadd(u1,u2);}
316 if(c==SUB){ vldouble=zldsub(d1,d2);vmax=zmsub(l1,l2);vumax=zumsub(u1,u2);}
317 if(c==ADDI2P){ vmax=zmadd(l1,l2);vumax=zumadd(u1,u2);}
318 if(c==SUBIFP){ vmax=zmsub(l1,l2);vumax=zumsub(u1,u2);}
319 if(c==MULT){ vldouble=zldmult(d1,d2);vmax=zmmult(l1,l2);vumax=zummult(u1,u2);}
320 if(c==DIV||c==MOD){
321 if(zldeqto(d2,d2zld(0.0))&&zmeqto(l2,l2zm(0L))&&zumeqto(u2,ul2zum(0UL))){
322 err_ic=p;error(210);err_ic=0;
323 vmax=l2zm(0L);vumax=ul2zum(0L);vldouble=d2zld(0.0);
324 }else{
325 if(c==DIV){
326 vldouble=zlddiv(d1,d2);
327 if(!zmeqto(l2,l2zm(0L))) vmax=zmdiv(l1,l2);
328 if(!zumeqto(u2,ul2zum(0UL))) vumax=zumdiv(u1,u2);
329 }else{
330 if(!zmeqto(l2,l2zm(0L))) vmax=zmmod(l1,l2);
331 if(!zumeqto(u2,ul2zum(0UL))) vumax=zummod(u1,u2);
332 }
333 }
334 }
335 if(c==AND){ vmax=zmand(l1,l2);vumax=zumand(u1,u2);}
336 if(c==OR){ vmax=zmor(l1,l2);vumax=zumor(u1,u2);}
337 if(c==XOR){ vmax=zmxor(l1,l2);vumax=zumxor(u1,u2);}
338 if(c==LSHIFT){ vmax=zmlshift(l1,l2);vumax=zumlshift(u1,l2);}
339 if(c==RSHIFT){ vmax=zmrshift(l1,l2);vumax=zumrshift(u1,l2);}
340 if(c==MINUS){ vldouble=zldsub(d2zld(0.0),d1);vmax=zmsub(l2zm(0L),l1);vumax=zumsub(ul2zum(0UL),u1);}
341 if(c==KOMPLEMENT){ vmax=zmkompl(l1);vumax=zumkompl(u1);}
342
343 if(ISFLOAT(t)){
344 gval.vldouble=vldouble;
345 eval_const(&gval,LDOUBLE);
346 }else if(t&UNSIGNED){
347 gval.vumax=vumax;
348 eval_const(&gval,(UNSIGNED|MAXINT));
349 }else{
350 gval.vmax=vmax;
351 eval_const(&gval,MAXINT);
352 }
353 if(p) t=ztyp(p);
354 insert_const(z,t);
355}
356
357/* folds constant ICs */
358int fold(IC *p)
359{
360 int c;
361 if(!p) ierror(0);
362 c=p->code;
363 if(c==SUBPFP||c==ASSIGN||c==PUSH||c==SETRETURN) return 0;
364 if(DEBUG&1024) {printf("folding IC:\n");pric2(stdout,p);}
365 if(c==TEST||c==COMPARE){
366 union atyps val;int cc; /* condition codes */
367 IC *bp;
368 if(c==TEST){
369 eval_const(&p->q1.val,p->typf);
370 if(zmeqto(vmax,l2zm(0L))&&zumeqto(vumax,ul2zum(0UL))&&zldeqto(vldouble,d2zld(0.0)))
371 cc=0;
372 else
373 cc=1;
374 }else{
375 if(p->q1.flags&VARADR)
376 cc=compare_const(&p->q1.val,&p->q2.val,UNSIGNED|MAXINT);
377 else
378 cc=compare_const(&p->q1.val,&p->q2.val,p->typf);
379 }
380 bp=p->next;
381 if(bp->code>=BEQ&&bp->code<=BGT&&(!p->z.flags||p->z.v==bp->q1.v)){
382 if(DEBUG&1024) printf("(cc=%d; comparison eliminated)\n",cc);
383 if(have_alias){ free(p->use_list);free(p->change_list);}
384 remove_IC(p);
385 while(1){ /* zugehoerigen Branch suchen */
386 if(!bp||bp->code==LABEL||bp->code==BRA) ierror(0);
387 c=bp->code;
388 if(c>=BEQ&&c<=BGT) break;
389 bp=bp->next;
390 }
391 if((c==BEQ&&cc==0)||(c==BNE&&cc!=0)||(c==BLT&&cc<0)||(c==BGT&&cc>0)||(c==BLE&&cc<=0)||(c==BGE&&cc>=0)){
392 if(DEBUG&1024){ printf("changed following branch to BRA:\n");pric2(stdout,bp);}
393 bp->code=BRA;bp->q1.flags=0;
394 }else{
395 if(DEBUG&1024){ printf("removed following branch:\n");pric2(stdout,bp);}
396 if(have_alias){ free(bp->use_list);free(bp->change_list);}
397 remove_IC(bp);
398 }
399 return 1;
400 }
401 if(p->z.flags==0){
402 p->code=NOP;
403 p->q1.flags=p->q2.flags=p->z.flags=0;
404 return 1;
405 }else
406 return 0;
407 }
408 if(c==CONVERT){
409 eval_const(&p->q1.val,p->typf2);
410 insert_const(&p->q1.val,p->typf);
411 }else
412 calc(c,p->typf,&p->q1.val,&p->q2.val,&p->q1.val,p);
413 p->q2.flags=0;
414 if(p->code==ADDI2P||p->code==SUBIFP)
415 p->typf=p->typf2;
416 p->q2.val.vmax=sizetab[p->typf&NQ];
417 p->code=ASSIGN;
418 if(DEBUG&1024){printf("becomes\n");pric2(stdout,p);}
419 return 1;
420}
421
422/* tries to replace objects by constants and detects some uninitialized */
423/* variables; if cponly==0, address-constants will be replaced, */
424/* otherwise only real constants are replaced, sic points to the IC */
425/* containing the object pointed to by o */
426int propagate(IC *sic,obj *o,int cponly,int global)
427{
428 unsigned int i,j,t,found;union atyps *val=0;
429 Var *v,*vaddr=0;IC *p;
430 zmax voff;
431 if(!o||!o->v) ierror(0);
432 if(cponly){
433 if(is_volatile_obj(o))
434 return 0;
435 }else{
436 if((o->flags&VAR)&&(o->v->vtyp->flags&VOLATILE))
437 return 0;
438 }
439 if(disable&8) return 0;
440 v=o->v;
441 i=v->index;
442 /* do not replace in ICs of the form move char with size!=1,
443 because these are builtin memcpy */
444 if(cponly&&sic->code==ASSIGN&&(sic->typf&NQ)==CHAR&&!zmeqto(sic->q2.val.vmax,l2zm(1L)))
445 return 0;
446 if(cponly&&(o->flags&DREFOBJ)) i+=vcount-rcount;
447 if(DEBUG&2048){
448 printf("propagate(cponly=%d) <%s>(%p)\n",cponly,o->v->identifier,(void *)v);
449 if(o->flags&DREFOBJ) printf("(DREFOBJ)");
450 printf("\nall reaching definitions:\n");print_rd(rd_defs);
451 printf("defs for var:\n");
452 print_rd(var_defs[i]);
453 }
454 if(v->nesting==0||v->storage_class==STATIC||v->storage_class==EXTERN){
455 /* Wenn moeglich bei statischen Variablen den Wert bei der */
456 /* Initialisierung ermitteln. */
457 /*if(cponly&&ISARITH(v->vtyp->flags)&&((v->vtyp->flags&CONST)||(v->nesting>0&&!(v->flags&(USEDASADR|USEDASDEST))))){*/
458 if(cponly&&is_const(v->vtyp)){
459 /* Variable hat noch den Wert der Initialisierung. */
460 if(v->clist){
461 int t;
462 if(o==&sic->q1) t=q1typ(sic);
463 else if(o==&sic->q2) t=q2typ(sic);
464 else if(o==&sic->z) t=ztyp(sic);
465 else ierror(0);
466 if(ISARITH(v->vtyp->flags)){
467 /* Der Wert der Initialisierung ist noch gespeichert. */
468 if(DEBUG&1024) printf("using static initializer\n");
469 o->val=v->clist->val;
470 o->flags=KONST;
471 return 1;
472 }else if(ISINT(t&NQ)){
473 int state;
474 if(DEBUG&1024) printf("using static initializer (new version)\n");
475 gval.vumax=get_clist_int(v->vtyp,v->clist,o->val.vmax,sizetab[t&NQ],&state);
476 if(state){
477 if(DEBUG&1024) printf("using static initializer (new version)\n");
478 eval_const(&gval,UNSIGNED|MAXINT);
479 insert_const(&o->val,t);
480 o->flags=KONST;
481 return 1;
482 }
483 }
484 }else{
485 /* Hier evtl. eine implizite 0 erkennen. */
486 }
487 }
488 }
489 found=0;
490 for(j=1;j<=dcount;j++){
491 if((!BTST(rd_defs,UNDEF(j))||!BTST(var_defs[i],UNDEF(j)))&&
492 (!BTST(rd_defs,j)||!BTST(var_defs[i],j))) continue;
493 found=1;
494 p=dlist[j];
495 if(!(p->z.flags&VAR)) return 0;
496 if(p->z.v!=o->v) continue;
497 t=ztyp(p)&NU;
498 if(cponly&&!ISSCALAR(t)) continue;
499 if(!zmeqto(p->z.val.vmax,o->val.vmax)) continue;
500 if(cponly){
501 if(p->z.flags!=o->flags) continue;
502 }else{
503 if((p->z.flags|DREFOBJ)!=o->flags) continue;
504 if(p->z.flags&DREFOBJ) continue;
505 }
506 if(BTST(rd_defs,UNDEF(j))&&BTST(var_defs[i],UNDEF(j))) return 0;
507 if(BTST(rd_defs,UNDEF(j))&&BTST(var_defs[i],j)) return 0;
508
509 if((p->code!=ASSIGN||((p->q1.flags&(KONST|DREFOBJ))!=KONST&&(p->q1.flags&(VARADR|DREFOBJ))!=VARADR))
510 &&(p->code!=ADDRESS||!(o->flags&DREFOBJ))) return 0;
511 if(p->q1.flags&KONST){
512 if(vaddr) return 0;
513 if(val){
514 if((p->typf&NQ)!=(t&NQ)) return 0;
515 if(compare_const(&p->q1.val,val,t)) return 0;
516 }else{
517 val=&p->q1.val;t=p->typf&NU;
518 }
519 }
520 if(p->code==ADDRESS||(p->q1.flags&VARADR)){
521 if(val) return 0;
522 if(vaddr){
523 if(p->q1.v!=vaddr||!zmeqto(p->q1.val.vmax,voff)) return 0;
524 }
525 vaddr=p->q1.v;
526 voff=p->q1.val.vmax;
527 }
528 }
529
530 /* found constant */
531 if(val){
532 if(cponly){
533 if(o==&sic->q1&&(q1typ(sic)&NQ)!=(t&NQ)) return 0;
534 if(o==&sic->q2&&(q2typ(sic)&NQ)!=(t&NQ)) return 0;
535 if(o==&sic->z&&(ztyp(sic)&NQ)!=(t&NQ)) return 0;
536
537 if(DEBUG&1024) printf("can replace %ld+<%s>(%p) by constant\n",zm2l(o->val.vmax),o->v->identifier,o->v);
538 /* TODO: do we need eval_const/insert_const (if representation of unsigned is different? */
539 o->val=*val;
540 o->flags=KONST;
541 }else{
542 if(DEBUG&1024) printf("can replace <%s> by constant address\n",o->v->identifier);
543 o->val=*val;
544 o->flags|=KONST;
545 o->flags&=~VAR;
546 o->v=0;
547 }
548 return 1;
549 }
550 if(vaddr&&(vaddr->storage_class==EXTERN||vaddr->storage_class==STATIC)){
551 if(DEBUG&1024) printf("can replace <%s> by varadr\n",o->v->identifier);
552 o->v=vaddr;
553 o->val.vmax=voff;
554 if((o->flags&DREFOBJ)&&!cponly)
555 o->flags=VAR;
556 else
557 o->flags=VAR|VARADR;
558 return 2;
559 }
560 if(vaddr&&(o->flags&DREFOBJ)){
561 t=vaddr->vtyp->flags&NU;
562 if(o==&sic->q1&&(q1typ(sic)&NU)!=t) return 0;
563 if(o==&sic->q2&&(q2typ(sic)&NU)!=t) return 0;
564 if(o==&sic->z&&(ztyp(sic)&NU)!=t) return 0;
565 if(DEBUG&1024) printf("can replace *<%s> by address\n",o->v->identifier);
566 o->v=vaddr;
567 o->val.vmax=voff;
568 o->flags&=~DREFOBJ;
569 return 2;
570 }
571 /* no definition found */
572 if(!found&&global&&v->storage_class!=EXTERN&&v->storage_class!=STATIC&&!(v->flags&USEDBEFORE)&&v->reg==0&&zmleq(l2zm(0L),v->offset)){
573 if(*v->identifier||!(optflags&4096)){
574#ifdef HAVE_MISRA
575/* removed */
576#endif
577 error(171,v->identifier);v->flags|=USEDBEFORE;
578 if(!*v->identifier) {printf("<%p>\n",(void *)v);ierror(0);}
579 }
580 }
581 return 0;
582}
583
584/* searches for constant objects and uninitialized variables; if */
585/* global!=0, reaching definitions are used, otherwise only local */
586/* constant propagation will be done */
587int constant_propagation(flowgraph *fg,int global)
588{
589 IC *p;int changed=0,i,t;flowgraph *g;
590 rd_defs=mymalloc(dsize);
591 g=fg;
592 while(g){
593 if(global)
594 memcpy(rd_defs,g->rd_in,dsize);
595 else
596 memset(rd_defs,0,dsize);
597 p=g->start;
598 while(p){
599 int c=p->code;
600 /* if(DEBUG&1024){print_rd(rd_defs);pric2(stdout,p);}*/
601 if(c!=ADDRESS&&c!=NOP&&ISSCALAR(p->typf)&&(c<LABEL||c>BRA)){
602 if((p->q1.flags&(VAR|VARADR))==VAR){
603 if(!(q1typ(p)&VOLATILE)&&!is_volatile_obj(&p->q1))
604 changed|=propagate(p,&p->q1,1,global);
605 if((p->q1.flags&DREFOBJ)&&!(p->q1.v->vtyp->flags&VOLATILE))
606 changed|=propagate(p,&p->q1,0,global);
607 }
608 if((p->q2.flags&(VAR|VARADR))==VAR){
609 if(!(q2typ(p)&VOLATILE)&&!is_volatile_obj(&p->q2))
610 changed|=propagate(p,&p->q2,1,global);
611 if((p->q2.flags&DREFOBJ)&&!(p->q2.v->vtyp->flags&VOLATILE))
612 changed|=propagate(p,&p->q2,0,global);
613 }
614 }
615 /* only there to detect uninitialized variables */
616 if(((p->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ))){
617 if(!(p->z.v->vtyp->flags&VOLATILE))
618 changed|=propagate(p,&p->z,0,global);
619 }
620 rd_change(p);
621
622 if(p==g->end) break;
623 p=p->next;
624 }
625 break;
626 g=g->normalout;
627 }
628
629 gchanged|=changed;
630
631 free(rd_defs);
632 return changed;
633}
634
635/* performs changes to rd_defs which are caused by IC p */
636void rd_change(IC *p)
637{
638 if(DEBUG&4096) print_rd(rd_defs);
639 if(p->defindex){
640 bvdiff(rd_defs,defs_kill[p->defindex],dsize);
641 bvunite(rd_defs,defs_gen[p->defindex],dsize);
642 }
643 if(DEBUG&4096) pric2(stdout,p);
644}
645