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