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