* support/Util/SDCCerr.h,
[fw/sdcc] / src / SDCCcse.c
1 /*-------------------------------------------------------------------------
2   SDCCcse.c - source file for Common Subexpressions and other utility
3
4              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25 #include "common.h"
26 #include "newalloc.h"
27
28
29 /*-----------------------------------------------------------------*/
30 /* newCseDef - new cseDef                                          */
31 /*-----------------------------------------------------------------*/
32 cseDef *
33 newCseDef (operand * sym, iCode * ic)
34 {
35   cseDef *cdp;
36
37   assert (sym);
38   cdp = Safe_alloc (sizeof (cseDef));
39
40   cdp->sym = sym;
41   cdp->diCode = ic;
42   cdp->key = sym->key;
43   cdp->ancestors = newBitVect(iCodeKey);
44   cdp->fromGlobal = 0;
45
46   if (ic->op!=IF && ic->op!=JUMPTABLE)
47     {
48       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
49         {
50           bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
51           cdp->fromGlobal |= isOperandGlobal (IC_LEFT (ic));
52         }
53       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
54         {
55           bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
56           cdp->fromGlobal |= isOperandGlobal (IC_RIGHT (ic));
57         }
58     }
59   
60   return cdp;
61 }
62
63 void
64 updateCseDefAncestors(cseDef *cdp, set * cseSet)
65 {
66   cseDef *loop;
67   set *sl;
68   iCode *ic = cdp->diCode;
69   
70   if (ic->op!=IF && ic->op!=JUMPTABLE)
71     {
72       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
73         {
74           bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
75           for (sl = cseSet; sl; sl = sl->next)
76             {
77               loop = sl->item;
78               if (loop->sym->key == IC_LEFT (ic)->key)
79                 {
80                   cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
81                   cdp->fromGlobal |= loop->fromGlobal;
82                   break;
83                 }
84             }
85         }
86       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
87         {
88           bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
89           for (sl = cseSet; sl; sl = sl->next)
90             {
91               loop = sl->item;
92               if (loop->sym->key == IC_RIGHT (ic)->key)
93                 {
94                   cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
95                   cdp->fromGlobal |= loop->fromGlobal;
96                   break;
97                 }
98             }
99         }
100     }
101 }
102
103
104 /*-----------------------------------------------------------------*/
105 /* int isCseDefEqual - two definitions are equal                   */
106 /*-----------------------------------------------------------------*/
107 int 
108 isCseDefEqual (void *vsrc, void *vdest)
109 {
110   cseDef *src = vsrc;
111   cseDef *dest = vdest;
112
113   if (src == dest)
114     return 1;
115
116   return (src->key == dest->key &&
117           src->diCode == dest->diCode);
118
119 }
120
121 /*-----------------------------------------------------------------*/
122 /* pcseDef - in the cseDef                                         */
123 /*-----------------------------------------------------------------*/
124 int 
125 pcseDef (void *item, va_list ap)
126 {
127   cseDef *cdp = item;
128   iCodeTable *icTab;
129
130   (void) ap;
131
132   if (!cdp->sym)
133     fprintf (stdout, "**null op**");
134   printOperand (cdp->sym, stdout);
135   icTab = getTableEntry (cdp->diCode->op);
136   icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
137   return 1;
138 }
139
140 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
141 #ifdef RANGEHUNT
142   printf ("ReplaceOpWithCheaperOp %s with %s: ",
143           IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM",
144           IS_SYMOP(cop) ? OP_SYMBOL(cop)->name : "!SYM");
145   // if op is a register equivalent
146   if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
147     operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
148     if (isOperandEqual(*rop, *op)) {
149       printf ("true");
150       *rop=cop;
151       OP_SYMBOL((*op))->isreqv=0;
152       OP_SYMBOL(cop)->isreqv=1;
153     } else {
154       printf ("false");
155     }
156   }
157   printf ("\n");
158 #endif
159   *op=cop;
160 }
161
162 /*-----------------------------------------------------------------*/
163 /* replaceAllSymBySym - replaces all operands by operand in an     */
164 /*                      instruction chain                          */
165 /*-----------------------------------------------------------------*/
166 void
167 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
168 {
169   iCode *lic;
170
171   for (lic = ic; lic; lic = lic->next)
172     {
173       int siaddr;
174
175       /* do the special cases first */
176       if (lic->op == IFX)
177         {
178           if (IS_SYMOP (to) &&
179               IC_COND (lic)->key == from->key)
180             {
181
182               bitVectUnSetBit (OP_USES (from), lic->key);
183               OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
184               siaddr = IC_COND (lic)->isaddr;
185               IC_COND (lic) = operandFromOperand (to);
186               IC_COND (lic)->isaddr = siaddr;
187
188             }
189           continue;
190         }
191
192       if (lic->op == JUMPTABLE)
193         {
194           if (IS_SYMOP (to) &&
195               IC_JTCOND (lic)->key == from->key)
196             {
197
198               bitVectUnSetBit (OP_USES (from), lic->key);
199               OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
200               siaddr = IC_COND (lic)->isaddr;
201               IC_JTCOND (lic) = operandFromOperand (to);
202               IC_JTCOND (lic)->isaddr = siaddr;
203
204             }
205           continue;
206         }
207
208       if (IS_SYMOP(to) && 
209           IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
210         {
211           /* maintain du chains */
212           if (POINTER_SET (lic))
213             {
214               bitVectUnSetBit (OP_USES (from), lic->key);
215               OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
216
217               /* also check if the "from" was in the non-dominating
218                  pointer sets and replace it with "to" in the bitVector */
219               if (bitVectBitValue (*ndpset, from->key))
220                 {
221                   bitVectUnSetBit (*ndpset, from->key);
222                   bitVectSetBit (*ndpset, to->key);
223                 }
224
225             }
226           else
227             {
228               bitVectUnSetBit (OP_DEFS (from), lic->key);
229               OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
230             }
231           siaddr = IC_RESULT (lic)->isaddr;
232           IC_RESULT (lic) = operandFromOperand (to);
233           IC_RESULT (lic)->isaddr = siaddr;
234         }
235
236       if (IS_SYMOP (to) &&
237           IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
238         {
239           bitVectUnSetBit (OP_USES (from), lic->key);
240           OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
241           siaddr = IC_RIGHT (lic)->isaddr;
242           IC_RIGHT (lic) = operandFromOperand (to);
243           IC_RIGHT (lic)->isaddr = siaddr;
244         }
245
246       if (IS_SYMOP (to) &&
247           IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
248         {
249           bitVectUnSetBit (OP_USES (from), lic->key);
250           OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
251           siaddr = IC_LEFT (lic)->isaddr;
252           IC_LEFT (lic) = operandFromOperand (to);
253           IC_LEFT (lic)->isaddr = siaddr;
254         }
255     }
256 }
257
258 /*-----------------------------------------------------------------*/
259 /* iCodeKeyIs - if the icode keys match then return 1              */
260 /*-----------------------------------------------------------------*/
261 DEFSETFUNC (iCodeKeyIs)
262 {
263   cseDef *cdp = item;
264   V_ARG (int, key);
265
266   if (cdp->diCode->key == key)
267     return 1;
268   else
269     return 0;
270 }
271
272 /*-----------------------------------------------------------------*/
273 /* removeFromInExprs - removes an icode from inexpressions         */
274 /*-----------------------------------------------------------------*/
275 DEFSETFUNC (removeFromInExprs)
276 {
277   eBBlock *ebp = item;
278   V_ARG (iCode *, ic);
279   V_ARG (operand *, from);
280   V_ARG (operand *, to);
281   V_ARG (eBBlock *, cbp);
282
283   if (ebp->visited)
284     return 0;
285
286   ebp->visited = 1;
287   deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
288   if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
289     replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
290
291   applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
292   return 0;
293 }
294
295 /*-----------------------------------------------------------------*/
296 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
297 /*-----------------------------------------------------------------*/
298 static bool 
299 isGlobalInNearSpace (operand * op)
300 {
301   sym_link *type = getSpec (operandType (op));
302   /* this is 8051 specific: optimization
303      suggested by Jean-Louis VERN, with 8051s we have no
304      advantage of putting variables in near space into
305      registers */
306   if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
307       IN_DIRSPACE (SPEC_OCLS (type)))
308     return TRUE;
309   else
310     return FALSE;
311 }
312
313 /*-----------------------------------------------------------------*/
314 /* findCheaperOp - cseBBlock support routine, will check to see if */
315 /*              we have a operand previously defined               */
316 /*-----------------------------------------------------------------*/
317 DEFSETFUNC (findCheaperOp)
318 {
319   cseDef *cdp = item;
320   V_ARG (operand *, cop);
321   V_ARG (operand **, opp);
322   V_ARG (int, checkSign);
323
324   /* if we have already found it */
325   if (*opp)
326     return 1;
327
328   /* not found it yet check if this is the one */
329   /* and this is not the defining one          */
330   if (cop->key == cdp->key)
331     {
332
333       /* do a special check this will help in */
334       /* constant propagation & dead code elim */
335       /* for assignments only                 */
336       if (cdp->diCode->op == '=') {
337         /* if the result is volatile then return result */
338         if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
339           *opp = IC_RESULT (cdp->diCode);
340         else
341           /* if this is a straight assignment and
342              left is a temp then prefer the temporary to the
343              true symbol */
344           if (!POINTER_SET (cdp->diCode) &&
345               IS_ITEMP (IC_RESULT (cdp->diCode)) &&
346               IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
347             *opp = IC_RESULT (cdp->diCode);
348           else {
349             /* if straight assignement && and both
350                are temps then prefer the one that
351                will not need extra space to spil, also
352                take into consideration if right side
353                an induction variable
354             */
355             if (!POINTER_SET (cdp->diCode) &&
356                 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
357                 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
358                 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
359                 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
360                 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
361                   SPIL_LOC (IC_RESULT (cdp->diCode))) ||
362                  (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
363                   SPIL_LOC (IC_RESULT (cdp->diCode)) ==
364                   SPIL_LOC (IC_RIGHT (cdp->diCode)))))
365               *opp = IC_RESULT (cdp->diCode);
366             else
367               *opp = IC_RIGHT (cdp->diCode);
368           }
369       }
370       else
371         *opp = IC_RESULT (cdp->diCode);
372     }
373
374   /* if this is an assign to a temp. then check
375      if the right side is this then return this */
376   if (IS_TRUE_SYMOP (cop) &&
377       cdp->diCode->op == '=' &&
378       !POINTER_SET (cdp->diCode) &&
379       cop->key == IC_RIGHT (cdp->diCode)->key &&
380       !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
381       IS_ITEMP (IC_RESULT (cdp->diCode)))
382     *opp = IC_RESULT (cdp->diCode);
383
384   if ((*opp) &&
385       (isOperandLiteral(*opp) || !checkSign ||
386        (checkSign &&
387         IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
388         (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
389          (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
390       {
391
392       if ((isGlobalInNearSpace (cop) &&
393            !isOperandLiteral (*opp)) ||
394           isOperandVolatile (*opp, FALSE)
395         )
396         {
397           *opp = NULL;
398           return 0;
399         }
400
401       if (cop->key == (*opp)->key)
402         {
403           *opp = NULL;
404           return 0;
405         }
406
407       if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
408         {
409           *opp = operandFromOperand (*opp);
410           (*opp)->isaddr = cop->isaddr;
411         }
412
413       if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
414           SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
415         {
416             // special case: we can make an unsigned char literal
417             // into an int literal with no cost.
418             if (isOperandLiteral(*opp)
419              && SPEC_NOUN(operandType(*opp)) == V_CHAR
420              && SPEC_NOUN(operandType(cop)) == V_INT)
421             {
422                 *opp = operandFromOperand (*opp);
423                 SPEC_NOUN(operandType(*opp)) = V_INT;
424             }
425             else
426             {
427                 // No clue...
428                 *opp = NULL;
429                 return 0;
430             }
431
432         }
433
434       return 1;
435
436     }
437   *opp=NULL;
438   return 0;
439 }
440
441 /*-----------------------------------------------------------------*/
442 /* findPointerSet - finds the right side of a pointer set op       */
443 /*-----------------------------------------------------------------*/
444 DEFSETFUNC (findPointerSet)
445 {
446   cseDef *cdp = item;
447   V_ARG (operand *, op);
448   V_ARG (operand **, opp);
449   V_ARG (operand *, rop);
450
451   if (POINTER_SET (cdp->diCode) &&
452       IC_RESULT (cdp->diCode)->key == op->key &&
453       !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
454       !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
455       getSize (operandType (IC_RIGHT (cdp->diCode))) ==
456       getSize (operandType (rop)))
457     {
458       *opp = IC_RIGHT (cdp->diCode);
459       return 1;
460     }
461
462   return 0;
463 }
464
465 /*-----------------------------------------------------------------*/
466 /* findPrevIc - cseBBlock support function will return the iCode   */
467 /*              which matches the current one                      */
468 /*-----------------------------------------------------------------*/
469 DEFSETFUNC (findPrevIc)
470 {
471   cseDef *cdp = item;
472   V_ARG (iCode *, ic);
473   V_ARG (iCode **, icp);
474
475   /* if already found */
476   if (*icp)
477     return 1;
478
479   /* if the iCodes are the same */
480   if (isiCodeEqual (ic, cdp->diCode) &&
481       isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
482     {
483       *icp = cdp->diCode;
484       return 1;
485     }
486
487   /* if iCodes are not the same */
488   /* see the operands maybe interchanged */
489   if (ic->op == cdp->diCode->op &&
490       (ic->op == '+' || ic->op == '*') &&
491       isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
492       isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
493     {
494       *icp = cdp->diCode;
495       return 1;
496     }
497
498   return 0;
499 }
500
501 /*-------------------------------------------------------------------*/
502 /* ifAssignedFromGlobal - if definition is an assignment from global */
503 /*-------------------------------------------------------------------*/
504 DEFSETFUNC (ifAssignedFromGlobal)
505 {
506   cseDef *cdp = item;
507   iCode *dic=cdp->diCode;
508
509   if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
510     return 1;
511   }
512   return 0;
513 }
514
515 /*-------------------------------------------------------------------*/
516 /* ifFromGlobal - if definition is derived from global               */
517 /*-------------------------------------------------------------------*/
518 DEFSETFUNC (ifFromGlobal)
519 {
520   cseDef *cdp = item;
521   
522   return cdp->fromGlobal;
523 }
524
525 /*-----------------------------------------------------------------*/
526 /* ifDefGlobal - if definition is global                           */
527 /*-----------------------------------------------------------------*/
528 DEFSETFUNC (ifDefGlobal)
529 {
530   cseDef *cdp = item;
531
532   return (isOperandGlobal (cdp->sym));
533 }
534
535 /*-----------------------------------------------------------------*/
536 /* ifAnyGetPointer - if get pointer icode                          */
537 /*-----------------------------------------------------------------*/
538 DEFSETFUNC (ifAnyGetPointer)
539 {
540   cseDef *cdp = item;
541
542   if (cdp->diCode && POINTER_GET (cdp->diCode))
543     return 1;
544   return 0;
545 }
546
547 /*-----------------------------------------------------------------*/
548 /* ifOperandsHave - if any of the operand are the same as this     */
549 /*-----------------------------------------------------------------*/
550 DEFSETFUNC (ifOperandsHave)
551 {
552   cseDef *cdp = item;
553   V_ARG (operand *, op);
554
555   if (bitVectBitValue(cdp->ancestors, op->key))
556     return 1;
557   
558   if (IC_LEFT (cdp->diCode) &&
559       IS_SYMOP (IC_LEFT (cdp->diCode)) &&
560       IC_LEFT (cdp->diCode)->key == op->key)
561     return 1;
562
563   if (IC_RIGHT (cdp->diCode) &&
564       IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
565       IC_RIGHT (cdp->diCode)->key == op->key)
566     return 1;
567
568   /* or if any of the operands are volatile */
569   if (IC_LEFT (cdp->diCode) &&
570       IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
571     return 1;
572
573   if (IC_RIGHT (cdp->diCode) &&
574       IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
575     return 1;
576
577
578   if (IC_RESULT (cdp->diCode) &&
579       IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
580     return 1;
581
582   return 0;
583 }
584
585 /*-----------------------------------------------------------------*/
586 /* ifDefSymIs - if a definition is found in the set                */
587 /*-----------------------------------------------------------------*/
588 int
589 ifDefSymIs (set * cseSet, operand * sym)
590 {
591   cseDef *loop;
592   set *sl;
593
594   if (!sym || !IS_SYMOP (sym))
595     return 0;
596   for (sl = cseSet; sl; sl = sl->next)
597     {
598       loop = sl->item;
599       if (loop->sym->key == sym->key)
600         return 1;
601     }
602   return 0;
603 }
604
605
606 /*-----------------------------------------------------------------*/
607 /* ifDefSymIsX - will return 1 if the symbols match                */
608 /*-----------------------------------------------------------------*/
609 DEFSETFUNC (ifDefSymIsX)
610 {
611   cseDef *cdp = item;
612   V_ARG (operand *, op);
613   int match;
614   
615   if (op && cdp->sym)
616     match = cdp->sym->key == op->key;
617   else
618     match = (isOperandEqual (cdp->sym, op));
619   #if 0
620   if (match)
621     printf("%s ",OP_SYMBOL(cdp->sym)->name);
622   #endif
623   return match;
624 }
625
626
627 /*-----------------------------------------------------------------*/
628 /* ifDiCodeIs - returns truw if diCode is same                     */
629 /*-----------------------------------------------------------------*/
630 int
631 ifDiCodeIs (set * cseSet, iCode * ic)
632 {
633   cseDef *loop;
634   set *sl;
635
636   if (!ic)
637     return 0;
638
639   for (sl = cseSet; sl; sl = sl->next)
640     {
641       loop = sl->item;
642       if (loop->diCode == ic)
643         return 1;
644     }
645   return 0;
646
647 }
648
649 /*-----------------------------------------------------------------*/
650 /* ifPointerGet - returns true if the icode is pointer get sym     */
651 /*-----------------------------------------------------------------*/
652 DEFSETFUNC (ifPointerGet)
653 {
654   cseDef *cdp = item;
655   V_ARG (operand *, op);
656   iCode *dic = cdp->diCode;
657   operand *left = IC_LEFT (cdp->diCode);
658
659   if (POINTER_GET (dic) && left->key == op->key)
660     return 1;
661
662   return 0;
663 }
664
665 /*-----------------------------------------------------------------*/
666 /* ifPointerSet - returns true if the icode is pointer set sym     */
667 /*-----------------------------------------------------------------*/
668 DEFSETFUNC (ifPointerSet)
669 {
670   cseDef *cdp = item;
671   V_ARG (operand *, op);
672
673   if (POINTER_SET (cdp->diCode) &&
674       IC_RESULT (cdp->diCode)->key == op->key)
675     return 1;
676
677   return 0;
678 }
679
680 /*-----------------------------------------------------------------*/
681 /* ifDiCodeIsX - will return 1 if the symbols match                 */
682 /*-----------------------------------------------------------------*/
683 DEFSETFUNC (ifDiCodeIsX)
684 {
685   cseDef *cdp = item;
686   V_ARG (iCode *, ic);
687
688   return cdp->diCode == ic;
689
690 }
691
692 /*-----------------------------------------------------------------*/
693 /* findBackwardDef - scan backwards to find deinition of operand   */
694 /*-----------------------------------------------------------------*/
695 iCode *findBackwardDef(operand *op,iCode *ic)
696 {
697     iCode *lic;
698
699     for (lic = ic; lic ; lic = lic->prev) {
700         if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
701             return lic;
702     }
703     return NULL;
704 }
705
706 /*-----------------------------------------------------------------*/
707 /* algebraicOpts - does some algebraic optimizations               */
708 /*-----------------------------------------------------------------*/
709 static void
710 algebraicOpts (iCode * ic, eBBlock * ebp)
711 {
712   /* we don't deal with the following iCodes
713      here */
714   if (ic->op == IFX ||
715       ic->op == IPUSH ||
716       ic->op == IPOP ||
717       ic->op == CALL ||
718       ic->op == PCALL ||
719       ic->op == RETURN ||
720       POINTER_GET (ic))
721     return;
722
723   /* if both operands present & ! IFX */
724   /* then if they are both literal we */
725   /* perform the operation right now  */
726   if (IC_RESULT (ic) &&
727       IC_RIGHT (ic) &&
728       IC_LEFT (ic) &&
729       IS_OP_LITERAL (IC_LEFT (ic)) &&
730       IS_OP_LITERAL (IC_RIGHT (ic)))
731     {
732
733       IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
734                                         IC_RIGHT (ic),
735                                         ic->op,
736                                         operandType (IC_RESULT (ic)));
737       ic->op = '=';
738       IC_LEFT (ic) = NULL;
739       SET_RESULT_RIGHT (ic);
740       return;
741
742     }
743   /* if not ifx & only one operand present */
744   if (IC_RESULT (ic) &&
745       IC_LEFT (ic) &&
746       IS_OP_LITERAL (IC_LEFT (ic)) &&
747       !IC_RIGHT (ic))
748     {
749
750       IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
751                                         IC_RIGHT (ic),
752                                         ic->op,
753                                         operandType (IC_RESULT (ic)));
754       ic->op = '=';
755       IC_LEFT (ic) = NULL;
756       SET_RESULT_RIGHT (ic);
757       return;
758     }
759
760
761   /* a special case : or in short a kludgy solution will think
762      about a better solution over a glass of wine someday */
763   if (ic->op == GET_VALUE_AT_ADDRESS)
764     {
765
766       if (IS_ITEMP (IC_RESULT (ic)) &&
767           IS_TRUE_SYMOP (IC_LEFT (ic)))
768         {
769
770           ic->op = '=';
771           IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
772           IC_RIGHT (ic)->isaddr = 0;
773           IC_LEFT (ic) = NULL;
774           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
775           IC_RESULT (ic)->isaddr = 0;
776           setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
777           return;
778         }
779
780       if (IS_ITEMP (IC_LEFT (ic)) &&
781           IS_ITEMP (IC_RESULT (ic)) &&
782 /*      !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
783 /*      !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
784           !IC_LEFT (ic)->isaddr)
785         {
786           ic->op = '=';
787           IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
788           IC_RIGHT (ic)->isaddr = 0;
789           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
790           IC_RESULT (ic)->isaddr = 0;
791           IC_LEFT (ic) = NULL;
792           return;
793         }
794
795     }
796
797
798   /* depending on the operation */
799   switch (ic->op)
800     {
801     case '+':
802       /* if adding the same thing change to left shift by 1 */
803       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
804           !IS_FLOAT (operandType (IC_RESULT (ic))))
805         {
806           ic->op = LEFT_OP;
807           IC_RIGHT (ic) = operandFromLit (1);
808           return;
809         }
810       /* if addition then check if one of them is a zero */
811       /* if yes turn it into assignmnt or cast */
812       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
813           operandLitValue (IC_LEFT (ic)) == 0.0)
814         {
815           if (compareType (operandType (IC_RESULT (ic)),
816                            operandType (IC_RIGHT (ic)))<0)
817             {
818               ic->op = CAST;
819               IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
820             }
821           else
822             {
823               ic->op = '=';
824               IC_LEFT (ic) = NULL;
825             }
826           SET_ISADDR (IC_RESULT (ic), 0);
827           SET_ISADDR (IC_RIGHT (ic), 0);
828           return;
829         }
830       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
831           operandLitValue (IC_RIGHT (ic)) == 0.0)
832         {
833           if (compareType (operandType (IC_RESULT (ic)),
834                            operandType (IC_LEFT (ic)))<0)
835             {
836               ic->op = CAST;
837               IC_RIGHT (ic) = IC_LEFT (ic);
838               IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
839             }
840           else
841             {
842               ic->op = '=';
843               IC_RIGHT (ic) = IC_LEFT (ic);
844               IC_LEFT (ic) = NULL;
845             }
846           SET_ISADDR (IC_RIGHT (ic), 0);
847           SET_ISADDR (IC_RESULT (ic), 0);
848           return;
849         }
850       break;
851     case '-':
852       /* if subtracting the the same thing then zero     */
853       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
854         {
855           ic->op = '=';
856           IC_RIGHT (ic) = operandFromLit (0);
857           IC_LEFT (ic) = NULL;
858           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
859           IC_RESULT (ic)->isaddr = 0;
860           return;
861         }
862
863       /* if subtraction then check if one of the operand */
864       /* is zero then depending on which operand change  */
865       /* to assignment or unary minus                    */
866       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
867           operandLitValue (IC_RIGHT (ic)) == 0.0)
868         {
869           /* right size zero change to assignment */
870           ic->op = '=';
871           IC_RIGHT (ic) = IC_LEFT (ic);
872           IC_LEFT (ic) = NULL;
873           SET_ISADDR (IC_RIGHT (ic), 0);
874           SET_ISADDR (IC_RESULT (ic), 0);
875           return;
876         }
877       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
878           operandLitValue (IC_LEFT (ic)) == 0.0)
879         {
880           /* left zero turn into an unary minus */
881           ic->op = UNARYMINUS;
882           IC_LEFT (ic) = IC_RIGHT (ic);
883           IC_RIGHT (ic) = NULL;
884           return;
885         }
886       break;
887       /* if multiplication then check if either of */
888       /* them is zero then the result is zero      */
889       /* if either of them is one then result is   */
890       /* the other one                             */
891     case '*':
892       if (IS_OP_LITERAL (IC_LEFT (ic)))
893         {
894
895           if (operandLitValue (IC_LEFT (ic)) == 0.0)
896             {
897               ic->op = '=';
898               IC_RIGHT (ic) = IC_LEFT (ic);
899               IC_LEFT (ic) = NULL;
900               SET_RESULT_RIGHT (ic);
901               return;
902             }
903           if (operandLitValue (IC_LEFT (ic)) == 1.0)
904             {
905               /* '*' can have two unsigned chars as operands */
906               /* and an unsigned int as result.              */
907               if (compareType (operandType (IC_RESULT (ic)),
908                                operandType (IC_RIGHT (ic))) == 1)
909                 {
910                   ic->op = '=';
911                   IC_LEFT (ic) = NULL;
912                   SET_RESULT_RIGHT (ic);
913                 }
914               else
915                 {
916                   ic->op = CAST;
917                   IC_LEFT (ic)->type = TYPE;
918                   IC_LEFT (ic)->isLiteral = 0;
919                   setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
920                 }
921               return;
922             }
923         }
924
925       if (IS_OP_LITERAL (IC_RIGHT (ic)))
926         {
927
928           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
929             {
930               ic->op = '=';
931               IC_LEFT (ic) = NULL;
932               SET_RESULT_RIGHT (ic);
933               return;
934             }
935
936           if (operandLitValue (IC_RIGHT (ic)) == 1.0)
937             {
938               /* '*' can have two unsigned chars as operands */
939               /* and an unsigned int as result.              */
940               if (compareType (operandType (IC_RESULT (ic)),
941                                operandType (IC_LEFT (ic))) == 1)
942                 {
943                   ic->op = '=';
944                   IC_RIGHT (ic) = IC_LEFT (ic);
945                   IC_LEFT (ic) = NULL;
946                   SET_RESULT_RIGHT (ic);
947                 }
948               else
949                 {
950                   operand *op;
951
952                   ic->op = CAST;
953                   op = IC_RIGHT (ic);
954                   IC_RIGHT (ic) = IC_LEFT (ic);
955                   IC_LEFT (ic) = op;
956                   IC_LEFT (ic)->type = TYPE;
957                   IC_LEFT (ic)->isLiteral = 0;
958                   setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
959                 }
960               return;
961             }
962         }
963       break;
964     case '/':
965       /* if division by self then 1 */
966       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
967         {
968           ic->op = '=';
969           IC_RIGHT (ic) = operandFromLit (1);
970           IC_LEFT (ic) = NULL;
971           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
972           IC_RESULT (ic)->isaddr = 0;
973           break;
974         }
975       /* if this is a division then check if right */
976       /* is one then change it to an assignment    */
977       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
978           operandLitValue (IC_RIGHT (ic)) == 1.0)
979         {
980
981           ic->op = '=';
982           IC_RIGHT (ic) = IC_LEFT (ic);
983           IC_LEFT (ic) = NULL;
984           SET_RESULT_RIGHT (ic);
985           return;
986         }
987       break;
988       /* if both are the same for an comparison operators */
989     case EQ_OP:
990     case LE_OP:
991     case GE_OP:
992       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
993         {
994           ic->op = '=';
995           IC_RIGHT (ic) = operandFromLit (1);
996           IC_LEFT (ic) = NULL;
997           SET_RESULT_RIGHT (ic);
998         }
999       break;
1000     case NE_OP:
1001     case '>':
1002     case '<':
1003       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1004         {
1005           ic->op = '=';
1006           IC_RIGHT (ic) = operandFromLit (0);
1007           IC_LEFT (ic) = NULL;
1008           SET_RESULT_RIGHT (ic);
1009         }
1010       break;
1011     case CAST:
1012             {
1013                     sym_link *otype = operandType(IC_RIGHT(ic));
1014                     sym_link *ctype = operandType(IC_LEFT(ic));
1015                     /* if this is a cast of a literal value */
1016                     if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1017                         !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
1018                             ic->op = '=';
1019                             IC_RIGHT (ic) =
1020                                     operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
1021                                                                       operandLitValue (IC_RIGHT (ic))));
1022                             IC_LEFT (ic) = NULL;
1023                             SET_ISADDR (IC_RESULT (ic), 0);
1024                     }
1025                     /* if casting to the same */
1026                     if (compareType (operandType (IC_RESULT (ic)),
1027                                      operandType (IC_RIGHT (ic))) == 1) {
1028                             ic->op = '=';
1029                             IC_LEFT (ic) = NULL;
1030                             SET_ISADDR (IC_RESULT (ic), 0);
1031                     }
1032             }
1033             break;
1034     case '!':
1035       if (IS_OP_LITERAL (IC_LEFT (ic)))
1036         {
1037           ic->op = '=';
1038           IC_RIGHT (ic) =
1039             (operandLitValue (IC_LEFT (ic)) == 0 ?
1040              operandFromLit (1) : operandFromLit (0));
1041           IC_LEFT (ic) = NULL;
1042           SET_ISADDR (IC_RESULT (ic), 0);
1043         }
1044       break;
1045     case BITWISEAND:
1046       /* if both operands are equal */
1047       /* if yes turn it into assignment */
1048       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1049         {
1050           if (IS_OP_VOLATILE (IC_LEFT (ic)))
1051             {
1052               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1053               IC_RESULT (newic) = IC_LEFT (ic);
1054               newic->lineno = ic->lineno;
1055               addiCodeToeBBlock (ebp, newic, ic->next);
1056             }
1057           ic->op = '=';
1058           IC_LEFT (ic) = NULL;
1059           SET_RESULT_RIGHT (ic);
1060           return;
1061         }
1062       /* swap literal to right ic */
1063       if (IS_OP_LITERAL (IC_LEFT (ic)))
1064         {
1065           operand *op;
1066
1067           op = IC_LEFT (ic);
1068           IC_LEFT (ic) = IC_RIGHT (ic);
1069           IC_RIGHT (ic) = op;
1070         }
1071       if (IS_OP_LITERAL (IC_RIGHT (ic)))
1072         {
1073           /* if BITWISEAND then check if one of them is a zero */
1074           /* if yes turn it into 0 assignment */
1075           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1076             {
1077               if (IS_OP_VOLATILE (IC_LEFT (ic)))
1078                 {
1079                   iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1080                   IC_RESULT (newic) = IC_LEFT (ic);
1081                   newic->lineno = ic->lineno;
1082                   addiCodeToeBBlock (ebp, newic, ic->next);
1083                 }
1084               ic->op = '=';
1085               IC_LEFT (ic) = NULL;
1086               SET_RESULT_RIGHT (ic);
1087               return;
1088             }
1089           /* if BITWISEAND then check if one of them is 0xff... */
1090           /* if yes turn it into assignment */
1091           {
1092             unsigned val;
1093
1094             switch (getSize (operandType (IC_RIGHT (ic))))
1095               {
1096               case 1:
1097                 val = 0xff;
1098                 break;
1099               case 2:
1100                 val = 0xffff;
1101                 break;
1102               case 4:
1103                 val = 0xffffffff;
1104                 break;
1105               default:
1106                 return;
1107               }
1108             if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1109             {
1110               ic->op = '=';
1111               IC_RIGHT (ic) = IC_LEFT (ic);
1112               IC_LEFT (ic) = NULL;
1113               SET_RESULT_RIGHT (ic);
1114               return;
1115             }
1116           }
1117         }
1118       break;
1119     case '|':
1120       /* if both operands are equal */
1121       /* if yes turn it into assignment */
1122       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1123         {
1124           if (IS_OP_VOLATILE (IC_LEFT (ic)))
1125             {
1126               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1127               IC_RESULT (newic) = IC_LEFT (ic);
1128               newic->lineno = ic->lineno;
1129               addiCodeToeBBlock (ebp, newic, ic->next);
1130             }
1131             ic->op = '=';
1132             IC_LEFT (ic) = NULL;
1133             SET_RESULT_RIGHT (ic);
1134             return;
1135         }
1136       /* swap literal to right ic */
1137       if (IS_OP_LITERAL (IC_LEFT (ic)))
1138         {
1139           operand *op;
1140
1141           op = IC_LEFT (ic);
1142           IC_LEFT (ic) = IC_RIGHT (ic);
1143           IC_RIGHT (ic) = op;
1144         }
1145       if (IS_OP_LITERAL (IC_RIGHT (ic)))
1146         {
1147           /* if BITWISEOR then check if one of them is a zero */
1148           /* if yes turn it into assignment */
1149           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1150             {
1151               ic->op = '=';
1152               IC_RIGHT (ic) = IC_LEFT (ic);
1153               IC_LEFT (ic) = NULL;
1154               SET_RESULT_RIGHT (ic);
1155               return;
1156             }
1157           /* if BITWISEOR then check if one of them is 0xff... */
1158           /* if yes turn it into 0xff... assignment */
1159           {
1160             unsigned val;
1161
1162             switch (getSize (operandType (IC_RIGHT (ic))))
1163               {
1164               case 1:
1165                 val = 0xff;
1166                 break;
1167               case 2:
1168                 val = 0xffff;
1169                 break;
1170               case 4:
1171                 val = 0xffffffff;
1172                 break;
1173               default:
1174                 return;
1175               }
1176             if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1177               {
1178                 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1179                 {
1180                   iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1181                   IC_RESULT (newic) = IC_LEFT (ic);
1182                   newic->lineno = ic->lineno;
1183                   addiCodeToeBBlock (ebp, newic, ic->next);
1184                 }
1185                 ic->op = '=';
1186                 IC_LEFT (ic) = NULL;
1187                 SET_RESULT_RIGHT (ic);
1188                 return;
1189               }
1190           }
1191         }
1192       break;
1193     case '^':
1194       /* if both operands are equal */
1195       /* if yes turn it into 0 assignment */
1196       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1197         {
1198           if (IS_OP_VOLATILE (IC_LEFT (ic)))
1199             {
1200               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1201               IC_RESULT (newic) = IC_LEFT (ic);
1202               newic->lineno = ic->lineno;
1203               addiCodeToeBBlock (ebp, newic, ic->next);
1204
1205               newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1206               IC_RESULT (newic) = IC_LEFT (ic);
1207               newic->lineno = ic->lineno;
1208               addiCodeToeBBlock (ebp, newic, ic->next);
1209             }
1210             ic->op = '=';
1211             IC_RIGHT (ic) = operandFromLit (0);
1212             IC_LEFT (ic) = NULL;
1213             SET_RESULT_RIGHT (ic);
1214             return;
1215         }
1216       /* swap literal to right ic */
1217       if (IS_OP_LITERAL (IC_LEFT (ic)))
1218         {
1219           operand *op;
1220
1221           op = IC_LEFT (ic);
1222           IC_LEFT (ic) = IC_RIGHT (ic);
1223           IC_RIGHT (ic) = op;
1224         }
1225       /* if XOR then check if one of them is a zero */
1226       /* if yes turn it into assignment */
1227       if (IS_OP_LITERAL (IC_RIGHT (ic)))
1228         {
1229           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1230             {
1231               ic->op = '=';
1232               IC_RIGHT (ic) = IC_LEFT (ic);
1233               IC_LEFT (ic) = NULL;
1234               SET_RESULT_RIGHT (ic);
1235               return;
1236             }
1237         }
1238       break;
1239     }
1240
1241   return;
1242 }
1243 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1244 /*-----------------------------------------------------------------*/
1245 /* updateSpillLocation - keeps track of register spill location    */
1246 /*-----------------------------------------------------------------*/
1247 void
1248 updateSpillLocation (iCode * ic, int induction)
1249 {
1250         sym_link *setype;
1251
1252         if (POINTER_SET (ic))
1253                 return;
1254
1255         if (ic->nosupdate)
1256                 return;
1257
1258 #if 0
1259         /* for the form true_symbol := iTempNN */
1260         if (ASSIGN_ITEMP_TO_SYM (ic) && 
1261             !SPIL_LOC (IC_RIGHT (ic))) {
1262
1263                 setype = getSpec (operandType (IC_RESULT (ic)));
1264
1265                 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1266                     !IS_VOLATILE (setype) &&
1267                     !IN_FARSPACE (SPEC_OCLS (setype)) &&
1268                     !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1269                 {
1270                     wassert(IS_SYMOP(IC_RESULT (ic)));
1271                     wassert(IS_SYMOP(IC_RIGHT (ic)));
1272                         SPIL_LOC (IC_RIGHT (ic)) =
1273                                 IC_RESULT (ic)->operand.symOperand;
1274                 }
1275             
1276         }
1277 #endif
1278
1279 #if 0 /* this needs furthur investigation can save a lot of code */
1280         if (ASSIGN_SYM_TO_ITEMP(ic) &&
1281             !SPIL_LOC(IC_RESULT(ic))) {
1282             if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1283                 SPIL_LOC (IC_RESULT (ic)) =
1284                     IC_RIGHT (ic)->operand.symOperand;
1285         }
1286 #endif
1287         if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1288           
1289                 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1290                     !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1291                     OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1292
1293                         setype = getSpec (operandType (IC_RESULT (ic)));
1294               
1295                         if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1296                             !IS_VOLATILE (setype) &&
1297                             !IN_FARSPACE (SPEC_OCLS (setype)) &&
1298                             !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1299
1300                                 SPIL_LOC (IC_RIGHT (ic)) =
1301                                         SPIL_LOC (IC_RESULT (ic));
1302                 }
1303                 /* special case for inductions */
1304                 if (induction && 
1305                     OP_SYMBOL(IC_RIGHT(ic))->isreqv && 
1306                     !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1307                     !SPIL_LOC(IC_RESULT(ic))) {
1308                         SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1309                 }
1310         }
1311 }
1312 /*-----------------------------------------------------------------*/
1313 /* setUsesDef - sets the uses def bitvector for a given operand    */
1314 /*-----------------------------------------------------------------*/
1315 void 
1316 setUsesDefs (operand * op, bitVect * bdefs,
1317              bitVect * idefs, bitVect ** oud)
1318 {
1319   /* compute the definitions alive at this point */
1320   bitVect *adefs = bitVectUnion (bdefs, idefs);
1321
1322   /* of these definitions find the ones that are */
1323   /* for this operand */
1324   adefs = bitVectIntersect (adefs, OP_DEFS (op));
1325
1326   /* these are the definitions that this operand can use */
1327   op->usesDefs = adefs;
1328
1329   /* the out defs is an union */
1330   *oud = bitVectUnion (*oud, adefs);
1331 }
1332
1333 /*-----------------------------------------------------------------*/
1334 /* unsetDefsAndUses - clear this operation for the operands        */
1335 /*-----------------------------------------------------------------*/
1336 void 
1337 unsetDefsAndUses (iCode * ic)
1338 {
1339   if (ic->op == JUMPTABLE)
1340     return;
1341
1342   /* take away this definition from the def chain of the */
1343   /* result & take away from use set of the operands */
1344   if (ic->op != IFX)
1345     {
1346       /* turn off def set */
1347       if (IS_SYMOP (IC_RESULT (ic)))
1348         {
1349           if (!POINTER_SET (ic))
1350             bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1351           else
1352             bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1353         }
1354       /* turn off the useSet for the operands */
1355       if (IS_SYMOP (IC_LEFT (ic)))
1356         bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1357
1358       if (IS_SYMOP (IC_RIGHT (ic)))
1359         bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1360     }
1361   else
1362     /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1363     bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1364 }
1365
1366 /*-----------------------------------------------------------------*/
1367 /* ifxOptimize - changes ifx conditions if it can                  */
1368 /*-----------------------------------------------------------------*/
1369 void 
1370 ifxOptimize (iCode * ic, set * cseSet,
1371              int computeOnly,
1372              eBBlock * ebb, int *change,
1373              eBBlock ** ebbs, int count)
1374 {
1375   operand *pdop;
1376   symbol *label;
1377
1378   /* if the condition can be replaced */
1379   if (!computeOnly)
1380     {
1381       pdop = NULL;
1382       applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1383       if (pdop)
1384         {
1385           ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1386           (*change)++;
1387         }
1388     }
1389
1390   /* if the conditional is a literal then */
1391   if (IS_OP_LITERAL (IC_COND (ic)))
1392     {
1393
1394       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1395         {
1396
1397           /* change to a goto */
1398           ic->op = GOTO;
1399           IC_LABEL (ic) = IC_TRUE (ic);
1400           (*change)++;
1401
1402         }
1403       else
1404         {
1405
1406           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1407             {
1408               ic->op = GOTO;
1409               IC_LABEL (ic) = IC_FALSE (ic);
1410               (*change)++;
1411
1412             }
1413           else
1414             {
1415               /* then kill this if condition */
1416               remiCodeFromeBBlock (ebb, ic);
1417             }
1418         }
1419
1420       /* now we need to recompute the control flow */
1421       /* since the control flow has changed        */
1422       /* this is very expensive but it does not happen */
1423       /* too often, if it does happen then the user pays */
1424       /* the price */
1425       computeControlFlow (ebbs, count, 1);
1426       if (!options.lessPedantic) {
1427         werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1428       }
1429       return;
1430     }
1431
1432   /* if there is only one successor and that successor
1433      is the same one we are conditionally going to then
1434      we can remove this conditional statement */
1435   label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1436   if (elementsInSet (ebb->succList) == 1 &&
1437       isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1438     {
1439
1440       if (!options.lessPedantic) {
1441         werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1442       }
1443       if (IS_OP_VOLATILE (IC_COND (ic)))
1444         {
1445           IC_RIGHT (ic) = IC_COND (ic);
1446           IC_LEFT (ic) = NULL;
1447           IC_RESULT (ic) = NULL;
1448           ic->op = DUMMY_READ_VOLATILE;
1449         }
1450       else
1451         {
1452           remiCodeFromeBBlock (ebb, ic);
1453           computeControlFlow (ebbs, count, 1);
1454           return;
1455         }      
1456     }
1457
1458
1459   /* if it remains an IFX the update the use Set */
1460   if (ic->op == IFX)
1461     {
1462       OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1463       setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1464     }
1465   else if (ic->op == DUMMY_READ_VOLATILE)
1466     {
1467       OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1468       setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1469     }
1470   return;
1471 }
1472
1473 /*-----------------------------------------------------------------*/
1474 /* diCodeForSym - finds the definiting instruction for a symbol    */
1475 /*-----------------------------------------------------------------*/
1476 DEFSETFUNC (diCodeForSym)
1477 {
1478   cseDef *cdp = item;
1479   V_ARG (operand *, sym);
1480   V_ARG (iCode **, dic);
1481
1482   /* if already found */
1483   if (*dic)
1484     return 0;
1485
1486   /* if not if this is the defining iCode */
1487   if (sym->key == cdp->key)
1488     {
1489       *dic = cdp->diCode;
1490       return 1;
1491     }
1492
1493   return 0;
1494 }
1495
1496 /*-----------------------------------------------------------------*/
1497 /* constFold - does some constant folding                          */
1498 /*-----------------------------------------------------------------*/
1499 int 
1500 constFold (iCode * ic, set * cseSet)
1501 {
1502   iCode *dic = NULL;
1503   iCode *ldic = NULL;
1504   /* this routine will change
1505      a = b + 10;
1506      c = a + 10;
1507      to
1508      c = b + 20; */
1509
1510   /* deal with only + & - */
1511   if (ic->op != '+' &&
1512       ic->op != '-')
1513     return 0;
1514
1515   /* this check is a hueristic to prevent live ranges
1516      from becoming too long */
1517   if (IS_PTR (operandType (IC_RESULT (ic))))
1518       return 0;
1519
1520   /* check if operation with a literal */
1521   if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1522     return 0;
1523
1524   /* check if we can find a definition for the
1525      right hand side */
1526   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1527     return 0;
1528
1529   /* check that this is also a +/-  */
1530   if (dic->op != '+' && dic->op != '-')
1531     return 0;
1532
1533   /* with a literal */
1534   if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1535     return 0;
1536
1537   /* find the definition of the left operand
1538      of dic.then check if this defined with a
1539      get_pointer return 0 if the pointer size is
1540      less than 2 (MCS51 specific) */
1541   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1542     return 0;
1543
1544   if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1545     return 0;
1546
1547   /* it is if the operations are the same */
1548   /* the literal parts need to be added  */
1549   IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1550   if (ic->op == dic->op)
1551     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1552                                     operandLitValue (IC_RIGHT (dic)));
1553   else
1554     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1555                                     operandLitValue (IC_RIGHT (dic)));
1556
1557   if (IS_ITEMP (IC_RESULT (ic)))
1558     {
1559       SPIL_LOC (IC_RESULT (ic)) = NULL;
1560       OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1561     }
1562
1563
1564   return 1;
1565 }
1566
1567 /*-----------------------------------------------------------------*/
1568 /* deleteGetPointers - called when a pointer is passed as parm     */
1569 /* will delete from cseSet all get pointers computed from this     */
1570 /* pointer. A simple ifOperandsHave is not good enough here        */
1571 /*-----------------------------------------------------------------*/
1572 static void 
1573 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1574 {
1575   set *compItems = NULL;
1576   cseDef *cdp;
1577   operand *cop;
1578   int changes;
1579
1580   /* easy return */
1581   if (!*cseSet && !*pss)
1582     return;
1583
1584   addSet (&compItems, op);
1585   
1586   /* Recursively find all items computed from this operand .
1587      This done fairly simply go thru the list and find
1588      those that are computed by arthimetic with these
1589      ops */
1590   /* Also check for those computed from our computed
1591      list . This will take care of situations like
1592      iTemp1 = iTemp0 + 8;
1593      iTemp2 = iTemp1 + 8; */
1594   do
1595     {
1596       changes = 0;
1597       for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1598         {
1599           if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1600             {
1601               if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1602                                (insetwithFunc)isOperandEqual) ||
1603                   isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1604                                (insetwithFunc)isOperandEqual))
1605                 {
1606                   if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1607                                     (insetwithFunc)isOperandEqual))
1608                     {
1609                   addSet (&compItems, IC_RESULT (cdp->diCode));
1610                   changes++;
1611                     }
1612                 }
1613             }
1614         }
1615     }
1616   while (changes);
1617   
1618   /* now for the computed items */
1619   for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1620     {
1621       ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1622       deleteItemIf (cseSet, ifPointerGet, cop);
1623       deleteItemIf (cseSet, ifDefSymIsX, cop);
1624       deleteItemIf (pss, ifPointerSet, cop);
1625     }
1626 }
1627
1628 /*-----------------------------------------------------------------*/
1629 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1630 /*                     dfnum > supplied                            */
1631 /*-----------------------------------------------------------------*/
1632 DEFSETFUNC (delGetPointerSucc)
1633 {
1634   eBBlock *ebp = item;
1635   V_ARG (operand *, op);
1636   V_ARG (int, dfnum);
1637
1638   if (ebp->visited)
1639     return 0;
1640
1641   ebp->visited = 1;
1642   if (ebp->dfnum > dfnum)
1643     {
1644       deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1645     }
1646
1647   return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1648 }
1649
1650 /*-----------------------------------------------------------------*/
1651 /* fixUpTypes - KLUGE HACK fixup a lowering problem                */
1652 /*-----------------------------------------------------------------*/
1653 static void
1654 fixUpTypes (iCode * ic)
1655 {
1656   sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1657
1658   /* if (TARGET_IS_DS390) */
1659   if (options.model == MODEL_FLAT24)
1660     {
1661       /* hack-o-matic! */
1662       return;
1663     }
1664
1665   /* for pointer_gets if the types of result & left r the
1666      same then change it type of result to next */
1667   if (IS_PTR (t1) &&
1668       compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1669     {
1670       setOperandType (IC_RESULT (ic), t2->next);
1671     }
1672 }
1673
1674 /*-----------------------------------------------------------------*/
1675 /* isSignedOp - will return 1 if sign is important to operation    */
1676 /*-----------------------------------------------------------------*/
1677 static int isSignedOp (iCode *ic)
1678 {
1679     switch (ic->op) {
1680     case '!':
1681     case '~':
1682     case UNARYMINUS:
1683     case IPUSH:
1684     case IPOP:
1685     case CALL:
1686     case PCALL:
1687     case RETURN:
1688     case '+':
1689     case '-':
1690     case EQ_OP:
1691     case AND_OP:
1692     case OR_OP:
1693     case '^':
1694     case '|':
1695     case BITWISEAND:
1696     case INLINEASM:
1697     case LEFT_OP:
1698     case GET_VALUE_AT_ADDRESS:
1699     case '=':
1700     case IFX:
1701     case RECEIVE:
1702     case SEND:
1703         return 0;
1704     case '*':
1705     case '/':
1706     case '%':
1707     case '>':
1708     case '<':
1709     case LE_OP:
1710     case GE_OP:
1711     case NE_OP:
1712     case RRC:
1713     case RLC:
1714     case GETHBIT:
1715     case RIGHT_OP:
1716     case CAST:
1717     case ARRAYINIT:
1718         return 1;
1719     default:
1720         return 0;
1721     }
1722  }
1723
1724 #if 0
1725 static void
1726 dumpCseSet(set *cseSet)
1727 {
1728   while (cseSet)
1729     {
1730       cseDef *item=cseSet->item;
1731       printf("->");
1732       printOperand (item->sym, NULL);
1733       printf("  ");
1734       piCode (item->diCode, NULL);
1735       cseSet = cseSet->next;
1736     }
1737 }
1738 #endif
1739
1740 /*-----------------------------------------------------------------*/
1741 /* cseBBlock - common subexpression elimination for basic blocks   */
1742 /*             this is the hackiest kludgiest routine in the whole */
1743 /*             system. also the most important, since almost all   */
1744 /*             data flow related information is computed by it     */
1745 /*-----------------------------------------------------------------*/
1746 int
1747 cseBBlock (eBBlock * ebb, int computeOnly,
1748            eBBlock ** ebbs, int count)
1749 {
1750   set *cseSet;
1751   iCode *ic;
1752   int change = 0;
1753   int i;
1754   set *ptrSetSet = NULL;
1755   cseDef *expr;
1756
1757   /* if this block is not reachable */
1758   if (ebb->noPath)
1759     return 0;
1760
1761   /* set of common subexpressions */
1762   cseSet = setFromSet (ebb->inExprs);
1763
1764   /* these will be computed by this routine */
1765   setToNull ((void *) &ebb->outDefs);
1766   setToNull ((void *) &ebb->defSet);
1767   setToNull ((void *) &ebb->usesDefs);
1768   setToNull ((void *) &ebb->ptrsSet);
1769   setToNull ((void *) &ebb->addrOf);
1770   setToNull ((void *) &ebb->ldefs);
1771
1772   ebb->outDefs = bitVectCopy (ebb->inDefs);
1773   bitVectDefault = iCodeKey;
1774   ebb->defSet = newBitVect (iCodeKey);
1775   ebb->usesDefs = newBitVect (iCodeKey);
1776
1777   /* for all the instructions in this block do */
1778   for (ic = ebb->sch; ic; ic = ic->next)
1779     {
1780       iCode *pdic;
1781       operand *pdop;
1782       iCode *defic;
1783       int checkSign ;
1784
1785       ic->eBBlockNum = ebb->bbnum;
1786
1787       if (SKIP_IC2 (ic))
1788         continue;
1789
1790       /* if this is an assignment from true symbol
1791          to a temp then do pointer post inc/dec optimzation */
1792       if (ic->op == '=' && !POINTER_SET (ic) &&
1793           IS_PTR (operandType (IC_RESULT (ic))))
1794         {
1795           ptrPostIncDecOpt (ic);
1796         }        
1797
1798       /* clear the def & use chains for the operands involved */
1799       /* in this operation . since it can change due to opts  */
1800       unsetDefsAndUses (ic);
1801
1802       if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1803         {
1804           /* add to defSet of the symbol */
1805           OP_DEFS(IC_RESULT (ic))=
1806             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1807           /* add to the definition set of this block */
1808           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1809           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1810           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1811           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1812           /* delete global variables from the cseSet
1813              since they can be modified by the function call */
1814           deleteItemIf (&cseSet, ifDefGlobal);
1815
1816           /* and also itemps derived from globals */
1817           deleteItemIf (&cseSet, ifFromGlobal);
1818
1819           /* delete all getpointer iCodes from cseSet, this should
1820              be done only for global arrays & pointers but at this
1821              point we don't know if globals, so to be safe do all */
1822           deleteItemIf (&cseSet, ifAnyGetPointer);
1823           
1824           /* can't cache pointer set/get operations across a call */
1825           deleteSet (&ptrSetSet);
1826         }
1827
1828       /* for pcall & ipush we need to add to the useSet */
1829       if ((ic->op == PCALL ||
1830            ic->op == IPUSH ||
1831            ic->op == IPOP ||
1832            ic->op == SEND) &&
1833           IS_SYMOP (IC_LEFT (ic)))
1834         {
1835
1836           /* check if they can be replaced */
1837           if (!computeOnly)
1838             {
1839               pdop = NULL;
1840               applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1841               if (pdop)
1842                 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1843             }
1844           /* the lookup could have changed it */
1845           if (IS_SYMOP (IC_LEFT (ic)))
1846             {
1847               OP_USES(IC_LEFT (ic))=
1848                 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1849               setUsesDefs (IC_LEFT (ic), ebb->defSet,
1850                            ebb->outDefs, &ebb->usesDefs);
1851             }
1852
1853
1854           /* if we a sending a pointer as a parameter
1855              then kill all cse since the pointed to item
1856              might be changed in the function being called */
1857           if ((ic->op == IPUSH || ic->op == SEND) &&
1858               IS_PTR (operandType (IC_LEFT (ic))))
1859             {
1860               deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1861               ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1862               for (i = 0; i < count; ebbs[i++]->visited = 0);
1863               applyToSet (ebb->succList, delGetPointerSucc,
1864                           IC_LEFT (ic), ebb->dfnum);
1865             }
1866           continue;
1867         }
1868
1869       /* if jumptable then mark the usage */
1870       if (ic->op == JUMPTABLE)
1871         {
1872           if (IS_SYMOP (IC_JTCOND (ic)))
1873             {
1874               OP_USES(IC_JTCOND (ic)) =
1875                 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1876               setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1877                            ebb->outDefs, &ebb->usesDefs);
1878             }
1879           continue;
1880         }
1881
1882       if (SKIP_IC (ic))
1883         continue;
1884
1885       if (!computeOnly) {
1886         /* do some algebraic optimizations if possible */
1887         algebraicOpts (ic, ebb);
1888         while (constFold (ic, cseSet));
1889       }
1890
1891       /* small klugde */
1892       if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1893         {
1894           setOperandType (IC_LEFT (ic),
1895                           aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1896           fixUpTypes (ic);
1897
1898         }
1899       if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1900         {
1901           setOperandType (IC_RESULT (ic),
1902                           aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1903         }
1904
1905       /* if this is a condition statement then */
1906       /* check if the condition can be replaced */
1907       if (ic->op == IFX)
1908         {
1909           ifxOptimize (ic, cseSet, computeOnly,
1910                        ebb, &change,
1911                        ebbs, count);
1912           continue;
1913         }
1914
1915       /* if the assignment & result is a temp */
1916       /* see if we can replace it             */
1917       if (!computeOnly && ic->op == '=')
1918         {
1919
1920           /* update the spill location for this */
1921           updateSpillLocation (ic,0);
1922
1923           if (POINTER_SET (ic) &&
1924               !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1925             {
1926               pdop = NULL;
1927               applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1928               if (pdop && !computeOnly &&
1929                   IS_ITEMP (pdop) && IS_PTR(operandType(pdop)))
1930                 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1931             }
1932         }
1933
1934       checkSign = isSignedOp(ic);
1935
1936       /* do the operand lookup i.e. for both the */
1937       /* right & left operand : check the cseSet */
1938       /* to see if they have been replaced if yes */
1939       /* then replace them with those from cseSet */
1940       /* left operand */
1941       /* and left is a symbol  */
1942       if (IS_SYMOP (IC_LEFT (ic)) &&
1943           !computeOnly && ic->op != ADDRESS_OF)
1944         {
1945
1946           pdop = NULL;
1947           applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1948           if (pdop)
1949             {
1950               if (POINTER_GET (ic))
1951                 {
1952                   if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1953                     {
1954                         /* some non dominating block does POINTER_SET with
1955                            this variable .. unsafe to remove any POINTER_GETs */
1956                         if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1957                             ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1958                         ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1959                       change = 1;
1960                     }
1961                   /* check if there is a pointer set
1962                      for the same pointer visible if yes
1963                      then change this into an assignment */
1964                   pdop = NULL;
1965                   if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1966                       !bitVectBitValue (ebb->ptrsSet, pdop->key))
1967                     {
1968                       ic->op = '=';
1969                       IC_LEFT (ic) = NULL;
1970                       ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1971                       SET_ISADDR (IC_RESULT (ic), 0);
1972                     }
1973
1974                 }
1975               else
1976                 {
1977                   ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1978                   change = 1;
1979                 }
1980             }
1981         }
1982
1983       /*right operand */
1984       if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1985         {
1986
1987           pdop = NULL;
1988           applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1989           if (pdop) {
1990             ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1991             change = 1;
1992           }
1993         }
1994
1995       /* if left or right changed then do algebraic */
1996       if (!computeOnly && change)
1997         {
1998           algebraicOpts (ic, ebb);
1999           while (constFold (ic, cseSet));
2000         }
2001
2002       /* if after all this it becomes an assignment to self
2003          then delete it and continue */
2004       if (ASSIGNMENT_TO_SELF (ic))
2005         {
2006           remiCodeFromeBBlock (ebb, ic);
2007           continue;
2008         }
2009
2010       /* now we will check to see if the entire */
2011       /* operation has been performed before    */
2012       /* and is available                       */
2013       /* don't do assignments they will be killed */
2014       /* by dead code elimination if required  do */
2015       /* it only if result is a temporary         */
2016       pdic = NULL;
2017       if (!(POINTER_GET (ic) &&
2018             (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2019              isOperandVolatile (IC_LEFT (ic), TRUE) ||
2020              bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2021           !ASSIGNMENT (ic) &&
2022           IS_ITEMP (IC_RESULT (ic)) &&
2023           !computeOnly)
2024         {
2025             applyToSet (cseSet, findPrevIc, ic, &pdic);
2026           if (pdic && compareType (operandType (IC_RESULT (pdic)),
2027                                  operandType (IC_RESULT (ic))) != 1)
2028             pdic = NULL;
2029           if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2030               pdic = NULL;
2031         }
2032
2033       /* Alternate code */
2034       if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2035         if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2036           /* Mmm, found an equivalent pointer get at a lower level.
2037              This could be a loop however with the same pointer set
2038              later on */
2039         } else {
2040           /* if previous definition found change this to an assignment */
2041           ic->op = '=';
2042           IC_LEFT(ic) = NULL;
2043           IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2044           SET_ISADDR(IC_RESULT(ic),0);
2045           SET_ISADDR(IC_RIGHT (ic),0);
2046         }
2047       }
2048
2049       if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2050           cseDef *csed;
2051           deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2052           csed = newCseDef (IC_RESULT (ic), ic);
2053           updateCseDefAncestors (csed, cseSet);
2054           addSetHead (&cseSet, csed);
2055       }
2056       defic = ic;
2057
2058       /* if assignment to a parameter which is not
2059          mine and type is a pointer then delete
2060          pointerGets to take care of aliasing */
2061       if (ASSIGNMENT (ic) &&
2062           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2063           IS_PTR (operandType (IC_RESULT (ic))))
2064         {
2065           deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2066           for (i = 0; i < count; ebbs[i++]->visited = 0);
2067           applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2068           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2069         }
2070
2071       /* if this is a pointerget then see if we can replace
2072          this with a previously assigned pointer value */
2073       if (POINTER_GET (ic) &&
2074           !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2075             isOperandVolatile (IC_LEFT (ic), TRUE)))
2076         {
2077           pdop = NULL;
2078           applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2079           /* if we find it then locally replace all
2080              references to the result with what we assigned */
2081           if (pdop)
2082             {
2083               replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2084             }
2085         }
2086
2087       /* delete from the cseSet anything that has */
2088       /* operands matching the result of this     */
2089       /* except in case of pointer access         */
2090       if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2091         {
2092           deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2093           /* delete any previous definitions */
2094           ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2095
2096         }
2097
2098       /* add the left & right to the defUse set */
2099       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2100         {
2101           OP_USES(IC_LEFT (ic))=
2102             bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2103           setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2104
2105         }
2106
2107       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2108         {
2109           OP_USES(IC_RIGHT (ic))=
2110             bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2111           setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2112
2113         }
2114
2115       /* for the result it is special case, put the result */
2116       /* in the defuseSet if it a pointer or array access  */
2117       if (POINTER_SET (defic))
2118         {
2119           OP_USES(IC_RESULT (ic))=
2120             bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2121           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2122           deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2123           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2124           /* delete from inexpressions of all successors which
2125              have dfNum > than this block */
2126           for (i = 0; i < count; ebbs[i++]->visited = 0);
2127           applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2128
2129           /* delete from cseSet all other pointer sets
2130              for this operand */
2131           deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2132           /* add to the local pointerset set */
2133           addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2134         }
2135       else
2136         /* add the result to defintion set */ if (IC_RESULT (ic))
2137         {
2138           OP_DEFS(IC_RESULT (ic))=
2139             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2140           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2141           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2142           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2143         }
2144
2145
2146       /* if this is an addressof instruction then */
2147       /* put the symbol in the address of list &  */
2148       /* delete it from the cseSet                */
2149       if (defic->op == ADDRESS_OF)
2150         {
2151           addSetHead (&ebb->addrOf, IC_LEFT (ic));
2152           deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2153         }
2154     }
2155
2156   for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2157     if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2158         !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2159     addSetHead (&ebb->killedExprs, expr);
2160   }
2161   setToNull ((void *) &ebb->outExprs);
2162   ebb->outExprs = cseSet;
2163   ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2164   ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2165   return change;
2166 }
2167
2168 /*-----------------------------------------------------------------*/
2169 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2170 /*-----------------------------------------------------------------*/
2171 int
2172 cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
2173 {
2174   int i;
2175   int change = 0;
2176
2177   /* if optimization turned off */
2178
2179   for (i = 0; i < count; i++)
2180     change += cseBBlock (ebbs[i], computeOnly, ebbs, count);
2181
2182   return change;
2183 }