updateSpillocation did not check for nosupdate flag for inductions
[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) && 
331           !IS_SPEC(OP_SYMBOL(cop)->type)) {
332         // this could be a pointer to some space, so we can not
333         *opp=NULL;
334         return 0;
335       }
336
337       return 1;
338
339     }
340   *opp=NULL;
341   return 0;
342 }
343
344 /*-----------------------------------------------------------------*/
345 /* findPointerSet - finds the right side of a pointer set op       */
346 /*-----------------------------------------------------------------*/
347 DEFSETFUNC (findPointerSet)
348 {
349   cseDef *cdp = item;
350   V_ARG (operand *, op);
351   V_ARG (operand **, opp);
352   V_ARG (operand *, rop);
353
354   if (POINTER_SET (cdp->diCode) &&
355       IC_RESULT (cdp->diCode)->key == op->key &&
356       !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
357       !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
358       getSize (operandType (IC_RIGHT (cdp->diCode))) ==
359       getSize (operandType (rop)))
360     {
361       *opp = IC_RIGHT (cdp->diCode);
362       return 1;
363     }
364
365   return 0;
366 }
367
368 /*-----------------------------------------------------------------*/
369 /* findPrevIc - cseBBlock support function will return the iCode   */
370 /*              which matches the current one                      */
371 /*-----------------------------------------------------------------*/
372 DEFSETFUNC (findPrevIc)
373 {
374   cseDef *cdp = item;
375   V_ARG (iCode *, ic);
376   V_ARG (iCode **, icp);
377
378   /* if already found */
379   if (*icp)
380     return 1;
381
382   /* if the iCodes are the same */
383   if (isiCodeEqual (ic, cdp->diCode) &&
384       isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
385     {
386       *icp = cdp->diCode;
387       return 1;
388     }
389
390   /* if iCodes are not the same */
391   /* see the operands maybe interchanged */
392   if (ic->op == cdp->diCode->op &&
393       (ic->op == '+' || ic->op == '*') &&
394       isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
395       isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
396     {
397       *icp = cdp->diCode;
398       return 1;
399     }
400
401   return 0;
402 }
403
404 /*-----------------------------------------------------------------*/
405 /* ifDefGlobal - if definition is global                           */
406 /*-----------------------------------------------------------------*/
407 DEFSETFUNC (ifDefGlobal)
408 {
409   cseDef *cdp = item;
410
411   return (isOperandGlobal (cdp->sym));
412 }
413
414 /*-----------------------------------------------------------------*/
415 /* ifAnyGetPointer - if get pointer icode                          */
416 /*-----------------------------------------------------------------*/
417 DEFSETFUNC (ifAnyGetPointer)
418 {
419   cseDef *cdp = item;
420
421   if (cdp->diCode && POINTER_GET (cdp->diCode))
422     return 1;
423   return 0;
424 }
425
426 /*-----------------------------------------------------------------*/
427 /* ifOperandsHave - if any of the operand are the same as this     */
428 /*-----------------------------------------------------------------*/
429 DEFSETFUNC (ifOperandsHave)
430 {
431   cseDef *cdp = item;
432   V_ARG (operand *, op);
433
434
435   if (IC_LEFT (cdp->diCode) &&
436       IS_SYMOP (IC_LEFT (cdp->diCode)) &&
437       IC_LEFT (cdp->diCode)->key == op->key)
438     return 1;
439
440   if (IC_RIGHT (cdp->diCode) &&
441       IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
442       IC_RIGHT (cdp->diCode)->key == op->key)
443     return 1;
444
445   /* or if any of the operands are volatile */
446   if (IC_LEFT (cdp->diCode) &&
447       IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
448     return 1;
449
450   if (IC_RIGHT (cdp->diCode) &&
451       IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
452     return 1;
453
454
455   if (IC_RESULT (cdp->diCode) &&
456       IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
457     return 1;
458
459   return 0;
460 }
461
462 /*-----------------------------------------------------------------*/
463 /* ifDefSymIs - if a definition is found in the set                */
464 /*-----------------------------------------------------------------*/
465 int 
466 ifDefSymIs (set * cseSet, operand * sym)
467 {
468   cseDef *loop;
469   set *sl;
470
471   if (!sym || !IS_SYMOP (sym))
472     return 0;
473   for (sl = cseSet; sl; sl = sl->next)
474     {
475       loop = sl->item;
476       if (loop->sym->key == sym->key)
477         return 1;
478     }
479   return 0;
480 }
481
482
483 /*-----------------------------------------------------------------*/
484 /* ifDefSymIsX - will return 1 if the symbols match                */
485 /*-----------------------------------------------------------------*/
486 DEFSETFUNC (ifDefSymIsX)
487 {
488   cseDef *cdp = item;
489   V_ARG (operand *, op);
490
491   if (op && cdp->sym)
492     return cdp->sym->key == op->key;
493   else
494     return (isOperandEqual (cdp->sym, op));
495
496 }
497
498
499 /*-----------------------------------------------------------------*/
500 /* ifDiCodeIs - returns truw if diCode is same                     */
501 /*-----------------------------------------------------------------*/
502 int 
503 ifDiCodeIs (set * cseSet, iCode * ic)
504 {
505   cseDef *loop;
506   set *sl;
507
508   if (!ic)
509     return 0;
510
511   for (sl = cseSet; sl; sl = sl->next)
512     {
513       loop = sl->item;
514       if (loop->diCode == ic)
515         return 1;
516     }
517   return 0;
518
519 }
520
521 /*-----------------------------------------------------------------*/
522 /* ifPointerGet - returns true if the icode is pointer get sym     */
523 /*-----------------------------------------------------------------*/
524 DEFSETFUNC (ifPointerGet)
525 {
526   cseDef *cdp = item;
527   V_ARG (operand *, op);
528   iCode *dic = cdp->diCode;
529   operand *left = IC_LEFT (cdp->diCode);
530
531   if (POINTER_GET (dic) && left->key == op->key)
532     return 1;
533
534   return 0;
535 }
536
537 /*-----------------------------------------------------------------*/
538 /* ifPointerSet - returns true if the icode is pointer set sym     */
539 /*-----------------------------------------------------------------*/
540 DEFSETFUNC (ifPointerSet)
541 {
542   cseDef *cdp = item;
543   V_ARG (operand *, op);
544
545   if (POINTER_SET (cdp->diCode) &&
546       IC_RESULT (cdp->diCode)->key == op->key)
547     return 1;
548
549   return 0;
550 }
551
552 /*-----------------------------------------------------------------*/
553 /* ifDiCodeIsX - will return 1 if the symbols match                 */
554 /*-----------------------------------------------------------------*/
555 DEFSETFUNC (ifDiCodeIsX)
556 {
557   cseDef *cdp = item;
558   V_ARG (iCode *, ic);
559
560   return cdp->diCode == ic;
561
562 }
563
564 /*-----------------------------------------------------------------*/
565 /* algebraicOpts - does some algebraic optimizations               */
566 /*-----------------------------------------------------------------*/
567 void 
568 algebraicOpts (iCode * ic)
569 {
570   /* we don't deal with the following iCodes
571      here */
572   if (ic->op == IFX ||
573       ic->op == IPUSH ||
574       ic->op == IPOP ||
575       ic->op == CALL ||
576       ic->op == PCALL ||
577       ic->op == RETURN ||
578       POINTER_GET (ic))
579     return;
580
581   /* if both operands present & ! IFX */
582   /* then if they are both literal we */
583   /* perform the operation right now  */
584   if (IC_RESULT (ic) &&
585       IC_RIGHT (ic) &&
586       IC_LEFT (ic) &&
587       IS_OP_LITERAL (IC_LEFT (ic)) &&
588       IS_OP_LITERAL (IC_RIGHT (ic)))
589     {
590
591       IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
592                                         IC_RIGHT (ic),
593                                         ic->op,
594                                         operandType (IC_RESULT (ic)));
595       ic->op = '=';
596       IC_LEFT (ic) = NULL;
597       SET_RESULT_RIGHT (ic);
598       return;
599
600     }
601   /* if not ifx & only one operand present */
602   if (IC_RESULT (ic) &&
603       IC_LEFT (ic) &&
604       IS_OP_LITERAL (IC_LEFT (ic)) &&
605       !IC_RIGHT (ic))
606     {
607
608       IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
609                                         IC_RIGHT (ic),
610                                         ic->op,
611                                         operandType (IC_RESULT (ic)));
612       ic->op = '=';
613       IC_LEFT (ic) = NULL;
614       SET_RESULT_RIGHT (ic);
615       return;
616     }
617
618
619   /* a special case : or in short a kludgy solution will think
620      about a better solution over a glass of wine someday */
621   if (ic->op == GET_VALUE_AT_ADDRESS)
622     {
623
624       if (IS_ITEMP (IC_RESULT (ic)) &&
625           IS_TRUE_SYMOP (IC_LEFT (ic)))
626         {
627
628           ic->op = '=';
629           IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
630           IC_RIGHT (ic)->isaddr = 0;
631           IC_LEFT (ic) = NULL;
632           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
633           IC_RESULT (ic)->isaddr = 0;
634           setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
635           return;
636         }
637
638       if (IS_ITEMP (IC_LEFT (ic)) &&
639           IS_ITEMP (IC_RESULT (ic)) &&
640 /*      !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
641 /*      !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
642           !IC_LEFT (ic)->isaddr)
643         {
644           ic->op = '=';
645           IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
646           IC_RIGHT (ic)->isaddr = 0;
647           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
648           IC_RESULT (ic)->isaddr = 0;
649           IC_LEFT (ic) = NULL;
650           return;
651         }
652
653     }
654
655
656   /* depending on the operation */
657   switch (ic->op)
658     {
659     case '+':
660       /* if adding the same thing change to left shift by 1 */
661       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
662           !IS_FLOAT (operandType (IC_RESULT (ic))))
663         {
664           ic->op = LEFT_OP;
665           IC_RIGHT (ic) = operandFromLit (1);
666           return;
667         }
668       /* if addition then check if one of them is a zero */
669       /* if yes turn it  into assignmnt */
670       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
671           operandLitValue (IC_LEFT (ic)) == 0.0)
672         {
673
674           ic->op = '=';
675           IC_LEFT (ic) = NULL;
676           SET_ISADDR (IC_RESULT (ic), 0);
677           SET_ISADDR (IC_RIGHT (ic), 0);
678           return;
679         }
680       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
681           operandLitValue (IC_RIGHT (ic)) == 0.0)
682         {
683
684           ic->op = '=';
685           IC_RIGHT (ic) = IC_LEFT (ic);
686           IC_LEFT (ic) = 0;
687           SET_ISADDR (IC_RIGHT (ic), 0);
688           SET_ISADDR (IC_RESULT (ic), 0);
689           return;
690         }
691       break;
692     case '-':
693       /* if subtracting the the same thing then zero     */
694       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
695         {
696           ic->op = '=';
697           IC_RIGHT (ic) = operandFromLit (0);
698           IC_LEFT (ic) = NULL;
699           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
700           IC_RESULT (ic)->isaddr = 0;
701           return;
702         }
703
704       /* if subtraction then check if one of the operand */
705       /* is zero then depending on which operand change  */
706       /* to assignment or unary minus                    */
707       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
708           operandLitValue (IC_RIGHT (ic)) == 0.0)
709         {
710           /* right size zero change to assignment */
711           ic->op = '=';
712           IC_RIGHT (ic) = IC_LEFT (ic);
713           IC_LEFT (ic) = NULL;
714           SET_ISADDR (IC_RIGHT (ic), 0);
715           SET_ISADDR (IC_RESULT (ic), 0);
716           return;
717         }
718       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
719           operandLitValue (IC_LEFT (ic)) == 0.0)
720         {
721           /* left zero turn into an unary minus */
722           ic->op = UNARYMINUS;
723           IC_LEFT (ic) = IC_RIGHT (ic);
724           IC_RIGHT (ic) = NULL;
725           return;
726         }
727       break;
728       /* if multiplication then check if either of */
729       /* them is zero then the result is zero      */
730       /* if either of them is one then result is   */
731       /* the other one                             */
732     case '*':
733       if (IS_OP_LITERAL (IC_LEFT (ic)))
734         {
735
736           if (operandLitValue (IC_LEFT (ic)) == 0.0)
737             {
738               ic->op = '=';
739               IC_RIGHT (ic) = IC_LEFT (ic);
740               IC_LEFT (ic) = NULL;
741               SET_RESULT_RIGHT (ic);
742               return;
743             }
744           if (operandLitValue (IC_LEFT (ic)) == 1.0)
745             {
746               ic->op = '=';
747               IC_LEFT (ic) = NULL;
748               SET_RESULT_RIGHT (ic);
749               return;
750             }
751         }
752
753       if (IS_OP_LITERAL (IC_RIGHT (ic)))
754         {
755
756           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
757             {
758               ic->op = '=';
759               IC_LEFT (ic) = NULL;
760               SET_RESULT_RIGHT (ic);
761               return;
762             }
763
764           if (operandLitValue (IC_RIGHT (ic)) == 1.0)
765             {
766               ic->op = '=';
767               IC_RIGHT (ic) = IC_LEFT (ic);
768               IC_LEFT (ic) = NULL;
769               SET_RESULT_RIGHT (ic);
770               return;
771             }
772         }
773       break;
774     case '/':
775       /* if division by self then 1 */
776       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
777         {
778           ic->op = '=';
779           IC_RIGHT (ic) = operandFromLit (1);
780           IC_LEFT (ic) = NULL;
781           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
782           IC_RESULT (ic)->isaddr = 0;
783         }
784       /* if this is a division then check if right */
785       /* is one then change it to an assignment    */
786       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
787           operandLitValue (IC_RIGHT (ic)) == 1.0)
788         {
789
790           ic->op = '=';
791           IC_RIGHT (ic) = IC_LEFT (ic);
792           IC_LEFT (ic) = NULL;
793           SET_RESULT_RIGHT (ic);
794           return;
795         }
796       break;
797       /* if both are the same for an comparison operators */
798     case EQ_OP:
799     case LE_OP:
800     case GE_OP:
801       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
802         {
803           ic->op = '=';
804           IC_RIGHT (ic) = operandFromLit (1);
805           IC_LEFT (ic) = NULL;
806           SET_RESULT_RIGHT (ic);
807         }
808       break;
809     case NE_OP:
810     case '>':
811     case '<':
812       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
813         {
814           ic->op = '=';
815           IC_RIGHT (ic) = operandFromLit (0);
816           IC_LEFT (ic) = NULL;
817           SET_RESULT_RIGHT (ic);
818         }
819       break;
820     case CAST:
821       /* if this is a cast of a literal value */
822       if (IS_OP_LITERAL (IC_RIGHT (ic)))
823         {
824           ic->op = '=';
825           IC_RIGHT (ic) =
826             operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
827                                           operandLitValue (IC_RIGHT (ic))));
828           IC_LEFT (ic) = NULL;
829           SET_ISADDR (IC_RESULT (ic), 0);
830         }
831       /* if casting to the same */
832       if (compareType (operandType (IC_RESULT (ic)),
833                      operandType (IC_RIGHT (ic))) == 1)
834         {
835           ic->op = '=';
836           IC_LEFT (ic) = NULL;
837           SET_ISADDR (IC_RESULT (ic), 0);
838         }
839       break;
840     case '!':
841       if (IS_OP_LITERAL (IC_LEFT (ic)))
842         {
843           ic->op = '=';
844           IC_RIGHT (ic) =
845             (operandLitValue (IC_LEFT (ic)) == 0 ?
846              operandFromLit (1) : operandFromLit (0));
847           IC_LEFT (ic) = NULL;
848           SET_ISADDR (IC_RESULT (ic), 0);
849         }
850     }
851
852   return;
853 }
854 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
855 /*-----------------------------------------------------------------*/
856 /* updateSpillLocation - keeps track of register spill location    */
857 /*-----------------------------------------------------------------*/
858 void 
859 updateSpillLocation (iCode * ic, int induction)
860 {
861
862         sym_link *setype;
863
864         if (POINTER_SET (ic))
865                 return;
866
867         if (ic->nosupdate)
868                 return;
869
870         /* for the form true_symbol := iTempNN */
871         if (ASSIGN_ITEMP_TO_SYM (ic) && 
872             !SPIL_LOC (IC_RIGHT (ic))) {
873
874                 setype = getSpec (operandType (IC_RESULT (ic)));
875
876                 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
877                     !IS_VOLATILE (setype) &&
878                     !IN_FARSPACE (SPEC_OCLS (setype)) &&
879                     !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
880
881                         SPIL_LOC (IC_RIGHT (ic)) =
882                                 IC_RESULT (ic)->operand.symOperand;
883         }
884
885         if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
886           
887                 if (!SPIL_LOC (IC_RIGHT (ic)) &&
888                     !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
889                     OP_SYMBOL (IC_RESULT (ic))->isreqv) {
890
891                         setype = getSpec (operandType (IC_RESULT (ic)));
892               
893                         if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
894                             !IS_VOLATILE (setype) &&
895                             !IN_FARSPACE (SPEC_OCLS (setype)) &&
896                             !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
897
898                                 SPIL_LOC (IC_RIGHT (ic)) =
899                                         SPIL_LOC (IC_RESULT (ic));
900                 }
901                 /* special case for inductions */
902                 if (induction && 
903                     OP_SYMBOL(IC_RIGHT(ic))->isreqv && 
904                     !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
905                     !SPIL_LOC(IC_RESULT(ic))) {
906                         SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
907                 }
908         }
909 }
910 /*-----------------------------------------------------------------*/
911 /* setUsesDef - sets the uses def bitvector for a given operand    */
912 /*-----------------------------------------------------------------*/
913 void 
914 setUsesDefs (operand * op, bitVect * bdefs,
915              bitVect * idefs, bitVect ** oud)
916 {
917   /* compute the definitions alive at this point */
918   bitVect *adefs = bitVectUnion (bdefs, idefs);
919
920   /* of these definitions find the ones that are */
921   /* for this operand */
922   adefs = bitVectIntersect (adefs, OP_DEFS (op));
923
924   /* these are the definitions that this operand can use */
925   op->usesDefs = adefs;
926
927   /* the out defs is an union */
928   *oud = bitVectUnion (*oud, adefs);
929 }
930
931 /*-----------------------------------------------------------------*/
932 /* unsetDefsAndUses - clear this operation for the operands        */
933 /*-----------------------------------------------------------------*/
934 void 
935 unsetDefsAndUses (iCode * ic)
936 {
937   if (ic->op == JUMPTABLE)
938     return;
939
940   /* take away this definition from the def chain of the */
941   /* result & take away from use set of the operands */
942   if (ic->op != IFX)
943     {
944       /* turn off def set */
945       if (IS_SYMOP (IC_RESULT (ic)))
946         {
947           if (!POINTER_SET (ic))
948             bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
949           else
950             bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
951         }
952       /* turn off the useSet for the operands */
953       if (IS_SYMOP (IC_LEFT (ic)))
954         bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
955
956       if (IS_SYMOP (IC_RIGHT (ic)))
957         bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
958     }
959   else
960     /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
961     bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
962 }
963
964 /*-----------------------------------------------------------------*/
965 /* ifxOptimize - changes ifx conditions if it can                  */
966 /*-----------------------------------------------------------------*/
967 void 
968 ifxOptimize (iCode * ic, set * cseSet,
969              int computeOnly,
970              eBBlock * ebb, int *change,
971              eBBlock ** ebbs, int count)
972 {
973   operand *pdop;
974   symbol *label;
975
976   /* if the condition can be replaced */
977   if (!computeOnly)
978     {
979       pdop = NULL;
980       applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop);
981       if (pdop)
982         {
983           IC_COND (ic) = pdop;
984           (*change)++;
985         }
986     }
987
988   /* if the conditional is a literal then */
989   if (IS_OP_LITERAL (IC_COND (ic)))
990     {
991
992       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
993         {
994
995           /* change to a goto */
996           ic->op = GOTO;
997           IC_LABEL (ic) = IC_TRUE (ic);
998           (*change)++;
999
1000         }
1001       else
1002         {
1003
1004           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1005             {
1006               ic->op = GOTO;
1007               IC_LABEL (ic) = IC_FALSE (ic);
1008               (*change)++;
1009
1010             }
1011           else
1012             {
1013               /* then kill this if condition */
1014               remiCodeFromeBBlock (ebb, ic);
1015             }
1016         }
1017
1018       /* now we need to recompute the control flow */
1019       /* since the control flow has changed        */
1020       /* this is very expensive but it does not happen */
1021       /* too often, if it does happen then the user pays */
1022       /* the price */
1023       computeControlFlow (ebbs, count, 1);
1024       werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1025       return;
1026     }
1027
1028   /* if there is only one successor and that successor
1029      is the same one we are conditionally going to then
1030      we can remove this conditional statement */
1031   label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1032   if (elementsInSet (ebb->succList) == 1 &&
1033       isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1034     {
1035
1036       remiCodeFromeBBlock (ebb, ic);
1037       computeControlFlow (ebbs, count, 1);
1038       werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
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 found then eliminate this and add to */
1520       /* to cseSet an element containing result */
1521       /* of this with previous opcode           */
1522       if (pdic)
1523         {
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
1577       /* if assignment to a parameter which is not
1578          mine and type is a pointer then delete
1579          pointerGets to take care of aliasing */
1580       if (ASSIGNMENT (ic) &&
1581           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1582           IS_PTR (operandType (IC_RESULT (ic))))
1583         {
1584           deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1585           for (i = 0; i < count; ebbs[i++]->visited = 0);
1586           applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1587           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1588         }
1589
1590       /* if this is a pointerget then see if we can replace
1591          this with a previously assigned pointer value */
1592       if (POINTER_GET (ic) &&
1593           !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1594             isOperandVolatile (IC_LEFT (ic), TRUE)))
1595         {
1596           pdop = NULL;
1597           applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
1598           /* if we find it then locally replace all
1599              references to the result with what we assigned */
1600           if (pdop)
1601             {
1602               replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
1603             }
1604         }
1605
1606       /* delete from the cseSet anything that has */
1607       /* operands matching the result of this     */
1608       /* except in case of pointer access         */
1609       if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1610         {
1611           deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
1612           /* delete any previous definitions */
1613           ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
1614
1615         }
1616
1617       /* add the left & right to the defUse set */
1618       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
1619         {
1620           OP_USES (IC_LEFT (ic)) =
1621             bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1622           setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1623
1624         }
1625
1626       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
1627         {
1628           OP_USES (IC_RIGHT (ic)) =
1629             bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1630           setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1631
1632         }
1633
1634       /* for the result it is special case, put the result */
1635       /* in the defuseSet if it a pointer or array access  */
1636       if (POINTER_SET (defic))
1637         {
1638           OP_USES (IC_RESULT (ic)) =
1639             bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1640           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1641           deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
1642           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
1643           /* delete from inexpressions of all successors which
1644              have dfNum > than this block */
1645           for (i = 0; i < count; ebbs[i++]->visited = 0);
1646           applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
1647
1648           /* delete from cseSet all other pointer sets
1649              for this operand */
1650           deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
1651           /* add to the local pointerset set */
1652           addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
1653         }
1654       else
1655         /* add the result to defintion set */ if (IC_RESULT (ic))
1656         {
1657           OP_DEFS (IC_RESULT (ic)) =
1658             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1659           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1660           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1661           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1662         }
1663
1664
1665       /* if this is an addressof instruction then */
1666       /* put the symbol in the address of list &  */
1667       /* delete it from the cseSet                */
1668       if (defic->op == ADDRESS_OF)
1669         {
1670           addSetHead (&ebb->addrOf, IC_LEFT (ic));
1671           deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
1672         }
1673     }
1674
1675   setToNull ((void **) &ebb->outExprs);
1676   ebb->outExprs = cseSet;
1677   ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
1678   ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
1679   return change;
1680 }
1681
1682 /*-----------------------------------------------------------------*/
1683 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
1684 /*-----------------------------------------------------------------*/
1685 int 
1686 cseAllBlocks (eBBlock ** ebbs, int count)
1687 {
1688   int i;
1689   int change = 0;
1690
1691   /* if optimization turned off */
1692
1693   for (i = 0; i < count; i++)
1694     change += cseBBlock (ebbs[i], FALSE, ebbs, count);
1695
1696   return change;
1697 }