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