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