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