work on avr port start by defining the new
[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         bitVectnBitsOn(OP_USES(IC_RIGHT(ic))) == 0 &&
766         OP_SYMBOL(IC_RESULT(ic))->isreqv) {
767         
768         setype = getSpec(operandType(IC_RESULT(ic)));
769
770         if (!IC_RIGHT(ic)->noSpilLoc           &&
771             !IS_VOLATILE(setype)               &&
772             !IN_FARSPACE(SPEC_OCLS(setype))    &&
773             !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )  
774             
775             SPIL_LOC(IC_RIGHT(ic)) = 
776                 SPIL_LOC(IC_RESULT(ic));
777     }
778 }
779
780 /*-----------------------------------------------------------------*/
781 /* setUsesDef - sets the uses def bitvector for a given operand    */
782 /*-----------------------------------------------------------------*/
783 void setUsesDefs (operand *op, bitVect *bdefs, 
784                   bitVect *idefs, bitVect **oud)
785 {
786     /* compute the definitions alive at this point */
787     bitVect *adefs = bitVectUnion(bdefs,idefs);
788
789     /* of these definitions find the ones that are */
790     /* for this operand */
791     adefs = bitVectIntersect(adefs,OP_DEFS(op));
792     
793     /* these are the definitions that this operand can use */
794     op->usesDefs = adefs;
795     
796     /* the out defs is an union */
797     *oud = bitVectUnion(*oud,adefs);
798 }
799
800 /*-----------------------------------------------------------------*/
801 /* unsetDefsAndUses - clear this operation for the operands        */
802 /*-----------------------------------------------------------------*/
803 void unsetDefsAndUses ( iCode *ic ) 
804 {
805     if ( ic->op == JUMPTABLE)
806         return ;
807
808     /* take away this definition from the def chain of the */
809     /* result & take away from use set of the operands */
810     if (ic->op != IFX) {
811         /* turn off def set */
812         if (IS_SYMOP(IC_RESULT(ic))) {
813             if ( !POINTER_SET(ic)) 
814                 bitVectUnSetBit(OP_DEFS(IC_RESULT(ic)),ic->key);
815             else
816                 bitVectUnSetBit(OP_USES(IC_RESULT(ic)),ic->key);
817         }
818         /* turn off the useSet for the operands */
819         if (IS_SYMOP(IC_LEFT(ic)))
820             bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key);
821         
822         if (IS_SYMOP(IC_RIGHT(ic)))
823             bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
824     }
825     else /* must be ifx turn off the use */
826         if (IS_SYMOP(IC_COND(ic)))
827             bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key);    
828 }
829
830 /*-----------------------------------------------------------------*/
831 /* ifxOptimize - changes ifx conditions if it can                  */
832 /*-----------------------------------------------------------------*/
833 void ifxOptimize (iCode *ic, set *cseSet, 
834                          int computeOnly , 
835                          eBBlock *ebb, int *change,
836                          eBBlock **ebbs, int count)
837 {
838     operand *pdop ;
839     symbol *label;
840
841     /* if the condition can be replaced */
842     if (!computeOnly) {
843         pdop = NULL ;
844         applyToSetFTrue (cseSet,findCheaperOp,IC_COND(ic),&pdop);
845         if (pdop) {
846             IC_COND(ic) = pdop ;
847             (*change)++;
848         }
849     }
850     
851     /* if the conditional is a literal then */
852     if (IS_OP_LITERAL(IC_COND(ic))) {          
853
854         if ( operandLitValue(IC_COND(ic)) && IC_TRUE(ic)) {
855             
856             /* change to a goto */
857             ic->op = GOTO ;
858             IC_LABEL(ic) = IC_TRUE(ic);
859             (*change)++;
860             
861         } else {
862             
863             if (!operandLitValue(IC_COND(ic)) && IC_FALSE(ic)) {                
864                 ic->op = GOTO ;
865                 IC_LABEL(ic) = IC_FALSE(ic);
866                 (*change)++;
867                 
868             } else {
869                 /* then kill this if condition */                       
870                 remiCodeFromeBBlock (ebb,ic);           
871             }       
872         }
873         
874         /* now we need to recompute the control flow */
875         /* since the control flow has changed        */
876         /* this is very expensive but it does not happen */
877         /* too often, if it does happen then the user pays */
878         /* the price */
879         computeControlFlow (ebbs,count,1);
880         werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
881         return ;
882     }
883     
884     /* if there is only one successor and that successor
885        is the same one we are conditionally going to then
886        we can remove this conditional statement */
887     label = (IC_TRUE(ic) ? IC_TRUE(ic) : IC_FALSE(ic));
888     if (elementsInSet(ebb->succList) == 1 &&
889         isinSet(ebb->succList,eBBWithEntryLabel(ebbs,label,count))) {
890
891         remiCodeFromeBBlock(ebb,ic);
892         computeControlFlow (ebbs,count,1);
893         werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
894         return ;        
895     }
896         
897         
898     /* if it remains an IFX the update the use Set */
899     OP_USES(IC_COND(ic)) = bitVectSetBit(OP_USES(IC_COND(ic)),ic->key);
900     setUsesDefs(IC_COND(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
901     return ;  
902 }
903
904 /*-----------------------------------------------------------------*/
905 /* diCodeForSym - finds the definiting instruction for a symbol    */
906 /*-----------------------------------------------------------------*/
907 DEFSETFUNC(diCodeForSym)
908 {
909     cseDef *cdp = item;
910     V_ARG(operand *,sym);
911     V_ARG(iCode **,dic);
912
913     /* if already found */
914     if (*dic)
915         return 0;
916
917     /* if not if this is the defining iCode */
918     if (sym->key == cdp->key) {
919         *dic = cdp->diCode ;
920         return 1;
921     }
922
923     return 0;
924 }
925
926 /*-----------------------------------------------------------------*/
927 /* constFold - does some constant folding                          */
928 /*-----------------------------------------------------------------*/
929 int constFold (iCode *ic, set *cseSet)
930 {
931     iCode *dic = NULL;
932     /* this routine will change
933        a = b + 10;
934        c = a + 10;
935        to
936        c = b + 20; */
937
938     /* deal with only + & - */
939     if (ic->op != '+' &&
940         ic->op != '-' )
941         return 0;
942
943     /* this check is a hueristic to prevent live ranges
944        from becoming too long */
945     if (IS_PTR(operandType(IC_RESULT(ic))))
946         return 0;
947
948     /* check if operation with a literal */
949     if (!IS_OP_LITERAL(IC_RIGHT(ic)))
950         return 0;
951
952     /* check if we can find a definition for the
953        right hand side */
954     if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(ic),&dic)))
955         return 0;
956
957     /* check that this is also a +/-  */
958     if (dic->op != '+' && dic->op != '-')
959         return 0;
960
961     /* with a literal */
962     if (!IS_OP_LITERAL(IC_RIGHT(dic)))
963         return 0;
964
965     /* it is if the operations are the same*/
966     /* the literal parts need to be added  */
967     IC_LEFT(ic) = operandFromOperand(IC_LEFT(dic));    
968     if (ic->op == dic->op )
969         IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic))+
970                                       operandLitValue(IC_RIGHT(dic)));
971     else
972         IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) -
973                                       operandLitValue(IC_RIGHT(dic)));
974
975     if (IS_ITEMP(IC_RESULT(ic))) {
976         SPIL_LOC(IC_RESULT(ic)) = NULL;
977         IC_RESULT(ic)->noSpilLoc = 1;
978     }
979         
980     
981     return 1;
982 }
983
984 /*-----------------------------------------------------------------*/
985 /* deleteGetPointers - called when a pointer is passed as parm     */
986 /* will delete from cseSet all get pointers computed from this     */
987 /* pointer. A simple ifOperandsHave is not good enough here        */
988 /*-----------------------------------------------------------------*/
989 static void deleteGetPointers (set **cseSet, set **pss, operand *op,eBBlock *ebb)
990 {
991     set *compItems = NULL;
992     cseDef *cdp ;
993     operand *cop;
994     
995     /* easy return */
996     if (!*cseSet && !*pss)
997         return ;
998     
999     /* first find all items computed from this operand .
1000        This done fairly simply go thru the list and find
1001        those that are computed by arthimetic with this
1002        op */
1003     for (cdp = setFirstItem(*cseSet); cdp ; cdp = setNextItem(*cseSet)) {
1004         if (IS_ARITHMETIC_OP(cdp->diCode)) {
1005             if (isOperandEqual(IC_LEFT(cdp->diCode),op) ||
1006                 isOperandEqual(IC_RIGHT(cdp->diCode),op)) {
1007                                 /* save it in our list of items */
1008                 addSet(&compItems,IC_RESULT(cdp->diCode));
1009             }
1010             /* also check for those computed from our computed 
1011                list . This will take care of situations like
1012                iTemp1 = iTemp0 + 8;
1013                iTemp2 = iTemp1 + 8; */
1014             if (isinSetWith(compItems,IC_LEFT(cdp->diCode),isOperandEqual) ||
1015                 isinSetWith(compItems,IC_RIGHT(cdp->diCode),isOperandEqual)) {
1016                     addSet(&compItems,IC_RESULT(cdp->diCode));
1017             }
1018         }
1019     }
1020     
1021     /* now delete all pointer gets with this op */
1022     deleteItemIf(cseSet,ifPointerGet,op);
1023     deleteItemIf(pss,ifPointerSet,op);
1024
1025     /* set the bit vector used by dataFlow computation later */
1026     ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,op->key);
1027     /* now for the computed items */
1028     for (cop = setFirstItem(compItems); cop ; cop = setNextItem(compItems)) {
1029         ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,cop->key);    
1030         deleteItemIf(cseSet,ifPointerGet,cop);
1031         deleteItemIf(pss,ifPointerSet,cop);
1032     }
1033 }
1034
1035 /*-----------------------------------------------------------------*/
1036 /* delGetPointerSucc - delete get pointer from inExprs of succ with*/
1037 /*                     dfnum > supplied                            */
1038 /*-----------------------------------------------------------------*/
1039 DEFSETFUNC(delGetPointerSucc)
1040 {
1041     eBBlock *ebp = item;
1042     V_ARG(operand *,op);
1043     V_ARG(int,dfnum);
1044
1045     if (ebp->visited)
1046         return 0;
1047     
1048     ebp->visited = 1;
1049     if (ebp->dfnum > dfnum) {
1050         deleteItemIf(&ebp->inExprs,ifPointerGet,op);
1051     }
1052
1053     return applyToSet(ebp->succList,delGetPointerSucc,op,dfnum);
1054 }    
1055
1056 /*-----------------------------------------------------------------*/
1057 /* cseBBlock - common subexpression elimination for basic blocks   */
1058 /*             this is the hackiest kludgiest routine in the whole */
1059 /*             system. also the most important, since almost all   */
1060 /*             data flow related information is computed by it     */
1061 /*-----------------------------------------------------------------*/
1062 int cseBBlock ( eBBlock *ebb, int computeOnly, 
1063                 eBBlock **ebbs, int count)
1064 {
1065     set *cseSet ;
1066     iCode *ic ;           
1067     int change = 0 ;
1068     int i;   
1069     set *ptrSetSet = NULL;
1070
1071     /* if this block is not reachable */
1072     if (ebb->noPath)
1073         return change;
1074
1075    /* set of common subexpressions */   
1076     cseSet = setFromSet (ebb->inExprs) ;      
1077       
1078     /* these will be computed by this routine */
1079     setToNull ((void **)&ebb->outDefs);    
1080     setToNull ((void **)&ebb->defSet);
1081     setToNull ((void **)&ebb->usesDefs);
1082     setToNull ((void **)&ebb->ptrsSet);
1083     setToNull ((void **)&ebb->addrOf);
1084     setToNull ((void **)&ebb->ldefs);
1085
1086     ebb->outDefs = bitVectCopy (ebb->inDefs);
1087     bitVectDefault = iCodeKey;
1088     ebb->defSet = newBitVect(iCodeKey);
1089     ebb->usesDefs=newBitVect(iCodeKey);
1090
1091     /* for all the instructions in this block do */
1092     for (ic = ebb->sch ; ic ; ic = ic->next ) {
1093         
1094         iCode *pdic; 
1095         operand *pdop ;
1096         iCode *defic;
1097         
1098         if (SKIP_IC2(ic))
1099             continue ;
1100
1101         /* clear the def & use chains for the operands involved */
1102         /* in this operation . since it can change due to opts  */
1103         unsetDefsAndUses (ic);
1104         
1105         if ( ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE) {
1106             /* add to defSet of the symbol */
1107             OP_DEFS(IC_RESULT(ic)) = 
1108                 bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
1109             /* add to the definition set of this block */
1110             ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);      
1111             ebb->ldefs  = bitVectSetBit (ebb->ldefs,ic->key);
1112             ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic)));
1113             setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1114             /* delete global variables from the cseSet
1115                since they can be modified by the function call */
1116             deleteItemIf(&cseSet,ifDefGlobal);
1117         }
1118
1119         /* for pcall & ipush we need to add to the useSet */
1120         if ((ic->op == PCALL || 
1121              ic->op == IPUSH || 
1122              ic->op == IPOP  || 
1123              ic->op == SEND) && 
1124             IS_SYMOP(IC_LEFT(ic))) {
1125             
1126             /* check if they can be replaced */
1127             if ( !computeOnly ) {
1128                 pdop = NULL ;
1129                 applyToSetFTrue(cseSet,findCheaperOp,IC_LEFT(ic),&pdop);
1130                 if (pdop)
1131                     IC_LEFT(ic) = pdop ;
1132             }
1133             /* the lookup could have changed it*/
1134             if (IS_SYMOP(IC_LEFT(ic))) {
1135                 OP_USES(IC_LEFT(ic)) = 
1136                     bitVectSetBit(OP_USES(IC_LEFT(ic)),ic->key);
1137                 setUsesDefs(IC_LEFT(ic),ebb->defSet,
1138                             ebb->outDefs,&ebb->usesDefs);
1139             }
1140
1141             
1142             /* if we a sending a pointer as a parameter
1143                then kill all cse since the pointed to item
1144                might be changed in the function being called */
1145             if ((ic->op == IPUSH || ic->op == SEND) &&
1146                 IS_PTR(operandType(IC_LEFT(ic)))) {
1147                 deleteGetPointers(&cseSet,&ptrSetSet,IC_LEFT(ic),ebb);
1148                 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_LEFT(ic)->key);
1149                 for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1150                 applyToSet(ebb->succList,delGetPointerSucc,
1151                            IC_LEFT(ic),ebb->dfnum);
1152             }
1153             continue;
1154         }
1155
1156         /* if jumptable then mark the usage */
1157         if (ic->op == JUMPTABLE ) {
1158             OP_USES(IC_JTCOND(ic)) = 
1159                 bitVectSetBit(OP_USES(IC_JTCOND(ic)),ic->key);
1160             setUsesDefs(IC_JTCOND(ic),ebb->defSet,
1161                         ebb->outDefs,&ebb->usesDefs);
1162             continue;
1163         }
1164
1165         if (SKIP_IC(ic))
1166             continue ;
1167         
1168         /* do some algebraic optimizations if possible */
1169         algebraicOpts (ic);
1170         while (constFold(ic,cseSet));
1171
1172         /* small klugde */
1173         if (POINTER_GET(ic) && !IS_PTR(operandType(IC_LEFT(ic)))) {
1174             setOperandType(IC_LEFT(ic),
1175                            aggrToPtr(operandType(IC_LEFT(ic)),FALSE));
1176         }
1177         if (POINTER_SET(ic) && !IS_PTR(operandType(IC_RESULT(ic)))) {
1178             setOperandType(IC_RESULT(ic),
1179                            aggrToPtr(operandType(IC_RESULT(ic)),FALSE));
1180         }
1181
1182         /* if this is a condition statment then */
1183         /* check if the condition can be replaced */
1184         if (ic->op == IFX ) {
1185             ifxOptimize (ic, cseSet, computeOnly, 
1186                          ebb, &change, 
1187                          ebbs, count);
1188             continue ;
1189         }
1190             
1191         /* if the assignment & result is a temp */
1192         /* see if we can replace it             */
1193         if (ic->op == '=') {
1194             
1195             /* update the spill location for this */
1196             updateSpillLocation (ic);
1197
1198             if (POINTER_SET(ic)) {
1199                 pdop = NULL ;
1200                 applyToSetFTrue (cseSet,findCheaperOp,IC_RESULT(ic),&pdop);
1201                 if (pdop && IS_ITEMP(pdop) && !computeOnly)                 
1202                     IC_RESULT(ic) = pdop;                               
1203             }
1204         }           
1205         
1206         /* do the operand lookup i.e. for both the */
1207         /* right & left operand : check the cseSet */
1208         /* to see if they have been replaced if yes*/
1209         /* then replace them with those from cseSet*/
1210         /* left operand */
1211         /* and left is a symbol  */
1212         if (IS_SYMOP(IC_LEFT(ic)) && 
1213             !computeOnly && ic->op != ADDRESS_OF ) {  
1214             
1215             pdop = NULL;                
1216             applyToSetFTrue (cseSet,findCheaperOp,IC_LEFT(ic),&pdop) ;
1217             if (pdop)  { 
1218                 if (POINTER_GET(ic)) {
1219                     if (IS_ITEMP(pdop) || IS_OP_LITERAL(pdop)) {
1220                         IC_LEFT(ic) = pdop;
1221                         change = 1;
1222                     }
1223                     /* check if there is a pointer set
1224                        for the same pointer visible if yes
1225                        then change this into an assignment */
1226                     pdop = NULL;
1227                     if (applyToSetFTrue(cseSet,findPointerSet,IC_LEFT(ic),&pdop) &&
1228                         !bitVectBitValue(ebb->ptrsSet,pdop->key)){
1229                         ic->op = '=';
1230                         IC_LEFT(ic) = NULL;
1231                         IC_RIGHT(ic) = pdop;
1232                         SET_ISADDR(IC_RESULT(ic),0);
1233                     }
1234                         
1235                 }
1236                 else {
1237                     IC_LEFT(ic)  = pdop ;
1238                     change = 1;
1239                 }
1240             }       
1241         }
1242         
1243         /*right operand */
1244         if (IS_SYMOP(IC_RIGHT(ic)) && !computeOnly) {
1245             
1246             pdop = NULL ;
1247             applyToSetFTrue (cseSet,findCheaperOp,IC_RIGHT(ic),&pdop);
1248             if (pdop) {
1249                 
1250                 IC_RIGHT(ic) = pdop;
1251                 change = 1;
1252             }
1253         }
1254         
1255         /* if left or right changed then do algebraic */
1256         if (change) {
1257             algebraicOpts(ic);
1258             while(constFold(ic,cseSet));
1259         }
1260
1261         /* if after all this it becomes a assignment to self 
1262            then delete it and continue */
1263         if (ASSIGNMENT_TO_SELF(ic)) {      
1264             remiCodeFromeBBlock(ebb,ic);
1265             continue;
1266         }           
1267         
1268         /* now we will check to see if the entire */
1269         /* operation has been performed before    */
1270         /* and is available                       */     
1271         /* don't do assignments they will be killed */
1272         /* by dead code elimination if required  do */
1273         /* it only if result is a temporary         */
1274         pdic = NULL ;   
1275         if (!( POINTER_GET(ic)                      &&
1276                (IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
1277                isOperandVolatile(IC_LEFT(ic),TRUE))) &&
1278             ! ASSIGNMENT(ic)                        && 
1279               IS_ITEMP(IC_RESULT(ic))               &&
1280             ! computeOnly) {
1281             applyToSet (cseSet,findPrevIc,ic,&pdic);
1282         } 
1283        
1284         /* if found then eliminate this and add to*/
1285         /* to cseSet an element containing result */
1286         /* of this with previous opcode           */      
1287         if (pdic) {
1288
1289             if (IS_ITEMP(IC_RESULT(ic))) {
1290
1291                 /* replace in the remaining of this block */
1292                 replaceAllSymBySym(ic->next,IC_RESULT(ic),IC_RESULT(pdic));
1293                 /* remove this iCode from inexpressions of all
1294                    its successors, it cannot be in the in expressions
1295                    of any of the predecessors */        
1296                 for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1297                 applyToSet(ebb->succList,removeFromInExprs,ic,IC_RESULT(ic),
1298                            IC_RESULT(pdic),ebb);
1299
1300                 /* if this was moved from another block */
1301                 /* then replace in those blocks too     */
1302                 if ( ic->movedFrom ) {
1303                     eBBlock *owner ;
1304                     for (owner = setFirstItem(ic->movedFrom); owner ;
1305                          owner = setNextItem(ic->movedFrom))
1306                         replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic));
1307                 }
1308                 pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE);
1309             } 
1310             else
1311                 addSetHead (&cseSet,newCseDef(IC_RESULT(ic),pdic));                     
1312             
1313             if (!computeOnly) 
1314                 /* eliminate this */
1315                 remiCodeFromeBBlock (ebb,ic);               
1316                     
1317             defic = pdic ;          
1318             change++ ;
1319
1320             if (IS_ITEMP(IC_RESULT(ic)))
1321                 continue ;
1322
1323         } else {
1324
1325             /* just add this as a previous expression except in */
1326             /* case of a pointer access in which case this is a */
1327             /* usage not a definition                           */
1328             if (! (POINTER_SET(ic)) && IC_RESULT(ic)){
1329                 deleteItemIf (&cseSet, ifDefSymIsX,IC_RESULT(ic));
1330                 addSetHead(&cseSet,newCseDef(IC_RESULT(ic),ic));
1331             }
1332             defic = ic;
1333
1334         }
1335         
1336         /* if assignment to a parameter which is not
1337            mine and type is a pointer then delete
1338            pointerGets to take care of aliasing */
1339         if (ASSIGNMENT(ic)                        && 
1340             OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) &&
1341             IS_PTR(operandType(IC_RESULT(ic)))) {
1342             deleteGetPointers(&cseSet,&ptrSetSet,IC_RIGHT(ic),ebb);
1343             for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1344             applyToSet(ebb->succList,delGetPointerSucc,IC_RIGHT(ic),ebb->dfnum);
1345             ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RIGHT(ic)->key);
1346         }
1347
1348         /* if this is a pointerget then see if we can replace
1349            this with a previously assigned pointer value */
1350         if (POINTER_GET(ic) && 
1351             !(IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
1352                isOperandVolatile(IC_LEFT(ic),TRUE))) {
1353             pdop = NULL;
1354             applyToSet(ptrSetSet,findPointerSet,IC_LEFT(ic),&pdop);
1355             /* if we find it then locally replace all
1356                references to the result with what we assigned */
1357             if (pdop) {
1358                 replaceAllSymBySym(ic->next,IC_RESULT(ic),pdop);
1359             }
1360         }
1361
1362         /* delete from the cseSet anything that has */
1363         /* operands matching the result of this     */
1364         /* except in case of pointer access         */
1365         if (!(POINTER_SET(ic)) && IC_RESULT(ic)) {
1366             deleteItemIf (&cseSet,ifOperandsHave,IC_RESULT(ic));            
1367             /* delete any previous definitions */ 
1368             ebb->defSet = bitVectCplAnd (ebb->defSet,OP_DEFS(IC_RESULT(ic)));     
1369             
1370         }
1371         
1372         /* add the left & right to the defUse set */
1373         if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic))) {
1374             OP_USES(IC_LEFT(ic)) = 
1375                 bitVectSetBit (OP_USES(IC_LEFT(ic)),ic->key);
1376             setUsesDefs(IC_LEFT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1377
1378         }
1379
1380         if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic))) {
1381             OP_USES(IC_RIGHT(ic)) = 
1382                 bitVectSetBit (OP_USES(IC_RIGHT(ic)),ic->key);  
1383             setUsesDefs(IC_RIGHT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1384
1385         }
1386
1387         /* for the result it is special case, put the result */
1388         /* in the defuseSet if it a pointer or array access  */
1389         if ( POINTER_SET(defic) ) {
1390             OP_USES(IC_RESULT(ic)) = 
1391                 bitVectSetBit (OP_USES(IC_RESULT(ic)),ic->key);
1392             setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1393             deleteItemIf(&cseSet,ifPointerGet,IC_RESULT(ic));
1394             ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RESULT(ic)->key);
1395             /* delete from inexpressions of all successors which
1396                have dfNum > than this block */
1397             for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1398             applyToSet(ebb->succList,delGetPointerSucc,IC_RESULT(ic),ebb->dfnum);
1399             
1400             /* delete from cseSet all other pointer sets
1401                for this operand */
1402             deleteItemIf(&ptrSetSet,ifPointerSet,IC_RESULT(ic));
1403             /* add to the local pointerset set */
1404             addSetHead(&ptrSetSet,newCseDef(IC_RESULT(ic),ic));
1405         }
1406         else /* add the result to defintion set */
1407             if (IC_RESULT(ic)) {
1408                 OP_DEFS(IC_RESULT(ic)) = 
1409                     bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
1410                 ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);              
1411                 ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic))); 
1412                 ebb->ldefs  = bitVectSetBit (ebb->ldefs,ic->key);
1413             }
1414                
1415
1416         /* if this is an addressof instruction then */
1417         /* put the symbol in the address of list &  */
1418         /* delete it from the cseSet                */
1419         if (defic->op == ADDRESS_OF) {
1420             addSetHead (&ebb->addrOf, IC_LEFT(ic));
1421             deleteItemIf(&cseSet,ifDefSymIsX,IC_LEFT(ic));
1422         }
1423     }
1424
1425     setToNull ((void **)&ebb->outExprs);
1426     ebb->outExprs = cseSet;        
1427     ebb->outDefs = bitVectUnion (ebb->outDefs,ebb->defSet);
1428     ebb->ptrsSet = bitVectUnion (ebb->ptrsSet,ebb->inPtrsSet);
1429     return change ;
1430 }
1431
1432 /*-----------------------------------------------------------------*/
1433 /* cseAllBlocks - will sequentially go thru & do cse for all blocks*/
1434 /*-----------------------------------------------------------------*/
1435 int cseAllBlocks (eBBlock **ebbs,int count)
1436 {
1437     int i;
1438     int change = 0 ;
1439
1440     /* if optimization turned off */
1441
1442     for (i = 0 ; i < count ;i++ ) 
1443         change += cseBBlock (ebbs[i],FALSE,ebbs,count);
1444
1445     return change;
1446 }
1447