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