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