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