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