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