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