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