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