* src/SDCCcse.c (algebraicOpts): copy operands before modification
[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) = operandFromOperand (IC_LEFT (ic));
918                   IC_LEFT (ic)->type = TYPE;
919                   IC_LEFT (ic)->isLiteral = 0;
920                   setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
921                 }
922               return;
923             }
924         }
925
926       if (IS_OP_LITERAL (IC_RIGHT (ic)))
927         {
928
929           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
930             {
931               ic->op = '=';
932               IC_LEFT (ic) = NULL;
933               SET_RESULT_RIGHT (ic);
934               return;
935             }
936
937           if (operandLitValue (IC_RIGHT (ic)) == 1.0)
938             {
939               /* '*' can have two unsigned chars as operands */
940               /* and an unsigned int as result.              */
941               if (compareType (operandType (IC_RESULT (ic)),
942                                operandType (IC_LEFT (ic))) == 1)
943                 {
944                   ic->op = '=';
945                   IC_RIGHT (ic) = IC_LEFT (ic);
946                   IC_LEFT (ic) = NULL;
947                   SET_RESULT_RIGHT (ic);
948                 }
949               else
950                 {
951                   operand *op;
952
953                   ic->op = CAST;
954                   op = IC_RIGHT (ic);
955                   IC_RIGHT (ic) = IC_LEFT (ic);
956                   IC_LEFT (ic) = operandFromOperand (op);
957                   IC_LEFT (ic)->type = TYPE;
958                   IC_LEFT (ic)->isLiteral = 0;
959                   setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
960                 }
961               return;
962             }
963         }
964       break;
965     case '/':
966       /* if division by self then 1 */
967       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
968         {
969           ic->op = '=';
970           IC_RIGHT (ic) = operandFromLit (1);
971           IC_LEFT (ic) = NULL;
972           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
973           IC_RESULT (ic)->isaddr = 0;
974           break;
975         }
976       /* if this is a division then check if right */
977       /* is one then change it to an assignment    */
978       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
979           operandLitValue (IC_RIGHT (ic)) == 1.0)
980         {
981
982           ic->op = '=';
983           IC_RIGHT (ic) = IC_LEFT (ic);
984           IC_LEFT (ic) = NULL;
985           SET_RESULT_RIGHT (ic);
986           return;
987         }
988       break;
989       /* if both are the same for an comparison operators */
990     case EQ_OP:
991     case LE_OP:
992     case GE_OP:
993       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
994         {
995           ic->op = '=';
996           IC_RIGHT (ic) = operandFromLit (1);
997           IC_LEFT (ic) = NULL;
998           SET_RESULT_RIGHT (ic);
999         }
1000       break;
1001     case NE_OP:
1002     case '>':
1003     case '<':
1004       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1005         {
1006           ic->op = '=';
1007           IC_RIGHT (ic) = operandFromLit (0);
1008           IC_LEFT (ic) = NULL;
1009           SET_RESULT_RIGHT (ic);
1010         }
1011       break;
1012     case CAST:
1013             {
1014                     sym_link *otype = operandType(IC_RIGHT(ic));
1015                     sym_link *ctype = operandType(IC_LEFT(ic));
1016                     /* if this is a cast of a literal value */
1017                     if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1018                         !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
1019                             ic->op = '=';
1020                             IC_RIGHT (ic) =
1021                                     operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
1022                                                                       operandLitValue (IC_RIGHT (ic))));
1023                             IC_LEFT (ic) = NULL;
1024                             SET_ISADDR (IC_RESULT (ic), 0);
1025                     }
1026                     /* if casting to the same */
1027                     if (compareType (operandType (IC_RESULT (ic)),
1028                                      operandType (IC_RIGHT (ic))) == 1) {
1029                             ic->op = '=';
1030                             IC_LEFT (ic) = NULL;
1031                             SET_ISADDR (IC_RESULT (ic), 0);
1032                     }
1033             }
1034             break;
1035     case '!':
1036       if (IS_OP_LITERAL (IC_LEFT (ic)))
1037         {
1038           ic->op = '=';
1039           IC_RIGHT (ic) =
1040             (operandLitValue (IC_LEFT (ic)) == 0 ?
1041              operandFromLit (1) : operandFromLit (0));
1042           IC_LEFT (ic) = NULL;
1043           SET_ISADDR (IC_RESULT (ic), 0);
1044         }
1045       break;
1046     case BITWISEAND:
1047       /* if both operands are equal */
1048       /* if yes turn it into assignment */
1049       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1050         {
1051           if (IS_OP_VOLATILE (IC_LEFT (ic)))
1052             {
1053               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1054               IC_RESULT (newic) = IC_LEFT (ic);
1055               newic->lineno = ic->lineno;
1056               addiCodeToeBBlock (ebp, newic, ic->next);
1057             }
1058           ic->op = '=';
1059           IC_LEFT (ic) = NULL;
1060           SET_RESULT_RIGHT (ic);
1061           return;
1062         }
1063       /* swap literal to right ic */
1064       if (IS_OP_LITERAL (IC_LEFT (ic)))
1065         {
1066           operand *op;
1067
1068           op = IC_LEFT (ic);
1069           IC_LEFT (ic) = IC_RIGHT (ic);
1070           IC_RIGHT (ic) = op;
1071         }
1072       if (IS_OP_LITERAL (IC_RIGHT (ic)))
1073         {
1074           /* if BITWISEAND then check if one of them is a zero */
1075           /* if yes turn it into 0 assignment */
1076           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1077             {
1078               if (IS_OP_VOLATILE (IC_LEFT (ic)))
1079                 {
1080                   iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1081                   IC_RESULT (newic) = IC_LEFT (ic);
1082                   newic->lineno = ic->lineno;
1083                   addiCodeToeBBlock (ebp, newic, ic->next);
1084                 }
1085               ic->op = '=';
1086               IC_LEFT (ic) = NULL;
1087               SET_RESULT_RIGHT (ic);
1088               return;
1089             }
1090           /* if BITWISEAND then check if one of them is 0xff... */
1091           /* if yes turn it into assignment */
1092           {
1093             unsigned val;
1094
1095             switch (getSize (operandType (IC_RIGHT (ic))))
1096               {
1097               case 1:
1098                 val = 0xff;
1099                 break;
1100               case 2:
1101                 val = 0xffff;
1102                 break;
1103               case 4:
1104                 val = 0xffffffff;
1105                 break;
1106               default:
1107                 return;
1108               }
1109             if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1110             {
1111               ic->op = '=';
1112               IC_RIGHT (ic) = IC_LEFT (ic);
1113               IC_LEFT (ic) = NULL;
1114               SET_RESULT_RIGHT (ic);
1115               return;
1116             }
1117           }
1118         }
1119       break;
1120     case '|':
1121       /* if both operands are equal */
1122       /* if yes turn it into assignment */
1123       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1124         {
1125           if (IS_OP_VOLATILE (IC_LEFT (ic)))
1126             {
1127               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1128               IC_RESULT (newic) = IC_LEFT (ic);
1129               newic->lineno = ic->lineno;
1130               addiCodeToeBBlock (ebp, newic, ic->next);
1131             }
1132             ic->op = '=';
1133             IC_LEFT (ic) = NULL;
1134             SET_RESULT_RIGHT (ic);
1135             return;
1136         }
1137       /* swap literal to right ic */
1138       if (IS_OP_LITERAL (IC_LEFT (ic)))
1139         {
1140           operand *op;
1141
1142           op = IC_LEFT (ic);
1143           IC_LEFT (ic) = IC_RIGHT (ic);
1144           IC_RIGHT (ic) = op;
1145         }
1146       if (IS_OP_LITERAL (IC_RIGHT (ic)))
1147         {
1148           /* if BITWISEOR then check if one of them is a zero */
1149           /* if yes turn it into assignment */
1150           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1151             {
1152               ic->op = '=';
1153               IC_RIGHT (ic) = IC_LEFT (ic);
1154               IC_LEFT (ic) = NULL;
1155               SET_RESULT_RIGHT (ic);
1156               return;
1157             }
1158           /* if BITWISEOR then check if one of them is 0xff... */
1159           /* if yes turn it into 0xff... assignment */
1160           {
1161             unsigned val;
1162
1163             switch (getSize (operandType (IC_RIGHT (ic))))
1164               {
1165               case 1:
1166                 val = 0xff;
1167                 break;
1168               case 2:
1169                 val = 0xffff;
1170                 break;
1171               case 4:
1172                 val = 0xffffffff;
1173                 break;
1174               default:
1175                 return;
1176               }
1177             if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1178               {
1179                 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1180                 {
1181                   iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1182                   IC_RESULT (newic) = IC_LEFT (ic);
1183                   newic->lineno = ic->lineno;
1184                   addiCodeToeBBlock (ebp, newic, ic->next);
1185                 }
1186                 ic->op = '=';
1187                 IC_LEFT (ic) = NULL;
1188                 SET_RESULT_RIGHT (ic);
1189                 return;
1190               }
1191           }
1192         }
1193       break;
1194     case '^':
1195       /* if both operands are equal */
1196       /* if yes turn it into 0 assignment */
1197       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1198         {
1199           if (IS_OP_VOLATILE (IC_LEFT (ic)))
1200             {
1201               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1202               IC_RESULT (newic) = IC_LEFT (ic);
1203               newic->lineno = ic->lineno;
1204               addiCodeToeBBlock (ebp, newic, ic->next);
1205
1206               newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1207               IC_RESULT (newic) = IC_LEFT (ic);
1208               newic->lineno = ic->lineno;
1209               addiCodeToeBBlock (ebp, newic, ic->next);
1210             }
1211             ic->op = '=';
1212             IC_RIGHT (ic) = operandFromLit (0);
1213             IC_LEFT (ic) = NULL;
1214             SET_RESULT_RIGHT (ic);
1215             return;
1216         }
1217       /* swap literal to right ic */
1218       if (IS_OP_LITERAL (IC_LEFT (ic)))
1219         {
1220           operand *op;
1221
1222           op = IC_LEFT (ic);
1223           IC_LEFT (ic) = IC_RIGHT (ic);
1224           IC_RIGHT (ic) = op;
1225         }
1226       /* if XOR then check if one of them is a zero */
1227       /* if yes turn it into assignment */
1228       if (IS_OP_LITERAL (IC_RIGHT (ic)))
1229         {
1230           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1231             {
1232               ic->op = '=';
1233               IC_RIGHT (ic) = IC_LEFT (ic);
1234               IC_LEFT (ic) = NULL;
1235               SET_RESULT_RIGHT (ic);
1236               return;
1237             }
1238         }
1239       break;
1240     }
1241
1242   return;
1243 }
1244 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1245 /*-----------------------------------------------------------------*/
1246 /* updateSpillLocation - keeps track of register spill location    */
1247 /*-----------------------------------------------------------------*/
1248 void
1249 updateSpillLocation (iCode * ic, int induction)
1250 {
1251         sym_link *setype;
1252
1253         if (POINTER_SET (ic))
1254                 return;
1255
1256         if (ic->nosupdate)
1257                 return;
1258
1259 #if 0
1260         /* for the form true_symbol := iTempNN */
1261         if (ASSIGN_ITEMP_TO_SYM (ic) && 
1262             !SPIL_LOC (IC_RIGHT (ic))) {
1263
1264                 setype = getSpec (operandType (IC_RESULT (ic)));
1265
1266                 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1267                     !IS_VOLATILE (setype) &&
1268                     !IN_FARSPACE (SPEC_OCLS (setype)) &&
1269                     !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1270                 {
1271                     wassert(IS_SYMOP(IC_RESULT (ic)));
1272                     wassert(IS_SYMOP(IC_RIGHT (ic)));
1273                         SPIL_LOC (IC_RIGHT (ic)) =
1274                                 IC_RESULT (ic)->operand.symOperand;
1275                 }
1276             
1277         }
1278 #endif
1279
1280 #if 0 /* this needs furthur investigation can save a lot of code */
1281         if (ASSIGN_SYM_TO_ITEMP(ic) &&
1282             !SPIL_LOC(IC_RESULT(ic))) {
1283             if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1284                 SPIL_LOC (IC_RESULT (ic)) =
1285                     IC_RIGHT (ic)->operand.symOperand;
1286         }
1287 #endif
1288         if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1289           
1290                 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1291                     !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1292                     OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1293
1294                         setype = getSpec (operandType (IC_RESULT (ic)));
1295               
1296                         if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1297                             !IS_VOLATILE (setype) &&
1298                             !IN_FARSPACE (SPEC_OCLS (setype)) &&
1299                             !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1300
1301                                 SPIL_LOC (IC_RIGHT (ic)) =
1302                                         SPIL_LOC (IC_RESULT (ic));
1303                 }
1304                 /* special case for inductions */
1305                 if (induction && 
1306                     OP_SYMBOL(IC_RIGHT(ic))->isreqv && 
1307                     !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1308                     !SPIL_LOC(IC_RESULT(ic))) {
1309                         SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1310                 }
1311         }
1312 }
1313 /*-----------------------------------------------------------------*/
1314 /* setUsesDef - sets the uses def bitvector for a given operand    */
1315 /*-----------------------------------------------------------------*/
1316 void 
1317 setUsesDefs (operand * op, bitVect * bdefs,
1318              bitVect * idefs, bitVect ** oud)
1319 {
1320   /* compute the definitions alive at this point */
1321   bitVect *adefs = bitVectUnion (bdefs, idefs);
1322
1323   /* of these definitions find the ones that are */
1324   /* for this operand */
1325   adefs = bitVectIntersect (adefs, OP_DEFS (op));
1326
1327   /* these are the definitions that this operand can use */
1328   op->usesDefs = adefs;
1329
1330   /* the out defs is an union */
1331   *oud = bitVectUnion (*oud, adefs);
1332 }
1333
1334 /*-----------------------------------------------------------------*/
1335 /* unsetDefsAndUses - clear this operation for the operands        */
1336 /*-----------------------------------------------------------------*/
1337 void 
1338 unsetDefsAndUses (iCode * ic)
1339 {
1340   if (ic->op == JUMPTABLE)
1341     return;
1342
1343   /* take away this definition from the def chain of the */
1344   /* result & take away from use set of the operands */
1345   if (ic->op != IFX)
1346     {
1347       /* turn off def set */
1348       if (IS_SYMOP (IC_RESULT (ic)))
1349         {
1350           if (!POINTER_SET (ic))
1351             bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1352           else
1353             bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1354         }
1355       /* turn off the useSet for the operands */
1356       if (IS_SYMOP (IC_LEFT (ic)))
1357         bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1358
1359       if (IS_SYMOP (IC_RIGHT (ic)))
1360         bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1361     }
1362   else
1363     /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1364     bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1365 }
1366
1367 /*-----------------------------------------------------------------*/
1368 /* ifxOptimize - changes ifx conditions if it can                  */
1369 /*-----------------------------------------------------------------*/
1370 void 
1371 ifxOptimize (iCode * ic, set * cseSet,
1372              int computeOnly,
1373              eBBlock * ebb, int *change,
1374              eBBlock ** ebbs, int count)
1375 {
1376   operand *pdop;
1377   symbol *label;
1378
1379   /* if the condition can be replaced */
1380   if (!computeOnly)
1381     {
1382       pdop = NULL;
1383       applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1384       if (pdop)
1385         {
1386           ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1387           (*change)++;
1388         }
1389     }
1390
1391   /* if the conditional is a literal then */
1392   if (IS_OP_LITERAL (IC_COND (ic)))
1393     {
1394
1395       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1396         {
1397
1398           /* change to a goto */
1399           ic->op = GOTO;
1400           IC_LABEL (ic) = IC_TRUE (ic);
1401           (*change)++;
1402
1403         }
1404       else
1405         {
1406
1407           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1408             {
1409               ic->op = GOTO;
1410               IC_LABEL (ic) = IC_FALSE (ic);
1411               (*change)++;
1412
1413             }
1414           else
1415             {
1416               /* then kill this if condition */
1417               remiCodeFromeBBlock (ebb, ic);
1418             }
1419         }
1420
1421       /* now we need to recompute the control flow */
1422       /* since the control flow has changed        */
1423       /* this is very expensive but it does not happen */
1424       /* too often, if it does happen then the user pays */
1425       /* the price */
1426       computeControlFlow (ebbs, count, 1);
1427       if (!options.lessPedantic) {
1428         werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1429       }
1430       return;
1431     }
1432
1433   /* if there is only one successor and that successor
1434      is the same one we are conditionally going to then
1435      we can remove this conditional statement */
1436   label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1437   if (elementsInSet (ebb->succList) == 1 &&
1438       isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1439     {
1440
1441       if (!options.lessPedantic) {
1442         werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1443       }
1444       if (IS_OP_VOLATILE (IC_COND (ic)))
1445         {
1446           IC_RIGHT (ic) = IC_COND (ic);
1447           IC_LEFT (ic) = NULL;
1448           IC_RESULT (ic) = NULL;
1449           ic->op = DUMMY_READ_VOLATILE;
1450         }
1451       else
1452         {
1453           remiCodeFromeBBlock (ebb, ic);
1454           computeControlFlow (ebbs, count, 1);
1455           return;
1456         }      
1457     }
1458
1459
1460   /* if it remains an IFX the update the use Set */
1461   if (ic->op == IFX)
1462     {
1463       OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1464       setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1465     }
1466   else if (ic->op == DUMMY_READ_VOLATILE)
1467     {
1468       OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1469       setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1470     }
1471   return;
1472 }
1473
1474 /*-----------------------------------------------------------------*/
1475 /* diCodeForSym - finds the definiting instruction for a symbol    */
1476 /*-----------------------------------------------------------------*/
1477 DEFSETFUNC (diCodeForSym)
1478 {
1479   cseDef *cdp = item;
1480   V_ARG (operand *, sym);
1481   V_ARG (iCode **, dic);
1482
1483   /* if already found */
1484   if (*dic)
1485     return 0;
1486
1487   /* if not if this is the defining iCode */
1488   if (sym->key == cdp->key)
1489     {
1490       *dic = cdp->diCode;
1491       return 1;
1492     }
1493
1494   return 0;
1495 }
1496
1497 /*-----------------------------------------------------------------*/
1498 /* constFold - does some constant folding                          */
1499 /*-----------------------------------------------------------------*/
1500 int 
1501 constFold (iCode * ic, set * cseSet)
1502 {
1503   iCode *dic = NULL;
1504   iCode *ldic = NULL;
1505   /* this routine will change
1506      a = b + 10;
1507      c = a + 10;
1508      to
1509      c = b + 20; */
1510
1511   /* deal with only + & - */
1512   if (ic->op != '+' &&
1513       ic->op != '-')
1514     return 0;
1515
1516   /* this check is a hueristic to prevent live ranges
1517      from becoming too long */
1518   if (IS_PTR (operandType (IC_RESULT (ic))))
1519       return 0;
1520
1521   /* check if operation with a literal */
1522   if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1523     return 0;
1524
1525   /* check if we can find a definition for the
1526      right hand side */
1527   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1528     return 0;
1529
1530   /* check that this is also a +/-  */
1531   if (dic->op != '+' && dic->op != '-')
1532     return 0;
1533
1534   /* with a literal */
1535   if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1536     return 0;
1537
1538   /* find the definition of the left operand
1539      of dic.then check if this defined with a
1540      get_pointer return 0 if the pointer size is
1541      less than 2 (MCS51 specific) */
1542   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1543     return 0;
1544
1545   if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1546     return 0;
1547
1548   /* it is if the operations are the same */
1549   /* the literal parts need to be added  */
1550   IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1551   if (ic->op == dic->op)
1552     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1553                                     operandLitValue (IC_RIGHT (dic)));
1554   else
1555     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1556                                     operandLitValue (IC_RIGHT (dic)));
1557
1558   if (IS_ITEMP (IC_RESULT (ic)))
1559     {
1560       SPIL_LOC (IC_RESULT (ic)) = NULL;
1561       OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1562     }
1563
1564
1565   return 1;
1566 }
1567
1568 /*-----------------------------------------------------------------*/
1569 /* deleteGetPointers - called when a pointer is passed as parm     */
1570 /* will delete from cseSet all get pointers computed from this     */
1571 /* pointer. A simple ifOperandsHave is not good enough here        */
1572 /*-----------------------------------------------------------------*/
1573 static void 
1574 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1575 {
1576   set *compItems = NULL;
1577   cseDef *cdp;
1578   operand *cop;
1579   int changes;
1580
1581   /* easy return */
1582   if (!*cseSet && !*pss)
1583     return;
1584
1585   addSet (&compItems, op);
1586   
1587   /* Recursively find all items computed from this operand .
1588      This done fairly simply go thru the list and find
1589      those that are computed by arthimetic with these
1590      ops */
1591   /* Also check for those computed from our computed
1592      list . This will take care of situations like
1593      iTemp1 = iTemp0 + 8;
1594      iTemp2 = iTemp1 + 8; */
1595   do
1596     {
1597       changes = 0;
1598       for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1599         {
1600           if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1601             {
1602               if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1603                                (insetwithFunc)isOperandEqual) ||
1604                   isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1605                                (insetwithFunc)isOperandEqual))
1606                 {
1607                   if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1608                                     (insetwithFunc)isOperandEqual))
1609                     {
1610                   addSet (&compItems, IC_RESULT (cdp->diCode));
1611                   changes++;
1612                     }
1613                 }
1614             }
1615         }
1616     }
1617   while (changes);
1618   
1619   /* now for the computed items */
1620   for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1621     {
1622       ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1623       deleteItemIf (cseSet, ifPointerGet, cop);
1624       deleteItemIf (cseSet, ifDefSymIsX, cop);
1625       deleteItemIf (pss, ifPointerSet, cop);
1626     }
1627 }
1628
1629 /*-----------------------------------------------------------------*/
1630 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1631 /*                     dfnum > supplied                            */
1632 /*-----------------------------------------------------------------*/
1633 DEFSETFUNC (delGetPointerSucc)
1634 {
1635   eBBlock *ebp = item;
1636   V_ARG (operand *, op);
1637   V_ARG (int, dfnum);
1638
1639   if (ebp->visited)
1640     return 0;
1641
1642   ebp->visited = 1;
1643   if (ebp->dfnum > dfnum)
1644     {
1645       deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1646     }
1647
1648   return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1649 }
1650
1651 /*-----------------------------------------------------------------*/
1652 /* fixUpTypes - KLUGE HACK fixup a lowering problem                */
1653 /*-----------------------------------------------------------------*/
1654 static void
1655 fixUpTypes (iCode * ic)
1656 {
1657   sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1658
1659   /* if (TARGET_IS_DS390) */
1660   if (options.model == MODEL_FLAT24)
1661     {
1662       /* hack-o-matic! */
1663       return;
1664     }
1665
1666   /* for pointer_gets if the types of result & left r the
1667      same then change it type of result to next */
1668   if (IS_PTR (t1) &&
1669       compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1670     {
1671       setOperandType (IC_RESULT (ic), t2->next);
1672     }
1673 }
1674
1675 /*-----------------------------------------------------------------*/
1676 /* isSignedOp - will return 1 if sign is important to operation    */
1677 /*-----------------------------------------------------------------*/
1678 static int isSignedOp (iCode *ic)
1679 {
1680     switch (ic->op) {
1681     case '!':
1682     case '~':
1683     case UNARYMINUS:
1684     case IPUSH:
1685     case IPOP:
1686     case CALL:
1687     case PCALL:
1688     case RETURN:
1689     case '+':
1690     case '-':
1691     case EQ_OP:
1692     case AND_OP:
1693     case OR_OP:
1694     case '^':
1695     case '|':
1696     case BITWISEAND:
1697     case INLINEASM:
1698     case LEFT_OP:
1699     case GET_VALUE_AT_ADDRESS:
1700     case '=':
1701     case IFX:
1702     case RECEIVE:
1703     case SEND:
1704         return 0;
1705     case '*':
1706     case '/':
1707     case '%':
1708     case '>':
1709     case '<':
1710     case LE_OP:
1711     case GE_OP:
1712     case NE_OP:
1713     case RRC:
1714     case RLC:
1715     case GETHBIT:
1716     case RIGHT_OP:
1717     case CAST:
1718     case ARRAYINIT:
1719         return 1;
1720     default:
1721         return 0;
1722     }
1723  }
1724
1725 #if 0
1726 static void
1727 dumpCseSet(set *cseSet)
1728 {
1729   while (cseSet)
1730     {
1731       cseDef *item=cseSet->item;
1732       printf("->");
1733       printOperand (item->sym, NULL);
1734       printf("  ");
1735       piCode (item->diCode, NULL);
1736       cseSet = cseSet->next;
1737     }
1738 }
1739 #endif
1740
1741 /*-----------------------------------------------------------------*/
1742 /* cseBBlock - common subexpression elimination for basic blocks   */
1743 /*             this is the hackiest kludgiest routine in the whole */
1744 /*             system. also the most important, since almost all   */
1745 /*             data flow related information is computed by it     */
1746 /*-----------------------------------------------------------------*/
1747 int
1748 cseBBlock (eBBlock * ebb, int computeOnly,
1749            eBBlock ** ebbs, int count)
1750 {
1751   set *cseSet;
1752   iCode *ic;
1753   int change = 0;
1754   int i;
1755   set *ptrSetSet = NULL;
1756   cseDef *expr;
1757
1758   /* if this block is not reachable */
1759   if (ebb->noPath)
1760     return 0;
1761
1762   /* set of common subexpressions */
1763   cseSet = setFromSet (ebb->inExprs);
1764
1765   /* these will be computed by this routine */
1766   setToNull ((void *) &ebb->outDefs);
1767   setToNull ((void *) &ebb->defSet);
1768   setToNull ((void *) &ebb->usesDefs);
1769   setToNull ((void *) &ebb->ptrsSet);
1770   setToNull ((void *) &ebb->addrOf);
1771   setToNull ((void *) &ebb->ldefs);
1772
1773   ebb->outDefs = bitVectCopy (ebb->inDefs);
1774   bitVectDefault = iCodeKey;
1775   ebb->defSet = newBitVect (iCodeKey);
1776   ebb->usesDefs = newBitVect (iCodeKey);
1777
1778   /* for all the instructions in this block do */
1779   for (ic = ebb->sch; ic; ic = ic->next)
1780     {
1781       iCode *pdic;
1782       operand *pdop;
1783       iCode *defic;
1784       int checkSign ;
1785
1786       ic->eBBlockNum = ebb->bbnum;
1787
1788       if (SKIP_IC2 (ic))
1789         continue;
1790
1791       /* if this is an assignment from true symbol
1792          to a temp then do pointer post inc/dec optimzation */
1793       if (ic->op == '=' && !POINTER_SET (ic) &&
1794           IS_PTR (operandType (IC_RESULT (ic))))
1795         {
1796           ptrPostIncDecOpt (ic);
1797         }        
1798
1799       /* clear the def & use chains for the operands involved */
1800       /* in this operation . since it can change due to opts  */
1801       unsetDefsAndUses (ic);
1802
1803       if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1804         {
1805           /* add to defSet of the symbol */
1806           OP_DEFS(IC_RESULT (ic))=
1807             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1808           /* add to the definition set of this block */
1809           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1810           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1811           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1812           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1813           /* delete global variables from the cseSet
1814              since they can be modified by the function call */
1815           deleteItemIf (&cseSet, ifDefGlobal);
1816
1817           /* and also itemps derived from globals */
1818           deleteItemIf (&cseSet, ifFromGlobal);
1819
1820           /* delete all getpointer iCodes from cseSet, this should
1821              be done only for global arrays & pointers but at this
1822              point we don't know if globals, so to be safe do all */
1823           deleteItemIf (&cseSet, ifAnyGetPointer);
1824           
1825           /* can't cache pointer set/get operations across a call */
1826           deleteSet (&ptrSetSet);
1827         }
1828
1829       /* for pcall & ipush we need to add to the useSet */
1830       if ((ic->op == PCALL ||
1831            ic->op == IPUSH ||
1832            ic->op == IPOP ||
1833            ic->op == SEND) &&
1834           IS_SYMOP (IC_LEFT (ic)))
1835         {
1836
1837           /* check if they can be replaced */
1838           if (!computeOnly)
1839             {
1840               pdop = NULL;
1841               applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1842               if (pdop)
1843                 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1844             }
1845           /* the lookup could have changed it */
1846           if (IS_SYMOP (IC_LEFT (ic)))
1847             {
1848               OP_USES(IC_LEFT (ic))=
1849                 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1850               setUsesDefs (IC_LEFT (ic), ebb->defSet,
1851                            ebb->outDefs, &ebb->usesDefs);
1852             }
1853
1854
1855           /* if we a sending a pointer as a parameter
1856              then kill all cse since the pointed to item
1857              might be changed in the function being called */
1858           if ((ic->op == IPUSH || ic->op == SEND) &&
1859               IS_PTR (operandType (IC_LEFT (ic))))
1860             {
1861               deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1862               ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1863               for (i = 0; i < count; ebbs[i++]->visited = 0);
1864               applyToSet (ebb->succList, delGetPointerSucc,
1865                           IC_LEFT (ic), ebb->dfnum);
1866             }
1867           continue;
1868         }
1869
1870       /* if jumptable then mark the usage */
1871       if (ic->op == JUMPTABLE)
1872         {
1873           if (IS_SYMOP (IC_JTCOND (ic)))
1874             {
1875               OP_USES(IC_JTCOND (ic)) =
1876                 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1877               setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1878                            ebb->outDefs, &ebb->usesDefs);
1879             }
1880           continue;
1881         }
1882
1883       if (SKIP_IC (ic))
1884         continue;
1885
1886       if (!computeOnly) {
1887         /* do some algebraic optimizations if possible */
1888         algebraicOpts (ic, ebb);
1889         while (constFold (ic, cseSet));
1890       }
1891
1892       /* small klugde */
1893       if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1894         {
1895           setOperandType (IC_LEFT (ic),
1896                           aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1897           fixUpTypes (ic);
1898
1899         }
1900       if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1901         {
1902           setOperandType (IC_RESULT (ic),
1903                           aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1904         }
1905
1906       /* if this is a condition statement then */
1907       /* check if the condition can be replaced */
1908       if (ic->op == IFX)
1909         {
1910           ifxOptimize (ic, cseSet, computeOnly,
1911                        ebb, &change,
1912                        ebbs, count);
1913           continue;
1914         }
1915
1916       /* if the assignment & result is a temp */
1917       /* see if we can replace it             */
1918       if (!computeOnly && ic->op == '=')
1919         {
1920
1921           /* update the spill location for this */
1922           updateSpillLocation (ic,0);
1923
1924           if (POINTER_SET (ic) &&
1925               !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1926             {
1927               pdop = NULL;
1928               applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1929               if (pdop && !computeOnly &&
1930                   IS_ITEMP (pdop) && IS_PTR(operandType(pdop)))
1931                 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1932             }
1933         }
1934
1935       checkSign = isSignedOp(ic);
1936
1937       /* do the operand lookup i.e. for both the */
1938       /* right & left operand : check the cseSet */
1939       /* to see if they have been replaced if yes */
1940       /* then replace them with those from cseSet */
1941       /* left operand */
1942       /* and left is a symbol  */
1943       if (IS_SYMOP (IC_LEFT (ic)) &&
1944           !computeOnly && ic->op != ADDRESS_OF)
1945         {
1946
1947           pdop = NULL;
1948           applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1949           if (pdop)
1950             {
1951               if (POINTER_GET (ic))
1952                 {
1953                   if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1954                     {
1955                         /* some non dominating block does POINTER_SET with
1956                            this variable .. unsafe to remove any POINTER_GETs */
1957                         if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1958                             ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1959                         ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1960                       change = 1;
1961                     }
1962                   /* check if there is a pointer set
1963                      for the same pointer visible if yes
1964                      then change this into an assignment */
1965                   pdop = NULL;
1966                   if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1967                       !bitVectBitValue (ebb->ptrsSet, pdop->key))
1968                     {
1969                       ic->op = '=';
1970                       IC_LEFT (ic) = NULL;
1971                       ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1972                       SET_ISADDR (IC_RESULT (ic), 0);
1973                     }
1974
1975                 }
1976               else
1977                 {
1978                   ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1979                   change = 1;
1980                 }
1981             }
1982         }
1983
1984       /*right operand */
1985       if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1986         {
1987
1988           pdop = NULL;
1989           applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1990           if (pdop) {
1991             ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1992             change = 1;
1993           }
1994         }
1995
1996       /* if left or right changed then do algebraic */
1997       if (!computeOnly && change)
1998         {
1999           algebraicOpts (ic, ebb);
2000           while (constFold (ic, cseSet));
2001         }
2002
2003       /* if after all this it becomes an assignment to self
2004          then delete it and continue */
2005       if (ASSIGNMENT_TO_SELF (ic))
2006         {
2007           remiCodeFromeBBlock (ebb, ic);
2008           continue;
2009         }
2010
2011       /* now we will check to see if the entire */
2012       /* operation has been performed before    */
2013       /* and is available                       */
2014       /* don't do assignments they will be killed */
2015       /* by dead code elimination if required  do */
2016       /* it only if result is a temporary         */
2017       pdic = NULL;
2018       if (!(POINTER_GET (ic) &&
2019             (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2020              isOperandVolatile (IC_LEFT (ic), TRUE) ||
2021              bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2022           !ASSIGNMENT (ic) &&
2023           IS_ITEMP (IC_RESULT (ic)) &&
2024           !computeOnly)
2025         {
2026             applyToSet (cseSet, findPrevIc, ic, &pdic);
2027           if (pdic && compareType (operandType (IC_RESULT (pdic)),
2028                                  operandType (IC_RESULT (ic))) != 1)
2029             pdic = NULL;
2030           if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2031               pdic = NULL;
2032         }
2033
2034       /* Alternate code */
2035       if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2036         if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2037           /* Mmm, found an equivalent pointer get at a lower level.
2038              This could be a loop however with the same pointer set
2039              later on */
2040         } else {
2041           /* if previous definition found change this to an assignment */
2042           ic->op = '=';
2043           IC_LEFT(ic) = NULL;
2044           IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2045           SET_ISADDR(IC_RESULT(ic),0);
2046           SET_ISADDR(IC_RIGHT (ic),0);
2047         }
2048       }
2049
2050       if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2051           cseDef *csed;
2052           deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2053           csed = newCseDef (IC_RESULT (ic), ic);
2054           updateCseDefAncestors (csed, cseSet);
2055           addSetHead (&cseSet, csed);
2056       }
2057       defic = ic;
2058
2059       /* if assignment to a parameter which is not
2060          mine and type is a pointer then delete
2061          pointerGets to take care of aliasing */
2062       if (ASSIGNMENT (ic) &&
2063           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2064           IS_PTR (operandType (IC_RESULT (ic))))
2065         {
2066           deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2067           for (i = 0; i < count; ebbs[i++]->visited = 0);
2068           applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2069           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2070         }
2071
2072       /* if this is a pointerget then see if we can replace
2073          this with a previously assigned pointer value */
2074       if (POINTER_GET (ic) &&
2075           !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2076             isOperandVolatile (IC_LEFT (ic), TRUE)))
2077         {
2078           pdop = NULL;
2079           applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2080           /* if we find it then locally replace all
2081              references to the result with what we assigned */
2082           if (pdop)
2083             {
2084               replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2085             }
2086         }
2087
2088       /* delete from the cseSet anything that has */
2089       /* operands matching the result of this     */
2090       /* except in case of pointer access         */
2091       if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2092         {
2093           deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2094           /* delete any previous definitions */
2095           ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2096
2097         }
2098
2099       /* add the left & right to the defUse set */
2100       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2101         {
2102           OP_USES(IC_LEFT (ic))=
2103             bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2104           setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2105
2106         }
2107
2108       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2109         {
2110           OP_USES(IC_RIGHT (ic))=
2111             bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2112           setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2113
2114         }
2115
2116       /* for the result it is special case, put the result */
2117       /* in the defuseSet if it a pointer or array access  */
2118       if (POINTER_SET (defic))
2119         {
2120           OP_USES(IC_RESULT (ic))=
2121             bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2122           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2123           deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2124           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2125           /* delete from inexpressions of all successors which
2126              have dfNum > than this block */
2127           for (i = 0; i < count; ebbs[i++]->visited = 0);
2128           applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2129
2130           /* delete from cseSet all other pointer sets
2131              for this operand */
2132           deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2133           /* add to the local pointerset set */
2134           addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2135         }
2136       else
2137         /* add the result to defintion set */ if (IC_RESULT (ic))
2138         {
2139           OP_DEFS(IC_RESULT (ic))=
2140             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2141           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2142           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2143           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2144         }
2145
2146
2147       /* if this is an addressof instruction then */
2148       /* put the symbol in the address of list &  */
2149       /* delete it from the cseSet                */
2150       if (defic->op == ADDRESS_OF)
2151         {
2152           addSetHead (&ebb->addrOf, IC_LEFT (ic));
2153           deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2154         }
2155     }
2156
2157   for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2158     if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2159         !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2160     addSetHead (&ebb->killedExprs, expr);
2161   }
2162   setToNull ((void *) &ebb->outExprs);
2163   ebb->outExprs = cseSet;
2164   ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2165   ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2166   return change;
2167 }
2168
2169 /*-----------------------------------------------------------------*/
2170 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2171 /*-----------------------------------------------------------------*/
2172 int
2173 cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
2174 {
2175   int i;
2176   int change = 0;
2177
2178   /* if optimization turned off */
2179
2180   for (i = 0; i < count; i++)
2181     change += cseBBlock (ebbs[i], computeOnly, ebbs, count);
2182
2183   return change;
2184 }