dos cvs had problem with .lnk file
[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             {
814                     sym_link *otype = operandType(IC_RIGHT(ic));
815                     sym_link *ctype = operandType(IC_LEFT(ic));
816                     /* if this is a cast of a literal value */
817                     if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
818                         !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
819                             ic->op = '=';
820                             IC_RIGHT (ic) =
821                                     operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
822                                                                       operandLitValue (IC_RIGHT (ic))));
823                             IC_LEFT (ic) = NULL;
824                             SET_ISADDR (IC_RESULT (ic), 0);
825                     }
826                     /* if casting to the same */
827                     if (compareType (operandType (IC_RESULT (ic)),
828                                      operandType (IC_RIGHT (ic))) == 1) {
829                             ic->op = '=';
830                             IC_LEFT (ic) = NULL;
831                             SET_ISADDR (IC_RESULT (ic), 0);
832                     }
833             }
834             break;
835     case '!':
836       if (IS_OP_LITERAL (IC_LEFT (ic)))
837         {
838           ic->op = '=';
839           IC_RIGHT (ic) =
840             (operandLitValue (IC_LEFT (ic)) == 0 ?
841              operandFromLit (1) : operandFromLit (0));
842           IC_LEFT (ic) = NULL;
843           SET_ISADDR (IC_RESULT (ic), 0);
844         }
845     }
846
847   return;
848 }
849 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
850 /*-----------------------------------------------------------------*/
851 /* updateSpillLocation - keeps track of register spill location    */
852 /*-----------------------------------------------------------------*/
853 void 
854 updateSpillLocation (iCode * ic, int induction)
855 {
856
857         sym_link *setype;
858
859         if (POINTER_SET (ic))
860                 return;
861
862         if (ic->nosupdate)
863                 return;
864
865         /* for the form true_symbol := iTempNN */
866         if (ASSIGN_ITEMP_TO_SYM (ic) && 
867             !SPIL_LOC (IC_RIGHT (ic))) {
868
869                 setype = getSpec (operandType (IC_RESULT (ic)));
870
871                 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
872                     !IS_VOLATILE (setype) &&
873                     !IN_FARSPACE (SPEC_OCLS (setype)) &&
874                     !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
875
876                         SPIL_LOC (IC_RIGHT (ic)) =
877                                 IC_RESULT (ic)->operand.symOperand;
878         }
879
880         if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
881           
882                 if (!SPIL_LOC (IC_RIGHT (ic)) &&
883                     !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
884                     OP_SYMBOL (IC_RESULT (ic))->isreqv) {
885
886                         setype = getSpec (operandType (IC_RESULT (ic)));
887               
888                         if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
889                             !IS_VOLATILE (setype) &&
890                             !IN_FARSPACE (SPEC_OCLS (setype)) &&
891                             !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
892
893                                 SPIL_LOC (IC_RIGHT (ic)) =
894                                         SPIL_LOC (IC_RESULT (ic));
895                 }
896                 /* special case for inductions */
897                 if (induction && 
898                     OP_SYMBOL(IC_RIGHT(ic))->isreqv && 
899                     !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
900                     !SPIL_LOC(IC_RESULT(ic))) {
901                         SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
902                 }
903         }
904 }
905 /*-----------------------------------------------------------------*/
906 /* setUsesDef - sets the uses def bitvector for a given operand    */
907 /*-----------------------------------------------------------------*/
908 void 
909 setUsesDefs (operand * op, bitVect * bdefs,
910              bitVect * idefs, bitVect ** oud)
911 {
912   /* compute the definitions alive at this point */
913   bitVect *adefs = bitVectUnion (bdefs, idefs);
914
915   /* of these definitions find the ones that are */
916   /* for this operand */
917   adefs = bitVectIntersect (adefs, OP_DEFS (op));
918
919   /* these are the definitions that this operand can use */
920   op->usesDefs = adefs;
921
922   /* the out defs is an union */
923   *oud = bitVectUnion (*oud, adefs);
924 }
925
926 /*-----------------------------------------------------------------*/
927 /* unsetDefsAndUses - clear this operation for the operands        */
928 /*-----------------------------------------------------------------*/
929 void 
930 unsetDefsAndUses (iCode * ic)
931 {
932   if (ic->op == JUMPTABLE)
933     return;
934
935   /* take away this definition from the def chain of the */
936   /* result & take away from use set of the operands */
937   if (ic->op != IFX)
938     {
939       /* turn off def set */
940       if (IS_SYMOP (IC_RESULT (ic)))
941         {
942           if (!POINTER_SET (ic))
943             bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
944           else
945             bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
946         }
947       /* turn off the useSet for the operands */
948       if (IS_SYMOP (IC_LEFT (ic)))
949         bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
950
951       if (IS_SYMOP (IC_RIGHT (ic)))
952         bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
953     }
954   else
955     /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
956     bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
957 }
958
959 /*-----------------------------------------------------------------*/
960 /* ifxOptimize - changes ifx conditions if it can                  */
961 /*-----------------------------------------------------------------*/
962 void 
963 ifxOptimize (iCode * ic, set * cseSet,
964              int computeOnly,
965              eBBlock * ebb, int *change,
966              eBBlock ** ebbs, int count)
967 {
968   operand *pdop;
969   symbol *label;
970
971   /* if the condition can be replaced */
972   if (!computeOnly)
973     {
974       pdop = NULL;
975       applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop);
976       if (pdop)
977         {
978           IC_COND (ic) = pdop;
979           (*change)++;
980         }
981     }
982
983   /* if the conditional is a literal then */
984   if (IS_OP_LITERAL (IC_COND (ic)))
985     {
986
987       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
988         {
989
990           /* change to a goto */
991           ic->op = GOTO;
992           IC_LABEL (ic) = IC_TRUE (ic);
993           (*change)++;
994
995         }
996       else
997         {
998
999           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1000             {
1001               ic->op = GOTO;
1002               IC_LABEL (ic) = IC_FALSE (ic);
1003               (*change)++;
1004
1005             }
1006           else
1007             {
1008               /* then kill this if condition */
1009               remiCodeFromeBBlock (ebb, ic);
1010             }
1011         }
1012
1013       /* now we need to recompute the control flow */
1014       /* since the control flow has changed        */
1015       /* this is very expensive but it does not happen */
1016       /* too often, if it does happen then the user pays */
1017       /* the price */
1018       computeControlFlow (ebbs, count, 1);
1019       werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1020       return;
1021     }
1022
1023   /* if there is only one successor and that successor
1024      is the same one we are conditionally going to then
1025      we can remove this conditional statement */
1026   label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1027   if (elementsInSet (ebb->succList) == 1 &&
1028       isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1029     {
1030
1031       remiCodeFromeBBlock (ebb, ic);
1032       computeControlFlow (ebbs, count, 1);
1033       werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1034       return;
1035     }
1036
1037
1038   /* if it remains an IFX the update the use Set */
1039   OP_USES (IC_COND (ic)) = bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1040   setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1041   return;
1042 }
1043
1044 /*-----------------------------------------------------------------*/
1045 /* diCodeForSym - finds the definiting instruction for a symbol    */
1046 /*-----------------------------------------------------------------*/
1047 DEFSETFUNC (diCodeForSym)
1048 {
1049   cseDef *cdp = item;
1050   V_ARG (operand *, sym);
1051   V_ARG (iCode **, dic);
1052
1053   /* if already found */
1054   if (*dic)
1055     return 0;
1056
1057   /* if not if this is the defining iCode */
1058   if (sym->key == cdp->key)
1059     {
1060       *dic = cdp->diCode;
1061       return 1;
1062     }
1063
1064   return 0;
1065 }
1066
1067 /*-----------------------------------------------------------------*/
1068 /* constFold - does some constant folding                          */
1069 /*-----------------------------------------------------------------*/
1070 int 
1071 constFold (iCode * ic, set * cseSet)
1072 {
1073   iCode *dic = NULL;
1074   iCode *ldic = NULL;
1075   /* this routine will change
1076      a = b + 10;
1077      c = a + 10;
1078      to
1079      c = b + 20; */
1080
1081   /* deal with only + & - */
1082   if (ic->op != '+' &&
1083       ic->op != '-')
1084     return 0;
1085
1086   /* this check is a hueristic to prevent live ranges
1087      from becoming too long */
1088   if (IS_PTR (operandType (IC_RESULT (ic))))
1089     return 0;
1090
1091   /* check if operation with a literal */
1092   if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1093     return 0;
1094
1095   /* check if we can find a definition for the
1096      right hand side */
1097   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1098     return 0;
1099
1100   /* check that this is also a +/-  */
1101   if (dic->op != '+' && dic->op != '-')
1102     return 0;
1103
1104   /* with a literal */
1105   if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1106     return 0;
1107
1108   /* find the definition of the left operand
1109      of dic.then check if this defined with a
1110      get_pointer return 0 if the pointer size is
1111      less than 2 (MCS51 specific) */
1112   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1113     return 0;
1114
1115   if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1116     return 0;
1117
1118   /* it is if the operations are the same */
1119   /* the literal parts need to be added  */
1120   IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1121   if (ic->op == dic->op)
1122     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1123                                     operandLitValue (IC_RIGHT (dic)));
1124   else
1125     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1126                                     operandLitValue (IC_RIGHT (dic)));
1127
1128   if (IS_ITEMP (IC_RESULT (ic)))
1129     {
1130       SPIL_LOC (IC_RESULT (ic)) = NULL;
1131       OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1132     }
1133
1134
1135   return 1;
1136 }
1137
1138 /*-----------------------------------------------------------------*/
1139 /* deleteGetPointers - called when a pointer is passed as parm     */
1140 /* will delete from cseSet all get pointers computed from this     */
1141 /* pointer. A simple ifOperandsHave is not good enough here        */
1142 /*-----------------------------------------------------------------*/
1143 static void 
1144 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1145 {
1146   set *compItems = NULL;
1147   cseDef *cdp;
1148   operand *cop;
1149
1150   /* easy return */
1151   if (!*cseSet && !*pss)
1152     return;
1153
1154   /* first find all items computed from this operand .
1155      This done fairly simply go thru the list and find
1156      those that are computed by arthimetic with this
1157      op */
1158   for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1159     {
1160       if (IS_ARITHMETIC_OP (cdp->diCode))
1161         {
1162           if (isOperandEqual (IC_LEFT (cdp->diCode), op) ||
1163               isOperandEqual (IC_RIGHT (cdp->diCode), op))
1164             {
1165               /* save it in our list of items */
1166               addSet (&compItems, IC_RESULT (cdp->diCode));
1167             }
1168           /* also check for those computed from our computed
1169              list . This will take care of situations like
1170              iTemp1 = iTemp0 + 8;
1171              iTemp2 = iTemp1 + 8; */
1172           if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode), 
1173                            (insetwithFunc)isOperandEqual) ||
1174               isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode), 
1175                            (insetwithFunc)isOperandEqual))
1176             {
1177               addSet (&compItems, IC_RESULT (cdp->diCode));
1178             }
1179         }
1180     }
1181
1182   /* now delete all pointer gets with this op */
1183   deleteItemIf (cseSet, ifPointerGet, op);
1184   deleteItemIf (pss, ifPointerSet, op);
1185
1186   /* set the bit vector used by dataFlow computation later */
1187   ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key);
1188   /* now for the computed items */
1189   for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1190     {
1191       ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1192       deleteItemIf (cseSet, ifPointerGet, cop);
1193       deleteItemIf (pss, ifPointerSet, cop);
1194     }
1195 }
1196
1197 /*-----------------------------------------------------------------*/
1198 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1199 /*                     dfnum > supplied                            */
1200 /*-----------------------------------------------------------------*/
1201 DEFSETFUNC (delGetPointerSucc)
1202 {
1203   eBBlock *ebp = item;
1204   V_ARG (operand *, op);
1205   V_ARG (int, dfnum);
1206
1207   if (ebp->visited)
1208     return 0;
1209
1210   ebp->visited = 1;
1211   if (ebp->dfnum > dfnum)
1212     {
1213       deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1214     }
1215
1216   return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1217 }
1218
1219 /*-----------------------------------------------------------------*/
1220 /* fixUpTypes - KLUGE HACK fixup a lowering problem                */
1221 /*-----------------------------------------------------------------*/
1222 static void 
1223 fixUpTypes (iCode * ic)
1224 {
1225   sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1226
1227   /* if (TARGET_IS_DS390) */
1228   if (options.model == MODEL_FLAT24)
1229     {
1230       /* hack-o-matic! */
1231       return;
1232     }
1233
1234   /* for pointer_gets if the types of result & left r the
1235      same then change it type of result to next */
1236   if (IS_PTR (t1) &&
1237       compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1238     {
1239       setOperandType (IC_RESULT (ic), t2->next);
1240     }
1241 }
1242
1243 /*-----------------------------------------------------------------*/
1244 /* cseBBlock - common subexpression elimination for basic blocks   */
1245 /*             this is the hackiest kludgiest routine in the whole */
1246 /*             system. also the most important, since almost all   */
1247 /*             data flow related information is computed by it     */
1248 /*-----------------------------------------------------------------*/
1249 int 
1250 cseBBlock (eBBlock * ebb, int computeOnly,
1251            eBBlock ** ebbs, int count)
1252 {
1253   set *cseSet;
1254   iCode *ic;
1255   int change = 0;
1256   int i;
1257   set *ptrSetSet = NULL;
1258
1259   /* if this block is not reachable */
1260   if (ebb->noPath)
1261     return change;
1262
1263   /* set of common subexpressions */
1264   cseSet = setFromSet (ebb->inExprs);
1265
1266   /* these will be computed by this routine */
1267   setToNull ((void **) &ebb->outDefs);
1268   setToNull ((void **) &ebb->defSet);
1269   setToNull ((void **) &ebb->usesDefs);
1270   setToNull ((void **) &ebb->ptrsSet);
1271   setToNull ((void **) &ebb->addrOf);
1272   setToNull ((void **) &ebb->ldefs);
1273
1274   ebb->outDefs = bitVectCopy (ebb->inDefs);
1275   bitVectDefault = iCodeKey;
1276   ebb->defSet = newBitVect (iCodeKey);
1277   ebb->usesDefs = newBitVect (iCodeKey);
1278
1279   /* for all the instructions in this block do */
1280   for (ic = ebb->sch; ic; ic = ic->next)
1281     {
1282
1283       iCode *pdic;
1284       operand *pdop;
1285       iCode *defic;
1286
1287       if (SKIP_IC2 (ic))
1288         continue;
1289
1290       /* if this is an assignment from true symbol
1291          to a temp then do pointer post inc/dec optimzation */
1292       if (ic->op == '=' && !POINTER_SET (ic) &&
1293           IS_PTR (operandType (IC_RESULT (ic))))
1294         {
1295           ptrPostIncDecOpt (ic);
1296         }
1297
1298       /* clear the def & use chains for the operands involved */
1299       /* in this operation . since it can change due to opts  */
1300       unsetDefsAndUses (ic);
1301
1302       if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1303         {
1304           /* add to defSet of the symbol */
1305           OP_DEFS (IC_RESULT (ic)) =
1306             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1307           /* add to the definition set of this block */
1308           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1309           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1310           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1311           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1312           /* delete global variables from the cseSet
1313              since they can be modified by the function call */
1314           deleteItemIf (&cseSet, ifDefGlobal);
1315           /* delete all getpointer iCodes from cseSet, this should
1316              be done only for global arrays & pointers but at this
1317              point we don't know if globals, so to be safe do all */
1318           deleteItemIf (&cseSet, ifAnyGetPointer);
1319         }
1320
1321       /* for pcall & ipush we need to add to the useSet */
1322       if ((ic->op == PCALL ||
1323            ic->op == IPUSH ||
1324            ic->op == IPOP ||
1325            ic->op == SEND) &&
1326           IS_SYMOP (IC_LEFT (ic)))
1327         {
1328
1329           /* check if they can be replaced */
1330           if (!computeOnly)
1331             {
1332               pdop = NULL;
1333               applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop);
1334               if (pdop)
1335                 IC_LEFT (ic) = pdop;
1336             }
1337           /* the lookup could have changed it */
1338           if (IS_SYMOP (IC_LEFT (ic)))
1339             {
1340               OP_USES (IC_LEFT (ic)) =
1341                 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1342               setUsesDefs (IC_LEFT (ic), ebb->defSet,
1343                            ebb->outDefs, &ebb->usesDefs);
1344             }
1345
1346
1347           /* if we a sending a pointer as a parameter
1348              then kill all cse since the pointed to item
1349              might be changed in the function being called */
1350           if ((ic->op == IPUSH || ic->op == SEND) &&
1351               IS_PTR (operandType (IC_LEFT (ic))))
1352             {
1353               deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1354               ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1355               for (i = 0; i < count; ebbs[i++]->visited = 0);
1356               applyToSet (ebb->succList, delGetPointerSucc,
1357                           IC_LEFT (ic), ebb->dfnum);
1358             }
1359           continue;
1360         }
1361
1362       /* if jumptable then mark the usage */
1363       if (ic->op == JUMPTABLE)
1364         {
1365           OP_USES (IC_JTCOND (ic)) =
1366             bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1367           setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1368                        ebb->outDefs, &ebb->usesDefs);
1369           continue;
1370         }
1371
1372       if (SKIP_IC (ic))
1373         continue;
1374
1375       /* do some algebraic optimizations if possible */
1376       algebraicOpts (ic);
1377       while (constFold (ic, cseSet));
1378
1379       /* small klugde */
1380       if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1381         {
1382           setOperandType (IC_LEFT (ic),
1383                           aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1384           fixUpTypes (ic);
1385
1386         }
1387       if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1388         {
1389           setOperandType (IC_RESULT (ic),
1390                           aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1391         }
1392
1393       /* if this is a condition statment then */
1394       /* check if the condition can be replaced */
1395       if (ic->op == IFX)
1396         {
1397           ifxOptimize (ic, cseSet, computeOnly,
1398                        ebb, &change,
1399                        ebbs, count);
1400           continue;
1401         }
1402
1403       /* if the assignment & result is a temp */
1404       /* see if we can replace it             */
1405       if (ic->op == '=')
1406         {
1407
1408           /* update the spill location for this */
1409           updateSpillLocation (ic,0);
1410
1411           if (POINTER_SET (ic) &&
1412               !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1413             {
1414               pdop = NULL;
1415               applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop);
1416               if (pdop && IS_ITEMP (pdop) && !computeOnly)
1417                 IC_RESULT (ic) = pdop;
1418             }
1419         }
1420
1421       /* do the operand lookup i.e. for both the */
1422       /* right & left operand : check the cseSet */
1423       /* to see if they have been replaced if yes */
1424       /* then replace them with those from cseSet */
1425       /* left operand */
1426       /* and left is a symbol  */
1427       if (IS_SYMOP (IC_LEFT (ic)) &&
1428           !computeOnly && ic->op != ADDRESS_OF)
1429         {
1430
1431           pdop = NULL;
1432           applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop);
1433           if (pdop)
1434             {
1435               if (POINTER_GET (ic))
1436                 {
1437                   if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1438                     {
1439                       IC_LEFT (ic) = pdop;
1440                       change = 1;
1441                     }
1442                   /* check if there is a pointer set
1443                      for the same pointer visible if yes
1444                      then change this into an assignment */
1445                   pdop = NULL;
1446                   if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1447                       !bitVectBitValue (ebb->ptrsSet, pdop->key))
1448                     {
1449                       ic->op = '=';
1450                       IC_LEFT (ic) = NULL;
1451                       IC_RIGHT (ic) = pdop;
1452                       SET_ISADDR (IC_RESULT (ic), 0);
1453                     }
1454
1455                 }
1456               else
1457                 {
1458                   IC_LEFT (ic) = pdop;
1459                   change = 1;
1460                 }
1461             }
1462         }
1463
1464       /*right operand */
1465       if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1466         {
1467
1468           pdop = NULL;
1469           applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop);
1470           if (pdop)
1471             {
1472
1473               IC_RIGHT (ic) = pdop;
1474               change = 1;
1475             }
1476         }
1477
1478       /* if left or right changed then do algebraic */
1479       if (change)
1480         {
1481           algebraicOpts (ic);
1482           while (constFold (ic, cseSet));
1483         }
1484
1485       /* if after all this it becomes a assignment to self
1486          then delete it and continue */
1487       if (ASSIGNMENT_TO_SELF (ic))
1488         {
1489           remiCodeFromeBBlock (ebb, ic);
1490           continue;
1491         }
1492
1493       /* now we will check to see if the entire */
1494       /* operation has been performed before    */
1495       /* and is available                       */
1496       /* don't do assignments they will be killed */
1497       /* by dead code elimination if required  do */
1498       /* it only if result is a temporary         */
1499       pdic = NULL;
1500       if (!(POINTER_GET (ic) &&
1501             (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1502              isOperandVolatile (IC_LEFT (ic), TRUE) ||
1503              bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
1504           !ASSIGNMENT (ic) &&
1505           IS_ITEMP (IC_RESULT (ic)) &&
1506           !computeOnly)
1507         {
1508           applyToSet (cseSet, findPrevIc, ic, &pdic);
1509           if (pdic && compareType (operandType (IC_RESULT (pdic)),
1510                                  operandType (IC_RESULT (ic))) != 1)
1511             pdic = NULL;
1512         }
1513
1514       /* if found then eliminate this and add to */
1515       /* to cseSet an element containing result */
1516       /* of this with previous opcode           */
1517       if (pdic)
1518         {
1519
1520           if (IS_ITEMP (IC_RESULT (ic)))
1521             {
1522
1523               /* replace in the remaining of this block */
1524               replaceAllSymBySym (ic->next, IC_RESULT (ic), IC_RESULT (pdic), &ebb->ndompset);
1525               /* remove this iCode from inexpressions of all
1526                  its successors, it cannot be in the in expressions
1527                  of any of the predecessors */
1528               for (i = 0; i < count; ebbs[i++]->visited = 0);
1529               applyToSet (ebb->succList, removeFromInExprs, ic, IC_RESULT (ic),
1530                           IC_RESULT (pdic), ebb);
1531
1532               /* if this was moved from another block */
1533               /* then replace in those blocks too     */
1534               if (ic->movedFrom)
1535                 {
1536                   eBBlock *owner;
1537                   for (owner = setFirstItem (ic->movedFrom); owner;
1538                        owner = setNextItem (ic->movedFrom))
1539                     replaceAllSymBySym (owner->sch, IC_RESULT (ic), IC_RESULT (pdic), &owner->ndompset);
1540                 }
1541               pdic->movedFrom = unionSets (pdic->movedFrom, ic->movedFrom, THROW_NONE);
1542             }
1543           else
1544             addSetHead (&cseSet, newCseDef (IC_RESULT (ic), pdic));
1545
1546           if (!computeOnly)
1547             /* eliminate this */
1548             remiCodeFromeBBlock (ebb, ic);
1549
1550           defic = pdic;
1551           change++;
1552
1553           if (IS_ITEMP (IC_RESULT (ic)))
1554             continue;
1555
1556         }
1557       else
1558         {
1559
1560           /* just add this as a previous expression except in */
1561           /* case of a pointer access in which case this is a */
1562           /* usage not a definition                           */
1563           if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1564             {
1565               deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
1566               addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
1567             }
1568           defic = ic;
1569
1570         }
1571
1572       /* if assignment to a parameter which is not
1573          mine and type is a pointer then delete
1574          pointerGets to take care of aliasing */
1575       if (ASSIGNMENT (ic) &&
1576           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1577           IS_PTR (operandType (IC_RESULT (ic))))
1578         {
1579           deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1580           for (i = 0; i < count; ebbs[i++]->visited = 0);
1581           applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1582           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1583         }
1584
1585       /* if this is a pointerget then see if we can replace
1586          this with a previously assigned pointer value */
1587       if (POINTER_GET (ic) &&
1588           !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1589             isOperandVolatile (IC_LEFT (ic), TRUE)))
1590         {
1591           pdop = NULL;
1592           applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
1593           /* if we find it then locally replace all
1594              references to the result with what we assigned */
1595           if (pdop)
1596             {
1597               replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
1598             }
1599         }
1600
1601       /* delete from the cseSet anything that has */
1602       /* operands matching the result of this     */
1603       /* except in case of pointer access         */
1604       if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1605         {
1606           deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
1607           /* delete any previous definitions */
1608           ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
1609
1610         }
1611
1612       /* add the left & right to the defUse set */
1613       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
1614         {
1615           OP_USES (IC_LEFT (ic)) =
1616             bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1617           setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1618
1619         }
1620
1621       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
1622         {
1623           OP_USES (IC_RIGHT (ic)) =
1624             bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1625           setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1626
1627         }
1628
1629       /* for the result it is special case, put the result */
1630       /* in the defuseSet if it a pointer or array access  */
1631       if (POINTER_SET (defic))
1632         {
1633           OP_USES (IC_RESULT (ic)) =
1634             bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1635           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1636           deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
1637           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
1638           /* delete from inexpressions of all successors which
1639              have dfNum > than this block */
1640           for (i = 0; i < count; ebbs[i++]->visited = 0);
1641           applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
1642
1643           /* delete from cseSet all other pointer sets
1644              for this operand */
1645           deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
1646           /* add to the local pointerset set */
1647           addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
1648         }
1649       else
1650         /* add the result to defintion set */ if (IC_RESULT (ic))
1651         {
1652           OP_DEFS (IC_RESULT (ic)) =
1653             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1654           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1655           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1656           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1657         }
1658
1659
1660       /* if this is an addressof instruction then */
1661       /* put the symbol in the address of list &  */
1662       /* delete it from the cseSet                */
1663       if (defic->op == ADDRESS_OF)
1664         {
1665           addSetHead (&ebb->addrOf, IC_LEFT (ic));
1666           deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
1667         }
1668     }
1669
1670   setToNull ((void **) &ebb->outExprs);
1671   ebb->outExprs = cseSet;
1672   ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
1673   ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
1674   return change;
1675 }
1676
1677 /*-----------------------------------------------------------------*/
1678 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
1679 /*-----------------------------------------------------------------*/
1680 int 
1681 cseAllBlocks (eBBlock ** ebbs, int count)
1682 {
1683   int i;
1684   int change = 0;
1685
1686   /* if optimization turned off */
1687
1688   for (i = 0; i < count; i++)
1689     change += cseBBlock (ebbs[i], FALSE, ebbs, count);
1690
1691   return change;
1692 }