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