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