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