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