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