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