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