]> git.gag.com Git - fw/sdcc/blob - src/SDCCcse.c
* Added common.h
[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
434     if (POINTER_GET(cdp->diCode) &&
435         IC_LEFT(cdp->diCode)->key == op->key)
436         return 1;
437
438     return 0;
439 }
440
441 /*-----------------------------------------------------------------*/
442 /* ifPointerSet - returns true if the icode is pointer set sym     */
443 /*-----------------------------------------------------------------*/
444 DEFSETFUNC(ifPointerSet)
445 {
446     cseDef *cdp = item;
447     V_ARG(operand *,op);
448
449     if (POINTER_SET(cdp->diCode) &&
450         IC_RESULT(cdp->diCode)->key == op->key)
451         return 1;
452
453     return 0;
454 }
455
456 /*-----------------------------------------------------------------*/
457 /* ifDiCodeIsX - will return 1 if the symbols match                 */
458 /*-----------------------------------------------------------------*/
459 DEFSETFUNC(ifDiCodeIsX)
460 {     
461     cseDef *cdp  = item;
462     V_ARG(iCode *,ic);    
463
464     return cdp->diCode == ic;
465              
466 }
467
468 /*-----------------------------------------------------------------*/
469 /* algebraicOpts - does some algebraic optimizations               */
470 /*-----------------------------------------------------------------*/
471 void algebraicOpts (iCode *ic)
472 {
473     /* we don't deal with the following iCodes
474        here */
475     if (ic->op == IFX   ||
476         ic->op == IPUSH ||
477         ic->op == IPOP  ||
478         ic->op == CALL  ||
479         ic->op == PCALL ||
480         ic->op == RETURN ||
481         POINTER_GET(ic))
482         return ;
483
484     /* if both operands present & ! IFX */
485     /* then if they are both literal we */
486     /* perform the operation right now  */
487     if (IC_RESULT(ic) &&
488         IC_RIGHT(ic)  &&
489         IC_LEFT(ic)   &&
490         IS_OP_LITERAL(IC_LEFT(ic)) &&
491         IS_OP_LITERAL(IC_RIGHT(ic))) {
492         
493         IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
494                                          IC_RIGHT(ic),
495                                          ic->op,
496                                          operandType(IC_RESULT(ic)));
497         ic->op = '=';       
498         IC_LEFT(ic) = NULL ;
499         SET_RESULT_RIGHT(ic);
500         return ;
501         
502     }
503     /* if not ifx & only one operand present */
504     if (IC_RESULT(ic) &&
505         IC_LEFT(ic)   &&
506         IS_OP_LITERAL(IC_LEFT(ic)) &&
507         !IC_RIGHT(ic)) {
508         
509         IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
510                                          IC_RIGHT(ic),
511                                          ic->op,
512                                          operandType(IC_RESULT(ic)));
513         ic->op = '=';
514         IC_LEFT(ic) = NULL ;
515         SET_RESULT_RIGHT(ic);
516         return ;
517     }
518
519     
520     /* a special case : or in short a kludgy solution will think 
521        about a better solution over a glass of wine someday */
522     if ( ic->op == GET_VALUE_AT_ADDRESS ) {
523
524         if (IS_ITEMP(IC_RESULT(ic)) &&
525             IS_TRUE_SYMOP(IC_LEFT(ic))) {
526
527             ic->op = '=' ;
528             IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic));
529             IC_RIGHT(ic)->isaddr = 0;
530             IC_LEFT(ic) = NULL;
531             IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
532             IC_RESULT(ic)->isaddr = 0;
533             setOperandType(IC_RESULT(ic),operandType(IC_RIGHT(ic)));
534             return;
535         }
536
537         if (IS_ITEMP(IC_LEFT(ic)) &&
538             IS_ITEMP(IC_RESULT(ic)) &&
539 /*          !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
540 /*          !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
541             !IC_LEFT(ic)->isaddr ) {
542             ic->op = '=' ;
543             IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic));
544             IC_RIGHT(ic)->isaddr = 0;
545             IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
546             IC_RESULT(ic)->isaddr = 0;
547             IC_LEFT(ic) = NULL;
548             return;
549         }
550
551     }
552    
553
554     /* depending on the operation */
555     switch (ic->op) {
556     case '+' :
557         /* if adding the same thing change to left shift by 1*/
558         if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key && 
559             !IS_FLOAT(operandType(IC_RESULT(ic)))) {
560             ic->op = LEFT_OP ;
561             IC_RIGHT(ic) = operandFromLit(1);
562             return;
563         }
564         /* if addition then check if one of them is a zero */ 
565         /* if yes turn it  into assignmnt*/
566         if (IS_OP_LITERAL(IC_LEFT(ic)) &&
567             operandLitValue(IC_LEFT(ic)) == 0.0 ) {
568
569             ic->op = '=' ;         
570             IC_LEFT(ic) = NULL ;
571             SET_ISADDR(IC_RESULT(ic),0);
572             SET_ISADDR(IC_RIGHT(ic),0);
573             return ;
574         }
575         if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
576             operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
577
578             ic->op = '=' ;          
579             IC_RIGHT(ic) = IC_LEFT(ic) ;
580             IC_LEFT(ic) = 0;
581             SET_ISADDR(IC_RIGHT(ic),0);
582             SET_ISADDR(IC_RESULT(ic),0);
583             return ;
584         }
585         break ;
586     case '-' :
587         /* if subtracting the the same thing then zero     */
588         if ( IC_LEFT(ic)->key == IC_RIGHT(ic)->key ) {
589             ic->op = '=';
590             IC_RIGHT(ic) = operandFromLit(0);
591             IC_LEFT(ic) = NULL ;
592             IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
593             IC_RESULT(ic)->isaddr = 0;
594             return ;
595         }           
596             
597         /* if subtraction then check if one of the operand */
598         /* is zero then depending on which operand change  */
599         /* to assignment or unary minus                    */
600         if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
601             operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
602             /* right size zero change to assignment */
603             ic->op = '=' ;          
604             IC_RIGHT(ic) = IC_LEFT(ic);
605             IC_LEFT(ic) = NULL;
606             SET_ISADDR(IC_RIGHT(ic),0);
607             SET_ISADDR(IC_RESULT(ic),0);
608             return ;
609         }
610         if (IS_OP_LITERAL(IC_LEFT(ic)) &&
611             operandLitValue (IC_LEFT(ic)) == 0.0) {
612             /* left zero turn into an unary minus */
613             ic->op = UNARYMINUS ;
614             IC_LEFT(ic) = IC_RIGHT(ic);
615             IC_RIGHT(ic) = NULL ;
616             return ;
617         }
618         break;
619         /* if multiplication then check if either of */
620         /* them is zero then the result is zero      */
621         /* if either of them is one then result is   */
622         /* the other one                             */
623     case '*' :
624         if (IS_OP_LITERAL(IC_LEFT(ic))) {
625             
626             if (operandLitValue(IC_LEFT(ic)) == 0.0) {      
627                 ic->op = '=' ;
628                 IC_RIGHT(ic) = IC_LEFT(ic);
629                 IC_LEFT(ic) = NULL;
630                 SET_RESULT_RIGHT(ic);
631                 return ;
632             }
633             if ( operandLitValue(IC_LEFT(ic)) == 1.0) {
634                 ic->op = '=' ;
635                 IC_LEFT(ic) = NULL ;
636                 SET_RESULT_RIGHT(ic);
637                 return ;
638             }       
639         }
640         
641         if (IS_OP_LITERAL(IC_RIGHT(ic))) {
642             
643             if (operandLitValue(IC_RIGHT(ic)) == 0.0 ) {            
644                 ic->op = '=';           
645                 IC_LEFT(ic) = NULL ;
646                 SET_RESULT_RIGHT(ic);
647                 return ;
648             }
649
650             if (operandLitValue(IC_RIGHT(ic)) == 1.0) {
651                 ic->op = '=' ;    
652                 IC_RIGHT(ic) = IC_LEFT(ic);
653                 IC_LEFT(ic) = NULL ;
654                 SET_RESULT_RIGHT(ic);
655                 return ;
656             }
657         }
658         break ;
659     case '/':
660         /* if division by self then 1 */
661         if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key) {
662             ic->op = '='; 
663             IC_RIGHT(ic) = operandFromLit(1);
664             IC_LEFT(ic) = NULL;
665             IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
666             IC_RESULT(ic)->isaddr = 0;
667         }
668         /* if this is a division then check if right */
669         /* is one then change it to an assignment    */
670         if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
671             operandLitValue(IC_RIGHT(ic)) == 1.0 ) {
672
673             ic->op = '=' ;
674             IC_RIGHT(ic) = IC_LEFT(ic);
675             IC_LEFT(ic) = NULL;
676             SET_RESULT_RIGHT(ic);
677             return ;
678         }
679         break;
680         /* if both are the same for an comparison operators */
681     case EQ_OP :
682     case LE_OP :
683     case GE_OP :
684         if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) {
685             ic->op = '=';
686             IC_RIGHT(ic) = operandFromLit(1);
687             IC_LEFT(ic) = NULL;
688             SET_RESULT_RIGHT(ic);
689         }
690         break;
691     case NE_OP :
692     case '>' :
693     case '<' :
694         if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) {
695             ic->op = '=';
696             IC_RIGHT(ic) = operandFromLit(0);
697             IC_LEFT(ic) = NULL ;
698             SET_RESULT_RIGHT(ic);
699         }
700         break ;
701     case CAST :
702         /* if this is a cast of a literal value */
703         if ( IS_OP_LITERAL(IC_RIGHT(ic))) {
704             ic->op = '=' ;
705             IC_RIGHT(ic) = 
706                 operandFromValue (valCastLiteral(operandType(IC_LEFT(ic)),
707                                                  operandLitValue(IC_RIGHT(ic))));
708             IC_LEFT(ic) = NULL;
709             SET_ISADDR(IC_RESULT(ic),0); 
710         }
711         /* if casting to the same */
712         if ( checkType(operandType(IC_RESULT(ic)),
713                        operandType(IC_RIGHT(ic))) == 1) {
714             ic->op = '=';
715             IC_LEFT(ic) = NULL;
716             SET_ISADDR(IC_RESULT(ic),0);                
717         }
718         break;
719     case '!' :
720         if (IS_OP_LITERAL(IC_LEFT(ic))) {
721             ic->op = '=' ;
722             IC_RIGHT(ic) = 
723                (operandLitValue(IC_LEFT(ic)) == 0 ? 
724                 operandFromLit(1) : operandFromLit(0));
725             IC_LEFT(ic) = NULL;
726             SET_ISADDR(IC_RESULT(ic),0);            
727         }
728     }
729     
730     return ;
731 }
732 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
733 /*-----------------------------------------------------------------*/
734 /* updateSpillLocation - keeps track of register spill location    */
735 /*-----------------------------------------------------------------*/
736 void updateSpillLocation ( iCode *ic)
737 {
738
739     link *setype;
740
741     if (POINTER_SET(ic)) 
742         return;
743     
744     if (ic->nosupdate)
745         return;       
746
747     /* for the form true_symbol := iTempNN */
748     if (ASSIGN_ITEMP_TO_SYM(ic)
749         && !SPIL_LOC(IC_RIGHT(ic))) {
750
751         setype = getSpec(operandType(IC_RESULT(ic)));
752         
753         if (!IC_RIGHT(ic)->noSpilLoc           &&
754             !IS_VOLATILE(setype)               &&
755             !IN_FARSPACE(SPEC_OCLS(setype))    &&
756             !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )
757             
758             SPIL_LOC(IC_RIGHT(ic))  =
759                 IC_RESULT(ic)->operand.symOperand;   
760     }
761
762     if (ASSIGN_ITEMP_TO_ITEMP(ic) &&
763         !SPIL_LOC(IC_RIGHT(ic))   &&
764         OP_SYMBOL(IC_RESULT(ic))->isreqv) {
765         
766         setype = getSpec(operandType(IC_RESULT(ic)));
767
768         if (!IC_RIGHT(ic)->noSpilLoc           &&
769             !IS_VOLATILE(setype)               &&
770             !IN_FARSPACE(SPEC_OCLS(setype))    &&
771             !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )  
772             
773             SPIL_LOC(IC_RIGHT(ic)) = 
774                 SPIL_LOC(IC_RESULT(ic));
775     }
776 }
777
778 /*-----------------------------------------------------------------*/
779 /* setUsesDef - sets the uses def bitvector for a given operand    */
780 /*-----------------------------------------------------------------*/
781 void setUsesDefs (operand *op, bitVect *bdefs, 
782                   bitVect *idefs, bitVect **oud)
783 {
784     /* compute the definitions alive at this point */
785     bitVect *adefs = bitVectUnion(bdefs,idefs);
786
787     /* of these definitions find the ones that are */
788     /* for this operand */
789     adefs = bitVectIntersect(adefs,OP_DEFS(op));
790     
791     /* these are the definitions that this operand can use */
792     op->usesDefs = adefs;
793     
794     /* the out defs is an union */
795     *oud = bitVectUnion(*oud,adefs);
796 }
797
798 /*-----------------------------------------------------------------*/
799 /* ifxOptimize - changes ifx conditions if it can                  */
800 /*-----------------------------------------------------------------*/
801 void ifxOptimize (iCode *ic, set *cseSet, 
802                          int computeOnly , 
803                          eBBlock *ebb, int *change,
804                          eBBlock **ebbs, int count)
805 {
806     operand *pdop ;
807     symbol *label;
808
809     /* if the condition can be replaced */
810     if (!computeOnly) {
811         pdop = NULL ;
812         applyToSetFTrue (cseSet,findCheaperOp,IC_COND(ic),&pdop);
813         if (pdop) {
814             IC_COND(ic) = pdop ;
815             (*change)++;
816         }
817     }
818     
819     /* if the conditional is a literal then */
820     if (IS_OP_LITERAL(IC_COND(ic))) {          
821
822         if ( operandLitValue(IC_COND(ic)) && IC_TRUE(ic)) {
823             
824             /* change to a goto */
825             ic->op = GOTO ;
826             IC_LABEL(ic) = IC_TRUE(ic);
827             (*change)++;
828             
829         } else {
830             
831             if (!operandLitValue(IC_COND(ic)) && IC_FALSE(ic)) {                
832                 ic->op = GOTO ;
833                 IC_LABEL(ic) = IC_FALSE(ic);
834                 (*change)++;
835                 
836             } else {
837                 /* then kill this if condition */                       
838                 remiCodeFromeBBlock (ebb,ic);           
839             }       
840         }
841         
842         /* now we need to recompute the control flow */
843         /* since the control flow has changed        */
844         /* this is very expensive but it does not happen */
845         /* too often, if it does happen then the user pays */
846         /* the price */
847         computeControlFlow (ebbs,count,1);
848         werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
849         return ;
850     }
851     
852     /* if there is only one successor and that successor
853        is the same one we are conditionally going to then
854        we can remove this conditional statement */
855     label = (IC_TRUE(ic) ? IC_TRUE(ic) : IC_FALSE(ic));
856     if (elementsInSet(ebb->succList) == 1 &&
857         isinSet(ebb->succList,eBBWithEntryLabel(ebbs,label,count))) {
858
859         remiCodeFromeBBlock(ebb,ic);
860         computeControlFlow (ebbs,count,1);
861         werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
862         return ;        
863     }
864         
865         
866     /* if it remains an IFX the update the use Set */
867     OP_USES(IC_COND(ic)) = bitVectSetBit(OP_USES(IC_COND(ic)),ic->key);
868     setUsesDefs(IC_COND(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
869     return ;  
870 }
871
872 /*-----------------------------------------------------------------*/
873 /* unsetDefsAndUses - clear this operation for the operands        */
874 /*-----------------------------------------------------------------*/
875 void unsetDefsAndUses ( iCode *ic ) 
876 {
877     if ( ic->op == JUMPTABLE)
878         return ;
879
880     /* take away this definition from the def chain of the */
881     /* result & take away from use set of the operands */
882     if (ic->op != IFX) {
883         /* turn off def set */
884         if (IS_SYMOP(IC_RESULT(ic))) {
885             if ( !POINTER_SET(ic)) 
886                 bitVectUnSetBit(OP_DEFS(IC_RESULT(ic)),ic->key);
887             else
888                 bitVectUnSetBit(OP_USES(IC_RESULT(ic)),ic->key);
889         }
890         /* turn off the useSet for the operands */
891         if (IS_SYMOP(IC_LEFT(ic)))
892             bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key);
893         
894         if (IS_SYMOP(IC_RIGHT(ic)))
895             bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
896     }
897     else /* must be ifx turn off the use */
898         if (IS_SYMOP(IC_COND(ic)))
899             bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key);    
900 }
901
902 /*-----------------------------------------------------------------*/
903 /* diCodeForSym - finds the definiting instruction for a symbol    */
904 /*-----------------------------------------------------------------*/
905 DEFSETFUNC(diCodeForSym)
906 {
907     cseDef *cdp = item;
908     V_ARG(operand *,sym);
909     V_ARG(iCode **,dic);
910
911     /* if already found */
912     if (*dic)
913         return 0;
914
915     /* if not if this is the defining iCode */
916     if (sym->key == cdp->key) {
917         *dic = cdp->diCode ;
918         return 1;
919     }
920
921     return 0;
922 }
923
924 /*-----------------------------------------------------------------*/
925 /* constFold - does some constant folding                          */
926 /*-----------------------------------------------------------------*/
927 int constFold (iCode *ic, set *cseSet)
928 {
929     iCode *dic = NULL;
930     /* this routine will change
931        a = b + 10;
932        c = a + 10;
933        to
934        c = b + 20; */
935
936     /* deal with only + & - */
937     if (ic->op != '+' &&
938         ic->op != '-' )
939         return 0;
940
941     /* this check is a hueristic to prevent live ranges
942        from becoming too long */
943     if (IS_PTR(operandType(IC_RESULT(ic))))
944         return 0;
945
946     /* check if operation with a literal */
947     if (!IS_OP_LITERAL(IC_RIGHT(ic)))
948         return 0;
949
950     /* check if we can find a definition for the
951        right hand side */
952     if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(ic),&dic)))
953         return 0;
954
955     /* check that this is also a +/-  */
956     if (dic->op != '+' && dic->op != '-')
957         return 0;
958
959     /* with a literal */
960     if (!IS_OP_LITERAL(IC_RIGHT(dic)))
961         return 0;
962
963     /* it is if the operations are the same*/
964     /* the literal parts need to be added  */
965     IC_LEFT(ic) = operandFromOperand(IC_LEFT(dic));    
966     if (ic->op == dic->op )
967         IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic))+
968                                       operandLitValue(IC_RIGHT(dic)));
969     else
970         IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) -
971                                       operandLitValue(IC_RIGHT(dic)));
972
973     if (IS_ITEMP(IC_RESULT(ic))) {
974         SPIL_LOC(IC_RESULT(ic)) = NULL;
975         IC_RESULT(ic)->noSpilLoc = 1;
976     }
977         
978     
979     return 1;
980 }
981
982 /*-----------------------------------------------------------------*/
983 /* deleteGetPointers - called when a pointer is passed as parm     */
984 /* will delete from cseSet all get pointers computed from this     */
985 /* pointer. A simple ifOperandsHave is not good enough here        */
986 /*-----------------------------------------------------------------*/
987 static void deleteGetPointers (set **cseSet,operand *op,eBBlock *ebb)
988 {
989     set *compItems = NULL;
990     cseDef *cdp ;
991     operand *cop;
992     
993     /* easy return */
994     if (!*cseSet)
995         return ;
996     
997     /* first find all items computed from this operand .
998        This done fairly simply go thru the list and find
999        those that are computed by arthimetic with this
1000        op */
1001     for (cdp = setFirstItem(*cseSet); cdp ; cdp = setNextItem(*cseSet)) {
1002         if (IS_ARITHMETIC_OP(cdp->diCode)) {
1003             if (isOperandEqual(IC_LEFT(cdp->diCode),op) ||
1004                 isOperandEqual(IC_RIGHT(cdp->diCode),op)) {
1005                                 /* save it in our list of items */
1006                 addSet(&compItems,IC_RESULT(cdp->diCode));
1007             }
1008             /* also check for those computed from our computed 
1009                list . This will take care of situations like
1010                iTemp1 = iTemp0 + 8;
1011                iTemp2 = iTemp1 + 8; */
1012             if (isinSetWith(compItems,IC_LEFT(cdp->diCode),isOperandEqual) ||
1013                 isinSetWith(compItems,IC_RIGHT(cdp->diCode),isOperandEqual)) {
1014                     addSet(&compItems,IC_RESULT(cdp->diCode));
1015             }
1016         }
1017     }
1018     
1019     /* now delete all pointer gets with this op */
1020     deleteItemIf(cseSet,ifPointerGet,op);
1021     /* set the bit vector used by dataFlow computation later */
1022     ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,op->key);
1023     /* now for the computed items */
1024     for (cop = setFirstItem(compItems); cop ; cop = setNextItem(compItems)) {
1025         ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,cop->key);    
1026         deleteItemIf(cseSet,ifPointerGet,cop);
1027     }
1028 }
1029
1030 /*-----------------------------------------------------------------*/
1031 /* delGetPointerSucc - delete get pointer from inExprs of succ with*/
1032 /*                     dfnum > supplied                            */
1033 /*-----------------------------------------------------------------*/
1034 DEFSETFUNC(delGetPointerSucc)
1035 {
1036     eBBlock *ebp = item;
1037     V_ARG(operand *,op);
1038     V_ARG(int,dfnum);
1039
1040     if (ebp->visited)
1041         return 0;
1042     
1043     ebp->visited = 1;
1044     if (ebp->dfnum > dfnum) {
1045         deleteItemIf(&ebp->inExprs,ifPointerGet,op);
1046     }
1047
1048     return applyToSet(ebp->succList,delGetPointerSucc,op,dfnum);
1049 }    
1050
1051 /*-----------------------------------------------------------------*/
1052 /* cseBBlock - common subexpression elimination for basic blocks   */
1053 /*             this is the hackiest kludgiest routine in the whole */
1054 /*             system. also the most important, since almost all   */
1055 /*             data flow related information is computed by it     */
1056 /*-----------------------------------------------------------------*/
1057 int cseBBlock ( eBBlock *ebb, int computeOnly, 
1058                 eBBlock **ebbs, int count)
1059 {
1060     set *cseSet ;
1061     iCode *ic ;           
1062     int change = 0 ;
1063     int i;   
1064     set *ptrSetSet = NULL;
1065
1066     /* if this block is not reachable */
1067     if (ebb->noPath)
1068         return change;
1069
1070    /* set of common subexpressions */   
1071     cseSet = setFromSet (ebb->inExprs) ;      
1072       
1073     /* these will be computed by this routine */
1074     setToNull ((void **)&ebb->outDefs);    
1075     setToNull ((void **)&ebb->defSet);
1076     setToNull ((void **)&ebb->usesDefs);
1077     setToNull ((void **)&ebb->ptrsSet);
1078     setToNull ((void **)&ebb->addrOf);
1079     setToNull ((void **)&ebb->ldefs);
1080
1081     ebb->outDefs = bitVectCopy (ebb->inDefs);
1082     bitVectDefault = iCodeKey;
1083     ebb->defSet = newBitVect(iCodeKey);
1084     ebb->usesDefs=newBitVect(iCodeKey);
1085
1086     /* for all the instructions in this block do */
1087     for (ic = ebb->sch ; ic ; ic = ic->next ) {
1088         
1089         iCode *pdic; 
1090         operand *pdop ;
1091         iCode *defic;
1092         
1093         if (SKIP_IC2(ic))
1094             continue ;
1095
1096         /* clear the def & use chains for the operands involved */
1097         /* in this operation . since it can change due to opts  */
1098         unsetDefsAndUses (ic);
1099         
1100         if ( ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE) {
1101             /* add to defSet of the symbol */
1102             OP_DEFS(IC_RESULT(ic)) = 
1103                 bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
1104             /* add to the definition set of this block */
1105             ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);      
1106             ebb->ldefs  = bitVectSetBit (ebb->ldefs,ic->key);
1107             ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic)));
1108             setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1109             /* delete global variables from the cseSet
1110                since they can be modified by the function call */
1111             deleteItemIf(&cseSet,ifDefGlobal);
1112         }
1113
1114         /* for pcall & ipush we need to add to the useSet */
1115         if ((ic->op == PCALL || 
1116              ic->op == IPUSH || 
1117              ic->op == IPOP  || 
1118              ic->op == SEND) && 
1119             IS_SYMOP(IC_LEFT(ic))) {
1120             
1121             /* check if they can be replaced */
1122             if ( !computeOnly ) {
1123                 pdop = NULL ;
1124                 applyToSetFTrue(cseSet,findCheaperOp,IC_LEFT(ic),&pdop);
1125                 if (pdop)
1126                     IC_LEFT(ic) = pdop ;
1127             }
1128             /* the lookup could have changed it*/
1129             if (IS_SYMOP(IC_LEFT(ic))) {
1130                 OP_USES(IC_LEFT(ic)) = 
1131                     bitVectSetBit(OP_USES(IC_LEFT(ic)),ic->key);
1132                 setUsesDefs(IC_LEFT(ic),ebb->defSet,
1133                             ebb->outDefs,&ebb->usesDefs);
1134             }
1135             /* if we a sending a pointer as a parameter
1136                then kill all cse since the pointed to item
1137                might be changed in the function being called */
1138             if (IS_PTR(operandType(IC_LEFT(ic)))) {
1139                     deleteGetPointers(&cseSet,IC_LEFT(ic),ebb);
1140             }
1141             continue;
1142         }
1143
1144         /* if jumptable then mark the usage */
1145         if (ic->op == JUMPTABLE ) {
1146             OP_USES(IC_JTCOND(ic)) = 
1147                 bitVectSetBit(OP_USES(IC_JTCOND(ic)),ic->key);
1148             setUsesDefs(IC_JTCOND(ic),ebb->defSet,
1149                         ebb->outDefs,&ebb->usesDefs);
1150             continue;
1151         }
1152
1153         if (SKIP_IC(ic))
1154             continue ;
1155         
1156         /* do some algebraic optimizations if possible */
1157         algebraicOpts (ic);
1158         while (constFold(ic,cseSet));
1159
1160         /* if this is a condition statment then */
1161         /* check if the condition can be replaced */
1162         if (ic->op == IFX ) {
1163             ifxOptimize (ic, cseSet, computeOnly, 
1164                          ebb, &change, 
1165                          ebbs, count);
1166             continue ;
1167         }
1168             
1169         /* if the assignment & result is a temp */
1170         /* see if we can replace it             */
1171         if (ic->op == '=') {
1172             
1173             /* update the spill location for this */
1174             updateSpillLocation (ic);
1175
1176             if (POINTER_SET(ic)) {
1177                 pdop = NULL ;
1178                 applyToSetFTrue (cseSet,findCheaperOp,IC_RESULT(ic),&pdop);
1179                 if (pdop && IS_ITEMP(pdop) && !computeOnly)                 
1180                     IC_RESULT(ic) = pdop;                               
1181             }
1182         }           
1183         
1184         /* do the operand lookup i.e. for both the */
1185         /* right & left operand : check the cseSet */
1186         /* to see if they have been replaced if yes*/
1187         /* then replace them with those from cseSet*/
1188         /* left operand */
1189         /* and left is a symbol  */
1190         if (IS_SYMOP(IC_LEFT(ic)) && 
1191             !computeOnly && ic->op != ADDRESS_OF ) {  
1192             
1193             pdop = NULL;                
1194             applyToSetFTrue (cseSet,findCheaperOp,IC_LEFT(ic),&pdop) ;
1195             if (pdop)  { 
1196                 if (POINTER_GET(ic)) {
1197                     if (IS_ITEMP(pdop) || IS_OP_LITERAL(pdop)) {
1198                         IC_LEFT(ic) = pdop;
1199                         change = 1;
1200                     }
1201                     /* check if there is a pointer set
1202                        for the same pointer visible if yes
1203                        then change this into an assignment */
1204                     pdop = NULL;
1205                     if (applyToSetFTrue(cseSet,findPointerSet,IC_LEFT(ic),&pdop)){
1206                         ic->op = '=';
1207                         IC_LEFT(ic) = NULL;
1208                         IC_RIGHT(ic) = pdop;
1209                         SET_ISADDR(IC_RESULT(ic),0);
1210                     }
1211                         
1212                 }
1213                 else {
1214                     IC_LEFT(ic)  = pdop ;
1215                     change = 1;
1216                 }
1217             }       
1218         }
1219         
1220         /*right operand */
1221         if (IS_SYMOP(IC_RIGHT(ic)) && !computeOnly) {
1222             
1223             pdop = NULL ;
1224             applyToSetFTrue (cseSet,findCheaperOp,IC_RIGHT(ic),&pdop);
1225             if (pdop) {
1226                 
1227                 IC_RIGHT(ic) = pdop;
1228                 change = 1;
1229             }
1230         }
1231         
1232         /* if left or right changed then do algebraic */
1233         if (change) {
1234             algebraicOpts(ic);
1235             while(constFold(ic,cseSet));
1236         }
1237
1238         /* if after all this it becomes a assignment to self 
1239            then delete it and continue */
1240         if (ASSIGNMENT_TO_SELF(ic)) {      
1241             remiCodeFromeBBlock(ebb,ic);
1242             continue;
1243         }           
1244         
1245         /* now we will check to see if the entire */
1246         /* operation has been performed before    */
1247         /* and is available                       */     
1248         /* don't do assignments they will be killed */
1249         /* by dead code elimination if required  do */
1250         /* it only if result is a temporary         */
1251         pdic = NULL ;   
1252         if (!( POINTER_GET(ic)                      &&
1253                (IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
1254                isOperandVolatile(IC_LEFT(ic),TRUE))) &&
1255             ! ASSIGNMENT(ic)                        && 
1256               IS_ITEMP(IC_RESULT(ic))               &&
1257             ! computeOnly) {
1258             applyToSet (cseSet,findPrevIc,ic,&pdic);
1259         } 
1260        
1261         /* if found then eliminate this and add to*/
1262         /* to cseSet an element containing result */
1263         /* of this with previous opcode           */      
1264         if (pdic) {
1265
1266             if (IS_ITEMP(IC_RESULT(ic))) {
1267
1268                 /* replace in the remaining of this block */
1269                 replaceAllSymBySym(ic->next,IC_RESULT(ic),IC_RESULT(pdic));
1270                 /* remove this iCode from inexpressions of all
1271                    its successors, it cannot be in the in expressions
1272                    of any of the predecessors */        
1273                 for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1274                 applyToSet(ebb->succList,removeFromInExprs,ic,IC_RESULT(ic),
1275                            IC_RESULT(pdic),ebb);
1276
1277                 /* if this was moved from another block */
1278                 /* then replace in those blocks too     */
1279                 if ( ic->movedFrom ) {
1280                     eBBlock *owner ;
1281                     for (owner = setFirstItem(ic->movedFrom); owner ;
1282                          owner = setNextItem(ic->movedFrom))
1283                         replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic));
1284                 }
1285                 pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE);
1286             } 
1287             else
1288                 addSetHead (&cseSet,newCseDef(IC_RESULT(ic),pdic));                     
1289             
1290             if (!computeOnly) 
1291                 /* eliminate this */
1292                 remiCodeFromeBBlock (ebb,ic);               
1293                     
1294             defic = pdic ;          
1295             change++ ;
1296
1297             if (IS_ITEMP(IC_RESULT(ic)))
1298                 continue ;
1299
1300         } else {
1301
1302             /* just add this as a previous expression except in */
1303             /* case of a pointer access in which case this is a */
1304             /* usage not a definition                           */
1305             if (! (POINTER_SET(ic)) && IC_RESULT(ic)){
1306                 deleteItemIf (&cseSet, ifDefSymIsX,IC_RESULT(ic));
1307                 addSetHead(&cseSet,newCseDef(IC_RESULT(ic),ic));
1308             }
1309             defic = ic;
1310
1311         }
1312         
1313         /* if assignment to a parameter which is not
1314            mine and type is a pointer then delete
1315            pointerGets to take care of aliasing */
1316         if (ASSIGNMENT(ic)                        && 
1317             OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) &&
1318             IS_PTR(operandType(IC_RESULT(ic)))) {
1319             deleteGetPointers(&cseSet,IC_RIGHT(ic),ebb);
1320         }
1321
1322         /* if this is a pointerget then see if we can replace
1323            this with a previously assigned pointer value */
1324         if (POINTER_GET(ic) && 
1325             !(IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
1326                isOperandVolatile(IC_LEFT(ic),TRUE))) {
1327             pdop = NULL;
1328             applyToSet(ptrSetSet,findPointerSet,IC_LEFT(ic),&pdop);
1329             /* if we find it then locally replace all
1330                references to the result with what we assigned */
1331             if (pdop) {
1332                 replaceAllSymBySym(ic->next,IC_RESULT(ic),pdop);
1333             }
1334         }
1335
1336         /* delete from the cseSet anything that has */
1337         /* operands matching the result of this     */
1338         /* except in case of pointer access         */
1339         if (!(POINTER_SET(ic)) && IC_RESULT(ic)) {
1340             deleteItemIf (&cseSet,ifOperandsHave,IC_RESULT(ic));            
1341             /* delete any previous definitions */ 
1342             ebb->defSet = bitVectCplAnd (ebb->defSet,OP_DEFS(IC_RESULT(ic)));     
1343             
1344         }
1345         
1346         /* add the left & right to the defUse set */
1347         if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic))) {
1348             OP_USES(IC_LEFT(ic)) = 
1349                 bitVectSetBit (OP_USES(IC_LEFT(ic)),ic->key);
1350             setUsesDefs(IC_LEFT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1351
1352         }
1353
1354         if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic))) {
1355             OP_USES(IC_RIGHT(ic)) = 
1356                 bitVectSetBit (OP_USES(IC_RIGHT(ic)),ic->key);  
1357             setUsesDefs(IC_RIGHT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1358
1359         }
1360
1361         /* for the result it is special case, put the result */
1362         /* in the defuseSet if it a pointer or array access  */
1363         if ( POINTER_SET(defic) ) {
1364             OP_USES(IC_RESULT(ic)) = 
1365                 bitVectSetBit (OP_USES(IC_RESULT(ic)),ic->key);
1366             setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1367             deleteItemIf(&cseSet,ifPointerGet,IC_RESULT(ic));
1368             ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RESULT(ic)->key);
1369             /* delete from inexpressions of all successors which
1370                have dfNum > than this block */
1371             for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1372             applyToSet(ebb->succList,delGetPointerSucc,IC_RESULT(ic),ebb->dfnum);
1373             
1374             /* delete from cseSet all other pointer sets
1375                for this operand */
1376             deleteItemIf(&ptrSetSet,ifPointerSet,IC_RESULT(ic));
1377             /* add to the local pointerset set */
1378             addSetHead(&ptrSetSet,newCseDef(IC_RESULT(ic),ic));
1379         }
1380         else /* add the result to defintion set */
1381             if (IC_RESULT(ic)) {
1382                 OP_DEFS(IC_RESULT(ic)) = 
1383                     bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
1384                 ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);              
1385                 ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic))); 
1386                 ebb->ldefs  = bitVectSetBit (ebb->ldefs,ic->key);
1387             }
1388                
1389
1390         /* if this is an addressof instruction then */
1391         /* put the symbol in the address of list &  */
1392         /* delete it from the cseSet                */
1393         if (defic->op == ADDRESS_OF) {
1394             addSetHead (&ebb->addrOf, IC_LEFT(ic));
1395             deleteItemIf(&cseSet,ifDefSymIsX,IC_LEFT(ic));
1396         }
1397     }
1398
1399     setToNull ((void **)&ebb->outExprs);
1400     ebb->outExprs = cseSet;        
1401     ebb->outDefs = bitVectUnion (ebb->outDefs,ebb->defSet);
1402     ebb->ptrsSet = bitVectUnion (ebb->ptrsSet,ebb->inPtrsSet);
1403     return change ;
1404 }
1405
1406 /*-----------------------------------------------------------------*/
1407 /* cseAllBlocks - will sequentially go thru & do cse for all blocks*/
1408 /*-----------------------------------------------------------------*/
1409 int cseAllBlocks (eBBlock **ebbs,int count)
1410 {
1411     int i;
1412     int change = 0 ;
1413
1414     /* if optimization turned off */
1415
1416     for (i = 0 ; i < count ;i++ ) 
1417         change += cseBBlock (ebbs[i],FALSE,ebbs,count);
1418
1419     return change;
1420 }
1421