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