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