1: // Copyright (C) 1986-1998 by Symantec
  2: // Copyright (C) 2000-2011 by Digital Mars
  3: // All Rights Reserved
  4: // http://www.digitalmars.com
  5: // Written by Walter Bright
  6: /*
  7:  * This source file is made available for personal use
  8:  * only. The license is in /dmd/src/dmd/backendlicense.txt
  9:  * or /dm/src/dmd/backendlicense.txt
 10:  * For any other uses, please contact Digital Mars.
 11:  */
 12: 
 13: 
 14: #if (SCPP || MARS) && !HTOD
 15: 
 16: #include        <stdio.h>
 17: #include        <time.h>
 18: 
 19: #include        "cc.h"
 20: #include        "global.h"
 21: #include        "el.h"
 22: #include        "go.h"
 23: #include        "ty.h"
 24: #include        "oper.h"
 25: #include        "vec.h"
 26: 
 27: static char __file__[] = __FILE__;      /* for tassert.h                */
 28: #include        "tassert.h"
 29: 
 30: STATIC void aewalk(elem **pn , vec_t ae);
 31: STATIC elem * delcse(elem **pe);
 32: STATIC void removecses(elem **pe);
 33: STATIC void boundscheck(elem *e, vec_t ae);
 34: 
 35: enum Aetype { AEcse, AEarraybounds };
 36: static Aetype aetype;
 37: 
 38: /*************************************
 39:  * Determine if floating point should be cse'd.
 40:  */
 41: 
 42: inline int cse_float(elem *e)
 43: {
 44: #if TX86
 45:     // Don't CSE floating stuff if generating
 46:     // inline 8087 code, the code generator
 47:     // can't handle it yet
 48:     return !(tyfloating(e->Ety) && config.inline8087 &&
 49:            e->Eoper != OPvar && e->Eoper != OPconst);
 50: #else
 51:     return 1;
 52: #endif
 53: }
 54: 
 55: /************************************
 56:  * Build DAGs (basically find all the common subexpressions).
 57:  * Must be done after all other optimizations, because most
 58:  * of them depend on the trees being trees, not DAGs.
 59:  * The general strategy is:
 60:  *      Compute available expressions (AEs)
 61:  *      For each block
 62:  *              stick together nodes that match, keeping AEs up to date
 63:  *      For each block
 64:  *              unstick unprofitable common subexpressions
 65:  *              (this is generally target-dependent)
 66:  */
 67: 
 68: void builddags()
 69: {       register unsigned i;
 70:         register vec_t aevec;
 71: 
 72:         cmes("builddags()\n");
 73:         assert(dfo);
 74:         flowae();                       /* compute available expressions */
 75:         if (exptop <= 1)                /* if no AEs                    */
 76:                 return;
 77:         aetype = AEcse;
 78: #ifdef DEBUG
 79:         for (i = 0; i < exptop; i++)
 80:         {
 81:             //dbg_printf("expnod[%d] = %p\n",i,expnod[i]);
 82:             if (expnod[i])
 83:                 elem_debug(expnod[i]);
 84:         }
 85: #endif
 86: #if 0
 87:         dbg_printf("defkill  "); vec_println(defkill,exptop);
 88:         dbg_printf("starkill "); vec_println(starkill,exptop);
 89:         dbg_printf("vptrkill "); vec_println(vptrkill,exptop);
 90: #endif
 91: 
 92: #if 0
 93:         /* This is the 'correct' algorithm for CSEs. We can't use it    */
 94:         /* till we fix the code generator.                              */
 95:         for (i = 0; i < dfotop; i++)
 96:         {       register block *b;
 97: 
 98:                 b = dfo[i];
 99:                 if (b->Belem)
100:                 {
101: #if 0
102:                         dbg_printf("dfo[%d] = %p\n",i,b);
103:                         dbg_printf("b->Bin   "); vec_println(b->Bin,exptop);
104:                         dbg_printf("b->Bout  "); vec_println(b->Bout,exptop);
105:                         aewalk(&(b->Belem),b->Bin);
106:                         dbg_printf("b->Bin   "); vec_println(b->Bin,exptop);
107:                         dbg_printf("b->Bout  "); vec_println(b->Bout,exptop);
108: #else
109:                         aewalk(&(b->Belem),b->Bin);
110: #endif
111:                         /* Bin and Bout would be equal at this point    */
112:                         /* except that we deleted some elems from       */
113:                         /* expnod[] and so it's a subset of Bout        */
114:                         /* assert(veceq(b->Bin,b->Bout));               */
115:                 }
116:         }
117: #else
118:         /* Do CSEs across extended basic blocks only. This is because   */
119:         /* the code generator can only track register contents          */
120:         /* properly across extended basic blocks.                       */
121:         aevec = vec_calloc(exptop);
122:         for (i = 0; i < dfotop; i++)
123:         {       register block *b;
124: 
125:                 b = dfo[i];
126:                 /* if not first block and (there are more than one      */
127:                 /* predecessor or the only predecessor is not the       */
128:                 /* previous block), then zero out the available         */
129:                 /* expressions.                                         */
130:                 if ((i != 0 &&
131:                      (list_block(b->Bpred) != dfo[i - 1] ||
132:                       list_next(b->Bpred) != NULL))
133:                     || b->BC == BCasm
134:                     || b->BC == BC_finally
135: #if SCPP
136:                     || b->BC == BCcatch
137: #endif
138: #if MARS
139:                     || b->BC == BCjcatch
140: #endif
141:                    )
142:                         vec_clear(aevec);
143:                 if (b->Belem)           /* if there is an expression    */
144:                         aewalk(&(b->Belem),aevec);
145: 
146:         }
147:         vec_free(aevec);
148: #endif
149:         // Need 2 passes to converge on solution
150:         for (int j = 0; j < 2; j++)
151:             for (i = 0; i < dfotop; i++)
152:             {   register block *b;
153: 
154:                 b = dfo[i];
155:                 if (b->Belem)
156:                 {
157: #if 0
158:                         dbg_printf("b = 0x%x\n",b);
159: #endif
160:                         removecses(&(b->Belem));
161:                 }
162:             }
163: }
164: 
165: /**********************************
166:  */
167: 
168: STATIC void aeclear(elem *n,vec_t ae)
169: {   int i;
170: 
171:     i = n->Eexp;
172:     assert(i);
173:     if (n->Ecount == 0)
174:     {
175:         expnod[i] = 0;
176:         vec_clearbit(i,ae);
177:         if (EUNA(n))
178:             aeclear(n->E1,ae);
179:         else if (EBIN(n))
180:         {   aeclear(n->E1,ae);
181:             aeclear(n->E2,ae);
182:         }
183:     }
184: }
185: 
186: /****************************
187:  * Walk tree, building DAG as we go.
188:  *      ae = vector of available expressions
189:  */
190: 
191: STATIC void aewalk(register elem **pn,register vec_t ae)
192: {       register vec_t aer;
193:         register unsigned i,op;
194:         register elem *n,*t;
195: 
196:         n = *pn;
197:         assert(n && ae);
198:         //printf("visiting  %d: (",n->Eexp); WReqn(*pn); dbg_printf(")\n");
199:         //chkvecdim(exptop);
200:         op = n->Eoper;
201:         if (n->Eexp)                            // if an AE
202:         {   // Try to find an equivalent AE, and point to it instead
203:             assert(expnod[n->Eexp] == n);
204:             if (aetype == AEcse)
205:             {
206:                 foreach (i,exptop,ae)
207:                 {   elem *e = expnod[i];
208: 
209:                     // Attempt to replace n with e
210:                     if (e == NULL)              // if elem no longer exists
211:                         vec_clearbit(i,ae);     // it's not available
212:                     else if (n != e &&
213:                         el_match(n,e) &&
214:                         e->Ecount < 0xFF-1 &&   // must fit in unsigned char
215:                         cse_float(n)
216:                         )
217:                     {
218:                         *pn = e;                // replace n with e
219:                         //dbg_printf("cse: %p (",n); WReqn(*pn); dbg_printf(")\n");
220:                         e->Ecount++;
221: #ifdef DEBUG
222:                         assert(e->Ecount != 0);
223: #endif
224:                         aeclear(n,ae);
225:                         el_free(n);
226:                         return;
227:                     }
228:                 }
229:             }
230:         }
231:         switch (op)
232:         {   case OPcolon:
233:             case OPcolon2:
234:                 // ae = ae & ael & aer
235:                 // AEs gened by ael and aer are mutually exclusive
236:                 aer = vec_clone(ae);
237:                 aewalk(&(n->E1),ae);
238:                 aewalk(&(n->E2),aer);
239:                 vec_andass(ae,aer);
240:                 vec_free(aer);
241:                 break;
242:             case OPandand:
243:             case OPoror:
244:                 aewalk(&(n->E1),ae);
245:                 /* ae &= aer    */
246:                 aer = vec_clone(ae);
247:                 aewalk(&(n->E2),aer);
248:                 if (!el_noreturn(n->E2))
249:                     vec_andass(ae,aer);
250:                 vec_free(aer);
251:                 break;
252:             case OPnegass:
253:                 t = Elvalue(n);
254:                 if (t->Eoper == OPind)
255:                     aewalk(&(t->E1),ae);
256:                 break;
257:             case OPctor:
258:             case OPdtor:
259:             case OPdctor:
260:                 break;
261:             case OPasm:
262:                 vec_clear(ae);          // kill everything
263:                 return;
264: 
265:             default:
266:                 if (OTbinary(op))
267:                 {       if (ERTOL(n))
268:                         {
269:                             // Don't CSE constants that will turn into
270:                             // an INC or DEC anyway
271:                             if (n->E2->Eoper == OPconst &&
272:                                 n->E2->EV.Vint == 1 &&
273:                                 (op == OPaddass || op == OPminass ||
274:                                  op == OPpostinc || op == OPpostdec)
275:                                )
276:                                 ;
277:                             else
278:                                 aewalk(&(n->E2),ae);
279:                         }
280:                         if (OTassign(op))
281:                         {   t = Elvalue(n);
282:                             if (t->Eoper == OPind)
283:                                 aewalk(&(t->E1),ae);
284:                         }
285:                         else
286:                             aewalk(&(n->E1),ae);
287:                         if (!ERTOL(n))
288:                             aewalk(&(n->E2),ae);
289:                 }
290:                 else if (OTunary(op))
291:                 {   assert(op != OPnegass);
292:                     aewalk(&(n->E1),ae);
293:                 }
294:         }
295: 
296:         if (OTdef(op))
297:         {
298:                 assert(n->Eexp == 0);   // should not be an AE
299:                 /* remove all AEs that could be affected by this def    */
300:                 if (Eunambig(n))        // if unambiguous definition
301:                 {       symbol *s;
302: 
303:                         assert(t->Eoper == OPvar);
304:                         s = t->EV.sp.Vsym;
305:                         if (!(s->Sflags & SFLunambig))
306:                                 vec_subass(ae,starkill);
307:                         foreach (i,exptop,ae)   /* for each ae elem     */
308:                         {       register elem *e = expnod[i];
309: 
310:                                 if (!e) continue;
311:                                 if (OTunary(e->Eoper))
312:                                 {
313:                                         if (vec_testbit(e->E1->Eexp,ae))
314:                                                 continue;
315:                                 }
316:                                 else if (OTbinary(e->Eoper))
317:                                 {
318:                                         if (vec_testbit(e->E1->Eexp,ae) &&
319:                                             vec_testbit(e->E2->Eexp,ae))
320:                                                 continue;
321:                                 }
322:                                 else if (e->Eoper == OPvar)
323:                                 {       if (e->EV.sp.Vsym != s)
324:                                                 continue;
325:                                 }
326:                                 else
327:                                         continue;
328:                                 vec_clearbit(i,ae);
329:                         }
330:                 }
331:                 else                    /* else ambiguous definition    */
332:                 {
333:                     vec_subass(ae,defkill);
334:                     if (OTcalldef(op))
335:                         vec_subass(ae,vptrkill);
336:                 }
337: 
338:                 // GEN the lvalue of an assignment operator
339:                 if (OTassign(op) && !OTpost(op) && t->Eexp)
340:                     vec_setbit(t->Eexp,ae);
341:         }
342:         if (n->Eexp)            // if an AE
343:         {
344:             if (op == OPvptrfptr || op == OPcvptrfptr)
345:                 /* Invalidate all other OPvptrfptrs     */
346:                 vec_subass(ae,vptrkill);
347: 
348:             /*dbg_printf("available: ("); WReqn(n); dbg_printf(")\n");
349:             elem_print(n);*/
350:             vec_setbit(n->Eexp,ae);     /* mark this elem as available  */
351:         }
352: }
353: 
354: /**************************
355:  * Remove a CSE.
356:  * Input:
357:  *      pe      pointer to pointer to CSE
358:  * Output:
359:  *      *pe     new elem to replace the old
360:  * Returns:
361:  *      *pe
362:  */
363: 
364: STATIC elem * delcse(elem **pe)
365: {       elem *e;
366: 
367:         e = el_calloc();
368:         el_copy(e,*pe);
369: #ifdef DEBUG
370:         if (debugc)
371:         {       dbg_printf("deleting unprofitable CSE (");
372:                 WReqn(e);
373:                 dbg_printf(")\n");
374:         }
375: #endif
376:         assert(e->Ecount != 0);
377:         if (EOP(e))
378:         {
379: #if 1 || !TX86
380:                 if (e->E1->Ecount == 0xFF-1)
381:                 {       elem *ereplace;
382:                         ereplace = el_calloc();
383:                         el_copy(ereplace,e->E1);
384:                         e->E1 = ereplace;
385:                         ereplace->Ecount = 0;
386:                 }
387:                 else
388: #endif
389:                 {
390:                     e->E1->Ecount++;
391: #ifdef DEBUG
392:                     assert(e->E1->Ecount != 0);
393: #endif
394:                 }
395:                 if (EBIN(e))
396:                 {
397: #if 1 || !TX86
398:                         if (e->E2->Ecount == 0xFF-1)
399:                         {       elem *ereplace;
400:                                 ereplace = el_calloc();
401:                                 el_copy(ereplace,e->E2);
402:                                 e->E2 = ereplace;
403:                                 ereplace->Ecount = 0;
404:                         }
405:                         else
406: #endif
407:                         {   e->E2->Ecount++;
408: #ifdef DEBUG
409:                             assert(e->E2->Ecount != 0);
410: #endif
411:                         }
412: 
413:                 }
414:         }
415:         --(*pe)->Ecount;
416: #ifdef DEBUG
417:         assert((*pe)->Ecount != 0xFF);
418: #endif
419:         (*pe)->Nflags |= NFLdelcse;     // not generating node
420:         e->Ecount = 0;
421: #if FLOATS_IN_CODE
422:         if (FLT_CODESEG_CELEM(e))
423:             flt_record_const(e);
424: #endif
425:         *pe = e;
426:         return *pe;
427: }
428: 
429: /******************************
430:  * 'Unstick' CSEs that would be unprofitable to do. These are usually
431:  * things like addressing modes, and are usually target-dependent.
432:  */
433: 
434: STATIC void removecses(elem **pe)
435: {       unsigned op;
436:         elem *e;
437: 
438: L1:     e = *pe;
439:         assert(e);
440:         elem_debug(e);
441:         if (e->Nflags & NFLdelcse && e->Ecount)
442:         {
443:             delcse(pe);
444:             goto L1;
445:         }
446:         op = e->Eoper;
447:         if (OTunary(op))
448:         {
449:             if (op == OPind)
450:             {   elem *e1;
451: 
452:                 e1 = e->E1;
453:                 if (e1->Eoper == OPadd &&
454:                     e1->Ecount // == 1
455:                    )
456:                 {
457:                     if (I32)
458:                     {
459:                         e1 = delcse(&e->E1);
460:                         if (e1->E1->Ecount) // == 1)
461:                             delcse(&e1->E1);
462:                         if (e1->E2->Ecount && e1->E2->Eoper != OPind)
463:                             delcse(&e1->E2);
464:                     }
465:                     // Look for *(var + const). The + and the const
466:                     // shouldn't be CSEs.
467:                     else if (e1->E2->Eoper == OPconst &&
468:                         (e1->E1->Eoper == OPvar || (e1->E1->Eoper == OPind && e1->E1->Ety & (mTYconst | mTYimmutable)))
469:                        )
470:                     {
471:                         e1 = delcse(&e->E1);
472:                     }
473:                 }
474: 
475:                 if (I32 && e1->Eoper == OPadd &&
476:                     e1->E1->Eoper == OPadd &&
477:                     e1->E1->E1->Ecount &&
478:                     e1->E1->E1->Eoper == OPshl &&
479:                     e1->E1->E1->E2->Eoper == OPconst &&
480:                     e1->E1->E1->E2->EV.Vuns <= 3
481:                    )
482:                 {
483:                     delcse(&e1->E1->E1);
484:                 }
485: 
486:                 if (I32 && e1->Eoper == OPadd &&
487:                     e1->E1->Eoper == OPadd &&
488:                     e1->E1->Ecount &&
489:                     e1->E1->E1->Eoper == OPshl &&
490:                     e1->E1->E1->E2->Eoper == OPconst &&
491:                     e1->E1->E1->E2->EV.Vuns <= 3
492:                    )
493:                 {
494:                     delcse(&e1->E1);
495:                 }
496: 
497:                 else if (I32 && e1->Eoper == OPadd &&
498:                     e1->E1->Ecount &&
499:                     e1->E1->Eoper == OPshl &&
500:                     e1->E1->E2->Eoper == OPconst &&
501:                     e1->E1->E2->EV.Vuns <= 3
502:                    )
503:                 {
504:                     delcse(&e1->E1);
505:                 }
506: 
507:                 // Remove *e1 where it's a double
508:                 if (e->Ecount &&
509: #if 1
510:                     tyfloating(e->Ety)
511: #else
512:                     // Why not TYfloat? Same issue in cgcs.c
513:                     (tybasic(e->Ety) == TYdouble ||
514:                      tybasic(e->Ety) == TYdouble_alias ||
515:                      tybasic(e->Ety) == TYldouble)
516: #endif
517:                    )
518:                     e = delcse(pe);
519: 
520:             }
521: #if TX86
522:             // This CSE is too easy to regenerate
523:             else if (op == OPushtlng && !I32 && e->Ecount)
524:                 e = delcse(pe);
525: #endif
526:         }
527:         else if (OTbinary(op))
528:         {
529:                 if (e->Ecount > 0 && OTrel(op) && e->Ecount < 4
530: #if TX86
531:                     /* Don't CSE floating stuff if generating   */
532:                     /* inline 8087 code, the code generator     */
533:                     /* can't handle it yet                      */
534:                     && !(tyfloating(e->E1->Ety) && config.inline8087)
535: #endif
536:                    )
537:                         e = delcse(pe);
538:                 removecses(&(e->E2));
539:         }
540:         else /* leaf node */
541:         {
542:                 return;
543:         }
544:         pe = &(e->E1);
545:         goto L1;
546: }
547: 
548: /*****************************************
549:  * Do optimizations based on if we know an expression is
550:  * 0 or !=0, even though we don't know anything else.
551:  */
552: 
553: STATIC void abewalk(elem *n,vec_t ae,vec_t aeval);
554: STATIC void abeboolres(elem *n,vec_t abe,vec_t abeval);
555: STATIC void abefree(elem *e,vec_t abe);
556: STATIC void abeset(elem *n,vec_t abe,vec_t abeval,int flag);
557: 
558: void boolopt()
559: {       unsigned i;
560:         vec_t aevec;
561:         vec_t aevecval;
562: 
563:         cmes("boolopt()\n");
564:         if (!dfo)
565:             compdfo();
566:         flowae();                       /* compute available expressions */
567:         if (exptop <= 1)                /* if no AEs                    */
568:                 return;
569: #if 0
570:         for (i = 0; i < exptop; i++)
571:                 dbg_printf("expnod[%d] = 0x%x\n",i,expnod[i]);
572:         dbg_printf("defkill  "); vec_println(defkill,exptop);
573:         dbg_printf("starkill "); vec_println(starkill,exptop);
574:         dbg_printf("vptrkill "); vec_println(vptrkill,exptop);
575: #endif
576: 
577:         /* Do CSEs across extended basic blocks only. This is because   */
578:         /* the code generator can only track register contents          */
579:         /* properly across extended basic blocks.                       */
580:         aevec = vec_calloc(exptop);
581:         aevecval = vec_calloc(exptop);
582: 
583:         // Mark each expression that we know starts off with a non-zero value
584:         for (i = 0; i < exptop; i++)
585:         {   elem *e = expnod[i];
586: 
587:             if (e)
588:             {   elem_debug(e);
589:                 if (e->Eoper == OPvar && e->EV.sp.Vsym->Sflags & SFLtrue)
590:                 {   vec_setbit(i,aevec);
591:                     vec_setbit(i,aevecval);
592:                 }
593:             }
594:         }
595: 
596:         for (i = 0; i < dfotop; i++)
597:         {       register block *b;
598: 
599:                 b = dfo[i];
warning C6011: Dereferencing NULL pointer 'struct block * * dfo': Lines: 559, 560, 561, 564, 565, 566, 567, 580, 581, 584, 585, 587, 589, 584, 585, 587, 589, 584, 585, 587, 589, 584, 596, 597, 599
600: /* if not first block and (there are more than one */ 601: /* predecessor or the only predecessor is not the */ 602: /* previous block), then zero out the available */ 603: /* expressions. */ 604: if ((i != 0 && 605: (list_block(b->Bpred) != dfo[i - 1] || 606: list_next(b->Bpred) != NULL)) 607: || b->BC == BCasm 608: ) 609: vec_clear(aevec); 610: if (b->Belem) /* if there is an expression */ 611: abewalk(b->Belem,aevec,aevecval); 612: 613: } 614: vec_free(aevec); 615: vec_free(aevecval); 616: } 617: 618: /**************************** 619: * Walk tree, replacing bool expressions that we know 620: * ae = vector of available boolean expressions 621: * aeval = parallel vector of values corresponding to whether bool 622: * value is 1 or 0 623: * n = elem tree to look at 624: */ 625: 626: STATIC void abewalk(elem *n,vec_t ae,vec_t aeval) 627: { vec_t aer,aerval; 628: unsigned i,op; 629: unsigned i1,i2; 630: elem *t; 631: 632: assert(n && ae); 633: elem_debug(n); 634: /*dbg_printf("visiting: ("); WReqn(*pn); dbg_printf("), Eexp = %d\n",n->Eexp);*/ 635: /*chkvecdim(exptop);*/ 636: op = n->Eoper; 637: switch (op) 638: { case OPcolon: 639: case OPcolon2: 640: /* ae = ae & ael & aer */ 641: /* AEs gened by ael and aer are mutually exclusive */ 642: aer = vec_clone(ae); 643: aerval = vec_clone(aeval); 644: abewalk(n->E1,ae,aeval); 645: goto L1; 646: case OPandand: 647: case OPoror: 648: abewalk(n->E1,ae,aeval); 649: abeboolres(n->E1,ae,aeval); 650: /* ae &= aer */ 651: aer = vec_clone(ae); 652: aerval = vec_clone(aeval); 653: abeset(n->E1,aer,aerval,(op == OPandand)); 654: L1: 655: abewalk(n->E2,aer,aerval); 656: if (!el_noreturn(n->E2)) 657: { vec_xorass(aerval,aeval); 658: vec_subass(aer,aerval); 659: vec_andass(ae,aer); 660: } 661: vec_free(aer); 662: vec_free(aerval); 663: break; 664: case OPbool: 665: case OPnot: 666: abewalk(n->E1,ae,aeval); 667: abeboolres(n->E1,ae,aeval); 668: break; 669: case OPnegass: 670: t = Elvalue(n); 671: if (t->Eoper == OPind) 672: abewalk(t->E1,ae,aeval); 673: break; 674: 675: case OPasm: 676: vec_clear(ae); // kill everything 677: return; 678: 679: default: 680: if (OTbinary(op)) 681: { if (ERTOL(n)) 682: abewalk(n->E2,ae,aeval); 683: if (OTassign(op)) 684: { t = Elvalue(n); 685: if (t->Eoper == OPind) 686: abewalk(t->E1,ae,aeval); 687: } 688: else 689: abewalk(n->E1,ae,aeval); 690: if (!ERTOL(n)) 691: abewalk(n->E2,ae,aeval); 692: } 693: else if (OTunary(op)) 694: abewalk(n->E1,ae,aeval); 695: break; 696: } 697: 698: if (OTdef(op)) 699: { assert(n->Eexp == 0); // should not be an AE 700: /* remove all AEs that could be affected by this def */ 701: if (Eunambig(n)) /* if unambiguous definition */ 702: { symbol *s; 703: 704: assert(t->Eoper == OPvar); 705: s = t->EV.sp.Vsym; 706: if (!(s->Sflags & SFLunambig)) 707: vec_subass(ae,starkill); 708: foreach (i,exptop,ae) /* for each ae elem */ 709: { register elem *e = expnod[i]; 710: 711: if (!e) continue; 712: if (OTunary(e->Eoper)) 713: { 714: if (vec_testbit(e->E1->Eexp,ae)) 715: continue; 716: } 717: else if (OTbinary(e->Eoper)) 718: { 719: if (vec_testbit(e->E1->Eexp,ae) && 720: vec_testbit(e->E2->Eexp,ae)) 721: continue; 722: } 723: else if (e->Eoper == OPvar) 724: { if (e->EV.sp.Vsym != s) 725: continue; 726: } 727: else 728: continue; 729: vec_clearbit(i,ae); 730: } 731: } 732: else /* else ambiguous definition */ 733: { 734: vec_subass(ae,defkill); 735: if (OTcalldef(op)) 736: vec_subass(ae,vptrkill); 737: } 738: /* GEN the lvalue of an assignment operator */ 739: #if 1 740: if (op == OPeq && (i1 = t->Eexp) != 0 && (i2 = n->E2->Eexp) != 0) 741: { 742: if (vec_testbit(i2,ae)) 743: { 744: vec_setbit(i1,ae); 745: if (vec_testbit(i2,aeval)) 746: vec_setbit(i1,aeval); 747: else 748: vec_clearbit(i1,aeval); 749: } 750: } 751: #else 752: if ((OTopeq(op) || op == OPeq || op == OPnegass) && n->E1->Eexp) 753: { vec_setbit(t->Eexp,ae); 754: if (n->E1->Eoper == OPbit) 755: vec_setbit(n->E1->Eexp,ae); 756: } 757: #endif 758: } 759: else if (n->Eexp) /* if an AE */ 760: { 761: if (op == OPvptrfptr || op == OPcvptrfptr) 762: /* Invalidate all other OPvptrfptrs */ 763: vec_subass(ae,vptrkill); 764: 765: /*dbg_printf("available: ("); WReqn(n); dbg_printf(")\n"); 766: elem_print(n);*/ 767: // vec_setbit(n->Eexp,ae); /* mark this elem as available */ 768: } 769: } 770: 771: /************************************ 772: * Elem e is to be evaluated for a boolean result. 773: * See if we already know its value. 774: */ 775: 776: STATIC void abeboolres(elem *n,vec_t ae,vec_t aeval) 777: { unsigned i; 778: 779: elem_debug(n); 780: if (n->Eexp) 781: { /* Try to find an equivalent AE, and point to it instead */ 782: assert(expnod[n->Eexp] == n); 783: foreach (i,exptop,ae) 784: { elem *e = expnod[i]; 785: 786: // Attempt to replace n with e 787: //dbg_printf("Looking at expnod[%d] = %p\n",i,e); 788: assert(e); 789: elem_debug(e); 790: if (n != e && el_match(n,e)) 791: { 792: #ifdef DEBUG 793: if (debugc) 794: { dbg_printf("Elem %p: ",n); 795: WReqn(n); 796: dbg_printf(" is replaced by %d\n",vec_testbit(i,aeval) != 0); 797: } 798: #endif 799: abefree(n,ae); 800: n->EV.Vlong = vec_testbit(i,aeval) != 0; 801: n->Eoper = OPconst; 802: n->Ety = TYint; 803: changes++; 804: break; 805: } 806: } 807: } 808: } 809: 810: /**************************** 811: * Remove e from available expressions, and its children. 812: */ 813: 814: STATIC void abefree(elem *e,vec_t ae) 815: { 816: //dbg_printf("abefree %p: "); WReqn(e); dbg_printf("\n"); 817: assert(e->Eexp); 818: vec_clearbit(e->Eexp,ae); 819: expnod[e->Eexp] = NULL; 820: if (EOP(e)) 821: { if (EBIN(e)) 822: { abefree(e->E2,ae); 823: el_free(e->E2); 824: e->E2 = NULL; 825: } 826: abefree(e->E1,ae); 827: el_free(e->E1); 828: e->E1 = NULL; 829: } 830: } 831: 832: /************************************ 833: * Elem e is to be evaluated for a boolean result. 834: * Set its result according to flag. 835: */ 836: 837: STATIC void abeset(elem *e,vec_t ae,vec_t aeval,int flag) 838: { unsigned i; 839: 840: while (1) 841: { 842: i = e->Eexp; 843: if (i && expnod[i]) 844: { 845: //dbg_printf("abeset for expnod[%d] = %p: ",i,e); WReqn(e); dbg_printf("\n"); 846: vec_setbit(i,ae); 847: if (flag) 848: vec_setbit(i,aeval); 849: else 850: vec_clearbit(i,aeval); 851: } 852: switch (e->Eoper) 853: { case OPnot: 854: flag ^= 1; 855: case OPbool: 856: case OPeq: 857: e = e->E1; 858: continue; 859: } 860: break; 861: } 862: } 863: 864: #endif 865: