1 //#define LIVERANGEHUNT
7 /*-------------------------------------------------------------------------
8 SDCCcse.c - source file for Common Subexpressions and other utility
10 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
12 This program is free software; you can redistribute it and/or modify it
13 under the terms of the GNU General Public License as published by the
14 Free Software Foundation; either version 2, or (at your option) any
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 In other words, you are welcome to use, share and improve this program.
27 You are forbidden to forbid anyone else to use, share and improve
28 what you give them. Help stamp out software-hoarding!
29 -------------------------------------------------------------------------*/
34 /*-----------------------------------------------------------------*/
35 /* newCseDef - new cseDef */
36 /*-----------------------------------------------------------------*/
38 newCseDef (operand * sym, iCode * ic)
43 cdp = Safe_alloc (sizeof (cseDef));
54 /*-----------------------------------------------------------------*/
55 /* int isCseDefEqual - two definitions are equal */
56 /*-----------------------------------------------------------------*/
58 isCseDefEqual (void *vsrc, void *vdest)
66 return (src->key == dest->key &&
67 src->diCode == dest->diCode);
71 /*-----------------------------------------------------------------*/
72 /* pcseDef - in the cseDef */
73 /*-----------------------------------------------------------------*/
75 pcseDef (void *item, va_list ap)
83 fprintf (stdout, "**null op**");
84 printOperand (cdp->sym, stdout);
85 icTab = getTableEntry (cdp->diCode->op);
86 icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
90 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
92 printf ("ReplaceOpWithCheaperOp (%s:%d with %s:%d): ",
93 OP_SYMBOL((*op))->name, OP_SYMBOL((*op))->isreqv,
94 OP_SYMBOL(cop)->name, OP_SYMBOL(cop)->isreqv);
95 // if op is a register equivalent
96 if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
97 operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
98 if (isOperandEqual(*rop, *op)) {
101 OP_SYMBOL((*op))->isreqv=0;
102 OP_SYMBOL(cop)->isreqv=1;
112 /*-----------------------------------------------------------------*/
113 /* replaceAllSymBySym - replaces all operands by operand in an */
114 /* instruction chain */
115 /*-----------------------------------------------------------------*/
117 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
121 LRH(printf ("replaceAllSymBySym: from %s to %s\n", OP_SYMBOL(from)->name, OP_SYMBOL(to)->name));
122 for (lic = ic; lic; lic = lic->next)
126 /* do the special cases first */
130 IC_COND (lic)->key == from->key)
133 bitVectUnSetBit (OP_USES (from), lic->key);
134 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
135 siaddr = IC_COND (lic)->isaddr;
136 IC_COND (lic) = operandFromOperand (to);
137 IC_COND (lic)->isaddr = siaddr;
143 if (lic->op == JUMPTABLE)
146 IC_JTCOND (lic)->key == from->key)
149 bitVectUnSetBit (OP_USES (from), lic->key);
150 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
151 siaddr = IC_COND (lic)->isaddr;
152 IC_JTCOND (lic) = operandFromOperand (to);
153 IC_JTCOND (lic)->isaddr = siaddr;
159 if (IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
161 /* maintain du chains */
162 if (POINTER_SET (lic))
164 bitVectUnSetBit (OP_USES (from), lic->key);
165 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
167 /* also check if the "from" was in the non-dominating
168 pointer sets and replace it with "to" in the bitVector */
169 if (bitVectBitValue (*ndpset, from->key))
171 bitVectUnSetBit (*ndpset, from->key);
172 bitVectSetBit (*ndpset, to->key);
178 bitVectUnSetBit (OP_DEFS (from), lic->key);
179 OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
181 siaddr = IC_RESULT (lic)->isaddr;
182 IC_RESULT (lic) = operandFromOperand (to);
183 IC_RESULT (lic)->isaddr = siaddr;
187 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
189 bitVectUnSetBit (OP_USES (from), lic->key);
190 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
191 siaddr = IC_RIGHT (lic)->isaddr;
192 IC_RIGHT (lic) = operandFromOperand (to);
193 IC_RIGHT (lic)->isaddr = siaddr;
197 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
199 bitVectUnSetBit (OP_USES (from), lic->key);
200 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
201 siaddr = IC_LEFT (lic)->isaddr;
202 IC_LEFT (lic) = operandFromOperand (to);
203 IC_LEFT (lic)->isaddr = siaddr;
208 /*-----------------------------------------------------------------*/
209 /* iCodeKeyIs - if the icode keys match then return 1 */
210 /*-----------------------------------------------------------------*/
211 DEFSETFUNC (iCodeKeyIs)
216 if (cdp->diCode->key == key)
222 /*-----------------------------------------------------------------*/
223 /* removeFromInExprs - removes an icode from inexpressions */
224 /*-----------------------------------------------------------------*/
225 DEFSETFUNC (removeFromInExprs)
229 V_ARG (operand *, from);
230 V_ARG (operand *, to);
231 V_ARG (eBBlock *, cbp);
237 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
238 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
239 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
241 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
245 /*-----------------------------------------------------------------*/
246 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
247 /*-----------------------------------------------------------------*/
249 isGlobalInNearSpace (operand * op)
251 sym_link *type = getSpec (operandType (op));
252 /* this is 8051 specific: optimization
253 suggested by Jean-Louis VERN, with 8051s we have no
254 advantage of putting variables in near space into
256 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
257 IN_DIRSPACE (SPEC_OCLS (type)))
263 /*-----------------------------------------------------------------*/
264 /* findCheaperOp - cseBBlock support routine, will check to see if */
265 /* we have a operand previously defined */
266 /*-----------------------------------------------------------------*/
267 DEFSETFUNC (findCheaperOp)
270 V_ARG (operand *, cop);
271 V_ARG (operand **, opp);
272 V_ARG (int, checkSign);
274 /* if we have already found it */
278 /* not found it yet check if this is the one */
279 /* and this is not the defining one */
280 if (cop->key == cdp->key)
283 /* do a special check this will help in */
284 /* constant propagation & dead code elim */
285 /* for assignments only */
286 if (cdp->diCode->op == '=') {
287 /* if the result is volatile then return result */
288 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
289 *opp = IC_RESULT (cdp->diCode);
291 /* if this is a straight assignment and
292 left is a temp then prefer the temporary to the
294 if (!POINTER_SET (cdp->diCode) &&
295 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
296 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
297 *opp = IC_RESULT (cdp->diCode);
299 /* if straight assignement && and both
300 are temps then prefer the one that
301 will not need extra space to spil, also
302 take into consideration if right side
303 an induction variable
305 if (!POINTER_SET (cdp->diCode) &&
306 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
307 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
308 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
309 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
310 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
311 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
312 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
313 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
314 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
315 *opp = IC_RESULT (cdp->diCode);
317 *opp = IC_RIGHT (cdp->diCode);
321 *opp = IC_RESULT (cdp->diCode);
324 /* if this is an assign to a temp. then check
325 if the right side is this then return this */
326 if (IS_TRUE_SYMOP (cop) &&
327 cdp->diCode->op == '=' &&
328 !POINTER_SET (cdp->diCode) &&
329 cop->key == IC_RIGHT (cdp->diCode)->key &&
330 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
331 IS_ITEMP (IC_RESULT (cdp->diCode)))
332 *opp = IC_RESULT (cdp->diCode);
335 (isOperandLiteral(*opp) || !checkSign ||
337 IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
338 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
339 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
342 if ((isGlobalInNearSpace (cop) &&
343 !isOperandLiteral (*opp)) ||
344 isOperandVolatile (*opp, FALSE)
351 if (cop->key == (*opp)->key)
357 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
359 *opp = operandFromOperand (*opp);
360 (*opp)->isaddr = cop->isaddr;
363 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
364 SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
366 // special case: we can make an unsigned char literal
367 // into an int literal with no cost.
368 if (isOperandLiteral(*opp)
369 && SPEC_NOUN(operandType(*opp)) == V_CHAR
370 && SPEC_NOUN(operandType(cop)) == V_INT)
372 *opp = operandFromOperand (*opp);
373 SPEC_NOUN(operandType(*opp)) = V_INT;
384 LRH(printf ("findCheaperOp: %s < %s\n",\
385 IS_SYMOP((*opp)) ? OP_SYMBOL((*opp))->name : "!SYM",\
386 OP_SYMBOL(cop)->name));
394 /*-----------------------------------------------------------------*/
395 /* findPointerSet - finds the right side of a pointer set op */
396 /*-----------------------------------------------------------------*/
397 DEFSETFUNC (findPointerSet)
400 V_ARG (operand *, op);
401 V_ARG (operand **, opp);
402 V_ARG (operand *, rop);
404 if (POINTER_SET (cdp->diCode) &&
405 IC_RESULT (cdp->diCode)->key == op->key &&
406 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
407 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
408 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
409 getSize (operandType (rop)))
411 *opp = IC_RIGHT (cdp->diCode);
418 /*-----------------------------------------------------------------*/
419 /* findPrevIc - cseBBlock support function will return the iCode */
420 /* which matches the current one */
421 /*-----------------------------------------------------------------*/
422 DEFSETFUNC (findPrevIc)
426 V_ARG (iCode **, icp);
428 /* if already found */
432 /* if the iCodes are the same */
433 if (isiCodeEqual (ic, cdp->diCode) &&
434 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
436 LRH(printf ("findPrevIc same: %d %d\n", ic->key, cdp->diCode->key));
441 /* if iCodes are not the same */
442 /* see the operands maybe interchanged */
443 if (ic->op == cdp->diCode->op &&
444 (ic->op == '+' || ic->op == '*') &&
445 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
446 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
448 LRH(printf ("findPrevIc inter: %d %d\n", ic->key, cdp->diCode->key));
456 /*-------------------------------------------------------------------*/
457 /* ifAssignedFromGlobal - if definition is an assignment from global */
458 /*-------------------------------------------------------------------*/
459 DEFSETFUNC (ifAssignedFromGlobal)
462 iCode *dic=cdp->diCode;
464 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
470 /*-----------------------------------------------------------------*/
471 /* ifDefGlobal - if definition is global */
472 /*-----------------------------------------------------------------*/
473 DEFSETFUNC (ifDefGlobal)
477 return (isOperandGlobal (cdp->sym));
480 /*-----------------------------------------------------------------*/
481 /* ifAnyGetPointer - if get pointer icode */
482 /*-----------------------------------------------------------------*/
483 DEFSETFUNC (ifAnyGetPointer)
487 if (cdp->diCode && POINTER_GET (cdp->diCode))
492 /*-----------------------------------------------------------------*/
493 /* ifOperandsHave - if any of the operand are the same as this */
494 /*-----------------------------------------------------------------*/
495 DEFSETFUNC (ifOperandsHave)
498 V_ARG (operand *, op);
501 if (IC_LEFT (cdp->diCode) &&
502 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
503 IC_LEFT (cdp->diCode)->key == op->key)
506 if (IC_RIGHT (cdp->diCode) &&
507 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
508 IC_RIGHT (cdp->diCode)->key == op->key)
511 /* or if any of the operands are volatile */
512 if (IC_LEFT (cdp->diCode) &&
513 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
516 if (IC_RIGHT (cdp->diCode) &&
517 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
521 if (IC_RESULT (cdp->diCode) &&
522 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
528 /*-----------------------------------------------------------------*/
529 /* ifDefSymIs - if a definition is found in the set */
530 /*-----------------------------------------------------------------*/
532 ifDefSymIs (set * cseSet, operand * sym)
537 if (!sym || !IS_SYMOP (sym))
539 for (sl = cseSet; sl; sl = sl->next)
542 if (loop->sym->key == sym->key)
549 /*-----------------------------------------------------------------*/
550 /* ifDefSymIsX - will return 1 if the symbols match */
551 /*-----------------------------------------------------------------*/
552 DEFSETFUNC (ifDefSymIsX)
555 V_ARG (operand *, op);
558 return cdp->sym->key == op->key;
560 return (isOperandEqual (cdp->sym, op));
565 /*-----------------------------------------------------------------*/
566 /* ifDiCodeIs - returns truw if diCode is same */
567 /*-----------------------------------------------------------------*/
569 ifDiCodeIs (set * cseSet, iCode * ic)
577 for (sl = cseSet; sl; sl = sl->next)
580 if (loop->diCode == ic)
587 /*-----------------------------------------------------------------*/
588 /* ifPointerGet - returns true if the icode is pointer get sym */
589 /*-----------------------------------------------------------------*/
590 DEFSETFUNC (ifPointerGet)
593 V_ARG (operand *, op);
594 iCode *dic = cdp->diCode;
595 operand *left = IC_LEFT (cdp->diCode);
597 if (POINTER_GET (dic) && left->key == op->key)
603 /*-----------------------------------------------------------------*/
604 /* ifPointerSet - returns true if the icode is pointer set sym */
605 /*-----------------------------------------------------------------*/
606 DEFSETFUNC (ifPointerSet)
609 V_ARG (operand *, op);
611 if (POINTER_SET (cdp->diCode) &&
612 IC_RESULT (cdp->diCode)->key == op->key)
618 /*-----------------------------------------------------------------*/
619 /* ifDiCodeIsX - will return 1 if the symbols match */
620 /*-----------------------------------------------------------------*/
621 DEFSETFUNC (ifDiCodeIsX)
626 return cdp->diCode == ic;
630 /*-----------------------------------------------------------------*/
631 /* findBackwardDef - scan backwards to find deinition of operand */
632 /*-----------------------------------------------------------------*/
633 iCode *findBackwardDef(operand *op,iCode *ic)
637 for (lic = ic; lic ; lic = lic->prev) {
638 if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
644 /*-----------------------------------------------------------------*/
645 /* algebraicOpts - does some algebraic optimizations */
646 /*-----------------------------------------------------------------*/
648 algebraicOpts (iCode * ic)
650 /* we don't deal with the following iCodes
661 /* if both operands present & ! IFX */
662 /* then if they are both literal we */
663 /* perform the operation right now */
664 if (IC_RESULT (ic) &&
667 IS_OP_LITERAL (IC_LEFT (ic)) &&
668 IS_OP_LITERAL (IC_RIGHT (ic)))
671 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
674 operandType (IC_RESULT (ic)));
677 SET_RESULT_RIGHT (ic);
681 /* if not ifx & only one operand present */
682 if (IC_RESULT (ic) &&
684 IS_OP_LITERAL (IC_LEFT (ic)) &&
688 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
691 operandType (IC_RESULT (ic)));
694 SET_RESULT_RIGHT (ic);
699 /* a special case : or in short a kludgy solution will think
700 about a better solution over a glass of wine someday */
701 if (ic->op == GET_VALUE_AT_ADDRESS)
704 if (IS_ITEMP (IC_RESULT (ic)) &&
705 IS_TRUE_SYMOP (IC_LEFT (ic)))
709 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
710 IC_RIGHT (ic)->isaddr = 0;
712 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
713 IC_RESULT (ic)->isaddr = 0;
714 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
718 if (IS_ITEMP (IC_LEFT (ic)) &&
719 IS_ITEMP (IC_RESULT (ic)) &&
720 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
721 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
722 !IC_LEFT (ic)->isaddr)
725 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
726 IC_RIGHT (ic)->isaddr = 0;
727 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
728 IC_RESULT (ic)->isaddr = 0;
736 /* depending on the operation */
740 /* if adding the same thing change to left shift by 1 */
741 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
742 !IS_FLOAT (operandType (IC_RESULT (ic))))
745 IC_RIGHT (ic) = operandFromLit (1);
748 /* if addition then check if one of them is a zero */
749 /* if yes turn it into assignmnt */
750 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
751 operandLitValue (IC_LEFT (ic)) == 0.0)
756 SET_ISADDR (IC_RESULT (ic), 0);
757 SET_ISADDR (IC_RIGHT (ic), 0);
760 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
761 operandLitValue (IC_RIGHT (ic)) == 0.0)
765 IC_RIGHT (ic) = IC_LEFT (ic);
767 SET_ISADDR (IC_RIGHT (ic), 0);
768 SET_ISADDR (IC_RESULT (ic), 0);
773 /* if subtracting the the same thing then zero */
774 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
777 IC_RIGHT (ic) = operandFromLit (0);
779 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
780 IC_RESULT (ic)->isaddr = 0;
784 /* if subtraction then check if one of the operand */
785 /* is zero then depending on which operand change */
786 /* to assignment or unary minus */
787 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
788 operandLitValue (IC_RIGHT (ic)) == 0.0)
790 /* right size zero change to assignment */
792 IC_RIGHT (ic) = IC_LEFT (ic);
794 SET_ISADDR (IC_RIGHT (ic), 0);
795 SET_ISADDR (IC_RESULT (ic), 0);
798 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
799 operandLitValue (IC_LEFT (ic)) == 0.0)
801 /* left zero turn into an unary minus */
803 IC_LEFT (ic) = IC_RIGHT (ic);
804 IC_RIGHT (ic) = NULL;
808 /* if multiplication then check if either of */
809 /* them is zero then the result is zero */
810 /* if either of them is one then result is */
813 if (IS_OP_LITERAL (IC_LEFT (ic)))
816 if (operandLitValue (IC_LEFT (ic)) == 0.0)
819 IC_RIGHT (ic) = IC_LEFT (ic);
821 SET_RESULT_RIGHT (ic);
824 if (operandLitValue (IC_LEFT (ic)) == 1.0)
828 SET_RESULT_RIGHT (ic);
833 if (IS_OP_LITERAL (IC_RIGHT (ic)))
836 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
840 SET_RESULT_RIGHT (ic);
844 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
847 IC_RIGHT (ic) = IC_LEFT (ic);
849 SET_RESULT_RIGHT (ic);
855 /* if division by self then 1 */
856 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
859 IC_RIGHT (ic) = operandFromLit (1);
861 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
862 IC_RESULT (ic)->isaddr = 0;
865 /* if this is a division then check if right */
866 /* is one then change it to an assignment */
867 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
868 operandLitValue (IC_RIGHT (ic)) == 1.0)
872 IC_RIGHT (ic) = IC_LEFT (ic);
874 SET_RESULT_RIGHT (ic);
878 /* if both are the same for an comparison operators */
882 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
885 IC_RIGHT (ic) = operandFromLit (1);
887 SET_RESULT_RIGHT (ic);
893 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
896 IC_RIGHT (ic) = operandFromLit (0);
898 SET_RESULT_RIGHT (ic);
903 sym_link *otype = operandType(IC_RIGHT(ic));
904 sym_link *ctype = operandType(IC_LEFT(ic));
905 /* if this is a cast of a literal value */
906 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
907 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
910 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
911 operandLitValue (IC_RIGHT (ic))));
913 SET_ISADDR (IC_RESULT (ic), 0);
915 /* if casting to the same */
916 if (compareType (operandType (IC_RESULT (ic)),
917 operandType (IC_RIGHT (ic))) == 1) {
920 SET_ISADDR (IC_RESULT (ic), 0);
925 if (IS_OP_LITERAL (IC_LEFT (ic)))
929 (operandLitValue (IC_LEFT (ic)) == 0 ?
930 operandFromLit (1) : operandFromLit (0));
932 SET_ISADDR (IC_RESULT (ic), 0);
938 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
939 /*-----------------------------------------------------------------*/
940 /* updateSpillLocation - keeps track of register spill location */
941 /*-----------------------------------------------------------------*/
943 updateSpillLocation (iCode * ic, int induction)
947 if (POINTER_SET (ic))
953 /* for the form true_symbol := iTempNN */
954 if (ASSIGN_ITEMP_TO_SYM (ic) &&
955 !SPIL_LOC (IC_RIGHT (ic))) {
957 setype = getSpec (operandType (IC_RESULT (ic)));
959 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
960 !IS_VOLATILE (setype) &&
961 !IN_FARSPACE (SPEC_OCLS (setype)) &&
962 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
964 wassert(IS_SYMOP(IC_RESULT (ic)));
965 wassert(IS_SYMOP(IC_RIGHT (ic)));
966 SPIL_LOC (IC_RIGHT (ic)) =
967 IC_RESULT (ic)->operand.symOperand;
972 #if 0 /* this needs furthur investigation can save a lot of code */
973 if (ASSIGN_SYM_TO_ITEMP(ic) &&
974 !SPIL_LOC(IC_RESULT(ic))) {
975 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
976 SPIL_LOC (IC_RESULT (ic)) =
977 IC_RIGHT (ic)->operand.symOperand;
980 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
982 if (!SPIL_LOC (IC_RIGHT (ic)) &&
983 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
984 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
986 setype = getSpec (operandType (IC_RESULT (ic)));
988 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
989 !IS_VOLATILE (setype) &&
990 !IN_FARSPACE (SPEC_OCLS (setype)) &&
991 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
993 SPIL_LOC (IC_RIGHT (ic)) =
994 SPIL_LOC (IC_RESULT (ic));
996 /* special case for inductions */
998 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
999 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1000 !SPIL_LOC(IC_RESULT(ic))) {
1001 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1005 /*-----------------------------------------------------------------*/
1006 /* setUsesDef - sets the uses def bitvector for a given operand */
1007 /*-----------------------------------------------------------------*/
1009 setUsesDefs (operand * op, bitVect * bdefs,
1010 bitVect * idefs, bitVect ** oud)
1012 /* compute the definitions alive at this point */
1013 bitVect *adefs = bitVectUnion (bdefs, idefs);
1015 /* of these definitions find the ones that are */
1016 /* for this operand */
1017 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1019 /* these are the definitions that this operand can use */
1020 op->usesDefs = adefs;
1022 /* the out defs is an union */
1023 *oud = bitVectUnion (*oud, adefs);
1026 /*-----------------------------------------------------------------*/
1027 /* unsetDefsAndUses - clear this operation for the operands */
1028 /*-----------------------------------------------------------------*/
1030 unsetDefsAndUses (iCode * ic)
1032 if (ic->op == JUMPTABLE)
1035 /* take away this definition from the def chain of the */
1036 /* result & take away from use set of the operands */
1039 /* turn off def set */
1040 if (IS_SYMOP (IC_RESULT (ic)))
1042 if (!POINTER_SET (ic))
1043 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1045 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1047 /* turn off the useSet for the operands */
1048 if (IS_SYMOP (IC_LEFT (ic)))
1049 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1051 if (IS_SYMOP (IC_RIGHT (ic)))
1052 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1055 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1056 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1059 /*-----------------------------------------------------------------*/
1060 /* ifxOptimize - changes ifx conditions if it can */
1061 /*-----------------------------------------------------------------*/
1063 ifxOptimize (iCode * ic, set * cseSet,
1065 eBBlock * ebb, int *change,
1066 eBBlock ** ebbs, int count)
1071 /* if the condition can be replaced */
1075 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1078 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1083 /* if the conditional is a literal then */
1084 if (IS_OP_LITERAL (IC_COND (ic)))
1087 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1090 /* change to a goto */
1092 IC_LABEL (ic) = IC_TRUE (ic);
1099 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1102 IC_LABEL (ic) = IC_FALSE (ic);
1108 /* then kill this if condition */
1109 remiCodeFromeBBlock (ebb, ic);
1113 /* now we need to recompute the control flow */
1114 /* since the control flow has changed */
1115 /* this is very expensive but it does not happen */
1116 /* too often, if it does happen then the user pays */
1118 computeControlFlow (ebbs, count, 1);
1119 if (!options.lessPedantic) {
1120 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1125 /* if there is only one successor and that successor
1126 is the same one we are conditionally going to then
1127 we can remove this conditional statement */
1128 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1129 if (elementsInSet (ebb->succList) == 1 &&
1130 isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1133 remiCodeFromeBBlock (ebb, ic);
1134 computeControlFlow (ebbs, count, 1);
1135 if (!options.lessPedantic) {
1136 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1142 /* if it remains an IFX the update the use Set */
1143 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1144 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1148 /*-----------------------------------------------------------------*/
1149 /* diCodeForSym - finds the definiting instruction for a symbol */
1150 /*-----------------------------------------------------------------*/
1151 DEFSETFUNC (diCodeForSym)
1154 V_ARG (operand *, sym);
1155 V_ARG (iCode **, dic);
1157 /* if already found */
1161 /* if not if this is the defining iCode */
1162 if (sym->key == cdp->key)
1171 /*-----------------------------------------------------------------*/
1172 /* constFold - does some constant folding */
1173 /*-----------------------------------------------------------------*/
1175 constFold (iCode * ic, set * cseSet)
1179 /* this routine will change
1185 /* deal with only + & - */
1186 if (ic->op != '+' &&
1190 /* this check is a hueristic to prevent live ranges
1191 from becoming too long */
1192 if (IS_PTR (operandType (IC_RESULT (ic))))
1195 /* check if operation with a literal */
1196 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1199 /* check if we can find a definition for the
1201 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1204 /* check that this is also a +/- */
1205 if (dic->op != '+' && dic->op != '-')
1208 /* with a literal */
1209 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1212 /* find the definition of the left operand
1213 of dic.then check if this defined with a
1214 get_pointer return 0 if the pointer size is
1215 less than 2 (MCS51 specific) */
1216 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1219 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1222 /* it is if the operations are the same */
1223 /* the literal parts need to be added */
1224 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1225 if (ic->op == dic->op)
1226 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1227 operandLitValue (IC_RIGHT (dic)));
1229 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1230 operandLitValue (IC_RIGHT (dic)));
1232 if (IS_ITEMP (IC_RESULT (ic)))
1234 SPIL_LOC (IC_RESULT (ic)) = NULL;
1235 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1242 /*-----------------------------------------------------------------*/
1243 /* deleteGetPointers - called when a pointer is passed as parm */
1244 /* will delete from cseSet all get pointers computed from this */
1245 /* pointer. A simple ifOperandsHave is not good enough here */
1246 /*-----------------------------------------------------------------*/
1248 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1250 set *compItems = NULL;
1255 if (!*cseSet && !*pss)
1258 /* first find all items computed from this operand .
1259 This done fairly simply go thru the list and find
1260 those that are computed by arthimetic with this
1262 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1264 if (IS_ARITHMETIC_OP (cdp->diCode))
1266 if (isOperandEqual (IC_LEFT (cdp->diCode), op) ||
1267 isOperandEqual (IC_RIGHT (cdp->diCode), op))
1269 /* save it in our list of items */
1270 addSet (&compItems, IC_RESULT (cdp->diCode));
1272 /* also check for those computed from our computed
1273 list . This will take care of situations like
1274 iTemp1 = iTemp0 + 8;
1275 iTemp2 = iTemp1 + 8; */
1276 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1277 (insetwithFunc)isOperandEqual) ||
1278 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1279 (insetwithFunc)isOperandEqual))
1281 addSet (&compItems, IC_RESULT (cdp->diCode));
1286 /* now delete all pointer gets with this op */
1287 deleteItemIf (cseSet, ifPointerGet, op);
1288 deleteItemIf (pss, ifPointerSet, op);
1290 /* set the bit vector used by dataFlow computation later */
1291 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key);
1292 /* now for the computed items */
1293 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1295 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1296 deleteItemIf (cseSet, ifPointerGet, cop);
1297 deleteItemIf (pss, ifPointerSet, cop);
1301 /*-----------------------------------------------------------------*/
1302 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1303 /* dfnum > supplied */
1304 /*-----------------------------------------------------------------*/
1305 DEFSETFUNC (delGetPointerSucc)
1307 eBBlock *ebp = item;
1308 V_ARG (operand *, op);
1315 if (ebp->dfnum > dfnum)
1317 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1320 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1323 /*-----------------------------------------------------------------*/
1324 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1325 /*-----------------------------------------------------------------*/
1327 fixUpTypes (iCode * ic)
1329 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1331 /* if (TARGET_IS_DS390) */
1332 if (options.model == MODEL_FLAT24)
1338 /* for pointer_gets if the types of result & left r the
1339 same then change it type of result to next */
1341 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1343 setOperandType (IC_RESULT (ic), t2->next);
1347 /*-----------------------------------------------------------------*/
1348 /* isSignedOp - will return 1 if sign is important to operation */
1349 /*-----------------------------------------------------------------*/
1350 static int isSignedOp (iCode *ic)
1371 case GET_VALUE_AT_ADDRESS:
1397 /*-----------------------------------------------------------------*/
1398 /* cseBBlock - common subexpression elimination for basic blocks */
1399 /* this is the hackiest kludgiest routine in the whole */
1400 /* system. also the most important, since almost all */
1401 /* data flow related information is computed by it */
1402 /*-----------------------------------------------------------------*/
1404 cseBBlock (eBBlock * ebb, int computeOnly,
1405 eBBlock ** ebbs, int count)
1411 set *ptrSetSet = NULL;
1413 /* if this block is not reachable */
1417 /* set of common subexpressions */
1418 cseSet = setFromSet (ebb->inExprs);
1420 /* these will be computed by this routine */
1421 setToNull ((void **) &ebb->outDefs);
1422 setToNull ((void **) &ebb->defSet);
1423 setToNull ((void **) &ebb->usesDefs);
1424 setToNull ((void **) &ebb->ptrsSet);
1425 setToNull ((void **) &ebb->addrOf);
1426 setToNull ((void **) &ebb->ldefs);
1428 ebb->outDefs = bitVectCopy (ebb->inDefs);
1429 bitVectDefault = iCodeKey;
1430 ebb->defSet = newBitVect (iCodeKey);
1431 ebb->usesDefs = newBitVect (iCodeKey);
1433 /* for all the instructions in this block do */
1434 for (ic = ebb->sch; ic; ic = ic->next)
1441 ic->eBBlockNum = ebb->bbnum;
1446 /* if this is an assignment from true symbol
1447 to a temp then do pointer post inc/dec optimzation */
1448 if (ic->op == '=' && !POINTER_SET (ic) &&
1449 IS_PTR (operandType (IC_RESULT (ic))))
1451 ptrPostIncDecOpt (ic);
1454 /* clear the def & use chains for the operands involved */
1455 /* in this operation . since it can change due to opts */
1456 unsetDefsAndUses (ic);
1458 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1460 /* add to defSet of the symbol */
1461 OP_DEFS(IC_RESULT (ic))=
1462 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1463 /* add to the definition set of this block */
1464 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1465 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1466 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1467 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1468 /* delete global variables from the cseSet
1469 since they can be modified by the function call */
1470 deleteItemIf (&cseSet, ifDefGlobal);
1472 /* and also itemps assigned from globals */
1473 deleteItemIf (&cseSet, ifAssignedFromGlobal);
1475 /* delete all getpointer iCodes from cseSet, this should
1476 be done only for global arrays & pointers but at this
1477 point we don't know if globals, so to be safe do all */
1478 deleteItemIf (&cseSet, ifAnyGetPointer);
1481 /* for pcall & ipush we need to add to the useSet */
1482 if ((ic->op == PCALL ||
1486 IS_SYMOP (IC_LEFT (ic)))
1489 /* check if they can be replaced */
1493 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1495 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1497 /* the lookup could have changed it */
1498 if (IS_SYMOP (IC_LEFT (ic)))
1500 OP_USES(IC_LEFT (ic))=
1501 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1502 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1503 ebb->outDefs, &ebb->usesDefs);
1507 /* if we a sending a pointer as a parameter
1508 then kill all cse since the pointed to item
1509 might be changed in the function being called */
1510 if ((ic->op == IPUSH || ic->op == SEND) &&
1511 IS_PTR (operandType (IC_LEFT (ic))))
1513 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1514 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1515 for (i = 0; i < count; ebbs[i++]->visited = 0);
1516 applyToSet (ebb->succList, delGetPointerSucc,
1517 IC_LEFT (ic), ebb->dfnum);
1522 /* if jumptable then mark the usage */
1523 if (ic->op == JUMPTABLE)
1525 OP_USES(IC_JTCOND (ic))=
1526 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1527 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1528 ebb->outDefs, &ebb->usesDefs);
1535 /* do some algebraic optimizations if possible */
1537 while (constFold (ic, cseSet));
1540 if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1542 setOperandType (IC_LEFT (ic),
1543 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1547 if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1549 setOperandType (IC_RESULT (ic),
1550 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1553 /* if this is a condition statment then */
1554 /* check if the condition can be replaced */
1557 ifxOptimize (ic, cseSet, computeOnly,
1563 /* if the assignment & result is a temp */
1564 /* see if we can replace it */
1568 /* update the spill location for this */
1569 updateSpillLocation (ic,0);
1571 if (POINTER_SET (ic) &&
1572 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1575 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1576 if (pdop && IS_ITEMP (pdop) && !computeOnly)
1577 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1581 checkSign = isSignedOp(ic);
1583 /* do the operand lookup i.e. for both the */
1584 /* right & left operand : check the cseSet */
1585 /* to see if they have been replaced if yes */
1586 /* then replace them with those from cseSet */
1588 /* and left is a symbol */
1589 if (IS_SYMOP (IC_LEFT (ic)) &&
1590 !computeOnly && ic->op != ADDRESS_OF)
1594 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1597 if (POINTER_GET (ic))
1599 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1601 /* some non dominating block does POINTER_SET with
1602 this variable .. unsafe to remove any POINTER_GETs */
1603 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1604 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1605 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1608 /* check if there is a pointer set
1609 for the same pointer visible if yes
1610 then change this into an assignment */
1612 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1613 !bitVectBitValue (ebb->ptrsSet, pdop->key))
1616 IC_LEFT (ic) = NULL;
1617 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1618 SET_ISADDR (IC_RESULT (ic), 0);
1624 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1631 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1635 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1637 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1642 /* if left or right changed then do algebraic */
1646 while (constFold (ic, cseSet));
1649 /* if after all this it becomes a assignment to self
1650 then delete it and continue */
1651 if (ASSIGNMENT_TO_SELF (ic))
1653 remiCodeFromeBBlock (ebb, ic);
1657 /* now we will check to see if the entire */
1658 /* operation has been performed before */
1659 /* and is available */
1660 /* don't do assignments they will be killed */
1661 /* by dead code elimination if required do */
1662 /* it only if result is a temporary */
1664 if (!(POINTER_GET (ic) &&
1665 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1666 isOperandVolatile (IC_LEFT (ic), TRUE) ||
1667 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
1669 IS_ITEMP (IC_RESULT (ic)) &&
1672 applyToSet (cseSet, findPrevIc, ic, &pdic);
1673 if (pdic && compareType (operandType (IC_RESULT (pdic)),
1674 operandType (IC_RESULT (ic))) != 1)
1676 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
1680 /* Alternate code */
1681 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
1682 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
1683 /* Mmm, found an equivalent pointer get at a lower level.
1684 This could be a loop however with the same pointer set
1687 /* if previous definition found change this to an assignment */
1690 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
1691 SET_ISADDR(IC_RESULT(ic),0);
1692 SET_ISADDR(IC_RIGHT (ic),0);
1696 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
1697 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
1698 addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
1702 /* if assignment to a parameter which is not
1703 mine and type is a pointer then delete
1704 pointerGets to take care of aliasing */
1705 if (ASSIGNMENT (ic) &&
1706 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1707 IS_PTR (operandType (IC_RESULT (ic))))
1709 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1710 for (i = 0; i < count; ebbs[i++]->visited = 0);
1711 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1712 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1715 /* if this is a pointerget then see if we can replace
1716 this with a previously assigned pointer value */
1717 if (POINTER_GET (ic) &&
1718 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1719 isOperandVolatile (IC_LEFT (ic), TRUE)))
1722 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
1723 /* if we find it then locally replace all
1724 references to the result with what we assigned */
1727 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
1731 /* delete from the cseSet anything that has */
1732 /* operands matching the result of this */
1733 /* except in case of pointer access */
1734 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1736 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
1737 /* delete any previous definitions */
1738 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
1742 /* add the left & right to the defUse set */
1743 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
1745 OP_USES(IC_LEFT (ic))=
1746 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1747 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1751 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
1753 OP_USES(IC_RIGHT (ic))=
1754 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1755 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1759 /* for the result it is special case, put the result */
1760 /* in the defuseSet if it a pointer or array access */
1761 if (POINTER_SET (defic))
1763 OP_USES(IC_RESULT (ic))=
1764 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1765 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1766 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
1767 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
1768 /* delete from inexpressions of all successors which
1769 have dfNum > than this block */
1770 for (i = 0; i < count; ebbs[i++]->visited = 0);
1771 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
1773 /* delete from cseSet all other pointer sets
1775 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
1776 /* add to the local pointerset set */
1777 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
1780 /* add the result to defintion set */ if (IC_RESULT (ic))
1782 OP_DEFS(IC_RESULT (ic))=
1783 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1784 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1785 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1786 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1790 /* if this is an addressof instruction then */
1791 /* put the symbol in the address of list & */
1792 /* delete it from the cseSet */
1793 if (defic->op == ADDRESS_OF)
1795 addSetHead (&ebb->addrOf, IC_LEFT (ic));
1796 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
1800 setToNull ((void **) &ebb->outExprs);
1801 ebb->outExprs = cseSet;
1802 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
1803 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
1807 /*-----------------------------------------------------------------*/
1808 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
1809 /*-----------------------------------------------------------------*/
1811 cseAllBlocks (eBBlock ** ebbs, int count)
1816 /* if optimization turned off */
1818 for (i = 0; i < count; i++)
1819 change += cseBBlock (ebbs[i], FALSE, ebbs, count);