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