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