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