OP_SYMBOL and OP_VALUE check their parameters are the proper type
[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_SET ((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_SET ((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_SET ((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_SET ((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_SET ((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_SET ((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_SET ((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
1414       iCode *pdic;
1415       operand *pdop;
1416       iCode *defic;
1417       int checkSign ;
1418
1419       ic->eBBlockNum = ebb->bbnum;
1420
1421       if (SKIP_IC2 (ic))
1422         continue;
1423
1424       /* if this is an assignment from true symbol
1425          to a temp then do pointer post inc/dec optimzation */
1426       if (ic->op == '=' && !POINTER_SET (ic) &&
1427           IS_PTR (operandType (IC_RESULT (ic))))
1428         {
1429           ptrPostIncDecOpt (ic);
1430         }
1431
1432       /* clear the def & use chains for the operands involved */
1433       /* in this operation . since it can change due to opts  */
1434       unsetDefsAndUses (ic);
1435
1436       if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1437         {
1438           /* add to defSet of the symbol */
1439           OP_DEFS_SET ((IC_RESULT (ic)),
1440             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key));
1441           /* add to the definition set of this block */
1442           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1443           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1444           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1445           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1446           /* delete global variables from the cseSet
1447              since they can be modified by the function call */
1448           deleteItemIf (&cseSet, ifDefGlobal);
1449
1450           /* and also itemps assigned from globals */
1451           deleteItemIf (&cseSet, ifAssignedFromGlobal);
1452
1453           /* delete all getpointer iCodes from cseSet, this should
1454              be done only for global arrays & pointers but at this
1455              point we don't know if globals, so to be safe do all */
1456           deleteItemIf (&cseSet, ifAnyGetPointer);
1457         }
1458
1459       /* for pcall & ipush we need to add to the useSet */
1460       if ((ic->op == PCALL ||
1461            ic->op == IPUSH ||
1462            ic->op == IPOP ||
1463            ic->op == SEND) &&
1464           IS_SYMOP (IC_LEFT (ic)))
1465         {
1466
1467           /* check if they can be replaced */
1468           if (!computeOnly)
1469             {
1470               pdop = NULL;
1471               applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1472               if (pdop)
1473                 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1474             }
1475           /* the lookup could have changed it */
1476           if (IS_SYMOP (IC_LEFT (ic)))
1477             {
1478               OP_USES_SET ((IC_LEFT (ic)),
1479                 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key));
1480               setUsesDefs (IC_LEFT (ic), ebb->defSet,
1481                            ebb->outDefs, &ebb->usesDefs);
1482             }
1483
1484
1485           /* if we a sending a pointer as a parameter
1486              then kill all cse since the pointed to item
1487              might be changed in the function being called */
1488           if ((ic->op == IPUSH || ic->op == SEND) &&
1489               IS_PTR (operandType (IC_LEFT (ic))))
1490             {
1491               deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1492               ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1493               for (i = 0; i < count; ebbs[i++]->visited = 0);
1494               applyToSet (ebb->succList, delGetPointerSucc,
1495                           IC_LEFT (ic), ebb->dfnum);
1496             }
1497           continue;
1498         }
1499
1500       /* if jumptable then mark the usage */
1501       if (ic->op == JUMPTABLE)
1502         {
1503           OP_USES_SET ((IC_JTCOND (ic)),
1504             bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key));
1505           setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1506                        ebb->outDefs, &ebb->usesDefs);
1507           continue;
1508         }
1509
1510       if (SKIP_IC (ic))
1511         continue;
1512
1513       /* do some algebraic optimizations if possible */
1514       algebraicOpts (ic);
1515       while (constFold (ic, cseSet));
1516
1517       /* small klugde */
1518       if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1519         {
1520           setOperandType (IC_LEFT (ic),
1521                           aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1522           fixUpTypes (ic);
1523
1524         }
1525       if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1526         {
1527           setOperandType (IC_RESULT (ic),
1528                           aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1529         }
1530
1531       /* if this is a condition statment then */
1532       /* check if the condition can be replaced */
1533       if (ic->op == IFX)
1534         {
1535           ifxOptimize (ic, cseSet, computeOnly,
1536                        ebb, &change,
1537                        ebbs, count);
1538           continue;
1539         }
1540
1541       /* if the assignment & result is a temp */
1542       /* see if we can replace it             */
1543       if (ic->op == '=')
1544         {
1545
1546           /* update the spill location for this */
1547           updateSpillLocation (ic,0);
1548
1549           if (POINTER_SET (ic) &&
1550               !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1551             {
1552               pdop = NULL;
1553               applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1554               if (pdop && IS_ITEMP (pdop) && !computeOnly)
1555                 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1556             }
1557         }
1558
1559       checkSign = isSignedOp(ic);
1560
1561       /* do the operand lookup i.e. for both the */
1562       /* right & left operand : check the cseSet */
1563       /* to see if they have been replaced if yes */
1564       /* then replace them with those from cseSet */
1565       /* left operand */
1566       /* and left is a symbol  */
1567       if (IS_SYMOP (IC_LEFT (ic)) &&
1568           !computeOnly && ic->op != ADDRESS_OF)
1569         {
1570
1571           pdop = NULL;
1572           applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1573           if (pdop)
1574             {
1575               if (POINTER_GET (ic))
1576                 {
1577                   if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1578                     {
1579                         /* some non dominating block does POINTER_SET with
1580                            this variable .. unsafe to remove any POINTER_GETs */
1581                         if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1582                             ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1583                         ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1584                       change = 1;
1585                     }
1586                   /* check if there is a pointer set
1587                      for the same pointer visible if yes
1588                      then change this into an assignment */
1589                   pdop = NULL;
1590                   if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1591                       !bitVectBitValue (ebb->ptrsSet, pdop->key))
1592                     {
1593                       ic->op = '=';
1594                       IC_LEFT (ic) = NULL;
1595                       ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1596                       SET_ISADDR (IC_RESULT (ic), 0);
1597                     }
1598
1599                 }
1600               else
1601                 {
1602                   ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1603                   change = 1;
1604                 }
1605             }
1606         }
1607
1608       /*right operand */
1609       if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1610         {
1611
1612           pdop = NULL;
1613           applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1614           if (pdop) {
1615             ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1616             change = 1;
1617           }
1618         }
1619         
1620       /* if left or right changed then do algebraic */
1621       if (change)
1622         {
1623           algebraicOpts (ic);
1624           while (constFold (ic, cseSet));
1625         }
1626
1627       /* if after all this it becomes a assignment to self
1628          then delete it and continue */
1629       if (ASSIGNMENT_TO_SELF (ic))
1630         {
1631           remiCodeFromeBBlock (ebb, ic);
1632           continue;
1633         }
1634
1635       /* now we will check to see if the entire */
1636       /* operation has been performed before    */
1637       /* and is available                       */
1638       /* don't do assignments they will be killed */
1639       /* by dead code elimination if required  do */
1640       /* it only if result is a temporary         */
1641       pdic = NULL;
1642       if (!(POINTER_GET (ic) &&
1643             (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1644              isOperandVolatile (IC_LEFT (ic), TRUE) ||
1645              bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
1646           !ASSIGNMENT (ic) &&
1647           IS_ITEMP (IC_RESULT (ic)) &&
1648           !computeOnly)
1649         {
1650             applyToSet (cseSet, findPrevIc, ic, &pdic);
1651           if (pdic && compareType (operandType (IC_RESULT (pdic)),
1652                                  operandType (IC_RESULT (ic))) != 1)
1653             pdic = NULL;
1654           if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0) 
1655               pdic = NULL;
1656         }
1657
1658       /* Alternate code */
1659       if (pdic && IS_ITEMP(IC_RESULT(ic))) {
1660         if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
1661           /* Mmm, found an equivalent pointer get at a lower level. 
1662              This could be a loop however with the same pointer set 
1663              later on */
1664         } else {
1665           /* if previous definition found change this to an assignment */
1666           ic->op = '=';
1667           IC_LEFT(ic) = NULL;
1668           IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
1669           SET_ISADDR(IC_RESULT(ic),0);
1670           SET_ISADDR(IC_RIGHT (ic),0);    
1671         }
1672       }
1673
1674       if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
1675           deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
1676           addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
1677       }
1678       defic = ic;
1679
1680       /* if assignment to a parameter which is not
1681          mine and type is a pointer then delete
1682          pointerGets to take care of aliasing */
1683       if (ASSIGNMENT (ic) &&
1684           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1685           IS_PTR (operandType (IC_RESULT (ic))))
1686         {
1687           deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1688           for (i = 0; i < count; ebbs[i++]->visited = 0);
1689           applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1690           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1691         }
1692
1693       /* if this is a pointerget then see if we can replace
1694          this with a previously assigned pointer value */
1695       if (POINTER_GET (ic) &&
1696           !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1697             isOperandVolatile (IC_LEFT (ic), TRUE)))
1698         {
1699           pdop = NULL;
1700           applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
1701           /* if we find it then locally replace all
1702              references to the result with what we assigned */
1703           if (pdop)
1704             {
1705               replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
1706             }
1707         }
1708
1709       /* delete from the cseSet anything that has */
1710       /* operands matching the result of this     */
1711       /* except in case of pointer access         */
1712       if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1713         {
1714           deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
1715           /* delete any previous definitions */
1716           ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
1717
1718         }
1719
1720       /* add the left & right to the defUse set */
1721       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
1722         {
1723           OP_USES_SET ((IC_LEFT (ic)),
1724             bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key));
1725           setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1726
1727         }
1728
1729       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
1730         {
1731           OP_USES_SET ((IC_RIGHT (ic)),
1732             bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key));
1733           setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1734
1735         }
1736
1737       /* for the result it is special case, put the result */
1738       /* in the defuseSet if it a pointer or array access  */
1739       if (POINTER_SET (defic))
1740         {
1741           OP_USES_SET ((IC_RESULT (ic)),
1742             bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key));
1743           setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1744           deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
1745           ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
1746           /* delete from inexpressions of all successors which
1747              have dfNum > than this block */
1748           for (i = 0; i < count; ebbs[i++]->visited = 0);
1749           applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
1750
1751           /* delete from cseSet all other pointer sets
1752              for this operand */
1753           deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
1754           /* add to the local pointerset set */
1755           addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
1756         }
1757       else
1758         /* add the result to defintion set */ if (IC_RESULT (ic))
1759         {
1760           OP_DEFS_SET ((IC_RESULT (ic)),
1761             bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key));
1762           ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1763           ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1764           ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1765         }
1766
1767
1768       /* if this is an addressof instruction then */
1769       /* put the symbol in the address of list &  */
1770       /* delete it from the cseSet                */
1771       if (defic->op == ADDRESS_OF)
1772         {
1773           addSetHead (&ebb->addrOf, IC_LEFT (ic));
1774           deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
1775         }
1776     }
1777
1778   setToNull ((void **) &ebb->outExprs);
1779   ebb->outExprs = cseSet;
1780   ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
1781   ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
1782   return change;
1783 }
1784
1785 /*-----------------------------------------------------------------*/
1786 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
1787 /*-----------------------------------------------------------------*/
1788 int 
1789 cseAllBlocks (eBBlock ** ebbs, int count)
1790 {
1791   int i;
1792   int change = 0;
1793
1794   /* if optimization turned off */
1795
1796   for (i = 0; i < count; i++)
1797     change += cseBBlock (ebbs[i], FALSE, ebbs, count);
1798
1799   return change;
1800 }