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