* src/SDCCcse.c (algebraicOpts): fix bug converting op from value to type
[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         /* for the form true_symbol := iTempNN */
1169         if (ASSIGN_ITEMP_TO_SYM (ic) && 
1170             !SPIL_LOC (IC_RIGHT (ic))) {
1171
1172                 setype = getSpec (operandType (IC_RESULT (ic)));
1173
1174                 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1175                     !IS_VOLATILE (setype) &&
1176                     !IN_FARSPACE (SPEC_OCLS (setype)) &&
1177                     !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1178                 {
1179                     wassert(IS_SYMOP(IC_RESULT (ic)));
1180                     wassert(IS_SYMOP(IC_RIGHT (ic)));
1181                         SPIL_LOC (IC_RIGHT (ic)) =
1182                                 IC_RESULT (ic)->operand.symOperand;
1183                 }
1184             
1185         }
1186
1187 #if 0 /* this needs furthur investigation can save a lot of code */
1188         if (ASSIGN_SYM_TO_ITEMP(ic) &&
1189             !SPIL_LOC(IC_RESULT(ic))) {
1190             if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1191                 SPIL_LOC (IC_RESULT (ic)) =
1192                     IC_RIGHT (ic)->operand.symOperand;
1193         }
1194 #endif
1195         if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1196           
1197                 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1198                     !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1199                     OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1200
1201                         setype = getSpec (operandType (IC_RESULT (ic)));
1202               
1203                         if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1204                             !IS_VOLATILE (setype) &&
1205                             !IN_FARSPACE (SPEC_OCLS (setype)) &&
1206                             !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1207
1208                                 SPIL_LOC (IC_RIGHT (ic)) =
1209                                         SPIL_LOC (IC_RESULT (ic));
1210                 }
1211                 /* special case for inductions */
1212                 if (induction && 
1213                     OP_SYMBOL(IC_RIGHT(ic))->isreqv && 
1214                     !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1215                     !SPIL_LOC(IC_RESULT(ic))) {
1216                         SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1217                 }
1218         }
1219 }
1220 /*-----------------------------------------------------------------*/
1221 /* setUsesDef - sets the uses def bitvector for a given operand    */
1222 /*-----------------------------------------------------------------*/
1223 void 
1224 setUsesDefs (operand * op, bitVect * bdefs,
1225              bitVect * idefs, bitVect ** oud)
1226 {
1227   /* compute the definitions alive at this point */
1228   bitVect *adefs = bitVectUnion (bdefs, idefs);
1229
1230   /* of these definitions find the ones that are */
1231   /* for this operand */
1232   adefs = bitVectIntersect (adefs, OP_DEFS (op));
1233
1234   /* these are the definitions that this operand can use */
1235   op->usesDefs = adefs;
1236
1237   /* the out defs is an union */
1238   *oud = bitVectUnion (*oud, adefs);
1239 }
1240
1241 /*-----------------------------------------------------------------*/
1242 /* unsetDefsAndUses - clear this operation for the operands        */
1243 /*-----------------------------------------------------------------*/
1244 void 
1245 unsetDefsAndUses (iCode * ic)
1246 {
1247   if (ic->op == JUMPTABLE)
1248     return;
1249
1250   /* take away this definition from the def chain of the */
1251   /* result & take away from use set of the operands */
1252   if (ic->op != IFX)
1253     {
1254       /* turn off def set */
1255       if (IS_SYMOP (IC_RESULT (ic)))
1256         {
1257           if (!POINTER_SET (ic))
1258             bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1259           else
1260             bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1261         }
1262       /* turn off the useSet for the operands */
1263       if (IS_SYMOP (IC_LEFT (ic)))
1264         bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1265
1266       if (IS_SYMOP (IC_RIGHT (ic)))
1267         bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1268     }
1269   else
1270     /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1271     bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1272 }
1273
1274 /*-----------------------------------------------------------------*/
1275 /* ifxOptimize - changes ifx conditions if it can                  */
1276 /*-----------------------------------------------------------------*/
1277 void 
1278 ifxOptimize (iCode * ic, set * cseSet,
1279              int computeOnly,
1280              eBBlock * ebb, int *change,
1281              eBBlock ** ebbs, int count)
1282 {
1283   operand *pdop;
1284   symbol *label;
1285
1286   /* if the condition can be replaced */
1287   if (!computeOnly)
1288     {
1289       pdop = NULL;
1290       applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1291       if (pdop)
1292         {
1293           ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1294           (*change)++;
1295         }
1296     }
1297
1298   /* if the conditional is a literal then */
1299   if (IS_OP_LITERAL (IC_COND (ic)))
1300     {
1301
1302       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1303         {
1304
1305           /* change to a goto */
1306           ic->op = GOTO;
1307           IC_LABEL (ic) = IC_TRUE (ic);
1308           (*change)++;
1309
1310         }
1311       else
1312         {
1313
1314           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1315             {
1316               ic->op = GOTO;
1317               IC_LABEL (ic) = IC_FALSE (ic);
1318               (*change)++;
1319
1320             }
1321           else
1322             {
1323               /* then kill this if condition */
1324               remiCodeFromeBBlock (ebb, ic);
1325             }
1326         }
1327
1328       /* now we need to recompute the control flow */
1329       /* since the control flow has changed        */
1330       /* this is very expensive but it does not happen */
1331       /* too often, if it does happen then the user pays */
1332       /* the price */
1333       computeControlFlow (ebbs, count, 1);
1334       if (!options.lessPedantic) {
1335         werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1336       }
1337       return;
1338     }
1339
1340   /* if there is only one successor and that successor
1341      is the same one we are conditionally going to then
1342      we can remove this conditional statement */
1343   label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1344   if (elementsInSet (ebb->succList) == 1 &&
1345       isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1346     {
1347
1348       remiCodeFromeBBlock (ebb, ic);
1349       computeControlFlow (ebbs, count, 1);
1350       if (!options.lessPedantic) {
1351         werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1352       }
1353       return;
1354     }
1355
1356
1357   /* if it remains an IFX the update the use Set */
1358   OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1359   setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1360   return;
1361 }
1362
1363 /*-----------------------------------------------------------------*/
1364 /* diCodeForSym - finds the definiting instruction for a symbol    */
1365 /*-----------------------------------------------------------------*/
1366 DEFSETFUNC (diCodeForSym)
1367 {
1368   cseDef *cdp = item;
1369   V_ARG (operand *, sym);
1370   V_ARG (iCode **, dic);
1371
1372   /* if already found */
1373   if (*dic)
1374     return 0;
1375
1376   /* if not if this is the defining iCode */
1377   if (sym->key == cdp->key)
1378     {
1379       *dic = cdp->diCode;
1380       return 1;
1381     }
1382
1383   return 0;
1384 }
1385
1386 /*-----------------------------------------------------------------*/
1387 /* constFold - does some constant folding                          */
1388 /*-----------------------------------------------------------------*/
1389 int 
1390 constFold (iCode * ic, set * cseSet)
1391 {
1392   iCode *dic = NULL;
1393   iCode *ldic = NULL;
1394   /* this routine will change
1395      a = b + 10;
1396      c = a + 10;
1397      to
1398      c = b + 20; */
1399
1400   /* deal with only + & - */
1401   if (ic->op != '+' &&
1402       ic->op != '-')
1403     return 0;
1404
1405   /* this check is a hueristic to prevent live ranges
1406      from becoming too long */
1407   if (IS_PTR (operandType (IC_RESULT (ic))))
1408       return 0;
1409
1410   /* check if operation with a literal */
1411   if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1412     return 0;
1413
1414   /* check if we can find a definition for the
1415      right hand side */
1416   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1417     return 0;
1418
1419   /* check that this is also a +/-  */
1420   if (dic->op != '+' && dic->op != '-')
1421     return 0;
1422
1423   /* with a literal */
1424   if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1425     return 0;
1426
1427   /* find the definition of the left operand
1428      of dic.then check if this defined with a
1429      get_pointer return 0 if the pointer size is
1430      less than 2 (MCS51 specific) */
1431   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1432     return 0;
1433
1434   if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1435     return 0;
1436
1437   /* it is if the operations are the same */
1438   /* the literal parts need to be added  */
1439   IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1440   if (ic->op == dic->op)
1441     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1442                                     operandLitValue (IC_RIGHT (dic)));
1443   else
1444     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1445                                     operandLitValue (IC_RIGHT (dic)));
1446
1447   if (IS_ITEMP (IC_RESULT (ic)))
1448     {
1449       SPIL_LOC (IC_RESULT (ic)) = NULL;
1450       OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1451     }
1452
1453
1454   return 1;
1455 }
1456
1457 /*-----------------------------------------------------------------*/
1458 /* deleteGetPointers - called when a pointer is passed as parm     */
1459 /* will delete from cseSet all get pointers computed from this     */
1460 /* pointer. A simple ifOperandsHave is not good enough here        */
1461 /*-----------------------------------------------------------------*/
1462 static void 
1463 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1464 {
1465   set *compItems = NULL;
1466   cseDef *cdp;
1467   operand *cop;
1468
1469   /* easy return */
1470   if (!*cseSet && !*pss)
1471     return;
1472
1473   /* first find all items computed from this operand .
1474      This done fairly simply go thru the list and find
1475      those that are computed by arthimetic with this
1476      op */
1477   for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1478     {
1479       if (IS_ARITHMETIC_OP (cdp->diCode))
1480         {
1481           if (isOperandEqual (IC_LEFT (cdp->diCode), op) ||
1482               isOperandEqual (IC_RIGHT (cdp->diCode), op))
1483             {
1484               /* save it in our list of items */
1485               addSet (&compItems, IC_RESULT (cdp->diCode));
1486             }
1487           /* also check for those computed from our computed
1488              list . This will take care of situations like
1489              iTemp1 = iTemp0 + 8;
1490              iTemp2 = iTemp1 + 8; */
1491           if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1492                            (insetwithFunc)isOperandEqual) ||
1493               isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1494                            (insetwithFunc)isOperandEqual))
1495             {
1496               addSet (&compItems, IC_RESULT (cdp->diCode));
1497             }
1498         }
1499     }
1500
1501   /* now delete all pointer gets with this op */
1502   deleteItemIf (cseSet, ifPointerGet, op);
1503   deleteItemIf (pss, ifPointerSet, op);
1504
1505   /* set the bit vector used by dataFlow computation later */
1506   ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key);
1507   /* now for the computed items */
1508   for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1509     {
1510       ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1511       deleteItemIf (cseSet, ifPointerGet, cop);
1512       deleteItemIf (pss, ifPointerSet, cop);
1513     }
1514 }
1515
1516 /*-----------------------------------------------------------------*/
1517 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1518 /*                     dfnum > supplied                            */
1519 /*-----------------------------------------------------------------*/
1520 DEFSETFUNC (delGetPointerSucc)
1521 {
1522   eBBlock *ebp = item;
1523   V_ARG (operand *, op);
1524   V_ARG (int, dfnum);
1525
1526   if (ebp->visited)
1527     return 0;
1528
1529   ebp->visited = 1;
1530   if (ebp->dfnum > dfnum)
1531     {
1532       deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1533     }
1534
1535   return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1536 }
1537
1538 /*-----------------------------------------------------------------*/
1539 /* fixUpTypes - KLUGE HACK fixup a lowering problem                */
1540 /*-----------------------------------------------------------------*/
1541 static void
1542 fixUpTypes (iCode * ic)
1543 {
1544   sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1545
1546   /* if (TARGET_IS_DS390) */
1547   if (options.model == MODEL_FLAT24)
1548     {
1549       /* hack-o-matic! */
1550       return;
1551     }
1552
1553   /* for pointer_gets if the types of result & left r the
1554      same then change it type of result to next */
1555   if (IS_PTR (t1) &&
1556       compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1557     {
1558       setOperandType (IC_RESULT (ic), t2->next);
1559     }
1560 }
1561
1562 /*-----------------------------------------------------------------*/
1563 /* isSignedOp - will return 1 if sign is important to operation    */
1564 /*-----------------------------------------------------------------*/
1565 static int isSignedOp (iCode *ic)
1566 {
1567     switch (ic->op) {
1568     case '!':
1569     case '~':
1570     case UNARYMINUS:
1571     case IPUSH:
1572     case IPOP:
1573     case CALL:
1574     case PCALL:
1575     case RETURN:
1576     case '+':
1577     case '-':
1578     case EQ_OP:
1579     case AND_OP:
1580     case OR_OP:
1581     case '^':
1582     case '|':
1583     case BITWISEAND:
1584     case INLINEASM:
1585     case LEFT_OP:
1586     case GET_VALUE_AT_ADDRESS:
1587     case '=':
1588     case IFX:
1589     case RECEIVE:
1590     case SEND:
1591         return 0;
1592     case '*':
1593     case '/':
1594     case '%':
1595     case '>':
1596     case '<':
1597     case LE_OP:
1598     case GE_OP:
1599     case NE_OP:
1600     case RRC:
1601     case RLC:
1602     case GETHBIT:
1603     case RIGHT_OP:
1604     case CAST:
1605     case ARRAYINIT:
1606         return 1;
1607     default:
1608         return 0;
1609     }
1610  }
1611
1612 /*-----------------------------------------------------------------*/
1613 /* cseBBlock - common subexpression elimination for basic blocks   */
1614 /*             this is the hackiest kludgiest routine in the whole */
1615 /*             system. also the most important, since almost all   */
1616 /*             data flow related information is computed by it     */
1617 /*-----------------------------------------------------------------*/
1618 int
1619 cseBBlock (eBBlock * ebb, int computeOnly,
1620            eBBlock ** ebbs, int count)
1621 {
1622   set *cseSet;
1623   iCode *ic;
1624   int change = 0;
1625   int i;
1626   set *ptrSetSet = NULL;
1627
1628   /* if this block is not reachable */
1629   if (ebb->noPath)
1630     return 0;
1631
1632   /* set of common subexpressions */
1633   cseSet = setFromSet (ebb->inExprs);
1634
1635   /* these will be computed by this routine */
1636   setToNull ((void **) &ebb->outDefs);
1637   setToNull ((void **) &ebb->defSet);
1638   setToNull ((void **) &ebb->usesDefs);
1639   setToNull ((void **) &ebb->ptrsSet);
1640   setToNull ((void **) &ebb->addrOf);
1641   setToNull ((void **) &ebb->ldefs);
1642
1643   ebb->outDefs = bitVectCopy (ebb->inDefs);
1644   bitVectDefault = iCodeKey;
1645   ebb->defSet = newBitVect (iCodeKey);
1646   ebb->usesDefs = newBitVect (iCodeKey);
1647
1648   /* for all the instructions in this block do */
1649   for (ic = ebb->sch; ic; ic = ic->next)
1650     {
1651       iCode *pdic;
1652       operand *pdop;
1653       iCode *defic;
1654       int checkSign ;
1655
1656       ic->eBBlockNum = ebb->bbnum;
1657
1658       if (SKIP_IC2 (ic))
1659         continue;
1660
1661       /* if this is an assignment from true symbol
1662          to a temp then do pointer post inc/dec optimzation */
1663       if (ic->op == '=' && !POINTER_SET (ic) &&
1664           IS_PTR (operandType (IC_RESULT (ic))))
1665         {
1666           ptrPostIncDecOpt (ic);
1667         }
1668
1669       /* clear the def & use chains for the operands involved */
1670       /* in this operation . since it can change due to opts  */
1671       unsetDefsAndUses (ic);
1672
1673       if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1674         {
1675           /* add to defSet of the symbol */
1676           OP_DEFS(IC_RESULT (ic))=
1677             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1678           /* add to the definition set of this block */
1679           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1680           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1681           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1682           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1683           /* delete global variables from the cseSet
1684              since they can be modified by the function call */
1685           deleteItemIf (&cseSet, ifDefGlobal);
1686
1687           /* and also itemps assigned from globals */
1688           deleteItemIf (&cseSet, ifAssignedFromGlobal);
1689
1690           /* delete all getpointer iCodes from cseSet, this should
1691              be done only for global arrays & pointers but at this
1692              point we don't know if globals, so to be safe do all */
1693           deleteItemIf (&cseSet, ifAnyGetPointer);
1694         }
1695
1696       /* for pcall & ipush we need to add to the useSet */
1697       if ((ic->op == PCALL ||
1698            ic->op == IPUSH ||
1699            ic->op == IPOP ||
1700            ic->op == SEND) &&
1701           IS_SYMOP (IC_LEFT (ic)))
1702         {
1703
1704           /* check if they can be replaced */
1705           if (!computeOnly)
1706             {
1707               pdop = NULL;
1708               applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1709               if (pdop)
1710                 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1711             }
1712           /* the lookup could have changed it */
1713           if (IS_SYMOP (IC_LEFT (ic)))
1714             {
1715               OP_USES(IC_LEFT (ic))=
1716                 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1717               setUsesDefs (IC_LEFT (ic), ebb->defSet,
1718                            ebb->outDefs, &ebb->usesDefs);
1719             }
1720
1721
1722           /* if we a sending a pointer as a parameter
1723              then kill all cse since the pointed to item
1724              might be changed in the function being called */
1725           if ((ic->op == IPUSH || ic->op == SEND) &&
1726               IS_PTR (operandType (IC_LEFT (ic))))
1727             {
1728               deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1729               ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1730               for (i = 0; i < count; ebbs[i++]->visited = 0);
1731               applyToSet (ebb->succList, delGetPointerSucc,
1732                           IC_LEFT (ic), ebb->dfnum);
1733             }
1734           continue;
1735         }
1736
1737       /* if jumptable then mark the usage */
1738       if (ic->op == JUMPTABLE)
1739         {
1740           OP_USES(IC_JTCOND (ic))=
1741             bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1742           setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1743                        ebb->outDefs, &ebb->usesDefs);
1744           continue;
1745         }
1746
1747       if (SKIP_IC (ic))
1748         continue;
1749
1750       if (!computeOnly) {
1751         /* do some algebraic optimizations if possible */
1752         algebraicOpts (ic, ebb);
1753         while (constFold (ic, cseSet));
1754       }
1755
1756       /* small klugde */
1757       if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1758         {
1759           setOperandType (IC_LEFT (ic),
1760                           aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1761           fixUpTypes (ic);
1762
1763         }
1764       if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1765         {
1766           setOperandType (IC_RESULT (ic),
1767                           aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1768         }
1769
1770       /* if this is a condition statement then */
1771       /* check if the condition can be replaced */
1772       if (ic->op == IFX)
1773         {
1774           ifxOptimize (ic, cseSet, computeOnly,
1775                        ebb, &change,
1776                        ebbs, count);
1777           continue;
1778         }
1779
1780       /* if the assignment & result is a temp */
1781       /* see if we can replace it             */
1782       if (!computeOnly && ic->op == '=')
1783         {
1784
1785           /* update the spill location for this */
1786           updateSpillLocation (ic,0);
1787
1788           if (POINTER_SET (ic) &&
1789               !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1790             {
1791               pdop = NULL;
1792               applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1793               if (pdop && !computeOnly &&
1794                   IS_ITEMP (pdop) && IS_PTR(operandType(pdop)))
1795                 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1796             }
1797         }
1798
1799       checkSign = isSignedOp(ic);
1800
1801       /* do the operand lookup i.e. for both the */
1802       /* right & left operand : check the cseSet */
1803       /* to see if they have been replaced if yes */
1804       /* then replace them with those from cseSet */
1805       /* left operand */
1806       /* and left is a symbol  */
1807       if (IS_SYMOP (IC_LEFT (ic)) &&
1808           !computeOnly && ic->op != ADDRESS_OF)
1809         {
1810
1811           pdop = NULL;
1812           applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1813           if (pdop)
1814             {
1815               if (POINTER_GET (ic))
1816                 {
1817                   if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1818                     {
1819                         /* some non dominating block does POINTER_SET with
1820                            this variable .. unsafe to remove any POINTER_GETs */
1821                         if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1822                             ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1823                         ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1824                       change = 1;
1825                     }
1826                   /* check if there is a pointer set
1827                      for the same pointer visible if yes
1828                      then change this into an assignment */
1829                   pdop = NULL;
1830                   if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1831                       !bitVectBitValue (ebb->ptrsSet, pdop->key))
1832                     {
1833                       ic->op = '=';
1834                       IC_LEFT (ic) = NULL;
1835                       ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1836                       SET_ISADDR (IC_RESULT (ic), 0);
1837                     }
1838
1839                 }
1840               else
1841                 {
1842                   ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1843                   change = 1;
1844                 }
1845             }
1846         }
1847
1848       /*right operand */
1849       if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1850         {
1851
1852           pdop = NULL;
1853           applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1854           if (pdop) {
1855             ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1856             change = 1;
1857           }
1858         }
1859
1860       /* if left or right changed then do algebraic */
1861       if (!computeOnly && change)
1862         {
1863           algebraicOpts (ic, ebb);
1864           while (constFold (ic, cseSet));
1865         }
1866
1867       /* if after all this it becomes an assignment to self
1868          then delete it and continue */
1869       if (ASSIGNMENT_TO_SELF (ic))
1870         {
1871           remiCodeFromeBBlock (ebb, ic);
1872           continue;
1873         }
1874
1875       /* now we will check to see if the entire */
1876       /* operation has been performed before    */
1877       /* and is available                       */
1878       /* don't do assignments they will be killed */
1879       /* by dead code elimination if required  do */
1880       /* it only if result is a temporary         */
1881       pdic = NULL;
1882       if (!(POINTER_GET (ic) &&
1883             (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1884              isOperandVolatile (IC_LEFT (ic), TRUE) ||
1885              bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
1886           !ASSIGNMENT (ic) &&
1887           IS_ITEMP (IC_RESULT (ic)) &&
1888           !computeOnly)
1889         {
1890             applyToSet (cseSet, findPrevIc, ic, &pdic);
1891           if (pdic && compareType (operandType (IC_RESULT (pdic)),
1892                                  operandType (IC_RESULT (ic))) != 1)
1893             pdic = NULL;
1894           if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
1895               pdic = NULL;
1896         }
1897
1898       /* Alternate code */
1899       if (pdic && IS_ITEMP(IC_RESULT(ic))) {
1900         if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
1901           /* Mmm, found an equivalent pointer get at a lower level.
1902              This could be a loop however with the same pointer set
1903              later on */
1904         } else {
1905           /* if previous definition found change this to an assignment */
1906           ic->op = '=';
1907           IC_LEFT(ic) = NULL;
1908           IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
1909           SET_ISADDR(IC_RESULT(ic),0);
1910           SET_ISADDR(IC_RIGHT (ic),0);
1911         }
1912       }
1913
1914       if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
1915           deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
1916           addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
1917       }
1918       defic = ic;
1919
1920       /* if assignment to a parameter which is not
1921          mine and type is a pointer then delete
1922          pointerGets to take care of aliasing */
1923       if (ASSIGNMENT (ic) &&
1924           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1925           IS_PTR (operandType (IC_RESULT (ic))))
1926         {
1927           deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1928           for (i = 0; i < count; ebbs[i++]->visited = 0);
1929           applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1930           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1931         }
1932
1933       /* if this is a pointerget then see if we can replace
1934          this with a previously assigned pointer value */
1935       if (POINTER_GET (ic) &&
1936           !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1937             isOperandVolatile (IC_LEFT (ic), TRUE)))
1938         {
1939           pdop = NULL;
1940           applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
1941           /* if we find it then locally replace all
1942              references to the result with what we assigned */
1943           if (pdop)
1944             {
1945               replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
1946             }
1947         }
1948
1949       /* delete from the cseSet anything that has */
1950       /* operands matching the result of this     */
1951       /* except in case of pointer access         */
1952       if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1953         {
1954           deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
1955           /* delete any previous definitions */
1956           ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
1957
1958         }
1959
1960       /* add the left & right to the defUse set */
1961       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
1962         {
1963           OP_USES(IC_LEFT (ic))=
1964             bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1965           setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1966
1967         }
1968
1969       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
1970         {
1971           OP_USES(IC_RIGHT (ic))=
1972             bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1973           setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1974
1975         }
1976
1977       /* for the result it is special case, put the result */
1978       /* in the defuseSet if it a pointer or array access  */
1979       if (POINTER_SET (defic))
1980         {
1981           OP_USES(IC_RESULT (ic))=
1982             bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1983           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1984           deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
1985           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
1986           /* delete from inexpressions of all successors which
1987              have dfNum > than this block */
1988           for (i = 0; i < count; ebbs[i++]->visited = 0);
1989           applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
1990
1991           /* delete from cseSet all other pointer sets
1992              for this operand */
1993           deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
1994           /* add to the local pointerset set */
1995           addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
1996         }
1997       else
1998         /* add the result to defintion set */ if (IC_RESULT (ic))
1999         {
2000           OP_DEFS(IC_RESULT (ic))=
2001             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2002           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2003           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2004           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2005         }
2006
2007
2008       /* if this is an addressof instruction then */
2009       /* put the symbol in the address of list &  */
2010       /* delete it from the cseSet                */
2011       if (defic->op == ADDRESS_OF)
2012         {
2013           addSetHead (&ebb->addrOf, IC_LEFT (ic));
2014           deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2015         }
2016     }
2017
2018   setToNull ((void **) &ebb->outExprs);
2019   ebb->outExprs = cseSet;
2020   ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2021   ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2022   return change;
2023 }
2024
2025 /*-----------------------------------------------------------------*/
2026 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2027 /*-----------------------------------------------------------------*/
2028 int
2029 cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
2030 {
2031   int i;
2032   int change = 0;
2033
2034   /* if optimization turned off */
2035
2036   for (i = 0; i < count; i++)
2037     change += cseBBlock (ebbs[i], computeOnly, ebbs, count);
2038
2039   return change;
2040 }