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