* src/pic16/device.c (pic16_dump_usection): force udata sections
[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               /* 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             {
1103               ic->op = '=';
1104               IC_RIGHT (ic) = 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)), operandType (IC_RIGHT (ic))) == 1)
1111             {
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       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1489         {
1490           /* change to a goto */
1491           ic->op = GOTO;
1492           IC_LABEL (ic) = IC_TRUE (ic);
1493           (*change)++;
1494         }
1495       else
1496         {
1497           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1498             {
1499               ic->op = GOTO;
1500               IC_LABEL (ic) = IC_FALSE (ic);
1501               (*change)++;
1502             }
1503           else
1504             {
1505               /* then kill this if condition */
1506               remiCodeFromeBBlock (ebb, ic);
1507             }
1508         }
1509
1510       /* now we need to recompute the control flow */
1511       /* since the control flow has changed        */
1512       /* this is very expensive but it does not happen */
1513       /* too often, if it does happen then the user pays */
1514       /* the price */
1515       computeControlFlow (ebbi);
1516       if (!options.lessPedantic)
1517         {
1518           werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1519         }
1520       return;
1521     }
1522
1523   /* if there is only one successor and that successor
1524      is the same one we are conditionally going to then
1525      we can remove this conditional statement */
1526   label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1527   if (elementsInSet (ebb->succList) == 1 &&
1528       isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
1529     {
1530       if (!options.lessPedantic)
1531         {
1532           werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1533         }
1534       if (IS_OP_VOLATILE (IC_COND (ic)))
1535         {
1536           IC_RIGHT (ic) = IC_COND (ic);
1537           IC_LEFT (ic) = NULL;
1538           IC_RESULT (ic) = NULL;
1539           ic->op = DUMMY_READ_VOLATILE;
1540         }
1541       else
1542         {
1543           remiCodeFromeBBlock (ebb, ic);
1544           computeControlFlow (ebbi);
1545           return;
1546         }
1547     }
1548
1549   /* if it remains an IFX then update the use Set */
1550   if (ic->op == IFX)
1551     {
1552       OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1553       setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1554     }
1555   else if (ic->op == DUMMY_READ_VOLATILE)
1556     {
1557       OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1558       setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1559     }
1560   return;
1561 }
1562
1563 /*-----------------------------------------------------------------*/
1564 /* diCodeForSym - finds the definiting instruction for a symbol    */
1565 /*-----------------------------------------------------------------*/
1566 DEFSETFUNC (diCodeForSym)
1567 {
1568   cseDef *cdp = item;
1569   V_ARG (operand *, sym);
1570   V_ARG (iCode **, dic);
1571
1572   /* if already found */
1573   if (*dic)
1574     return 0;
1575
1576   /* if not if this is the defining iCode */
1577   if (sym->key == cdp->key)
1578     {
1579       *dic = cdp->diCode;
1580       return 1;
1581     }
1582
1583   return 0;
1584 }
1585
1586 /*-----------------------------------------------------------------*/
1587 /* constFold - does some constant folding                          */
1588 /*-----------------------------------------------------------------*/
1589 int
1590 constFold (iCode * ic, set * cseSet)
1591 {
1592   iCode *dic = NULL;
1593   iCode *ldic = NULL;
1594   /* this routine will change
1595      a = b + 10;
1596      c = a + 10;
1597      to
1598      c = b + 20; */
1599
1600   /* deal with only + & - */
1601   if (ic->op != '+' &&
1602       ic->op != '-')
1603     return 0;
1604
1605   /* this check is a heuristic to prevent live ranges
1606      from becoming too long */
1607   if (IS_PTR (operandType (IC_RESULT (ic))))
1608       return 0;
1609
1610   /* check if operation with a literal */
1611   if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1612     return 0;
1613
1614   /* check if we can find a definition for the
1615      left hand side */
1616   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1617     return 0;
1618
1619   /* check that this is also a +/-  */
1620   if (dic->op != '+' && dic->op != '-')
1621     return 0;
1622
1623   /* with a literal */
1624   if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1625     return 0;
1626
1627   /* find the definition of the left operand
1628      of dic.then check if this defined with a
1629      get_pointer return 0 if the pointer size is
1630      less than 2 (MCS51 specific) */
1631   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1632     return 0;
1633
1634   if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1635     return 0;
1636
1637   /* it is if the operations are the same */
1638   /* the literal parts need to be added  */
1639   IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1640   if (ic->op == dic->op)
1641     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1642                                     operandLitValue (IC_RIGHT (dic)));
1643   else
1644     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1645                                     operandLitValue (IC_RIGHT (dic)));
1646
1647   if (IS_ITEMP (IC_RESULT (ic)))
1648     {
1649       SPIL_LOC (IC_RESULT (ic)) = NULL;
1650       OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1651     }
1652
1653
1654   return 1;
1655 }
1656
1657 /*-----------------------------------------------------------------*/
1658 /* deleteGetPointers - called when a pointer is passed as parm     */
1659 /* will delete from cseSet all get pointers computed from this     */
1660 /* pointer. A simple ifOperandsHave is not good enough here        */
1661 /*-----------------------------------------------------------------*/
1662 static void
1663 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1664 {
1665   set *compItems = NULL;
1666   cseDef *cdp;
1667   operand *cop;
1668   int changes;
1669
1670   /* easy return */
1671   if (!*cseSet && !*pss)
1672     return;
1673
1674   addSet (&compItems, op);
1675
1676   /* Recursively find all items computed from this operand .
1677      This done fairly simply go thru the list and find
1678      those that are computed by arthimetic with these
1679      ops */
1680   /* Also check for those computed from our computed
1681      list . This will take care of situations like
1682      iTemp1 = iTemp0 + 8;
1683      iTemp2 = iTemp1 + 8; */
1684   do
1685     {
1686       changes = 0;
1687       for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1688         {
1689           if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1690             {
1691               if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1692                                (insetwithFunc)isOperandEqual) ||
1693                   isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1694                                (insetwithFunc)isOperandEqual))
1695                 {
1696                   if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1697                                     (insetwithFunc)isOperandEqual))
1698                     {
1699                   addSet (&compItems, IC_RESULT (cdp->diCode));
1700                   changes++;
1701                     }
1702                 }
1703             }
1704         }
1705     }
1706   while (changes);
1707
1708   /* now for the computed items */
1709   for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1710     {
1711       ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1712       deleteItemIf (cseSet, ifPointerGet, cop);
1713       deleteItemIf (cseSet, ifDefSymIsX, cop);
1714       deleteItemIf (pss, ifPointerSet, cop);
1715     }
1716 }
1717
1718 /*-----------------------------------------------------------------*/
1719 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1720 /*                     dfnum > supplied                            */
1721 /*-----------------------------------------------------------------*/
1722 DEFSETFUNC (delGetPointerSucc)
1723 {
1724   eBBlock *ebp = item;
1725   V_ARG (operand *, op);
1726   V_ARG (int, dfnum);
1727
1728   if (ebp->visited)
1729     return 0;
1730
1731   ebp->visited = 1;
1732   if (ebp->dfnum > dfnum)
1733     {
1734       deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1735     }
1736
1737   return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1738 }
1739
1740 /*-----------------------------------------------------------------*/
1741 /* fixUpTypes - KLUGE HACK fixup a lowering problem                */
1742 /*-----------------------------------------------------------------*/
1743 static void
1744 fixUpTypes (iCode * ic)
1745 {
1746   sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1747
1748   /* if (TARGET_IS_DS390) */
1749   if (options.model == MODEL_FLAT24)
1750     {
1751       /* hack-o-matic! */
1752       return;
1753     }
1754
1755   /* for pointer_gets if the types of result & left r the
1756      same then change it type of result to next */
1757   if (IS_PTR (t1) &&
1758       compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1759     {
1760       setOperandType (IC_RESULT (ic), t2->next);
1761     }
1762 }
1763
1764 /*-----------------------------------------------------------------*/
1765 /* isSignedOp - will return 1 if sign is important to operation    */
1766 /*-----------------------------------------------------------------*/
1767 static int isSignedOp (iCode *ic)
1768 {
1769     switch (ic->op) {
1770     case '!':
1771     case '~':
1772     case UNARYMINUS:
1773     case IPUSH:
1774     case IPOP:
1775     case CALL:
1776     case PCALL:
1777     case RETURN:
1778     case '+':
1779     case '-':
1780     case EQ_OP:
1781     case AND_OP:
1782     case OR_OP:
1783     case '^':
1784     case '|':
1785     case BITWISEAND:
1786     case INLINEASM:
1787     case LEFT_OP:
1788     case GET_VALUE_AT_ADDRESS:
1789     case '=':
1790     case IFX:
1791     case RECEIVE:
1792     case SEND:
1793         return 0;
1794     case '*':
1795     case '/':
1796     case '%':
1797     case '>':
1798     case '<':
1799     case LE_OP:
1800     case GE_OP:
1801     case NE_OP:
1802     case RRC:
1803     case RLC:
1804     case GETHBIT:
1805     case GETABIT:
1806     case GETBYTE:
1807     case GETWORD:
1808     case RIGHT_OP:
1809     case CAST:
1810     case ARRAYINIT:
1811         return 1;
1812     default:
1813         return 0;
1814     }
1815  }
1816
1817 #if 0
1818 static void
1819 dumpCseSet(set *cseSet)
1820 {
1821   while (cseSet)
1822     {
1823       cseDef *item=cseSet->item;
1824       printf("->");
1825       printOperand (item->sym, NULL);
1826       printf("  ");
1827       piCode (item->diCode, NULL);
1828       cseSet = cseSet->next;
1829     }
1830 }
1831 #endif
1832
1833 /*-----------------------------------------------------------------*/
1834 /* cseBBlock - common subexpression elimination for basic blocks   */
1835 /*             this is the hackiest kludgiest routine in the whole */
1836 /*             system. also the most important, since almost all   */
1837 /*             data flow related information is computed by it     */
1838 /*-----------------------------------------------------------------*/
1839 int
1840 cseBBlock (eBBlock * ebb, int computeOnly,
1841            ebbIndex * ebbi)
1842 {
1843   eBBlock ** ebbs = ebbi->bbOrder;
1844   int count = ebbi->count;
1845   set *cseSet;
1846   iCode *ic;
1847   int change = 0;
1848   int i;
1849   set *ptrSetSet = NULL;
1850   cseDef *expr;
1851
1852   /* if this block is not reachable */
1853   if (ebb->noPath)
1854     return 0;
1855
1856   /* set of common subexpressions */
1857   cseSet = setFromSet (ebb->inExprs);
1858
1859   /* these will be computed by this routine */
1860   setToNull ((void *) &ebb->outDefs);
1861   setToNull ((void *) &ebb->defSet);
1862   setToNull ((void *) &ebb->usesDefs);
1863   setToNull ((void *) &ebb->ptrsSet);
1864   setToNull ((void *) &ebb->addrOf);
1865   setToNull ((void *) &ebb->ldefs);
1866
1867   ebb->outDefs = bitVectCopy (ebb->inDefs);
1868   bitVectDefault = iCodeKey;
1869   ebb->defSet = newBitVect (iCodeKey);
1870   ebb->usesDefs = newBitVect (iCodeKey);
1871
1872   /* for all the instructions in this block do */
1873   for (ic = ebb->sch; ic; ic = ic->next)
1874     {
1875       iCode *pdic;
1876       operand *pdop;
1877       iCode *defic;
1878       int checkSign ;
1879
1880       ic->eBBlockNum = ebb->bbnum;
1881
1882       if (SKIP_IC2 (ic))
1883         continue;
1884
1885       /* if this is an assignment from true symbol
1886          to a temp then do pointer post inc/dec optimization */
1887       if (ic->op == '=' && !POINTER_SET (ic) &&
1888           IS_PTR (operandType (IC_RESULT (ic))))
1889         {
1890           ptrPostIncDecOpt (ic);
1891         }
1892
1893       /* clear the def & use chains for the operands involved */
1894       /* in this operation . since it can change due to opts  */
1895       unsetDefsAndUses (ic);
1896
1897       if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1898         {
1899           /* add to defSet of the symbol */
1900           OP_DEFS(IC_RESULT (ic))=
1901             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1902           /* add to the definition set of this block */
1903           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1904           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1905           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1906           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1907           /* delete global variables from the cseSet
1908              since they can be modified by the function call */
1909           deleteItemIf (&cseSet, ifDefGlobal);
1910
1911           /* and also iTemps derived from globals */
1912           deleteItemIf (&cseSet, ifFromGlobal);
1913
1914           /* Delete iTemps derived from symbols whose address */
1915           /* has been taken */
1916           deleteItemIf (&cseSet, ifFromAddrTaken);
1917
1918           /* delete all getpointer iCodes from cseSet, this should
1919              be done only for global arrays & pointers but at this
1920              point we don't know if globals, so to be safe do all */
1921           deleteItemIf (&cseSet, ifAnyGetPointer);
1922
1923           /* can't cache pointer set/get operations across a call */
1924           deleteSet (&ptrSetSet);
1925         }
1926
1927       /* for pcall & ipush we need to add to the useSet */
1928       if ((ic->op == PCALL ||
1929            ic->op == IPUSH ||
1930            ic->op == IPOP ||
1931            ic->op == SEND) &&
1932           IS_SYMOP (IC_LEFT (ic)))
1933         {
1934
1935           /* check if they can be replaced */
1936           if (!computeOnly)
1937             {
1938               pdop = NULL;
1939               applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1940               if (pdop)
1941                 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1942             }
1943           /* the lookup could have changed it */
1944           if (IS_SYMOP (IC_LEFT (ic)))
1945             {
1946               OP_USES(IC_LEFT (ic))=
1947                 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1948               setUsesDefs (IC_LEFT (ic), ebb->defSet,
1949                            ebb->outDefs, &ebb->usesDefs);
1950             }
1951
1952
1953           /* if we a sending a pointer as a parameter
1954              then kill all cse since the pointed to item
1955              might be changed in the function being called */
1956           if ((ic->op == IPUSH || ic->op == SEND) &&
1957               IS_PTR (operandType (IC_LEFT (ic))))
1958             {
1959               deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1960               ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1961               for (i = 0; i < count; ebbs[i++]->visited = 0);
1962               applyToSet (ebb->succList, delGetPointerSucc,
1963                           IC_LEFT (ic), ebb->dfnum);
1964             }
1965           continue;
1966         }
1967
1968       /* if jumptable then mark the usage */
1969       if (ic->op == JUMPTABLE)
1970         {
1971           if (IS_SYMOP (IC_JTCOND (ic)))
1972             {
1973               OP_USES(IC_JTCOND (ic)) =
1974                 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1975               setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1976                            ebb->outDefs, &ebb->usesDefs);
1977             }
1978           continue;
1979         }
1980
1981       if (SKIP_IC (ic))
1982         continue;
1983
1984       if (!computeOnly)
1985         {
1986           /* do some algebraic optimizations if possible */
1987           algebraicOpts (ic, ebb);
1988           while (constFold (ic, cseSet));
1989         }
1990
1991       /* small kludge */
1992       if (POINTER_GET (ic))
1993         {
1994           if (!IS_PTR (operandType (IC_LEFT (ic))))
1995             {
1996               setOperandType (IC_LEFT (ic),
1997                               aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1998               IC_LEFT (ic)->aggr2ptr = 0;
1999               fixUpTypes (ic);
2000             }
2001           else if (IC_LEFT (ic)->aggr2ptr == 1)
2002             {/* band aid for kludge */
2003               setOperandType (IC_LEFT (ic),
2004                               aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
2005               IC_LEFT (ic)->aggr2ptr++;
2006               fixUpTypes (ic);
2007             }
2008         }
2009
2010       if (POINTER_SET (ic))
2011         {
2012           if (!IS_PTR (operandType (IC_RESULT (ic))))
2013             {
2014               setOperandType (IC_RESULT (ic),
2015                               aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2016               IC_RESULT (ic)->aggr2ptr = 0;
2017             }
2018           else if (IC_RESULT (ic)->aggr2ptr == 1)
2019             {/* band aid for kludge */
2020               setOperandType (IC_RESULT (ic),
2021                               aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2022               IC_RESULT (ic)->aggr2ptr++;
2023             }
2024         }
2025
2026       /* if this is a condition statement then */
2027       /* check if the condition can be replaced */
2028       if (ic->op == IFX)
2029         {
2030           ifxOptimize (ic, cseSet, computeOnly,
2031                        ebb, &change,
2032                        ebbi);
2033           continue;
2034         }
2035
2036       /* if the assignment & result is a temp */
2037       /* see if we can replace it             */
2038       if (!computeOnly && ic->op == '=')
2039         {
2040
2041           /* update the spill location for this */
2042           updateSpillLocation (ic,0);
2043
2044           if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)) &&
2045               !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
2046             {
2047               pdop = NULL;
2048               applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
2049               if (pdop && !computeOnly && IS_ITEMP (pdop))
2050                 {
2051                   ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
2052                   if (!IS_PTR (operandType (IC_RESULT (ic))))
2053                     {
2054                       setOperandType (IC_RESULT (ic),
2055                                       aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2056                     }
2057                 }
2058             }
2059         }
2060
2061       checkSign = isSignedOp(ic);
2062
2063       /* do the operand lookup i.e. for both the */
2064       /* right & left operand : check the cseSet */
2065       /* to see if they have been replaced if yes */
2066       /* then replace them with those from cseSet */
2067       /* left operand */
2068       /* and left is a symbol  */
2069       if (IS_SYMOP (IC_LEFT (ic)) &&
2070           !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
2071           !computeOnly && ic->op != ADDRESS_OF)
2072         {
2073
2074           pdop = NULL;
2075           applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2076           if (pdop)
2077             {
2078               if (POINTER_GET (ic))
2079                 {
2080                   if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2081                     {
2082                         /* some non dominating block does POINTER_SET with
2083                            this variable .. unsafe to remove any POINTER_GETs */
2084                         if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
2085                             ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
2086                         ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2087                       change = 1;
2088                     }
2089                   /* check if there is a pointer set
2090                      for the same pointer visible if yes
2091                      then change this into an assignment */
2092                   pdop = NULL;
2093                   if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2094                       !bitVectBitValue (ebb->ptrsSet, pdop->key))
2095                     {
2096                       ic->op = '=';
2097                       IC_LEFT (ic) = NULL;
2098                       ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2099                       SET_ISADDR (IC_RESULT (ic), 0);
2100                     }
2101
2102                 }
2103               else
2104                 {
2105                   ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2106                   change = 1;
2107                 }
2108             }
2109         }
2110
2111       /* right operand */
2112       if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2113         {
2114
2115           pdop = NULL;
2116           applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2117           if (pdop) {
2118             ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2119             change = 1;
2120           }
2121         }
2122
2123       /* if left or right changed then do algebraic */
2124       if (!computeOnly && change)
2125         {
2126           algebraicOpts (ic, ebb);
2127           while (constFold (ic, cseSet));
2128         }
2129
2130       /* if after all this it becomes an assignment to self
2131          then delete it and continue */
2132       if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
2133         {
2134           remiCodeFromeBBlock (ebb, ic);
2135           continue;
2136         }
2137
2138       /* now we will check to see if the entire */
2139       /* operation has been performed before    */
2140       /* and is available                       */
2141       /* don't do assignments they will be killed */
2142       /* by dead code elimination if required  do */
2143       /* it only if result is a temporary         */
2144       pdic = NULL;
2145       if (!(POINTER_GET (ic) &&
2146             (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2147              isOperandVolatile (IC_LEFT (ic), TRUE) ||
2148              bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2149           !ASSIGNMENT (ic) &&
2150           IS_ITEMP (IC_RESULT (ic)) &&
2151           !computeOnly)
2152         {
2153           applyToSet (cseSet, findPrevIc, ic, &pdic);
2154           if (pdic && compareType (operandType (IC_RESULT (pdic)),
2155                                  operandType (IC_RESULT (ic))) != 1)
2156             pdic = NULL;
2157           if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2158               pdic = NULL;
2159         }
2160
2161       /* Alternate code */
2162       if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2163         if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2164           /* Mmm, found an equivalent pointer get at a lower level.
2165              This could be a loop however with the same pointer set
2166              later on */
2167         } else {
2168           /* if previous definition found change this to an assignment */
2169           ic->op = '=';
2170           IC_LEFT(ic) = NULL;
2171           IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2172           SET_ISADDR(IC_RESULT(ic),0);
2173           SET_ISADDR(IC_RIGHT (ic),0);
2174         }
2175       }
2176
2177       if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2178           cseDef *csed;
2179           deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2180           csed = newCseDef (IC_RESULT (ic), ic);
2181           updateCseDefAncestors (csed, cseSet);
2182           addSetHead (&cseSet, csed);
2183       }
2184       defic = ic;
2185
2186       /* if assignment to a parameter which is not
2187          mine and type is a pointer then delete
2188          pointerGets to take care of aliasing */
2189       if (ASSIGNMENT (ic) &&
2190                   IS_SYMOP (IC_RESULT (ic)) &&
2191           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2192           IS_PTR (operandType (IC_RESULT (ic))))
2193         {
2194           deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2195           for (i = 0; i < count; ebbs[i++]->visited = 0);
2196           applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2197           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2198         }
2199
2200       /* if this is a pointerget then see if we can replace
2201          this with a previously assigned pointer value */
2202       if (POINTER_GET (ic) &&
2203           !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2204             isOperandVolatile (IC_LEFT (ic), TRUE)))
2205         {
2206           pdop = NULL;
2207           applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2208           /* if we find it then locally replace all
2209              references to the result with what we assigned */
2210           if (pdop)
2211             {
2212               replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2213             }
2214         }
2215
2216       /* delete from the cseSet anything that has */
2217       /* operands matching the result of this     */
2218       /* except in case of pointer access         */
2219       if (!(POINTER_SET (ic)) && IS_SYMOP (IC_RESULT (ic)))
2220         {
2221           deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2222           /* delete any previous definitions */
2223           ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2224         }
2225
2226       /* add the left & right to the defUse set */
2227       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2228         {
2229           OP_USES(IC_LEFT (ic))=
2230             bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2231           setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2232         }
2233
2234       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2235         {
2236           OP_USES(IC_RIGHT (ic))=
2237             bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2238           setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2239         }
2240
2241       /* for the result it is special case, put the result */
2242       /* in the defuseSet if it a pointer or array access  */
2243       if (POINTER_SET (defic) && IS_SYMOP (IC_RESULT (ic)))
2244         {
2245           OP_USES(IC_RESULT (ic))=
2246             bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2247           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2248           deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2249           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2250           /* delete from inexpressions of all successors which
2251              have dfNum > than this block */
2252           for (i = 0; i < count; ebbs[i++]->visited = 0);
2253           applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2254
2255           /* delete from cseSet all other pointer sets
2256              for this operand */
2257           deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2258           /* add to the local pointerset set */
2259           addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2260         }
2261       else
2262         {
2263           /* add the result to definition set */
2264           if (IS_SYMOP (IC_RESULT (ic)))
2265             {
2266               OP_DEFS(IC_RESULT (ic))=
2267                 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2268               ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2269               ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2270               ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2271             }
2272         }
2273
2274       /* if this is an addressof instruction then */
2275       /* put the symbol in the address of list &  */
2276       /* delete it from the cseSet                */
2277       if (defic->op == ADDRESS_OF)
2278         {
2279           addSetHead (&ebb->addrOf, IC_LEFT (ic));
2280           deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2281         }
2282     }
2283
2284   for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2285     if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2286         !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2287     addSetHead (&ebb->killedExprs, expr);
2288   }
2289   setToNull ((void *) &ebb->outExprs);
2290   ebb->outExprs = cseSet;
2291   ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2292   ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2293   return change;
2294 }
2295
2296 /*-----------------------------------------------------------------*/
2297 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2298 /*-----------------------------------------------------------------*/
2299 int
2300 cseAllBlocks (ebbIndex * ebbi, int computeOnly)
2301 {
2302   eBBlock ** ebbs = ebbi->dfOrder;
2303   int count = ebbi->count;
2304   int i;
2305   int change = 0;
2306
2307   /* if optimization turned off */
2308
2309   for (i = 0; i < count; i++)
2310     change += cseBBlock (ebbs[i], computeOnly, ebbi);
2311
2312   return change;
2313 }