Changed Safe_calloc to use 2 arguements to mimic teh standard calloc function
[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(1,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