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