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