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