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