* src/SDCCcse.c (algebraicOpts): CSE fun with &|^ and 0x00/0xff literals
[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 void 
637 algebraicOpts (iCode * ic)
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                   setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
829                 }
830               return;
831             }
832         }
833
834       if (IS_OP_LITERAL (IC_RIGHT (ic)))
835         {
836
837           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
838             {
839               ic->op = '=';
840               IC_LEFT (ic) = NULL;
841               SET_RESULT_RIGHT (ic);
842               return;
843             }
844
845           if (operandLitValue (IC_RIGHT (ic)) == 1.0)
846             {
847               /* '*' can have two unsigned chars as operands */
848               /* and an unsigned int as result.              */
849               if (compareType (operandType (IC_RESULT (ic)),
850                                operandType (IC_LEFT (ic))) == 1)
851                 {
852                   ic->op = '=';
853                   IC_RIGHT (ic) = IC_LEFT (ic);
854                   IC_LEFT (ic) = NULL;
855                   SET_RESULT_RIGHT (ic);
856                 }
857               else
858                 {
859                   operand *op;
860
861                   ic->op = CAST;
862                   op = IC_RIGHT (ic);
863                   IC_RIGHT (ic) = IC_LEFT (ic);
864                   IC_LEFT (ic) = op;
865                   IC_LEFT (ic)->type = TYPE;
866                   setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
867                 }
868               return;
869             }
870         }
871       break;
872     case '/':
873       /* if division by self then 1 */
874       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
875         {
876           ic->op = '=';
877           IC_RIGHT (ic) = operandFromLit (1);
878           IC_LEFT (ic) = NULL;
879           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
880           IC_RESULT (ic)->isaddr = 0;
881           break;
882         }
883       /* if this is a division then check if right */
884       /* is one then change it to an assignment    */
885       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
886           operandLitValue (IC_RIGHT (ic)) == 1.0)
887         {
888
889           ic->op = '=';
890           IC_RIGHT (ic) = IC_LEFT (ic);
891           IC_LEFT (ic) = NULL;
892           SET_RESULT_RIGHT (ic);
893           return;
894         }
895       break;
896       /* if both are the same for an comparison operators */
897     case EQ_OP:
898     case LE_OP:
899     case GE_OP:
900       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
901         {
902           ic->op = '=';
903           IC_RIGHT (ic) = operandFromLit (1);
904           IC_LEFT (ic) = NULL;
905           SET_RESULT_RIGHT (ic);
906         }
907       break;
908     case NE_OP:
909     case '>':
910     case '<':
911       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
912         {
913           ic->op = '=';
914           IC_RIGHT (ic) = operandFromLit (0);
915           IC_LEFT (ic) = NULL;
916           SET_RESULT_RIGHT (ic);
917         }
918       break;
919     case CAST:
920             {
921                     sym_link *otype = operandType(IC_RIGHT(ic));
922                     sym_link *ctype = operandType(IC_LEFT(ic));
923                     /* if this is a cast of a literal value */
924                     if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
925                         !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
926                             ic->op = '=';
927                             IC_RIGHT (ic) =
928                                     operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
929                                                                       operandLitValue (IC_RIGHT (ic))));
930                             IC_LEFT (ic) = NULL;
931                             SET_ISADDR (IC_RESULT (ic), 0);
932                     }
933                     /* if casting to the same */
934                     if (compareType (operandType (IC_RESULT (ic)),
935                                      operandType (IC_RIGHT (ic))) == 1) {
936                             ic->op = '=';
937                             IC_LEFT (ic) = NULL;
938                             SET_ISADDR (IC_RESULT (ic), 0);
939                     }
940             }
941             break;
942     case '!':
943       if (IS_OP_LITERAL (IC_LEFT (ic)))
944         {
945           ic->op = '=';
946           IC_RIGHT (ic) =
947             (operandLitValue (IC_LEFT (ic)) == 0 ?
948              operandFromLit (1) : operandFromLit (0));
949           IC_LEFT (ic) = NULL;
950           SET_ISADDR (IC_RESULT (ic), 0);
951         }
952       break;
953     case BITWISEAND:
954       if (IS_OP_LITERAL (IC_LEFT (ic)))
955         {
956           /* if BITWISEAND then check if one of them is a zero */
957           /* if yes turn it into 0 assignment */
958           if (operandLitValue (IC_LEFT (ic)) == 0.0)
959             {
960               if (IS_OP_VOLATILE (IC_RIGHT (ic)))
961                 return;
962               ic->op = '=';
963               IC_RIGHT (ic) = IC_LEFT (ic);
964               IC_LEFT (ic) = NULL;
965               SET_RESULT_RIGHT (ic);
966               return;
967             }
968           /* if BITWISEAND then check if one of them is 0xff... */
969           /* if yes turn it into assignment */
970           if (operandLitValue (IC_LEFT (ic)) == -1.0)
971             {
972               ic->op = '=';
973               IC_LEFT (ic) = NULL;
974               SET_RESULT_RIGHT (ic);
975               return;
976             }
977         }
978       if (IS_OP_LITERAL (IC_RIGHT (ic)))
979         {
980           /* if BITWISEAND then check if one of them is a zero */
981           /* if yes turn it into 0 assignment */
982           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
983             {
984               if (IS_OP_VOLATILE (IC_LEFT (ic)))
985                 return;
986               ic->op = '=';
987               IC_LEFT (ic) = NULL;
988               SET_RESULT_RIGHT (ic);
989               return;
990             }
991           /* if BITWISEAND then check if one of them is 0xff... */
992           /* if yes turn it into assignment */
993           if (operandLitValue (IC_RIGHT (ic)) == -1.0)
994             {
995               ic->op = '=';
996               IC_RIGHT (ic) = IC_LEFT (ic);
997               IC_LEFT (ic) = NULL;
998               SET_RESULT_RIGHT (ic);
999               return;
1000             }
1001         }
1002       break;
1003     case '|':
1004       if (IS_OP_LITERAL (IC_LEFT (ic)))
1005         {
1006           /* if BITWISEOR then check if one of them is a zero */
1007           /* if yes turn it into assignment */
1008           if (operandLitValue (IC_LEFT (ic)) == 0.0)
1009             {
1010               ic->op = '=';
1011               IC_LEFT (ic) = NULL;
1012               SET_RESULT_RIGHT (ic);
1013               return;
1014             }
1015           /* if BITWISEOR then check if one of them is 0xff... */
1016           /* if yes turn it into 0xff... assignment */
1017           if (operandLitValue (IC_LEFT (ic)) == -1.0)
1018             {
1019               ic->op = '=';
1020               IC_RIGHT (ic) = IC_LEFT (ic);
1021               IC_LEFT (ic) = NULL;
1022               SET_RESULT_RIGHT (ic);
1023               return;
1024             }
1025         }
1026       if (IS_OP_LITERAL (IC_RIGHT (ic)))
1027         {
1028           /* if BITWISEOR then check if one of them is a zero */
1029           /* if yes turn it into assignment */
1030           if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1031             {
1032               ic->op = '=';
1033               IC_RIGHT (ic) = IC_LEFT (ic);
1034               IC_LEFT (ic) = NULL;
1035               SET_RESULT_RIGHT (ic);
1036               return;
1037             }
1038           /* if BITWISEOR then check if one of them is 0xff... */
1039           /* if yes turn it into 0xff... assignment */
1040           if (operandLitValue (IC_RIGHT (ic)) == -1.0)
1041             {
1042               ic->op = '=';
1043               IC_LEFT (ic) = NULL;
1044               SET_RESULT_RIGHT (ic);
1045               return;
1046             }
1047         }
1048       break;
1049     case '^':
1050       /* if XOR then check if one of them is a zero */
1051       /* if yes turn it into assignment */
1052       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
1053           operandLitValue (IC_LEFT (ic)) == 0.0)
1054         {
1055           ic->op = '=';
1056           IC_LEFT (ic) = NULL;
1057           SET_RESULT_RIGHT (ic);
1058           return;
1059         }
1060       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1061           operandLitValue (IC_RIGHT (ic)) == 0.0)
1062         {
1063           ic->op = '=';
1064           IC_RIGHT (ic) = IC_LEFT (ic);
1065           IC_LEFT (ic) = NULL;
1066           SET_RESULT_RIGHT (ic);
1067           return;
1068         }
1069       break;
1070     }
1071
1072   return;
1073 }
1074 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1075 /*-----------------------------------------------------------------*/
1076 /* updateSpillLocation - keeps track of register spill location    */
1077 /*-----------------------------------------------------------------*/
1078 void
1079 updateSpillLocation (iCode * ic, int induction)
1080 {
1081         sym_link *setype;
1082
1083         if (POINTER_SET (ic))
1084                 return;
1085
1086         if (ic->nosupdate)
1087                 return;
1088
1089         /* for the form true_symbol := iTempNN */
1090         if (ASSIGN_ITEMP_TO_SYM (ic) && 
1091             !SPIL_LOC (IC_RIGHT (ic))) {
1092
1093                 setype = getSpec (operandType (IC_RESULT (ic)));
1094
1095                 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1096                     !IS_VOLATILE (setype) &&
1097                     !IN_FARSPACE (SPEC_OCLS (setype)) &&
1098                     !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1099                 {
1100                     wassert(IS_SYMOP(IC_RESULT (ic)));
1101                     wassert(IS_SYMOP(IC_RIGHT (ic)));
1102                         SPIL_LOC (IC_RIGHT (ic)) =
1103                                 IC_RESULT (ic)->operand.symOperand;
1104                 }
1105             
1106         }
1107
1108 #if 0 /* this needs furthur investigation can save a lot of code */
1109         if (ASSIGN_SYM_TO_ITEMP(ic) &&
1110             !SPIL_LOC(IC_RESULT(ic))) {
1111             if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1112                 SPIL_LOC (IC_RESULT (ic)) =
1113                     IC_RIGHT (ic)->operand.symOperand;
1114         }
1115 #endif
1116         if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1117           
1118                 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1119                     !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1120                     OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1121
1122                         setype = getSpec (operandType (IC_RESULT (ic)));
1123               
1124                         if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1125                             !IS_VOLATILE (setype) &&
1126                             !IN_FARSPACE (SPEC_OCLS (setype)) &&
1127                             !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1128
1129                                 SPIL_LOC (IC_RIGHT (ic)) =
1130                                         SPIL_LOC (IC_RESULT (ic));
1131                 }
1132                 /* special case for inductions */
1133                 if (induction && 
1134                     OP_SYMBOL(IC_RIGHT(ic))->isreqv && 
1135                     !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1136                     !SPIL_LOC(IC_RESULT(ic))) {
1137                         SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1138                 }
1139         }
1140 }
1141 /*-----------------------------------------------------------------*/
1142 /* setUsesDef - sets the uses def bitvector for a given operand    */
1143 /*-----------------------------------------------------------------*/
1144 void 
1145 setUsesDefs (operand * op, bitVect * bdefs,
1146              bitVect * idefs, bitVect ** oud)
1147 {
1148   /* compute the definitions alive at this point */
1149   bitVect *adefs = bitVectUnion (bdefs, idefs);
1150
1151   /* of these definitions find the ones that are */
1152   /* for this operand */
1153   adefs = bitVectIntersect (adefs, OP_DEFS (op));
1154
1155   /* these are the definitions that this operand can use */
1156   op->usesDefs = adefs;
1157
1158   /* the out defs is an union */
1159   *oud = bitVectUnion (*oud, adefs);
1160 }
1161
1162 /*-----------------------------------------------------------------*/
1163 /* unsetDefsAndUses - clear this operation for the operands        */
1164 /*-----------------------------------------------------------------*/
1165 void 
1166 unsetDefsAndUses (iCode * ic)
1167 {
1168   if (ic->op == JUMPTABLE)
1169     return;
1170
1171   /* take away this definition from the def chain of the */
1172   /* result & take away from use set of the operands */
1173   if (ic->op != IFX)
1174     {
1175       /* turn off def set */
1176       if (IS_SYMOP (IC_RESULT (ic)))
1177         {
1178           if (!POINTER_SET (ic))
1179             bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1180           else
1181             bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1182         }
1183       /* turn off the useSet for the operands */
1184       if (IS_SYMOP (IC_LEFT (ic)))
1185         bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1186
1187       if (IS_SYMOP (IC_RIGHT (ic)))
1188         bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1189     }
1190   else
1191     /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1192     bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1193 }
1194
1195 /*-----------------------------------------------------------------*/
1196 /* ifxOptimize - changes ifx conditions if it can                  */
1197 /*-----------------------------------------------------------------*/
1198 void 
1199 ifxOptimize (iCode * ic, set * cseSet,
1200              int computeOnly,
1201              eBBlock * ebb, int *change,
1202              eBBlock ** ebbs, int count)
1203 {
1204   operand *pdop;
1205   symbol *label;
1206
1207   /* if the condition can be replaced */
1208   if (!computeOnly)
1209     {
1210       pdop = NULL;
1211       applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1212       if (pdop)
1213         {
1214           ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1215           (*change)++;
1216         }
1217     }
1218
1219   /* if the conditional is a literal then */
1220   if (IS_OP_LITERAL (IC_COND (ic)))
1221     {
1222
1223       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1224         {
1225
1226           /* change to a goto */
1227           ic->op = GOTO;
1228           IC_LABEL (ic) = IC_TRUE (ic);
1229           (*change)++;
1230
1231         }
1232       else
1233         {
1234
1235           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1236             {
1237               ic->op = GOTO;
1238               IC_LABEL (ic) = IC_FALSE (ic);
1239               (*change)++;
1240
1241             }
1242           else
1243             {
1244               /* then kill this if condition */
1245               remiCodeFromeBBlock (ebb, ic);
1246             }
1247         }
1248
1249       /* now we need to recompute the control flow */
1250       /* since the control flow has changed        */
1251       /* this is very expensive but it does not happen */
1252       /* too often, if it does happen then the user pays */
1253       /* the price */
1254       computeControlFlow (ebbs, count, 1);
1255       if (!options.lessPedantic) {
1256         werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1257       }
1258       return;
1259     }
1260
1261   /* if there is only one successor and that successor
1262      is the same one we are conditionally going to then
1263      we can remove this conditional statement */
1264   label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1265   if (elementsInSet (ebb->succList) == 1 &&
1266       isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1267     {
1268
1269       remiCodeFromeBBlock (ebb, ic);
1270       computeControlFlow (ebbs, count, 1);
1271       if (!options.lessPedantic) {
1272         werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1273       }
1274       return;
1275     }
1276
1277
1278   /* if it remains an IFX the update the use Set */
1279   OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1280   setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1281   return;
1282 }
1283
1284 /*-----------------------------------------------------------------*/
1285 /* diCodeForSym - finds the definiting instruction for a symbol    */
1286 /*-----------------------------------------------------------------*/
1287 DEFSETFUNC (diCodeForSym)
1288 {
1289   cseDef *cdp = item;
1290   V_ARG (operand *, sym);
1291   V_ARG (iCode **, dic);
1292
1293   /* if already found */
1294   if (*dic)
1295     return 0;
1296
1297   /* if not if this is the defining iCode */
1298   if (sym->key == cdp->key)
1299     {
1300       *dic = cdp->diCode;
1301       return 1;
1302     }
1303
1304   return 0;
1305 }
1306
1307 /*-----------------------------------------------------------------*/
1308 /* constFold - does some constant folding                          */
1309 /*-----------------------------------------------------------------*/
1310 int 
1311 constFold (iCode * ic, set * cseSet)
1312 {
1313   iCode *dic = NULL;
1314   iCode *ldic = NULL;
1315   /* this routine will change
1316      a = b + 10;
1317      c = a + 10;
1318      to
1319      c = b + 20; */
1320
1321   /* deal with only + & - */
1322   if (ic->op != '+' &&
1323       ic->op != '-')
1324     return 0;
1325
1326   /* this check is a hueristic to prevent live ranges
1327      from becoming too long */
1328   if (IS_PTR (operandType (IC_RESULT (ic))))
1329       return 0;
1330
1331   /* check if operation with a literal */
1332   if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1333     return 0;
1334
1335   /* check if we can find a definition for the
1336      right hand side */
1337   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1338     return 0;
1339
1340   /* check that this is also a +/-  */
1341   if (dic->op != '+' && dic->op != '-')
1342     return 0;
1343
1344   /* with a literal */
1345   if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1346     return 0;
1347
1348   /* find the definition of the left operand
1349      of dic.then check if this defined with a
1350      get_pointer return 0 if the pointer size is
1351      less than 2 (MCS51 specific) */
1352   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1353     return 0;
1354
1355   if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1356     return 0;
1357
1358   /* it is if the operations are the same */
1359   /* the literal parts need to be added  */
1360   IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1361   if (ic->op == dic->op)
1362     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1363                                     operandLitValue (IC_RIGHT (dic)));
1364   else
1365     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1366                                     operandLitValue (IC_RIGHT (dic)));
1367
1368   if (IS_ITEMP (IC_RESULT (ic)))
1369     {
1370       SPIL_LOC (IC_RESULT (ic)) = NULL;
1371       OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1372     }
1373
1374
1375   return 1;
1376 }
1377
1378 /*-----------------------------------------------------------------*/
1379 /* deleteGetPointers - called when a pointer is passed as parm     */
1380 /* will delete from cseSet all get pointers computed from this     */
1381 /* pointer. A simple ifOperandsHave is not good enough here        */
1382 /*-----------------------------------------------------------------*/
1383 static void 
1384 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1385 {
1386   set *compItems = NULL;
1387   cseDef *cdp;
1388   operand *cop;
1389
1390   /* easy return */
1391   if (!*cseSet && !*pss)
1392     return;
1393
1394   /* first find all items computed from this operand .
1395      This done fairly simply go thru the list and find
1396      those that are computed by arthimetic with this
1397      op */
1398   for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1399     {
1400       if (IS_ARITHMETIC_OP (cdp->diCode))
1401         {
1402           if (isOperandEqual (IC_LEFT (cdp->diCode), op) ||
1403               isOperandEqual (IC_RIGHT (cdp->diCode), op))
1404             {
1405               /* save it in our list of items */
1406               addSet (&compItems, IC_RESULT (cdp->diCode));
1407             }
1408           /* also check for those computed from our computed
1409              list . This will take care of situations like
1410              iTemp1 = iTemp0 + 8;
1411              iTemp2 = iTemp1 + 8; */
1412           if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode), 
1413                            (insetwithFunc)isOperandEqual) ||
1414               isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode), 
1415                            (insetwithFunc)isOperandEqual))
1416             {
1417               addSet (&compItems, IC_RESULT (cdp->diCode));
1418             }
1419         }
1420     }
1421
1422   /* now delete all pointer gets with this op */
1423   deleteItemIf (cseSet, ifPointerGet, op);
1424   deleteItemIf (pss, ifPointerSet, op);
1425
1426   /* set the bit vector used by dataFlow computation later */
1427   ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key);
1428   /* now for the computed items */
1429   for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1430     {
1431       ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1432       deleteItemIf (cseSet, ifPointerGet, cop);
1433       deleteItemIf (pss, ifPointerSet, cop);
1434     }
1435 }
1436
1437 /*-----------------------------------------------------------------*/
1438 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1439 /*                     dfnum > supplied                            */
1440 /*-----------------------------------------------------------------*/
1441 DEFSETFUNC (delGetPointerSucc)
1442 {
1443   eBBlock *ebp = item;
1444   V_ARG (operand *, op);
1445   V_ARG (int, dfnum);
1446
1447   if (ebp->visited)
1448     return 0;
1449
1450   ebp->visited = 1;
1451   if (ebp->dfnum > dfnum)
1452     {
1453       deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1454     }
1455
1456   return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1457 }
1458
1459 /*-----------------------------------------------------------------*/
1460 /* fixUpTypes - KLUGE HACK fixup a lowering problem                */
1461 /*-----------------------------------------------------------------*/
1462 static void 
1463 fixUpTypes (iCode * ic)
1464 {
1465   sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1466
1467   /* if (TARGET_IS_DS390) */
1468   if (options.model == MODEL_FLAT24)
1469     {
1470       /* hack-o-matic! */
1471       return;
1472     }
1473
1474   /* for pointer_gets if the types of result & left r the
1475      same then change it type of result to next */
1476   if (IS_PTR (t1) &&
1477       compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1478     {
1479       setOperandType (IC_RESULT (ic), t2->next);
1480     }
1481 }
1482
1483 /*-----------------------------------------------------------------*/
1484 /* isSignedOp - will return 1 if sign is important to operation    */
1485 /*-----------------------------------------------------------------*/
1486 static int isSignedOp (iCode *ic)
1487 {
1488     switch (ic->op) {
1489     case '!':
1490     case '~':
1491     case UNARYMINUS:
1492     case IPUSH:
1493     case IPOP:
1494     case CALL:
1495     case PCALL:
1496     case RETURN:
1497     case '+':
1498     case '-':
1499     case EQ_OP:
1500     case AND_OP:
1501     case OR_OP:
1502     case '^':
1503     case '|':
1504     case BITWISEAND:
1505     case INLINEASM:
1506     case LEFT_OP:
1507     case GET_VALUE_AT_ADDRESS:
1508     case '=':
1509     case IFX:
1510     case RECEIVE:
1511     case SEND:
1512         return 0;
1513     case '*':
1514     case '/':
1515     case '%':
1516     case '>':
1517     case '<':
1518     case LE_OP:
1519     case GE_OP:
1520     case NE_OP:
1521     case RRC:
1522     case RLC:
1523     case GETHBIT:
1524     case RIGHT_OP:
1525     case CAST:
1526     case ARRAYINIT:
1527         return 1;
1528     default:
1529         return 0;
1530     }
1531  }
1532
1533 /*-----------------------------------------------------------------*/
1534 /* cseBBlock - common subexpression elimination for basic blocks   */
1535 /*             this is the hackiest kludgiest routine in the whole */
1536 /*             system. also the most important, since almost all   */
1537 /*             data flow related information is computed by it     */
1538 /*-----------------------------------------------------------------*/
1539 int 
1540 cseBBlock (eBBlock * ebb, int computeOnly,
1541            eBBlock ** ebbs, int count)
1542 {
1543   set *cseSet;
1544   iCode *ic;
1545   int change = 0;
1546   int i;
1547   set *ptrSetSet = NULL;
1548
1549   /* if this block is not reachable */
1550   if (ebb->noPath)
1551     return 0;
1552
1553   /* set of common subexpressions */
1554   cseSet = setFromSet (ebb->inExprs);
1555
1556   /* these will be computed by this routine */
1557   setToNull ((void **) &ebb->outDefs);
1558   setToNull ((void **) &ebb->defSet);
1559   setToNull ((void **) &ebb->usesDefs);
1560   setToNull ((void **) &ebb->ptrsSet);
1561   setToNull ((void **) &ebb->addrOf);
1562   setToNull ((void **) &ebb->ldefs);
1563
1564   ebb->outDefs = bitVectCopy (ebb->inDefs);
1565   bitVectDefault = iCodeKey;
1566   ebb->defSet = newBitVect (iCodeKey);
1567   ebb->usesDefs = newBitVect (iCodeKey);
1568
1569   /* for all the instructions in this block do */
1570   for (ic = ebb->sch; ic; ic = ic->next)
1571     {
1572       iCode *pdic;
1573       operand *pdop;
1574       iCode *defic;
1575       int checkSign ;
1576
1577       ic->eBBlockNum = ebb->bbnum;
1578
1579       if (SKIP_IC2 (ic))
1580         continue;
1581
1582       /* if this is an assignment from true symbol
1583          to a temp then do pointer post inc/dec optimzation */
1584       if (ic->op == '=' && !POINTER_SET (ic) &&
1585           IS_PTR (operandType (IC_RESULT (ic))))
1586         {
1587           ptrPostIncDecOpt (ic);
1588         }
1589
1590       /* clear the def & use chains for the operands involved */
1591       /* in this operation . since it can change due to opts  */
1592       unsetDefsAndUses (ic);
1593
1594       if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1595         {
1596           /* add to defSet of the symbol */
1597           OP_DEFS(IC_RESULT (ic))=
1598             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1599           /* add to the definition set of this block */
1600           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1601           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1602           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1603           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1604           /* delete global variables from the cseSet
1605              since they can be modified by the function call */
1606           deleteItemIf (&cseSet, ifDefGlobal);
1607
1608           /* and also itemps assigned from globals */
1609           deleteItemIf (&cseSet, ifAssignedFromGlobal);
1610
1611           /* delete all getpointer iCodes from cseSet, this should
1612              be done only for global arrays & pointers but at this
1613              point we don't know if globals, so to be safe do all */
1614           deleteItemIf (&cseSet, ifAnyGetPointer);
1615         }
1616
1617       /* for pcall & ipush we need to add to the useSet */
1618       if ((ic->op == PCALL ||
1619            ic->op == IPUSH ||
1620            ic->op == IPOP ||
1621            ic->op == SEND) &&
1622           IS_SYMOP (IC_LEFT (ic)))
1623         {
1624
1625           /* check if they can be replaced */
1626           if (!computeOnly)
1627             {
1628               pdop = NULL;
1629               applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1630               if (pdop)
1631                 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1632             }
1633           /* the lookup could have changed it */
1634           if (IS_SYMOP (IC_LEFT (ic)))
1635             {
1636               OP_USES(IC_LEFT (ic))=
1637                 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1638               setUsesDefs (IC_LEFT (ic), ebb->defSet,
1639                            ebb->outDefs, &ebb->usesDefs);
1640             }
1641
1642
1643           /* if we a sending a pointer as a parameter
1644              then kill all cse since the pointed to item
1645              might be changed in the function being called */
1646           if ((ic->op == IPUSH || ic->op == SEND) &&
1647               IS_PTR (operandType (IC_LEFT (ic))))
1648             {
1649               deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1650               ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1651               for (i = 0; i < count; ebbs[i++]->visited = 0);
1652               applyToSet (ebb->succList, delGetPointerSucc,
1653                           IC_LEFT (ic), ebb->dfnum);
1654             }
1655           continue;
1656         }
1657
1658       /* if jumptable then mark the usage */
1659       if (ic->op == JUMPTABLE)
1660         {
1661           OP_USES(IC_JTCOND (ic))=
1662             bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1663           setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1664                        ebb->outDefs, &ebb->usesDefs);
1665           continue;
1666         }
1667
1668       if (SKIP_IC (ic))
1669         continue;
1670
1671       if (!computeOnly) {
1672         /* do some algebraic optimizations if possible */
1673         algebraicOpts (ic);
1674         while (constFold (ic, cseSet));
1675       }
1676
1677       /* small klugde */
1678       if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1679         {
1680           setOperandType (IC_LEFT (ic),
1681                           aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1682           fixUpTypes (ic);
1683
1684         }
1685       if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1686         {
1687           setOperandType (IC_RESULT (ic),
1688                           aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1689         }
1690
1691       /* if this is a condition statement then */
1692       /* check if the condition can be replaced */
1693       if (ic->op == IFX)
1694         {
1695           ifxOptimize (ic, cseSet, computeOnly,
1696                        ebb, &change,
1697                        ebbs, count);
1698           continue;
1699         }
1700
1701       /* if the assignment & result is a temp */
1702       /* see if we can replace it             */
1703       if (!computeOnly && ic->op == '=')
1704         {
1705
1706           /* update the spill location for this */
1707           updateSpillLocation (ic,0);
1708
1709           if (POINTER_SET (ic) && 
1710               !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1711             {
1712               pdop = NULL;
1713               applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1714               if (pdop && !computeOnly &&
1715                   IS_ITEMP (pdop) && IS_PTR(operandType(pdop)))
1716                 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1717             }
1718         }
1719
1720       checkSign = isSignedOp(ic);
1721
1722       /* do the operand lookup i.e. for both the */
1723       /* right & left operand : check the cseSet */
1724       /* to see if they have been replaced if yes */
1725       /* then replace them with those from cseSet */
1726       /* left operand */
1727       /* and left is a symbol  */
1728       if (IS_SYMOP (IC_LEFT (ic)) &&
1729           !computeOnly && ic->op != ADDRESS_OF)
1730         {
1731
1732           pdop = NULL;
1733           applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1734           if (pdop)
1735             {
1736               if (POINTER_GET (ic))
1737                 {
1738                   if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1739                     {
1740                         /* some non dominating block does POINTER_SET with
1741                            this variable .. unsafe to remove any POINTER_GETs */
1742                         if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1743                             ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1744                         ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1745                       change = 1;
1746                     }
1747                   /* check if there is a pointer set
1748                      for the same pointer visible if yes
1749                      then change this into an assignment */
1750                   pdop = NULL;
1751                   if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1752                       !bitVectBitValue (ebb->ptrsSet, pdop->key))
1753                     {
1754                       ic->op = '=';
1755                       IC_LEFT (ic) = NULL;
1756                       ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1757                       SET_ISADDR (IC_RESULT (ic), 0);
1758                     }
1759
1760                 }
1761               else
1762                 {
1763                   ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1764                   change = 1;
1765                 }
1766             }
1767         }
1768
1769       /*right operand */
1770       if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1771         {
1772
1773           pdop = NULL;
1774           applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1775           if (pdop) {
1776             ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1777             change = 1;
1778           }
1779         }
1780         
1781       /* if left or right changed then do algebraic */
1782       if (!computeOnly && change)
1783         {
1784           algebraicOpts (ic);
1785           while (constFold (ic, cseSet));
1786         }
1787
1788       /* if after all this it becomes an assignment to self
1789          then delete it and continue */
1790       if (ASSIGNMENT_TO_SELF (ic))
1791         {
1792           remiCodeFromeBBlock (ebb, ic);
1793           continue;
1794         }
1795
1796       /* now we will check to see if the entire */
1797       /* operation has been performed before    */
1798       /* and is available                       */
1799       /* don't do assignments they will be killed */
1800       /* by dead code elimination if required  do */
1801       /* it only if result is a temporary         */
1802       pdic = NULL;
1803       if (!(POINTER_GET (ic) &&
1804             (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1805              isOperandVolatile (IC_LEFT (ic), TRUE) ||
1806              bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
1807           !ASSIGNMENT (ic) &&
1808           IS_ITEMP (IC_RESULT (ic)) &&
1809           !computeOnly)
1810         {
1811             applyToSet (cseSet, findPrevIc, ic, &pdic);
1812           if (pdic && compareType (operandType (IC_RESULT (pdic)),
1813                                  operandType (IC_RESULT (ic))) != 1)
1814             pdic = NULL;
1815           if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0) 
1816               pdic = NULL;
1817         }
1818
1819       /* Alternate code */
1820       if (pdic && IS_ITEMP(IC_RESULT(ic))) {
1821         if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
1822           /* Mmm, found an equivalent pointer get at a lower level. 
1823              This could be a loop however with the same pointer set 
1824              later on */
1825         } else {
1826           /* if previous definition found change this to an assignment */
1827           ic->op = '=';
1828           IC_LEFT(ic) = NULL;
1829           IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
1830           SET_ISADDR(IC_RESULT(ic),0);
1831           SET_ISADDR(IC_RIGHT (ic),0);    
1832         }
1833       }
1834
1835       if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
1836           deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
1837           addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
1838       }
1839       defic = ic;
1840
1841       /* if assignment to a parameter which is not
1842          mine and type is a pointer then delete
1843          pointerGets to take care of aliasing */
1844       if (ASSIGNMENT (ic) &&
1845           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1846           IS_PTR (operandType (IC_RESULT (ic))))
1847         {
1848           deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1849           for (i = 0; i < count; ebbs[i++]->visited = 0);
1850           applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1851           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1852         }
1853
1854       /* if this is a pointerget then see if we can replace
1855          this with a previously assigned pointer value */
1856       if (POINTER_GET (ic) &&
1857           !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1858             isOperandVolatile (IC_LEFT (ic), TRUE)))
1859         {
1860           pdop = NULL;
1861           applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
1862           /* if we find it then locally replace all
1863              references to the result with what we assigned */
1864           if (pdop)
1865             {
1866               replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
1867             }
1868         }
1869
1870       /* delete from the cseSet anything that has */
1871       /* operands matching the result of this     */
1872       /* except in case of pointer access         */
1873       if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1874         {
1875           deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
1876           /* delete any previous definitions */
1877           ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
1878
1879         }
1880
1881       /* add the left & right to the defUse set */
1882       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
1883         {
1884           OP_USES(IC_LEFT (ic))=
1885             bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1886           setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1887
1888         }
1889
1890       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
1891         {
1892           OP_USES(IC_RIGHT (ic))=
1893             bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1894           setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1895
1896         }
1897
1898       /* for the result it is special case, put the result */
1899       /* in the defuseSet if it a pointer or array access  */
1900       if (POINTER_SET (defic))
1901         {
1902           OP_USES(IC_RESULT (ic))=
1903             bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1904           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1905           deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
1906           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
1907           /* delete from inexpressions of all successors which
1908              have dfNum > than this block */
1909           for (i = 0; i < count; ebbs[i++]->visited = 0);
1910           applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
1911
1912           /* delete from cseSet all other pointer sets
1913              for this operand */
1914           deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
1915           /* add to the local pointerset set */
1916           addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
1917         }
1918       else
1919         /* add the result to defintion set */ if (IC_RESULT (ic))
1920         {
1921           OP_DEFS(IC_RESULT (ic))=
1922             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1923           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1924           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1925           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1926         }
1927
1928
1929       /* if this is an addressof instruction then */
1930       /* put the symbol in the address of list &  */
1931       /* delete it from the cseSet                */
1932       if (defic->op == ADDRESS_OF)
1933         {
1934           addSetHead (&ebb->addrOf, IC_LEFT (ic));
1935           deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
1936         }
1937     }
1938
1939   setToNull ((void **) &ebb->outExprs);
1940   ebb->outExprs = cseSet;
1941   ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
1942   ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
1943   return change;
1944 }
1945
1946 /*-----------------------------------------------------------------*/
1947 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
1948 /*-----------------------------------------------------------------*/
1949 int 
1950 cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
1951 {
1952   int i;
1953   int change = 0;
1954
1955   /* if optimization turned off */
1956
1957   for (i = 0; i < count; i++)
1958     change += cseBBlock (ebbs[i], computeOnly, ebbs, count);
1959
1960   return change;
1961 }