* src/SDCCcse.c (updateSpillLocation): fixed bug #808027
[fw/sdcc] / src / SDCCcse.c
1 /*-------------------------------------------------------------------------
2   SDCCcse.c - source file for Common Subexpressions and other utility
3
4              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25 #include "common.h"
26 #include "newalloc.h"
27
28 /*-----------------------------------------------------------------*/
29 /* newCseDef - new cseDef                                          */
30 /*-----------------------------------------------------------------*/
31 cseDef *
32 newCseDef (operand * sym, iCode * ic)
33 {
34   cseDef *cdp;
35
36   assert (sym);
37   cdp = Safe_alloc (sizeof (cseDef));
38
39   cdp->sym = sym;
40   cdp->diCode = ic;
41   cdp->key = sym->key;
42
43   return cdp;
44 }
45
46
47
48 /*-----------------------------------------------------------------*/
49 /* int isCseDefEqual - two definitions are equal                   */
50 /*-----------------------------------------------------------------*/
51 int 
52 isCseDefEqual (void *vsrc, void *vdest)
53 {
54   cseDef *src = vsrc;
55   cseDef *dest = vdest;
56
57   if (src == dest)
58     return 1;
59
60   return (src->key == dest->key &&
61           src->diCode == dest->diCode);
62
63 }
64
65 /*-----------------------------------------------------------------*/
66 /* pcseDef - in the cseDef                                         */
67 /*-----------------------------------------------------------------*/
68 int 
69 pcseDef (void *item, va_list ap)
70 {
71   cseDef *cdp = item;
72   iCodeTable *icTab;
73
74   (void) ap;
75
76   if (!cdp->sym)
77     fprintf (stdout, "**null op**");
78   printOperand (cdp->sym, stdout);
79   icTab = getTableEntry (cdp->diCode->op);
80   icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
81   return 1;
82 }
83
84 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
85 #ifdef RANGEHUNT
86   printf ("ReplaceOpWithCheaperOp %s with %s: ",
87           IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM",
88           IS_SYMOP(cop) ? OP_SYMBOL(cop)->name : "!SYM");
89   // if op is a register equivalent
90   if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
91     operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
92     if (isOperandEqual(*rop, *op)) {
93       printf ("true");
94       *rop=cop;
95       OP_SYMBOL((*op))->isreqv=0;
96       OP_SYMBOL(cop)->isreqv=1;
97     } else {
98       printf ("false");
99     }
100   }
101   printf ("\n");
102 #endif
103   *op=cop;
104 }
105
106 /*-----------------------------------------------------------------*/
107 /* replaceAllSymBySym - replaces all operands by operand in an     */
108 /*                      instruction chain                          */
109 /*-----------------------------------------------------------------*/
110 void
111 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
112 {
113   iCode *lic;
114
115   for (lic = ic; lic; lic = lic->next)
116     {
117       int siaddr;
118
119       /* do the special cases first */
120       if (lic->op == IFX)
121         {
122           if (IS_SYMOP (to) &&
123               IC_COND (lic)->key == from->key)
124             {
125
126               bitVectUnSetBit (OP_USES (from), lic->key);
127               OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
128               siaddr = IC_COND (lic)->isaddr;
129               IC_COND (lic) = operandFromOperand (to);
130               IC_COND (lic)->isaddr = siaddr;
131
132             }
133           continue;
134         }
135
136       if (lic->op == JUMPTABLE)
137         {
138           if (IS_SYMOP (to) &&
139               IC_JTCOND (lic)->key == from->key)
140             {
141
142               bitVectUnSetBit (OP_USES (from), lic->key);
143               OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
144               siaddr = IC_COND (lic)->isaddr;
145               IC_JTCOND (lic) = operandFromOperand (to);
146               IC_JTCOND (lic)->isaddr = siaddr;
147
148             }
149           continue;
150         }
151
152       if (IS_SYMOP(to) && 
153           IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
154         {
155           /* maintain du chains */
156           if (POINTER_SET (lic))
157             {
158               bitVectUnSetBit (OP_USES (from), lic->key);
159               OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
160
161               /* also check if the "from" was in the non-dominating
162                  pointer sets and replace it with "to" in the bitVector */
163               if (bitVectBitValue (*ndpset, from->key))
164                 {
165                   bitVectUnSetBit (*ndpset, from->key);
166                   bitVectSetBit (*ndpset, to->key);
167                 }
168
169             }
170           else
171             {
172               bitVectUnSetBit (OP_DEFS (from), lic->key);
173               OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
174             }
175           siaddr = IC_RESULT (lic)->isaddr;
176           IC_RESULT (lic) = operandFromOperand (to);
177           IC_RESULT (lic)->isaddr = siaddr;
178         }
179
180       if (IS_SYMOP (to) &&
181           IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
182         {
183           bitVectUnSetBit (OP_USES (from), lic->key);
184           OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
185           siaddr = IC_RIGHT (lic)->isaddr;
186           IC_RIGHT (lic) = operandFromOperand (to);
187           IC_RIGHT (lic)->isaddr = siaddr;
188         }
189
190       if (IS_SYMOP (to) &&
191           IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
192         {
193           bitVectUnSetBit (OP_USES (from), lic->key);
194           OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
195           siaddr = IC_LEFT (lic)->isaddr;
196           IC_LEFT (lic) = operandFromOperand (to);
197           IC_LEFT (lic)->isaddr = siaddr;
198         }
199     }
200 }
201
202 /*-----------------------------------------------------------------*/
203 /* iCodeKeyIs - if the icode keys match then return 1              */
204 /*-----------------------------------------------------------------*/
205 DEFSETFUNC (iCodeKeyIs)
206 {
207   cseDef *cdp = item;
208   V_ARG (int, key);
209
210   if (cdp->diCode->key == key)
211     return 1;
212   else
213     return 0;
214 }
215
216 /*-----------------------------------------------------------------*/
217 /* removeFromInExprs - removes an icode from inexpressions         */
218 /*-----------------------------------------------------------------*/
219 DEFSETFUNC (removeFromInExprs)
220 {
221   eBBlock *ebp = item;
222   V_ARG (iCode *, ic);
223   V_ARG (operand *, from);
224   V_ARG (operand *, to);
225   V_ARG (eBBlock *, cbp);
226
227   if (ebp->visited)
228     return 0;
229
230   ebp->visited = 1;
231   deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
232   if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
233     replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
234
235   applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
236   return 0;
237 }
238
239 /*-----------------------------------------------------------------*/
240 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
241 /*-----------------------------------------------------------------*/
242 static bool 
243 isGlobalInNearSpace (operand * op)
244 {
245   sym_link *type = getSpec (operandType (op));
246   /* this is 8051 specific: optimization
247      suggested by Jean-Louis VERN, with 8051s we have no
248      advantage of putting variables in near space into
249      registers */
250   if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
251       IN_DIRSPACE (SPEC_OCLS (type)))
252     return TRUE;
253   else
254     return FALSE;
255 }
256
257 /*-----------------------------------------------------------------*/
258 /* findCheaperOp - cseBBlock support routine, will check to see if */
259 /*              we have a operand previously defined               */
260 /*-----------------------------------------------------------------*/
261 DEFSETFUNC (findCheaperOp)
262 {
263   cseDef *cdp = item;
264   V_ARG (operand *, cop);
265   V_ARG (operand **, opp);
266   V_ARG (int, checkSign);
267
268   /* if we have already found it */
269   if (*opp)
270     return 1;
271
272   /* not found it yet check if this is the one */
273   /* and this is not the defining one          */
274   if (cop->key == cdp->key)
275     {
276
277       /* do a special check this will help in */
278       /* constant propagation & dead code elim */
279       /* for assignments only                 */
280       if (cdp->diCode->op == '=') {
281         /* if the result is volatile then return result */
282         if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
283           *opp = IC_RESULT (cdp->diCode);
284         else
285           /* if this is a straight assignment and
286              left is a temp then prefer the temporary to the
287              true symbol */
288           if (!POINTER_SET (cdp->diCode) &&
289               IS_ITEMP (IC_RESULT (cdp->diCode)) &&
290               IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
291             *opp = IC_RESULT (cdp->diCode);
292           else {
293             /* if straight assignement && and both
294                are temps then prefer the one that
295                will not need extra space to spil, also
296                take into consideration if right side
297                an induction variable
298             */
299             if (!POINTER_SET (cdp->diCode) &&
300                 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
301                 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
302                 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
303                 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
304                 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
305                   SPIL_LOC (IC_RESULT (cdp->diCode))) ||
306                  (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
307                   SPIL_LOC (IC_RESULT (cdp->diCode)) ==
308                   SPIL_LOC (IC_RIGHT (cdp->diCode)))))
309               *opp = IC_RESULT (cdp->diCode);
310             else
311               *opp = IC_RIGHT (cdp->diCode);
312           }
313       }
314       else
315         *opp = IC_RESULT (cdp->diCode);
316     }
317
318   /* if this is an assign to a temp. then check
319      if the right side is this then return this */
320   if (IS_TRUE_SYMOP (cop) &&
321       cdp->diCode->op == '=' &&
322       !POINTER_SET (cdp->diCode) &&
323       cop->key == IC_RIGHT (cdp->diCode)->key &&
324       !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
325       IS_ITEMP (IC_RESULT (cdp->diCode)))
326     *opp = IC_RESULT (cdp->diCode);
327
328   if ((*opp) &&
329       (isOperandLiteral(*opp) || !checkSign ||
330        (checkSign &&
331         IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
332         (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
333          (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
334       {
335
336       if ((isGlobalInNearSpace (cop) &&
337            !isOperandLiteral (*opp)) ||
338           isOperandVolatile (*opp, FALSE)
339         )
340         {
341           *opp = NULL;
342           return 0;
343         }
344
345       if (cop->key == (*opp)->key)
346         {
347           *opp = NULL;
348           return 0;
349         }
350
351       if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
352         {
353           *opp = operandFromOperand (*opp);
354           (*opp)->isaddr = cop->isaddr;
355         }
356
357       if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
358           SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
359         {
360             // special case: we can make an unsigned char literal
361             // into an int literal with no cost.
362             if (isOperandLiteral(*opp)
363              && SPEC_NOUN(operandType(*opp)) == V_CHAR
364              && SPEC_NOUN(operandType(cop)) == V_INT)
365             {
366                 *opp = operandFromOperand (*opp);
367                 SPEC_NOUN(operandType(*opp)) = V_INT;
368             }
369             else
370             {
371                 // No clue...
372                 *opp = NULL;
373                 return 0;
374             }
375
376         }
377
378       return 1;
379
380     }
381   *opp=NULL;
382   return 0;
383 }
384
385 /*-----------------------------------------------------------------*/
386 /* findPointerSet - finds the right side of a pointer set op       */
387 /*-----------------------------------------------------------------*/
388 DEFSETFUNC (findPointerSet)
389 {
390   cseDef *cdp = item;
391   V_ARG (operand *, op);
392   V_ARG (operand **, opp);
393   V_ARG (operand *, rop);
394
395   if (POINTER_SET (cdp->diCode) &&
396       IC_RESULT (cdp->diCode)->key == op->key &&
397       !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
398       !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
399       getSize (operandType (IC_RIGHT (cdp->diCode))) ==
400       getSize (operandType (rop)))
401     {
402       *opp = IC_RIGHT (cdp->diCode);
403       return 1;
404     }
405
406   return 0;
407 }
408
409 /*-----------------------------------------------------------------*/
410 /* findPrevIc - cseBBlock support function will return the iCode   */
411 /*              which matches the current one                      */
412 /*-----------------------------------------------------------------*/
413 DEFSETFUNC (findPrevIc)
414 {
415   cseDef *cdp = item;
416   V_ARG (iCode *, ic);
417   V_ARG (iCode **, icp);
418
419   /* if already found */
420   if (*icp)
421     return 1;
422
423   /* if the iCodes are the same */
424   if (isiCodeEqual (ic, cdp->diCode) &&
425       isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
426     {
427       *icp = cdp->diCode;
428       return 1;
429     }
430
431   /* if iCodes are not the same */
432   /* see the operands maybe interchanged */
433   if (ic->op == cdp->diCode->op &&
434       (ic->op == '+' || ic->op == '*') &&
435       isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
436       isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
437     {
438       *icp = cdp->diCode;
439       return 1;
440     }
441
442   return 0;
443 }
444
445 /*-------------------------------------------------------------------*/
446 /* ifAssignedFromGlobal - if definition is an assignment from global */
447 /*-------------------------------------------------------------------*/
448 DEFSETFUNC (ifAssignedFromGlobal)
449 {
450   cseDef *cdp = item;
451   iCode *dic=cdp->diCode;
452
453   if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
454     return 1;
455   }
456   return 0;
457 }
458
459 /*-----------------------------------------------------------------*/
460 /* ifDefGlobal - if definition is global                           */
461 /*-----------------------------------------------------------------*/
462 DEFSETFUNC (ifDefGlobal)
463 {
464   cseDef *cdp = item;
465
466   return (isOperandGlobal (cdp->sym));
467 }
468
469 /*-----------------------------------------------------------------*/
470 /* ifAnyGetPointer - if get pointer icode                          */
471 /*-----------------------------------------------------------------*/
472 DEFSETFUNC (ifAnyGetPointer)
473 {
474   cseDef *cdp = item;
475
476   if (cdp->diCode && POINTER_GET (cdp->diCode))
477     return 1;
478   return 0;
479 }
480
481 /*-----------------------------------------------------------------*/
482 /* ifOperandsHave - if any of the operand are the same as this     */
483 /*-----------------------------------------------------------------*/
484 DEFSETFUNC (ifOperandsHave)
485 {
486   cseDef *cdp = item;
487   V_ARG (operand *, op);
488
489
490   if (IC_LEFT (cdp->diCode) &&
491       IS_SYMOP (IC_LEFT (cdp->diCode)) &&
492       IC_LEFT (cdp->diCode)->key == op->key)
493     return 1;
494
495   if (IC_RIGHT (cdp->diCode) &&
496       IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
497       IC_RIGHT (cdp->diCode)->key == op->key)
498     return 1;
499
500   /* or if any of the operands are volatile */
501   if (IC_LEFT (cdp->diCode) &&
502       IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
503     return 1;
504
505   if (IC_RIGHT (cdp->diCode) &&
506       IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
507     return 1;
508
509
510   if (IC_RESULT (cdp->diCode) &&
511       IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
512     return 1;
513
514   return 0;
515 }
516
517 /*-----------------------------------------------------------------*/
518 /* ifDefSymIs - if a definition is found in the set                */
519 /*-----------------------------------------------------------------*/
520 int
521 ifDefSymIs (set * cseSet, operand * sym)
522 {
523   cseDef *loop;
524   set *sl;
525
526   if (!sym || !IS_SYMOP (sym))
527     return 0;
528   for (sl = cseSet; sl; sl = sl->next)
529     {
530       loop = sl->item;
531       if (loop->sym->key == sym->key)
532         return 1;
533     }
534   return 0;
535 }
536
537
538 /*-----------------------------------------------------------------*/
539 /* ifDefSymIsX - will return 1 if the symbols match                */
540 /*-----------------------------------------------------------------*/
541 DEFSETFUNC (ifDefSymIsX)
542 {
543   cseDef *cdp = item;
544   V_ARG (operand *, op);
545
546   if (op && cdp->sym)
547     return cdp->sym->key == op->key;
548   else
549     return (isOperandEqual (cdp->sym, op));
550
551 }
552
553
554 /*-----------------------------------------------------------------*/
555 /* ifDiCodeIs - returns truw if diCode is same                     */
556 /*-----------------------------------------------------------------*/
557 int
558 ifDiCodeIs (set * cseSet, iCode * ic)
559 {
560   cseDef *loop;
561   set *sl;
562
563   if (!ic)
564     return 0;
565
566   for (sl = cseSet; sl; sl = sl->next)
567     {
568       loop = sl->item;
569       if (loop->diCode == ic)
570         return 1;
571     }
572   return 0;
573
574 }
575
576 /*-----------------------------------------------------------------*/
577 /* ifPointerGet - returns true if the icode is pointer get sym     */
578 /*-----------------------------------------------------------------*/
579 DEFSETFUNC (ifPointerGet)
580 {
581   cseDef *cdp = item;
582   V_ARG (operand *, op);
583   iCode *dic = cdp->diCode;
584   operand *left = IC_LEFT (cdp->diCode);
585
586   if (POINTER_GET (dic) && left->key == op->key)
587     return 1;
588
589   return 0;
590 }
591
592 /*-----------------------------------------------------------------*/
593 /* ifPointerSet - returns true if the icode is pointer set sym     */
594 /*-----------------------------------------------------------------*/
595 DEFSETFUNC (ifPointerSet)
596 {
597   cseDef *cdp = item;
598   V_ARG (operand *, op);
599
600   if (POINTER_SET (cdp->diCode) &&
601       IC_RESULT (cdp->diCode)->key == op->key)
602     return 1;
603
604   return 0;
605 }
606
607 /*-----------------------------------------------------------------*/
608 /* ifDiCodeIsX - will return 1 if the symbols match                 */
609 /*-----------------------------------------------------------------*/
610 DEFSETFUNC (ifDiCodeIsX)
611 {
612   cseDef *cdp = item;
613   V_ARG (iCode *, ic);
614
615   return cdp->diCode == ic;
616
617 }
618
619 /*-----------------------------------------------------------------*/
620 /* findBackwardDef - scan backwards to find deinition of operand   */
621 /*-----------------------------------------------------------------*/
622 iCode *findBackwardDef(operand *op,iCode *ic)
623 {
624     iCode *lic;
625
626     for (lic = ic; lic ; lic = lic->prev) {
627         if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
628             return lic;
629     }
630     return NULL;
631 }
632
633 /*-----------------------------------------------------------------*/
634 /* algebraicOpts - does some algebraic optimizations               */
635 /*-----------------------------------------------------------------*/
636 static void
637 algebraicOpts (iCode * ic, eBBlock * ebp)
638 {
639   /* we don't deal with the following iCodes
640      here */
641   if (ic->op == IFX ||
642       ic->op == IPUSH ||
643       ic->op == IPOP ||
644       ic->op == CALL ||
645       ic->op == PCALL ||
646       ic->op == RETURN ||
647       POINTER_GET (ic))
648     return;
649
650   /* if both operands present & ! IFX */
651   /* then if they are both literal we */
652   /* perform the operation right now  */
653   if (IC_RESULT (ic) &&
654       IC_RIGHT (ic) &&
655       IC_LEFT (ic) &&
656       IS_OP_LITERAL (IC_LEFT (ic)) &&
657       IS_OP_LITERAL (IC_RIGHT (ic)))
658     {
659
660       IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
661                                         IC_RIGHT (ic),
662                                         ic->op,
663                                         operandType (IC_RESULT (ic)));
664       ic->op = '=';
665       IC_LEFT (ic) = NULL;
666       SET_RESULT_RIGHT (ic);
667       return;
668
669     }
670   /* if not ifx & only one operand present */
671   if (IC_RESULT (ic) &&
672       IC_LEFT (ic) &&
673       IS_OP_LITERAL (IC_LEFT (ic)) &&
674       !IC_RIGHT (ic))
675     {
676
677       IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
678                                         IC_RIGHT (ic),
679                                         ic->op,
680                                         operandType (IC_RESULT (ic)));
681       ic->op = '=';
682       IC_LEFT (ic) = NULL;
683       SET_RESULT_RIGHT (ic);
684       return;
685     }
686
687
688   /* a special case : or in short a kludgy solution will think
689      about a better solution over a glass of wine someday */
690   if (ic->op == GET_VALUE_AT_ADDRESS)
691     {
692
693       if (IS_ITEMP (IC_RESULT (ic)) &&
694           IS_TRUE_SYMOP (IC_LEFT (ic)))
695         {
696
697           ic->op = '=';
698           IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
699           IC_RIGHT (ic)->isaddr = 0;
700           IC_LEFT (ic) = NULL;
701           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
702           IC_RESULT (ic)->isaddr = 0;
703           setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
704           return;
705         }
706
707       if (IS_ITEMP (IC_LEFT (ic)) &&
708           IS_ITEMP (IC_RESULT (ic)) &&
709 /*      !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
710 /*      !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
711           !IC_LEFT (ic)->isaddr)
712         {
713           ic->op = '=';
714           IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
715           IC_RIGHT (ic)->isaddr = 0;
716           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
717           IC_RESULT (ic)->isaddr = 0;
718           IC_LEFT (ic) = NULL;
719           return;
720         }
721
722     }
723
724
725   /* depending on the operation */
726   switch (ic->op)
727     {
728     case '+':
729       /* if adding the same thing change to left shift by 1 */
730       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
731           !IS_FLOAT (operandType (IC_RESULT (ic))))
732         {
733           ic->op = LEFT_OP;
734           IC_RIGHT (ic) = operandFromLit (1);
735           return;
736         }
737       /* if addition then check if one of them is a zero */
738       /* if yes turn it  into assignmnt */
739       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
740           operandLitValue (IC_LEFT (ic)) == 0.0)
741         {
742
743           ic->op = '=';
744           IC_LEFT (ic) = NULL;
745           SET_ISADDR (IC_RESULT (ic), 0);
746           SET_ISADDR (IC_RIGHT (ic), 0);
747           return;
748         }
749       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
750           operandLitValue (IC_RIGHT (ic)) == 0.0)
751         {
752
753           ic->op = '=';
754           IC_RIGHT (ic) = IC_LEFT (ic);
755           IC_LEFT (ic) = 0;
756           SET_ISADDR (IC_RIGHT (ic), 0);
757           SET_ISADDR (IC_RESULT (ic), 0);
758           return;
759         }
760       break;
761     case '-':
762       /* if subtracting the the same thing then zero     */
763       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
764         {
765           ic->op = '=';
766           IC_RIGHT (ic) = operandFromLit (0);
767           IC_LEFT (ic) = NULL;
768           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
769           IC_RESULT (ic)->isaddr = 0;
770           return;
771         }
772
773       /* if subtraction then check if one of the operand */
774       /* is zero then depending on which operand change  */
775       /* to assignment or unary minus                    */
776       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
777           operandLitValue (IC_RIGHT (ic)) == 0.0)
778         {
779           /* right size zero change to assignment */
780           ic->op = '=';
781           IC_RIGHT (ic) = IC_LEFT (ic);
782           IC_LEFT (ic) = NULL;
783           SET_ISADDR (IC_RIGHT (ic), 0);
784           SET_ISADDR (IC_RESULT (ic), 0);
785           return;
786         }
787       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
788           operandLitValue (IC_LEFT (ic)) == 0.0)
789         {
790           /* left zero turn into an unary minus */
791           ic->op = UNARYMINUS;
792           IC_LEFT (ic) = IC_RIGHT (ic);
793           IC_RIGHT (ic) = NULL;
794           return;
795         }
796       break;
797       /* if multiplication then check if either of */
798       /* them is zero then the result is zero      */
799       /* if either of them is one then result is   */
800       /* the other one                             */
801     case '*':
802       if (IS_OP_LITERAL (IC_LEFT (ic)))
803         {
804
805           if (operandLitValue (IC_LEFT (ic)) == 0.0)
806             {
807               ic->op = '=';
808               IC_RIGHT (ic) = IC_LEFT (ic);
809               IC_LEFT (ic) = NULL;
810               SET_RESULT_RIGHT (ic);
811               return;
812             }
813           if (operandLitValue (IC_LEFT (ic)) == 1.0)
814             {
815               /* '*' can have two unsigned chars as operands */
816               /* and an unsigned int as result.              */
817               if (compareType (operandType (IC_RESULT (ic)),
818                                operandType (IC_RIGHT (ic))) == 1)
819                 {
820                   ic->op = '=';
821                   IC_LEFT (ic) = NULL;
822                   SET_RESULT_RIGHT (ic);
823                 }
824               else
825                 {
826                   ic->op = CAST;
827                   IC_LEFT (ic)->type = TYPE;
828                   IC_LEFT (ic)->isLiteral = 0;
829                   setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
830                 }
831               return;
832             }
833         }
834
835       if (IS_OP_LITERAL (IC_RIGHT (ic)))
836         {
837
838           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
839             {
840               ic->op = '=';
841               IC_LEFT (ic) = NULL;
842               SET_RESULT_RIGHT (ic);
843               return;
844             }
845
846           if (operandLitValue (IC_RIGHT (ic)) == 1.0)
847             {
848               /* '*' can have two unsigned chars as operands */
849               /* and an unsigned int as result.              */
850               if (compareType (operandType (IC_RESULT (ic)),
851                                operandType (IC_LEFT (ic))) == 1)
852                 {
853                   ic->op = '=';
854                   IC_RIGHT (ic) = IC_LEFT (ic);
855                   IC_LEFT (ic) = NULL;
856                   SET_RESULT_RIGHT (ic);
857                 }
858               else
859                 {
860                   operand *op;
861
862                   ic->op = CAST;
863                   op = IC_RIGHT (ic);
864                   IC_RIGHT (ic) = IC_LEFT (ic);
865                   IC_LEFT (ic) = op;
866                   IC_LEFT (ic)->type = TYPE;
867                   IC_LEFT (ic)->isLiteral = 0;
868                   setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
869                 }
870               return;
871             }
872         }
873       break;
874     case '/':
875       /* if division by self then 1 */
876       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
877         {
878           ic->op = '=';
879           IC_RIGHT (ic) = operandFromLit (1);
880           IC_LEFT (ic) = NULL;
881           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
882           IC_RESULT (ic)->isaddr = 0;
883           break;
884         }
885       /* if this is a division then check if right */
886       /* is one then change it to an assignment    */
887       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
888           operandLitValue (IC_RIGHT (ic)) == 1.0)
889         {
890
891           ic->op = '=';
892           IC_RIGHT (ic) = IC_LEFT (ic);
893           IC_LEFT (ic) = NULL;
894           SET_RESULT_RIGHT (ic);
895           return;
896         }
897       break;
898       /* if both are the same for an comparison operators */
899     case EQ_OP:
900     case LE_OP:
901     case GE_OP:
902       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
903         {
904           ic->op = '=';
905           IC_RIGHT (ic) = operandFromLit (1);
906           IC_LEFT (ic) = NULL;
907           SET_RESULT_RIGHT (ic);
908         }
909       break;
910     case NE_OP:
911     case '>':
912     case '<':
913       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
914         {
915           ic->op = '=';
916           IC_RIGHT (ic) = operandFromLit (0);
917           IC_LEFT (ic) = NULL;
918           SET_RESULT_RIGHT (ic);
919         }
920       break;
921     case CAST:
922             {
923                     sym_link *otype = operandType(IC_RIGHT(ic));
924                     sym_link *ctype = operandType(IC_LEFT(ic));
925                     /* if this is a cast of a literal value */
926                     if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
927                         !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
928                             ic->op = '=';
929                             IC_RIGHT (ic) =
930                                     operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
931                                                                       operandLitValue (IC_RIGHT (ic))));
932                             IC_LEFT (ic) = NULL;
933                             SET_ISADDR (IC_RESULT (ic), 0);
934                     }
935                     /* if casting to the same */
936                     if (compareType (operandType (IC_RESULT (ic)),
937                                      operandType (IC_RIGHT (ic))) == 1) {
938                             ic->op = '=';
939                             IC_LEFT (ic) = NULL;
940                             SET_ISADDR (IC_RESULT (ic), 0);
941                     }
942             }
943             break;
944     case '!':
945       if (IS_OP_LITERAL (IC_LEFT (ic)))
946         {
947           ic->op = '=';
948           IC_RIGHT (ic) =
949             (operandLitValue (IC_LEFT (ic)) == 0 ?
950              operandFromLit (1) : operandFromLit (0));
951           IC_LEFT (ic) = NULL;
952           SET_ISADDR (IC_RESULT (ic), 0);
953         }
954       break;
955     case BITWISEAND:
956       /* if both operands are equal */
957       /* if yes turn it into assignment */
958       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
959         {
960           if (IS_OP_VOLATILE (IC_LEFT (ic)))
961             {
962               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
963               IC_RESULT (newic) = IC_LEFT (ic);
964               newic->lineno = ic->lineno;
965               addiCodeToeBBlock (ebp, newic, ic->next);
966             }
967           ic->op = '=';
968           IC_LEFT (ic) = NULL;
969           SET_RESULT_RIGHT (ic);
970           return;
971         }
972       /* swap literal to right ic */
973       if (IS_OP_LITERAL (IC_LEFT (ic)))
974         {
975           operand *op;
976
977           op = IC_LEFT (ic);
978           IC_LEFT (ic) = IC_RIGHT (ic);
979           IC_RIGHT (ic) = op;
980         }
981       if (IS_OP_LITERAL (IC_RIGHT (ic)))
982         {
983           /* if BITWISEAND then check if one of them is a zero */
984           /* if yes turn it into 0 assignment */
985           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
986             {
987               if (IS_OP_VOLATILE (IC_LEFT (ic)))
988                 {
989                   iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
990                   IC_RESULT (newic) = IC_LEFT (ic);
991                   newic->lineno = ic->lineno;
992                   addiCodeToeBBlock (ebp, newic, ic->next);
993                 }
994               ic->op = '=';
995               IC_LEFT (ic) = NULL;
996               SET_RESULT_RIGHT (ic);
997               return;
998             }
999           /* if BITWISEAND then check if one of them is 0xff... */
1000           /* if yes turn it into assignment */
1001           {
1002             unsigned val;
1003
1004             switch (getSize (operandType (IC_RIGHT (ic))))
1005               {
1006               case 1:
1007                 val = 0xff;
1008                 break;
1009               case 2:
1010                 val = 0xffff;
1011                 break;
1012               case 4:
1013                 val = 0xffffffff;
1014                 break;
1015               default:
1016                 return;
1017               }
1018             if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1019             {
1020               ic->op = '=';
1021               IC_RIGHT (ic) = IC_LEFT (ic);
1022               IC_LEFT (ic) = NULL;
1023               SET_RESULT_RIGHT (ic);
1024               return;
1025             }
1026           }
1027         }
1028       break;
1029     case '|':
1030       /* if both operands are equal */
1031       /* if yes turn it into assignment */
1032       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1033         {
1034           if (IS_OP_VOLATILE (IC_LEFT (ic)))
1035             {
1036               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1037               IC_RESULT (newic) = IC_LEFT (ic);
1038               newic->lineno = ic->lineno;
1039               addiCodeToeBBlock (ebp, newic, ic->next);
1040             }
1041             ic->op = '=';
1042             IC_LEFT (ic) = NULL;
1043             SET_RESULT_RIGHT (ic);
1044             return;
1045         }
1046       /* swap literal to right ic */
1047       if (IS_OP_LITERAL (IC_LEFT (ic)))
1048         {
1049           operand *op;
1050
1051           op = IC_LEFT (ic);
1052           IC_LEFT (ic) = IC_RIGHT (ic);
1053           IC_RIGHT (ic) = op;
1054         }
1055       if (IS_OP_LITERAL (IC_RIGHT (ic)))
1056         {
1057           /* if BITWISEOR then check if one of them is a zero */
1058           /* if yes turn it into assignment */
1059           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1060             {
1061               ic->op = '=';
1062               IC_RIGHT (ic) = IC_LEFT (ic);
1063               IC_LEFT (ic) = NULL;
1064               SET_RESULT_RIGHT (ic);
1065               return;
1066             }
1067           /* if BITWISEOR then check if one of them is 0xff... */
1068           /* if yes turn it into 0xff... assignment */
1069           {
1070             unsigned val;
1071
1072             switch (getSize (operandType (IC_RIGHT (ic))))
1073               {
1074               case 1:
1075                 val = 0xff;
1076                 break;
1077               case 2:
1078                 val = 0xffff;
1079                 break;
1080               case 4:
1081                 val = 0xffffffff;
1082                 break;
1083               default:
1084                 return;
1085               }
1086             if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1087               {
1088                 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1089                 {
1090                   iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1091                   IC_RESULT (newic) = IC_LEFT (ic);
1092                   newic->lineno = ic->lineno;
1093                   addiCodeToeBBlock (ebp, newic, ic->next);
1094                 }
1095                 ic->op = '=';
1096                 IC_LEFT (ic) = NULL;
1097                 SET_RESULT_RIGHT (ic);
1098                 return;
1099               }
1100           }
1101         }
1102       break;
1103     case '^':
1104       /* if both operands are equal */
1105       /* if yes turn it into 0 assignment */
1106       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1107         {
1108           if (IS_OP_VOLATILE (IC_LEFT (ic)))
1109             {
1110               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1111               IC_RESULT (newic) = IC_LEFT (ic);
1112               newic->lineno = ic->lineno;
1113               addiCodeToeBBlock (ebp, newic, ic->next);
1114
1115               newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1116               IC_RESULT (newic) = IC_LEFT (ic);
1117               newic->lineno = ic->lineno;
1118               addiCodeToeBBlock (ebp, newic, ic->next);
1119             }
1120             ic->op = '=';
1121             IC_RIGHT (ic) = operandFromLit (0);
1122             IC_LEFT (ic) = NULL;
1123             SET_RESULT_RIGHT (ic);
1124             return;
1125         }
1126       /* swap literal to right ic */
1127       if (IS_OP_LITERAL (IC_LEFT (ic)))
1128         {
1129           operand *op;
1130
1131           op = IC_LEFT (ic);
1132           IC_LEFT (ic) = IC_RIGHT (ic);
1133           IC_RIGHT (ic) = op;
1134         }
1135       /* if XOR then check if one of them is a zero */
1136       /* if yes turn it into assignment */
1137       if (IS_OP_LITERAL (IC_RIGHT (ic)))
1138         {
1139           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1140             {
1141               ic->op = '=';
1142               IC_RIGHT (ic) = IC_LEFT (ic);
1143               IC_LEFT (ic) = NULL;
1144               SET_RESULT_RIGHT (ic);
1145               return;
1146             }
1147         }
1148       break;
1149     }
1150
1151   return;
1152 }
1153 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1154 /*-----------------------------------------------------------------*/
1155 /* updateSpillLocation - keeps track of register spill location    */
1156 /*-----------------------------------------------------------------*/
1157 void
1158 updateSpillLocation (iCode * ic, int induction)
1159 {
1160         sym_link *setype;
1161
1162         if (POINTER_SET (ic))
1163                 return;
1164
1165         if (ic->nosupdate)
1166                 return;
1167
1168 #if 0
1169         /* for the form true_symbol := iTempNN */
1170         if (ASSIGN_ITEMP_TO_SYM (ic) && 
1171             !SPIL_LOC (IC_RIGHT (ic))) {
1172
1173                 setype = getSpec (operandType (IC_RESULT (ic)));
1174
1175                 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1176                     !IS_VOLATILE (setype) &&
1177                     !IN_FARSPACE (SPEC_OCLS (setype)) &&
1178                     !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1179                 {
1180                     wassert(IS_SYMOP(IC_RESULT (ic)));
1181                     wassert(IS_SYMOP(IC_RIGHT (ic)));
1182                         SPIL_LOC (IC_RIGHT (ic)) =
1183                                 IC_RESULT (ic)->operand.symOperand;
1184                 }
1185             
1186         }
1187 #endif
1188
1189 #if 0 /* this needs furthur investigation can save a lot of code */
1190         if (ASSIGN_SYM_TO_ITEMP(ic) &&
1191             !SPIL_LOC(IC_RESULT(ic))) {
1192             if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1193                 SPIL_LOC (IC_RESULT (ic)) =
1194                     IC_RIGHT (ic)->operand.symOperand;
1195         }
1196 #endif
1197         if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1198           
1199                 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1200                     !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1201                     OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1202
1203                         setype = getSpec (operandType (IC_RESULT (ic)));
1204               
1205                         if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1206                             !IS_VOLATILE (setype) &&
1207                             !IN_FARSPACE (SPEC_OCLS (setype)) &&
1208                             !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1209
1210                                 SPIL_LOC (IC_RIGHT (ic)) =
1211                                         SPIL_LOC (IC_RESULT (ic));
1212                 }
1213                 /* special case for inductions */
1214                 if (induction && 
1215                     OP_SYMBOL(IC_RIGHT(ic))->isreqv && 
1216                     !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1217                     !SPIL_LOC(IC_RESULT(ic))) {
1218                         SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1219                 }
1220         }
1221 }
1222 /*-----------------------------------------------------------------*/
1223 /* setUsesDef - sets the uses def bitvector for a given operand    */
1224 /*-----------------------------------------------------------------*/
1225 void 
1226 setUsesDefs (operand * op, bitVect * bdefs,
1227              bitVect * idefs, bitVect ** oud)
1228 {
1229   /* compute the definitions alive at this point */
1230   bitVect *adefs = bitVectUnion (bdefs, idefs);
1231
1232   /* of these definitions find the ones that are */
1233   /* for this operand */
1234   adefs = bitVectIntersect (adefs, OP_DEFS (op));
1235
1236   /* these are the definitions that this operand can use */
1237   op->usesDefs = adefs;
1238
1239   /* the out defs is an union */
1240   *oud = bitVectUnion (*oud, adefs);
1241 }
1242
1243 /*-----------------------------------------------------------------*/
1244 /* unsetDefsAndUses - clear this operation for the operands        */
1245 /*-----------------------------------------------------------------*/
1246 void 
1247 unsetDefsAndUses (iCode * ic)
1248 {
1249   if (ic->op == JUMPTABLE)
1250     return;
1251
1252   /* take away this definition from the def chain of the */
1253   /* result & take away from use set of the operands */
1254   if (ic->op != IFX)
1255     {
1256       /* turn off def set */
1257       if (IS_SYMOP (IC_RESULT (ic)))
1258         {
1259           if (!POINTER_SET (ic))
1260             bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1261           else
1262             bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1263         }
1264       /* turn off the useSet for the operands */
1265       if (IS_SYMOP (IC_LEFT (ic)))
1266         bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1267
1268       if (IS_SYMOP (IC_RIGHT (ic)))
1269         bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1270     }
1271   else
1272     /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1273     bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1274 }
1275
1276 /*-----------------------------------------------------------------*/
1277 /* ifxOptimize - changes ifx conditions if it can                  */
1278 /*-----------------------------------------------------------------*/
1279 void 
1280 ifxOptimize (iCode * ic, set * cseSet,
1281              int computeOnly,
1282              eBBlock * ebb, int *change,
1283              eBBlock ** ebbs, int count)
1284 {
1285   operand *pdop;
1286   symbol *label;
1287
1288   /* if the condition can be replaced */
1289   if (!computeOnly)
1290     {
1291       pdop = NULL;
1292       applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1293       if (pdop)
1294         {
1295           ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1296           (*change)++;
1297         }
1298     }
1299
1300   /* if the conditional is a literal then */
1301   if (IS_OP_LITERAL (IC_COND (ic)))
1302     {
1303
1304       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1305         {
1306
1307           /* change to a goto */
1308           ic->op = GOTO;
1309           IC_LABEL (ic) = IC_TRUE (ic);
1310           (*change)++;
1311
1312         }
1313       else
1314         {
1315
1316           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1317             {
1318               ic->op = GOTO;
1319               IC_LABEL (ic) = IC_FALSE (ic);
1320               (*change)++;
1321
1322             }
1323           else
1324             {
1325               /* then kill this if condition */
1326               remiCodeFromeBBlock (ebb, ic);
1327             }
1328         }
1329
1330       /* now we need to recompute the control flow */
1331       /* since the control flow has changed        */
1332       /* this is very expensive but it does not happen */
1333       /* too often, if it does happen then the user pays */
1334       /* the price */
1335       computeControlFlow (ebbs, count, 1);
1336       if (!options.lessPedantic) {
1337         werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1338       }
1339       return;
1340     }
1341
1342   /* if there is only one successor and that successor
1343      is the same one we are conditionally going to then
1344      we can remove this conditional statement */
1345   label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1346   if (elementsInSet (ebb->succList) == 1 &&
1347       isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1348     {
1349
1350       remiCodeFromeBBlock (ebb, ic);
1351       computeControlFlow (ebbs, count, 1);
1352       if (!options.lessPedantic) {
1353         werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1354       }
1355       return;
1356     }
1357
1358
1359   /* if it remains an IFX the update the use Set */
1360   OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1361   setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1362   return;
1363 }
1364
1365 /*-----------------------------------------------------------------*/
1366 /* diCodeForSym - finds the definiting instruction for a symbol    */
1367 /*-----------------------------------------------------------------*/
1368 DEFSETFUNC (diCodeForSym)
1369 {
1370   cseDef *cdp = item;
1371   V_ARG (operand *, sym);
1372   V_ARG (iCode **, dic);
1373
1374   /* if already found */
1375   if (*dic)
1376     return 0;
1377
1378   /* if not if this is the defining iCode */
1379   if (sym->key == cdp->key)
1380     {
1381       *dic = cdp->diCode;
1382       return 1;
1383     }
1384
1385   return 0;
1386 }
1387
1388 /*-----------------------------------------------------------------*/
1389 /* constFold - does some constant folding                          */
1390 /*-----------------------------------------------------------------*/
1391 int 
1392 constFold (iCode * ic, set * cseSet)
1393 {
1394   iCode *dic = NULL;
1395   iCode *ldic = NULL;
1396   /* this routine will change
1397      a = b + 10;
1398      c = a + 10;
1399      to
1400      c = b + 20; */
1401
1402   /* deal with only + & - */
1403   if (ic->op != '+' &&
1404       ic->op != '-')
1405     return 0;
1406
1407   /* this check is a hueristic to prevent live ranges
1408      from becoming too long */
1409   if (IS_PTR (operandType (IC_RESULT (ic))))
1410       return 0;
1411
1412   /* check if operation with a literal */
1413   if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1414     return 0;
1415
1416   /* check if we can find a definition for the
1417      right hand side */
1418   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1419     return 0;
1420
1421   /* check that this is also a +/-  */
1422   if (dic->op != '+' && dic->op != '-')
1423     return 0;
1424
1425   /* with a literal */
1426   if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1427     return 0;
1428
1429   /* find the definition of the left operand
1430      of dic.then check if this defined with a
1431      get_pointer return 0 if the pointer size is
1432      less than 2 (MCS51 specific) */
1433   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1434     return 0;
1435
1436   if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1437     return 0;
1438
1439   /* it is if the operations are the same */
1440   /* the literal parts need to be added  */
1441   IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1442   if (ic->op == dic->op)
1443     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1444                                     operandLitValue (IC_RIGHT (dic)));
1445   else
1446     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1447                                     operandLitValue (IC_RIGHT (dic)));
1448
1449   if (IS_ITEMP (IC_RESULT (ic)))
1450     {
1451       SPIL_LOC (IC_RESULT (ic)) = NULL;
1452       OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1453     }
1454
1455
1456   return 1;
1457 }
1458
1459 /*-----------------------------------------------------------------*/
1460 /* deleteGetPointers - called when a pointer is passed as parm     */
1461 /* will delete from cseSet all get pointers computed from this     */
1462 /* pointer. A simple ifOperandsHave is not good enough here        */
1463 /*-----------------------------------------------------------------*/
1464 static void 
1465 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1466 {
1467   set *compItems = NULL;
1468   cseDef *cdp;
1469   operand *cop;
1470
1471   /* easy return */
1472   if (!*cseSet && !*pss)
1473     return;
1474
1475   /* first find all items computed from this operand .
1476      This done fairly simply go thru the list and find
1477      those that are computed by arthimetic with this
1478      op */
1479   for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1480     {
1481       if (IS_ARITHMETIC_OP (cdp->diCode))
1482         {
1483           if (isOperandEqual (IC_LEFT (cdp->diCode), op) ||
1484               isOperandEqual (IC_RIGHT (cdp->diCode), op))
1485             {
1486               /* save it in our list of items */
1487               addSet (&compItems, IC_RESULT (cdp->diCode));
1488             }
1489           /* also check for those computed from our computed
1490              list . This will take care of situations like
1491              iTemp1 = iTemp0 + 8;
1492              iTemp2 = iTemp1 + 8; */
1493           if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1494                            (insetwithFunc)isOperandEqual) ||
1495               isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1496                            (insetwithFunc)isOperandEqual))
1497             {
1498               addSet (&compItems, IC_RESULT (cdp->diCode));
1499             }
1500         }
1501     }
1502
1503   /* now delete all pointer gets with this op */
1504   deleteItemIf (cseSet, ifPointerGet, op);
1505   deleteItemIf (pss, ifPointerSet, op);
1506
1507   /* set the bit vector used by dataFlow computation later */
1508   ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key);
1509   /* now for the computed items */
1510   for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1511     {
1512       ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1513       deleteItemIf (cseSet, ifPointerGet, cop);
1514       deleteItemIf (pss, ifPointerSet, cop);
1515     }
1516 }
1517
1518 /*-----------------------------------------------------------------*/
1519 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1520 /*                     dfnum > supplied                            */
1521 /*-----------------------------------------------------------------*/
1522 DEFSETFUNC (delGetPointerSucc)
1523 {
1524   eBBlock *ebp = item;
1525   V_ARG (operand *, op);
1526   V_ARG (int, dfnum);
1527
1528   if (ebp->visited)
1529     return 0;
1530
1531   ebp->visited = 1;
1532   if (ebp->dfnum > dfnum)
1533     {
1534       deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1535     }
1536
1537   return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1538 }
1539
1540 /*-----------------------------------------------------------------*/
1541 /* fixUpTypes - KLUGE HACK fixup a lowering problem                */
1542 /*-----------------------------------------------------------------*/
1543 static void
1544 fixUpTypes (iCode * ic)
1545 {
1546   sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1547
1548   /* if (TARGET_IS_DS390) */
1549   if (options.model == MODEL_FLAT24)
1550     {
1551       /* hack-o-matic! */
1552       return;
1553     }
1554
1555   /* for pointer_gets if the types of result & left r the
1556      same then change it type of result to next */
1557   if (IS_PTR (t1) &&
1558       compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1559     {
1560       setOperandType (IC_RESULT (ic), t2->next);
1561     }
1562 }
1563
1564 /*-----------------------------------------------------------------*/
1565 /* isSignedOp - will return 1 if sign is important to operation    */
1566 /*-----------------------------------------------------------------*/
1567 static int isSignedOp (iCode *ic)
1568 {
1569     switch (ic->op) {
1570     case '!':
1571     case '~':
1572     case UNARYMINUS:
1573     case IPUSH:
1574     case IPOP:
1575     case CALL:
1576     case PCALL:
1577     case RETURN:
1578     case '+':
1579     case '-':
1580     case EQ_OP:
1581     case AND_OP:
1582     case OR_OP:
1583     case '^':
1584     case '|':
1585     case BITWISEAND:
1586     case INLINEASM:
1587     case LEFT_OP:
1588     case GET_VALUE_AT_ADDRESS:
1589     case '=':
1590     case IFX:
1591     case RECEIVE:
1592     case SEND:
1593         return 0;
1594     case '*':
1595     case '/':
1596     case '%':
1597     case '>':
1598     case '<':
1599     case LE_OP:
1600     case GE_OP:
1601     case NE_OP:
1602     case RRC:
1603     case RLC:
1604     case GETHBIT:
1605     case RIGHT_OP:
1606     case CAST:
1607     case ARRAYINIT:
1608         return 1;
1609     default:
1610         return 0;
1611     }
1612  }
1613
1614 /*-----------------------------------------------------------------*/
1615 /* cseBBlock - common subexpression elimination for basic blocks   */
1616 /*             this is the hackiest kludgiest routine in the whole */
1617 /*             system. also the most important, since almost all   */
1618 /*             data flow related information is computed by it     */
1619 /*-----------------------------------------------------------------*/
1620 int
1621 cseBBlock (eBBlock * ebb, int computeOnly,
1622            eBBlock ** ebbs, int count)
1623 {
1624   set *cseSet;
1625   iCode *ic;
1626   int change = 0;
1627   int i;
1628   set *ptrSetSet = NULL;
1629
1630   /* if this block is not reachable */
1631   if (ebb->noPath)
1632     return 0;
1633
1634   /* set of common subexpressions */
1635   cseSet = setFromSet (ebb->inExprs);
1636
1637   /* these will be computed by this routine */
1638   setToNull ((void *) &ebb->outDefs);
1639   setToNull ((void *) &ebb->defSet);
1640   setToNull ((void *) &ebb->usesDefs);
1641   setToNull ((void *) &ebb->ptrsSet);
1642   setToNull ((void *) &ebb->addrOf);
1643   setToNull ((void *) &ebb->ldefs);
1644
1645   ebb->outDefs = bitVectCopy (ebb->inDefs);
1646   bitVectDefault = iCodeKey;
1647   ebb->defSet = newBitVect (iCodeKey);
1648   ebb->usesDefs = newBitVect (iCodeKey);
1649
1650   /* for all the instructions in this block do */
1651   for (ic = ebb->sch; ic; ic = ic->next)
1652     {
1653       iCode *pdic;
1654       operand *pdop;
1655       iCode *defic;
1656       int checkSign ;
1657
1658       ic->eBBlockNum = ebb->bbnum;
1659
1660       if (SKIP_IC2 (ic))
1661         continue;
1662
1663       /* if this is an assignment from true symbol
1664          to a temp then do pointer post inc/dec optimzation */
1665       if (ic->op == '=' && !POINTER_SET (ic) &&
1666           IS_PTR (operandType (IC_RESULT (ic))))
1667         {
1668           ptrPostIncDecOpt (ic);
1669         }
1670
1671       /* clear the def & use chains for the operands involved */
1672       /* in this operation . since it can change due to opts  */
1673       unsetDefsAndUses (ic);
1674
1675       if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1676         {
1677           /* add to defSet of the symbol */
1678           OP_DEFS(IC_RESULT (ic))=
1679             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1680           /* add to the definition set of this block */
1681           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1682           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1683           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1684           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1685           /* delete global variables from the cseSet
1686              since they can be modified by the function call */
1687           deleteItemIf (&cseSet, ifDefGlobal);
1688
1689           /* and also itemps assigned from globals */
1690           deleteItemIf (&cseSet, ifAssignedFromGlobal);
1691
1692           /* delete all getpointer iCodes from cseSet, this should
1693              be done only for global arrays & pointers but at this
1694              point we don't know if globals, so to be safe do all */
1695           deleteItemIf (&cseSet, ifAnyGetPointer);
1696         }
1697
1698       /* for pcall & ipush we need to add to the useSet */
1699       if ((ic->op == PCALL ||
1700            ic->op == IPUSH ||
1701            ic->op == IPOP ||
1702            ic->op == SEND) &&
1703           IS_SYMOP (IC_LEFT (ic)))
1704         {
1705
1706           /* check if they can be replaced */
1707           if (!computeOnly)
1708             {
1709               pdop = NULL;
1710               applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1711               if (pdop)
1712                 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1713             }
1714           /* the lookup could have changed it */
1715           if (IS_SYMOP (IC_LEFT (ic)))
1716             {
1717               OP_USES(IC_LEFT (ic))=
1718                 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1719               setUsesDefs (IC_LEFT (ic), ebb->defSet,
1720                            ebb->outDefs, &ebb->usesDefs);
1721             }
1722
1723
1724           /* if we a sending a pointer as a parameter
1725              then kill all cse since the pointed to item
1726              might be changed in the function being called */
1727           if ((ic->op == IPUSH || ic->op == SEND) &&
1728               IS_PTR (operandType (IC_LEFT (ic))))
1729             {
1730               deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1731               ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1732               for (i = 0; i < count; ebbs[i++]->visited = 0);
1733               applyToSet (ebb->succList, delGetPointerSucc,
1734                           IC_LEFT (ic), ebb->dfnum);
1735             }
1736           continue;
1737         }
1738
1739       /* if jumptable then mark the usage */
1740       if (ic->op == JUMPTABLE)
1741         {
1742           if (IS_SYMOP (IC_JTCOND (ic)))
1743             {
1744               OP_USES(IC_JTCOND (ic)) =
1745                 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1746               setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1747                            ebb->outDefs, &ebb->usesDefs);
1748             }
1749           continue;
1750         }
1751
1752       if (SKIP_IC (ic))
1753         continue;
1754
1755       if (!computeOnly) {
1756         /* do some algebraic optimizations if possible */
1757         algebraicOpts (ic, ebb);
1758         while (constFold (ic, cseSet));
1759       }
1760
1761       /* small klugde */
1762       if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1763         {
1764           setOperandType (IC_LEFT (ic),
1765                           aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1766           fixUpTypes (ic);
1767
1768         }
1769       if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1770         {
1771           setOperandType (IC_RESULT (ic),
1772                           aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1773         }
1774
1775       /* if this is a condition statement then */
1776       /* check if the condition can be replaced */
1777       if (ic->op == IFX)
1778         {
1779           ifxOptimize (ic, cseSet, computeOnly,
1780                        ebb, &change,
1781                        ebbs, count);
1782           continue;
1783         }
1784
1785       /* if the assignment & result is a temp */
1786       /* see if we can replace it             */
1787       if (!computeOnly && ic->op == '=')
1788         {
1789
1790           /* update the spill location for this */
1791           updateSpillLocation (ic,0);
1792
1793           if (POINTER_SET (ic) &&
1794               !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1795             {
1796               pdop = NULL;
1797               applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1798               if (pdop && !computeOnly &&
1799                   IS_ITEMP (pdop) && IS_PTR(operandType(pdop)))
1800                 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1801             }
1802         }
1803
1804       checkSign = isSignedOp(ic);
1805
1806       /* do the operand lookup i.e. for both the */
1807       /* right & left operand : check the cseSet */
1808       /* to see if they have been replaced if yes */
1809       /* then replace them with those from cseSet */
1810       /* left operand */
1811       /* and left is a symbol  */
1812       if (IS_SYMOP (IC_LEFT (ic)) &&
1813           !computeOnly && ic->op != ADDRESS_OF)
1814         {
1815
1816           pdop = NULL;
1817           applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1818           if (pdop)
1819             {
1820               if (POINTER_GET (ic))
1821                 {
1822                   if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1823                     {
1824                         /* some non dominating block does POINTER_SET with
1825                            this variable .. unsafe to remove any POINTER_GETs */
1826                         if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1827                             ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1828                         ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1829                       change = 1;
1830                     }
1831                   /* check if there is a pointer set
1832                      for the same pointer visible if yes
1833                      then change this into an assignment */
1834                   pdop = NULL;
1835                   if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1836                       !bitVectBitValue (ebb->ptrsSet, pdop->key))
1837                     {
1838                       ic->op = '=';
1839                       IC_LEFT (ic) = NULL;
1840                       ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1841                       SET_ISADDR (IC_RESULT (ic), 0);
1842                     }
1843
1844                 }
1845               else
1846                 {
1847                   ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1848                   change = 1;
1849                 }
1850             }
1851         }
1852
1853       /*right operand */
1854       if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1855         {
1856
1857           pdop = NULL;
1858           applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1859           if (pdop) {
1860             ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1861             change = 1;
1862           }
1863         }
1864
1865       /* if left or right changed then do algebraic */
1866       if (!computeOnly && change)
1867         {
1868           algebraicOpts (ic, ebb);
1869           while (constFold (ic, cseSet));
1870         }
1871
1872       /* if after all this it becomes an assignment to self
1873          then delete it and continue */
1874       if (ASSIGNMENT_TO_SELF (ic))
1875         {
1876           remiCodeFromeBBlock (ebb, ic);
1877           continue;
1878         }
1879
1880       /* now we will check to see if the entire */
1881       /* operation has been performed before    */
1882       /* and is available                       */
1883       /* don't do assignments they will be killed */
1884       /* by dead code elimination if required  do */
1885       /* it only if result is a temporary         */
1886       pdic = NULL;
1887       if (!(POINTER_GET (ic) &&
1888             (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1889              isOperandVolatile (IC_LEFT (ic), TRUE) ||
1890              bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
1891           !ASSIGNMENT (ic) &&
1892           IS_ITEMP (IC_RESULT (ic)) &&
1893           !computeOnly)
1894         {
1895             applyToSet (cseSet, findPrevIc, ic, &pdic);
1896           if (pdic && compareType (operandType (IC_RESULT (pdic)),
1897                                  operandType (IC_RESULT (ic))) != 1)
1898             pdic = NULL;
1899           if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
1900               pdic = NULL;
1901         }
1902
1903       /* Alternate code */
1904       if (pdic && IS_ITEMP(IC_RESULT(ic))) {
1905         if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
1906           /* Mmm, found an equivalent pointer get at a lower level.
1907              This could be a loop however with the same pointer set
1908              later on */
1909         } else {
1910           /* if previous definition found change this to an assignment */
1911           ic->op = '=';
1912           IC_LEFT(ic) = NULL;
1913           IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
1914           SET_ISADDR(IC_RESULT(ic),0);
1915           SET_ISADDR(IC_RIGHT (ic),0);
1916         }
1917       }
1918
1919       if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
1920           deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
1921           addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
1922       }
1923       defic = ic;
1924
1925       /* if assignment to a parameter which is not
1926          mine and type is a pointer then delete
1927          pointerGets to take care of aliasing */
1928       if (ASSIGNMENT (ic) &&
1929           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1930           IS_PTR (operandType (IC_RESULT (ic))))
1931         {
1932           deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1933           for (i = 0; i < count; ebbs[i++]->visited = 0);
1934           applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1935           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1936         }
1937
1938       /* if this is a pointerget then see if we can replace
1939          this with a previously assigned pointer value */
1940       if (POINTER_GET (ic) &&
1941           !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1942             isOperandVolatile (IC_LEFT (ic), TRUE)))
1943         {
1944           pdop = NULL;
1945           applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
1946           /* if we find it then locally replace all
1947              references to the result with what we assigned */
1948           if (pdop)
1949             {
1950               replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
1951             }
1952         }
1953
1954       /* delete from the cseSet anything that has */
1955       /* operands matching the result of this     */
1956       /* except in case of pointer access         */
1957       if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1958         {
1959           deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
1960           /* delete any previous definitions */
1961           ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
1962
1963         }
1964
1965       /* add the left & right to the defUse set */
1966       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
1967         {
1968           OP_USES(IC_LEFT (ic))=
1969             bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1970           setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1971
1972         }
1973
1974       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
1975         {
1976           OP_USES(IC_RIGHT (ic))=
1977             bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1978           setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1979
1980         }
1981
1982       /* for the result it is special case, put the result */
1983       /* in the defuseSet if it a pointer or array access  */
1984       if (POINTER_SET (defic))
1985         {
1986           OP_USES(IC_RESULT (ic))=
1987             bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1988           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1989           deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
1990           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
1991           /* delete from inexpressions of all successors which
1992              have dfNum > than this block */
1993           for (i = 0; i < count; ebbs[i++]->visited = 0);
1994           applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
1995
1996           /* delete from cseSet all other pointer sets
1997              for this operand */
1998           deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
1999           /* add to the local pointerset set */
2000           addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2001         }
2002       else
2003         /* add the result to defintion set */ if (IC_RESULT (ic))
2004         {
2005           OP_DEFS(IC_RESULT (ic))=
2006             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2007           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2008           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2009           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2010         }
2011
2012
2013       /* if this is an addressof instruction then */
2014       /* put the symbol in the address of list &  */
2015       /* delete it from the cseSet                */
2016       if (defic->op == ADDRESS_OF)
2017         {
2018           addSetHead (&ebb->addrOf, IC_LEFT (ic));
2019           deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2020         }
2021     }
2022
2023   setToNull ((void *) &ebb->outExprs);
2024   ebb->outExprs = cseSet;
2025   ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2026   ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2027   return change;
2028 }
2029
2030 /*-----------------------------------------------------------------*/
2031 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2032 /*-----------------------------------------------------------------*/
2033 int
2034 cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
2035 {
2036   int i;
2037   int change = 0;
2038
2039   /* if optimization turned off */
2040
2041   for (i = 0; i < count; i++)
2042     change += cseBBlock (ebbs[i], computeOnly, ebbs, count);
2043
2044   return change;
2045 }