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