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",
122 OP_SYMBOL(from)->name,
123 IS_SYMOP(to) ? OP_SYMBOL(to)->name) : "!SYM");
124 for (lic = ic; lic; lic = lic->next)
128 /* do the special cases first */
132 IC_COND (lic)->key == from->key)
135 bitVectUnSetBit (OP_USES (from), lic->key);
136 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
137 siaddr = IC_COND (lic)->isaddr;
138 IC_COND (lic) = operandFromOperand (to);
139 IC_COND (lic)->isaddr = siaddr;
145 if (lic->op == JUMPTABLE)
148 IC_JTCOND (lic)->key == from->key)
151 bitVectUnSetBit (OP_USES (from), lic->key);
152 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
153 siaddr = IC_COND (lic)->isaddr;
154 IC_JTCOND (lic) = operandFromOperand (to);
155 IC_JTCOND (lic)->isaddr = siaddr;
162 IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
164 /* maintain du chains */
165 if (POINTER_SET (lic))
167 bitVectUnSetBit (OP_USES (from), lic->key);
168 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
170 /* also check if the "from" was in the non-dominating
171 pointer sets and replace it with "to" in the bitVector */
172 if (bitVectBitValue (*ndpset, from->key))
174 bitVectUnSetBit (*ndpset, from->key);
175 bitVectSetBit (*ndpset, to->key);
181 bitVectUnSetBit (OP_DEFS (from), lic->key);
182 OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
184 siaddr = IC_RESULT (lic)->isaddr;
185 IC_RESULT (lic) = operandFromOperand (to);
186 IC_RESULT (lic)->isaddr = siaddr;
190 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
192 bitVectUnSetBit (OP_USES (from), lic->key);
193 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
194 siaddr = IC_RIGHT (lic)->isaddr;
195 IC_RIGHT (lic) = operandFromOperand (to);
196 IC_RIGHT (lic)->isaddr = siaddr;
200 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
202 bitVectUnSetBit (OP_USES (from), lic->key);
203 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
204 siaddr = IC_LEFT (lic)->isaddr;
205 IC_LEFT (lic) = operandFromOperand (to);
206 IC_LEFT (lic)->isaddr = siaddr;
211 /*-----------------------------------------------------------------*/
212 /* iCodeKeyIs - if the icode keys match then return 1 */
213 /*-----------------------------------------------------------------*/
214 DEFSETFUNC (iCodeKeyIs)
219 if (cdp->diCode->key == key)
225 /*-----------------------------------------------------------------*/
226 /* removeFromInExprs - removes an icode from inexpressions */
227 /*-----------------------------------------------------------------*/
228 DEFSETFUNC (removeFromInExprs)
232 V_ARG (operand *, from);
233 V_ARG (operand *, to);
234 V_ARG (eBBlock *, cbp);
240 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
241 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
242 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
244 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
248 /*-----------------------------------------------------------------*/
249 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
250 /*-----------------------------------------------------------------*/
252 isGlobalInNearSpace (operand * op)
254 sym_link *type = getSpec (operandType (op));
255 /* this is 8051 specific: optimization
256 suggested by Jean-Louis VERN, with 8051s we have no
257 advantage of putting variables in near space into
259 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
260 IN_DIRSPACE (SPEC_OCLS (type)))
266 /*-----------------------------------------------------------------*/
267 /* findCheaperOp - cseBBlock support routine, will check to see if */
268 /* we have a operand previously defined */
269 /*-----------------------------------------------------------------*/
270 DEFSETFUNC (findCheaperOp)
273 V_ARG (operand *, cop);
274 V_ARG (operand **, opp);
275 V_ARG (int, checkSign);
277 /* if we have already found it */
281 /* not found it yet check if this is the one */
282 /* and this is not the defining one */
283 if (cop->key == cdp->key)
286 /* do a special check this will help in */
287 /* constant propagation & dead code elim */
288 /* for assignments only */
289 if (cdp->diCode->op == '=') {
290 /* if the result is volatile then return result */
291 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
292 *opp = IC_RESULT (cdp->diCode);
294 /* if this is a straight assignment and
295 left is a temp then prefer the temporary to the
297 if (!POINTER_SET (cdp->diCode) &&
298 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
299 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
300 *opp = IC_RESULT (cdp->diCode);
302 /* if straight assignement && and both
303 are temps then prefer the one that
304 will not need extra space to spil, also
305 take into consideration if right side
306 an induction variable
308 if (!POINTER_SET (cdp->diCode) &&
309 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
310 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
311 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
312 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
313 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
314 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
315 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
316 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
317 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
318 *opp = IC_RESULT (cdp->diCode);
320 *opp = IC_RIGHT (cdp->diCode);
324 *opp = IC_RESULT (cdp->diCode);
327 /* if this is an assign to a temp. then check
328 if the right side is this then return this */
329 if (IS_TRUE_SYMOP (cop) &&
330 cdp->diCode->op == '=' &&
331 !POINTER_SET (cdp->diCode) &&
332 cop->key == IC_RIGHT (cdp->diCode)->key &&
333 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
334 IS_ITEMP (IC_RESULT (cdp->diCode)))
335 *opp = IC_RESULT (cdp->diCode);
338 (isOperandLiteral(*opp) || !checkSign ||
340 IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
341 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
342 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
345 if ((isGlobalInNearSpace (cop) &&
346 !isOperandLiteral (*opp)) ||
347 isOperandVolatile (*opp, FALSE)
354 if (cop->key == (*opp)->key)
360 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
362 *opp = operandFromOperand (*opp);
363 (*opp)->isaddr = cop->isaddr;
366 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
367 SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
369 // special case: we can make an unsigned char literal
370 // into an int literal with no cost.
371 if (isOperandLiteral(*opp)
372 && SPEC_NOUN(operandType(*opp)) == V_CHAR
373 && SPEC_NOUN(operandType(cop)) == V_INT)
375 *opp = operandFromOperand (*opp);
376 SPEC_NOUN(operandType(*opp)) = V_INT;
387 LRH(printf ("findCheaperOp: %s < %s\n",\
388 IS_SYMOP((*opp)) ? OP_SYMBOL((*opp))->name : "!SYM",\
389 OP_SYMBOL(cop)->name));
397 /*-----------------------------------------------------------------*/
398 /* findPointerSet - finds the right side of a pointer set op */
399 /*-----------------------------------------------------------------*/
400 DEFSETFUNC (findPointerSet)
403 V_ARG (operand *, op);
404 V_ARG (operand **, opp);
405 V_ARG (operand *, rop);
407 if (POINTER_SET (cdp->diCode) &&
408 IC_RESULT (cdp->diCode)->key == op->key &&
409 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
410 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
411 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
412 getSize (operandType (rop)))
414 *opp = IC_RIGHT (cdp->diCode);
421 /*-----------------------------------------------------------------*/
422 /* findPrevIc - cseBBlock support function will return the iCode */
423 /* which matches the current one */
424 /*-----------------------------------------------------------------*/
425 DEFSETFUNC (findPrevIc)
429 V_ARG (iCode **, icp);
431 /* if already found */
435 /* if the iCodes are the same */
436 if (isiCodeEqual (ic, cdp->diCode) &&
437 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
439 LRH(printf ("findPrevIc same: %d %d\n", ic->key, cdp->diCode->key));
444 /* if iCodes are not the same */
445 /* see the operands maybe interchanged */
446 if (ic->op == cdp->diCode->op &&
447 (ic->op == '+' || ic->op == '*') &&
448 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
449 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
451 LRH(printf ("findPrevIc inter: %d %d\n", ic->key, cdp->diCode->key));
459 /*-------------------------------------------------------------------*/
460 /* ifAssignedFromGlobal - if definition is an assignment from global */
461 /*-------------------------------------------------------------------*/
462 DEFSETFUNC (ifAssignedFromGlobal)
465 iCode *dic=cdp->diCode;
467 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
473 /*-----------------------------------------------------------------*/
474 /* ifDefGlobal - if definition is global */
475 /*-----------------------------------------------------------------*/
476 DEFSETFUNC (ifDefGlobal)
480 return (isOperandGlobal (cdp->sym));
483 /*-----------------------------------------------------------------*/
484 /* ifAnyGetPointer - if get pointer icode */
485 /*-----------------------------------------------------------------*/
486 DEFSETFUNC (ifAnyGetPointer)
490 if (cdp->diCode && POINTER_GET (cdp->diCode))
495 /*-----------------------------------------------------------------*/
496 /* ifOperandsHave - if any of the operand are the same as this */
497 /*-----------------------------------------------------------------*/
498 DEFSETFUNC (ifOperandsHave)
501 V_ARG (operand *, op);
504 if (IC_LEFT (cdp->diCode) &&
505 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
506 IC_LEFT (cdp->diCode)->key == op->key)
509 if (IC_RIGHT (cdp->diCode) &&
510 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
511 IC_RIGHT (cdp->diCode)->key == op->key)
514 /* or if any of the operands are volatile */
515 if (IC_LEFT (cdp->diCode) &&
516 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
519 if (IC_RIGHT (cdp->diCode) &&
520 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
524 if (IC_RESULT (cdp->diCode) &&
525 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
531 /*-----------------------------------------------------------------*/
532 /* ifDefSymIs - if a definition is found in the set */
533 /*-----------------------------------------------------------------*/
535 ifDefSymIs (set * cseSet, operand * sym)
540 if (!sym || !IS_SYMOP (sym))
542 for (sl = cseSet; sl; sl = sl->next)
545 if (loop->sym->key == sym->key)
552 /*-----------------------------------------------------------------*/
553 /* ifDefSymIsX - will return 1 if the symbols match */
554 /*-----------------------------------------------------------------*/
555 DEFSETFUNC (ifDefSymIsX)
558 V_ARG (operand *, op);
561 return cdp->sym->key == op->key;
563 return (isOperandEqual (cdp->sym, op));
568 /*-----------------------------------------------------------------*/
569 /* ifDiCodeIs - returns truw if diCode is same */
570 /*-----------------------------------------------------------------*/
572 ifDiCodeIs (set * cseSet, iCode * ic)
580 for (sl = cseSet; sl; sl = sl->next)
583 if (loop->diCode == ic)
590 /*-----------------------------------------------------------------*/
591 /* ifPointerGet - returns true if the icode is pointer get sym */
592 /*-----------------------------------------------------------------*/
593 DEFSETFUNC (ifPointerGet)
596 V_ARG (operand *, op);
597 iCode *dic = cdp->diCode;
598 operand *left = IC_LEFT (cdp->diCode);
600 if (POINTER_GET (dic) && left->key == op->key)
606 /*-----------------------------------------------------------------*/
607 /* ifPointerSet - returns true if the icode is pointer set sym */
608 /*-----------------------------------------------------------------*/
609 DEFSETFUNC (ifPointerSet)
612 V_ARG (operand *, op);
614 if (POINTER_SET (cdp->diCode) &&
615 IC_RESULT (cdp->diCode)->key == op->key)
621 /*-----------------------------------------------------------------*/
622 /* ifDiCodeIsX - will return 1 if the symbols match */
623 /*-----------------------------------------------------------------*/
624 DEFSETFUNC (ifDiCodeIsX)
629 return cdp->diCode == ic;
633 /*-----------------------------------------------------------------*/
634 /* findBackwardDef - scan backwards to find deinition of operand */
635 /*-----------------------------------------------------------------*/
636 iCode *findBackwardDef(operand *op,iCode *ic)
640 for (lic = ic; lic ; lic = lic->prev) {
641 if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
647 /*-----------------------------------------------------------------*/
648 /* algebraicOpts - does some algebraic optimizations */
649 /*-----------------------------------------------------------------*/
651 algebraicOpts (iCode * ic)
653 /* we don't deal with the following iCodes
664 /* if both operands present & ! IFX */
665 /* then if they are both literal we */
666 /* perform the operation right now */
667 if (IC_RESULT (ic) &&
670 IS_OP_LITERAL (IC_LEFT (ic)) &&
671 IS_OP_LITERAL (IC_RIGHT (ic)))
674 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
677 operandType (IC_RESULT (ic)));
680 SET_RESULT_RIGHT (ic);
684 /* if not ifx & only one operand present */
685 if (IC_RESULT (ic) &&
687 IS_OP_LITERAL (IC_LEFT (ic)) &&
691 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
694 operandType (IC_RESULT (ic)));
697 SET_RESULT_RIGHT (ic);
702 /* a special case : or in short a kludgy solution will think
703 about a better solution over a glass of wine someday */
704 if (ic->op == GET_VALUE_AT_ADDRESS)
707 if (IS_ITEMP (IC_RESULT (ic)) &&
708 IS_TRUE_SYMOP (IC_LEFT (ic)))
712 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
713 IC_RIGHT (ic)->isaddr = 0;
715 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
716 IC_RESULT (ic)->isaddr = 0;
717 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
721 if (IS_ITEMP (IC_LEFT (ic)) &&
722 IS_ITEMP (IC_RESULT (ic)) &&
723 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
724 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
725 !IC_LEFT (ic)->isaddr)
728 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
729 IC_RIGHT (ic)->isaddr = 0;
730 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
731 IC_RESULT (ic)->isaddr = 0;
739 /* depending on the operation */
743 /* if adding the same thing change to left shift by 1 */
744 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
745 !IS_FLOAT (operandType (IC_RESULT (ic))))
748 IC_RIGHT (ic) = operandFromLit (1);
751 /* if addition then check if one of them is a zero */
752 /* if yes turn it into assignmnt */
753 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
754 operandLitValue (IC_LEFT (ic)) == 0.0)
759 SET_ISADDR (IC_RESULT (ic), 0);
760 SET_ISADDR (IC_RIGHT (ic), 0);
763 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
764 operandLitValue (IC_RIGHT (ic)) == 0.0)
768 IC_RIGHT (ic) = IC_LEFT (ic);
770 SET_ISADDR (IC_RIGHT (ic), 0);
771 SET_ISADDR (IC_RESULT (ic), 0);
776 /* if subtracting the the same thing then zero */
777 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
780 IC_RIGHT (ic) = operandFromLit (0);
782 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
783 IC_RESULT (ic)->isaddr = 0;
787 /* if subtraction then check if one of the operand */
788 /* is zero then depending on which operand change */
789 /* to assignment or unary minus */
790 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
791 operandLitValue (IC_RIGHT (ic)) == 0.0)
793 /* right size zero change to assignment */
795 IC_RIGHT (ic) = IC_LEFT (ic);
797 SET_ISADDR (IC_RIGHT (ic), 0);
798 SET_ISADDR (IC_RESULT (ic), 0);
801 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
802 operandLitValue (IC_LEFT (ic)) == 0.0)
804 /* left zero turn into an unary minus */
806 IC_LEFT (ic) = IC_RIGHT (ic);
807 IC_RIGHT (ic) = NULL;
811 /* if multiplication then check if either of */
812 /* them is zero then the result is zero */
813 /* if either of them is one then result is */
816 if (IS_OP_LITERAL (IC_LEFT (ic)))
819 if (operandLitValue (IC_LEFT (ic)) == 0.0)
822 IC_RIGHT (ic) = IC_LEFT (ic);
824 SET_RESULT_RIGHT (ic);
827 if (operandLitValue (IC_LEFT (ic)) == 1.0)
831 SET_RESULT_RIGHT (ic);
836 if (IS_OP_LITERAL (IC_RIGHT (ic)))
839 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
843 SET_RESULT_RIGHT (ic);
847 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
850 IC_RIGHT (ic) = IC_LEFT (ic);
852 SET_RESULT_RIGHT (ic);
858 /* if division by self then 1 */
859 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
862 IC_RIGHT (ic) = operandFromLit (1);
864 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
865 IC_RESULT (ic)->isaddr = 0;
868 /* if this is a division then check if right */
869 /* is one then change it to an assignment */
870 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
871 operandLitValue (IC_RIGHT (ic)) == 1.0)
875 IC_RIGHT (ic) = IC_LEFT (ic);
877 SET_RESULT_RIGHT (ic);
881 /* if both are the same for an comparison operators */
885 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
888 IC_RIGHT (ic) = operandFromLit (1);
890 SET_RESULT_RIGHT (ic);
896 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
899 IC_RIGHT (ic) = operandFromLit (0);
901 SET_RESULT_RIGHT (ic);
906 sym_link *otype = operandType(IC_RIGHT(ic));
907 sym_link *ctype = operandType(IC_LEFT(ic));
908 /* if this is a cast of a literal value */
909 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
910 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
913 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
914 operandLitValue (IC_RIGHT (ic))));
916 SET_ISADDR (IC_RESULT (ic), 0);
918 /* if casting to the same */
919 if (compareType (operandType (IC_RESULT (ic)),
920 operandType (IC_RIGHT (ic))) == 1) {
923 SET_ISADDR (IC_RESULT (ic), 0);
928 if (IS_OP_LITERAL (IC_LEFT (ic)))
932 (operandLitValue (IC_LEFT (ic)) == 0 ?
933 operandFromLit (1) : operandFromLit (0));
935 SET_ISADDR (IC_RESULT (ic), 0);
941 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
942 /*-----------------------------------------------------------------*/
943 /* updateSpillLocation - keeps track of register spill location */
944 /*-----------------------------------------------------------------*/
946 updateSpillLocation (iCode * ic, int induction)
950 if (POINTER_SET (ic))
956 /* for the form true_symbol := iTempNN */
957 if (ASSIGN_ITEMP_TO_SYM (ic) &&
958 !SPIL_LOC (IC_RIGHT (ic))) {
960 setype = getSpec (operandType (IC_RESULT (ic)));
962 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
963 !IS_VOLATILE (setype) &&
964 !IN_FARSPACE (SPEC_OCLS (setype)) &&
965 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
967 wassert(IS_SYMOP(IC_RESULT (ic)));
968 wassert(IS_SYMOP(IC_RIGHT (ic)));
969 SPIL_LOC (IC_RIGHT (ic)) =
970 IC_RESULT (ic)->operand.symOperand;
975 #if 0 /* this needs furthur investigation can save a lot of code */
976 if (ASSIGN_SYM_TO_ITEMP(ic) &&
977 !SPIL_LOC(IC_RESULT(ic))) {
978 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
979 SPIL_LOC (IC_RESULT (ic)) =
980 IC_RIGHT (ic)->operand.symOperand;
983 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
985 if (!SPIL_LOC (IC_RIGHT (ic)) &&
986 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
987 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
989 setype = getSpec (operandType (IC_RESULT (ic)));
991 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
992 !IS_VOLATILE (setype) &&
993 !IN_FARSPACE (SPEC_OCLS (setype)) &&
994 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
996 SPIL_LOC (IC_RIGHT (ic)) =
997 SPIL_LOC (IC_RESULT (ic));
999 /* special case for inductions */
1001 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1002 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1003 !SPIL_LOC(IC_RESULT(ic))) {
1004 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1008 /*-----------------------------------------------------------------*/
1009 /* setUsesDef - sets the uses def bitvector for a given operand */
1010 /*-----------------------------------------------------------------*/
1012 setUsesDefs (operand * op, bitVect * bdefs,
1013 bitVect * idefs, bitVect ** oud)
1015 /* compute the definitions alive at this point */
1016 bitVect *adefs = bitVectUnion (bdefs, idefs);
1018 /* of these definitions find the ones that are */
1019 /* for this operand */
1020 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1022 /* these are the definitions that this operand can use */
1023 op->usesDefs = adefs;
1025 /* the out defs is an union */
1026 *oud = bitVectUnion (*oud, adefs);
1029 /*-----------------------------------------------------------------*/
1030 /* unsetDefsAndUses - clear this operation for the operands */
1031 /*-----------------------------------------------------------------*/
1033 unsetDefsAndUses (iCode * ic)
1035 if (ic->op == JUMPTABLE)
1038 /* take away this definition from the def chain of the */
1039 /* result & take away from use set of the operands */
1042 /* turn off def set */
1043 if (IS_SYMOP (IC_RESULT (ic)))
1045 if (!POINTER_SET (ic))
1046 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1048 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1050 /* turn off the useSet for the operands */
1051 if (IS_SYMOP (IC_LEFT (ic)))
1052 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1054 if (IS_SYMOP (IC_RIGHT (ic)))
1055 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1058 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1059 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1062 /*-----------------------------------------------------------------*/
1063 /* ifxOptimize - changes ifx conditions if it can */
1064 /*-----------------------------------------------------------------*/
1066 ifxOptimize (iCode * ic, set * cseSet,
1068 eBBlock * ebb, int *change,
1069 eBBlock ** ebbs, int count)
1074 /* if the condition can be replaced */
1078 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1081 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1086 /* if the conditional is a literal then */
1087 if (IS_OP_LITERAL (IC_COND (ic)))
1090 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1093 /* change to a goto */
1095 IC_LABEL (ic) = IC_TRUE (ic);
1102 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1105 IC_LABEL (ic) = IC_FALSE (ic);
1111 /* then kill this if condition */
1112 remiCodeFromeBBlock (ebb, ic);
1116 /* now we need to recompute the control flow */
1117 /* since the control flow has changed */
1118 /* this is very expensive but it does not happen */
1119 /* too often, if it does happen then the user pays */
1121 computeControlFlow (ebbs, count, 1);
1122 if (!options.lessPedantic) {
1123 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1128 /* if there is only one successor and that successor
1129 is the same one we are conditionally going to then
1130 we can remove this conditional statement */
1131 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1132 if (elementsInSet (ebb->succList) == 1 &&
1133 isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1136 remiCodeFromeBBlock (ebb, ic);
1137 computeControlFlow (ebbs, count, 1);
1138 if (!options.lessPedantic) {
1139 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1145 /* if it remains an IFX the update the use Set */
1146 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1147 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1151 /*-----------------------------------------------------------------*/
1152 /* diCodeForSym - finds the definiting instruction for a symbol */
1153 /*-----------------------------------------------------------------*/
1154 DEFSETFUNC (diCodeForSym)
1157 V_ARG (operand *, sym);
1158 V_ARG (iCode **, dic);
1160 /* if already found */
1164 /* if not if this is the defining iCode */
1165 if (sym->key == cdp->key)
1174 /*-----------------------------------------------------------------*/
1175 /* constFold - does some constant folding */
1176 /*-----------------------------------------------------------------*/
1178 constFold (iCode * ic, set * cseSet)
1182 /* this routine will change
1188 /* deal with only + & - */
1189 if (ic->op != '+' &&
1193 /* this check is a hueristic to prevent live ranges
1194 from becoming too long */
1195 if (IS_PTR (operandType (IC_RESULT (ic))))
1198 /* check if operation with a literal */
1199 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1202 /* check if we can find a definition for the
1204 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1207 /* check that this is also a +/- */
1208 if (dic->op != '+' && dic->op != '-')
1211 /* with a literal */
1212 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1215 /* find the definition of the left operand
1216 of dic.then check if this defined with a
1217 get_pointer return 0 if the pointer size is
1218 less than 2 (MCS51 specific) */
1219 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1222 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1225 /* it is if the operations are the same */
1226 /* the literal parts need to be added */
1227 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1228 if (ic->op == dic->op)
1229 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1230 operandLitValue (IC_RIGHT (dic)));
1232 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1233 operandLitValue (IC_RIGHT (dic)));
1235 if (IS_ITEMP (IC_RESULT (ic)))
1237 SPIL_LOC (IC_RESULT (ic)) = NULL;
1238 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1245 /*-----------------------------------------------------------------*/
1246 /* deleteGetPointers - called when a pointer is passed as parm */
1247 /* will delete from cseSet all get pointers computed from this */
1248 /* pointer. A simple ifOperandsHave is not good enough here */
1249 /*-----------------------------------------------------------------*/
1251 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1253 set *compItems = NULL;
1258 if (!*cseSet && !*pss)
1261 /* first find all items computed from this operand .
1262 This done fairly simply go thru the list and find
1263 those that are computed by arthimetic with this
1265 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1267 if (IS_ARITHMETIC_OP (cdp->diCode))
1269 if (isOperandEqual (IC_LEFT (cdp->diCode), op) ||
1270 isOperandEqual (IC_RIGHT (cdp->diCode), op))
1272 /* save it in our list of items */
1273 addSet (&compItems, IC_RESULT (cdp->diCode));
1275 /* also check for those computed from our computed
1276 list . This will take care of situations like
1277 iTemp1 = iTemp0 + 8;
1278 iTemp2 = iTemp1 + 8; */
1279 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1280 (insetwithFunc)isOperandEqual) ||
1281 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1282 (insetwithFunc)isOperandEqual))
1284 addSet (&compItems, IC_RESULT (cdp->diCode));
1289 /* now delete all pointer gets with this op */
1290 deleteItemIf (cseSet, ifPointerGet, op);
1291 deleteItemIf (pss, ifPointerSet, op);
1293 /* set the bit vector used by dataFlow computation later */
1294 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key);
1295 /* now for the computed items */
1296 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1298 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1299 deleteItemIf (cseSet, ifPointerGet, cop);
1300 deleteItemIf (pss, ifPointerSet, cop);
1304 /*-----------------------------------------------------------------*/
1305 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1306 /* dfnum > supplied */
1307 /*-----------------------------------------------------------------*/
1308 DEFSETFUNC (delGetPointerSucc)
1310 eBBlock *ebp = item;
1311 V_ARG (operand *, op);
1318 if (ebp->dfnum > dfnum)
1320 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1323 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1326 /*-----------------------------------------------------------------*/
1327 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1328 /*-----------------------------------------------------------------*/
1330 fixUpTypes (iCode * ic)
1332 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1334 /* if (TARGET_IS_DS390) */
1335 if (options.model == MODEL_FLAT24)
1341 /* for pointer_gets if the types of result & left r the
1342 same then change it type of result to next */
1344 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1346 setOperandType (IC_RESULT (ic), t2->next);
1350 /*-----------------------------------------------------------------*/
1351 /* isSignedOp - will return 1 if sign is important to operation */
1352 /*-----------------------------------------------------------------*/
1353 static int isSignedOp (iCode *ic)
1374 case GET_VALUE_AT_ADDRESS:
1400 /*-----------------------------------------------------------------*/
1401 /* cseBBlock - common subexpression elimination for basic blocks */
1402 /* this is the hackiest kludgiest routine in the whole */
1403 /* system. also the most important, since almost all */
1404 /* data flow related information is computed by it */
1405 /*-----------------------------------------------------------------*/
1407 cseBBlock (eBBlock * ebb, int computeOnly,
1408 eBBlock ** ebbs, int count)
1414 set *ptrSetSet = NULL;
1416 /* if this block is not reachable */
1420 /* set of common subexpressions */
1421 cseSet = setFromSet (ebb->inExprs);
1423 /* these will be computed by this routine */
1424 setToNull ((void **) &ebb->outDefs);
1425 setToNull ((void **) &ebb->defSet);
1426 setToNull ((void **) &ebb->usesDefs);
1427 setToNull ((void **) &ebb->ptrsSet);
1428 setToNull ((void **) &ebb->addrOf);
1429 setToNull ((void **) &ebb->ldefs);
1431 ebb->outDefs = bitVectCopy (ebb->inDefs);
1432 bitVectDefault = iCodeKey;
1433 ebb->defSet = newBitVect (iCodeKey);
1434 ebb->usesDefs = newBitVect (iCodeKey);
1436 /* for all the instructions in this block do */
1437 for (ic = ebb->sch; ic; ic = ic->next)
1444 ic->eBBlockNum = ebb->bbnum;
1449 /* if this is an assignment from true symbol
1450 to a temp then do pointer post inc/dec optimzation */
1451 if (ic->op == '=' && !POINTER_SET (ic) &&
1452 IS_PTR (operandType (IC_RESULT (ic))))
1454 ptrPostIncDecOpt (ic);
1457 /* clear the def & use chains for the operands involved */
1458 /* in this operation . since it can change due to opts */
1459 unsetDefsAndUses (ic);
1461 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1463 /* add to defSet of the symbol */
1464 OP_DEFS(IC_RESULT (ic))=
1465 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1466 /* add to the definition set of this block */
1467 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1468 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1469 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1470 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1471 /* delete global variables from the cseSet
1472 since they can be modified by the function call */
1473 deleteItemIf (&cseSet, ifDefGlobal);
1475 /* and also itemps assigned from globals */
1476 deleteItemIf (&cseSet, ifAssignedFromGlobal);
1478 /* delete all getpointer iCodes from cseSet, this should
1479 be done only for global arrays & pointers but at this
1480 point we don't know if globals, so to be safe do all */
1481 deleteItemIf (&cseSet, ifAnyGetPointer);
1484 /* for pcall & ipush we need to add to the useSet */
1485 if ((ic->op == PCALL ||
1489 IS_SYMOP (IC_LEFT (ic)))
1492 /* check if they can be replaced */
1496 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1498 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1500 /* the lookup could have changed it */
1501 if (IS_SYMOP (IC_LEFT (ic)))
1503 OP_USES(IC_LEFT (ic))=
1504 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1505 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1506 ebb->outDefs, &ebb->usesDefs);
1510 /* if we a sending a pointer as a parameter
1511 then kill all cse since the pointed to item
1512 might be changed in the function being called */
1513 if ((ic->op == IPUSH || ic->op == SEND) &&
1514 IS_PTR (operandType (IC_LEFT (ic))))
1516 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1517 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1518 for (i = 0; i < count; ebbs[i++]->visited = 0);
1519 applyToSet (ebb->succList, delGetPointerSucc,
1520 IC_LEFT (ic), ebb->dfnum);
1525 /* if jumptable then mark the usage */
1526 if (ic->op == JUMPTABLE)
1528 OP_USES(IC_JTCOND (ic))=
1529 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1530 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1531 ebb->outDefs, &ebb->usesDefs);
1538 /* do some algebraic optimizations if possible */
1540 while (constFold (ic, cseSet));
1543 if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1545 setOperandType (IC_LEFT (ic),
1546 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1550 if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1552 setOperandType (IC_RESULT (ic),
1553 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1556 /* if this is a condition statment then */
1557 /* check if the condition can be replaced */
1560 ifxOptimize (ic, cseSet, computeOnly,
1566 /* if the assignment & result is a temp */
1567 /* see if we can replace it */
1571 /* update the spill location for this */
1572 updateSpillLocation (ic,0);
1574 if (POINTER_SET (ic) &&
1575 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1578 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1579 if (pdop && IS_ITEMP (pdop) && !computeOnly)
1580 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1584 checkSign = isSignedOp(ic);
1586 /* do the operand lookup i.e. for both the */
1587 /* right & left operand : check the cseSet */
1588 /* to see if they have been replaced if yes */
1589 /* then replace them with those from cseSet */
1591 /* and left is a symbol */
1592 if (IS_SYMOP (IC_LEFT (ic)) &&
1593 !computeOnly && ic->op != ADDRESS_OF)
1597 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1600 if (POINTER_GET (ic))
1602 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1604 /* some non dominating block does POINTER_SET with
1605 this variable .. unsafe to remove any POINTER_GETs */
1606 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1607 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1608 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1611 /* check if there is a pointer set
1612 for the same pointer visible if yes
1613 then change this into an assignment */
1615 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1616 !bitVectBitValue (ebb->ptrsSet, pdop->key))
1619 IC_LEFT (ic) = NULL;
1620 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1621 SET_ISADDR (IC_RESULT (ic), 0);
1627 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1634 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1638 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1640 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1645 /* if left or right changed then do algebraic */
1649 while (constFold (ic, cseSet));
1652 /* if after all this it becomes a assignment to self
1653 then delete it and continue */
1654 if (ASSIGNMENT_TO_SELF (ic))
1656 remiCodeFromeBBlock (ebb, ic);
1660 /* now we will check to see if the entire */
1661 /* operation has been performed before */
1662 /* and is available */
1663 /* don't do assignments they will be killed */
1664 /* by dead code elimination if required do */
1665 /* it only if result is a temporary */
1667 if (!(POINTER_GET (ic) &&
1668 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1669 isOperandVolatile (IC_LEFT (ic), TRUE) ||
1670 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
1672 IS_ITEMP (IC_RESULT (ic)) &&
1675 applyToSet (cseSet, findPrevIc, ic, &pdic);
1676 if (pdic && compareType (operandType (IC_RESULT (pdic)),
1677 operandType (IC_RESULT (ic))) != 1)
1679 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
1683 /* Alternate code */
1684 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
1685 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
1686 /* Mmm, found an equivalent pointer get at a lower level.
1687 This could be a loop however with the same pointer set
1690 /* if previous definition found change this to an assignment */
1693 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
1694 SET_ISADDR(IC_RESULT(ic),0);
1695 SET_ISADDR(IC_RIGHT (ic),0);
1699 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
1700 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
1701 addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
1705 /* if assignment to a parameter which is not
1706 mine and type is a pointer then delete
1707 pointerGets to take care of aliasing */
1708 if (ASSIGNMENT (ic) &&
1709 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1710 IS_PTR (operandType (IC_RESULT (ic))))
1712 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1713 for (i = 0; i < count; ebbs[i++]->visited = 0);
1714 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1715 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1718 /* if this is a pointerget then see if we can replace
1719 this with a previously assigned pointer value */
1720 if (POINTER_GET (ic) &&
1721 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1722 isOperandVolatile (IC_LEFT (ic), TRUE)))
1725 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
1726 /* if we find it then locally replace all
1727 references to the result with what we assigned */
1730 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
1734 /* delete from the cseSet anything that has */
1735 /* operands matching the result of this */
1736 /* except in case of pointer access */
1737 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1739 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
1740 /* delete any previous definitions */
1741 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
1745 /* add the left & right to the defUse set */
1746 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
1748 OP_USES(IC_LEFT (ic))=
1749 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1750 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1754 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
1756 OP_USES(IC_RIGHT (ic))=
1757 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1758 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1762 /* for the result it is special case, put the result */
1763 /* in the defuseSet if it a pointer or array access */
1764 if (POINTER_SET (defic))
1766 OP_USES(IC_RESULT (ic))=
1767 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1768 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1769 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
1770 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
1771 /* delete from inexpressions of all successors which
1772 have dfNum > than this block */
1773 for (i = 0; i < count; ebbs[i++]->visited = 0);
1774 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
1776 /* delete from cseSet all other pointer sets
1778 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
1779 /* add to the local pointerset set */
1780 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
1783 /* add the result to defintion set */ if (IC_RESULT (ic))
1785 OP_DEFS(IC_RESULT (ic))=
1786 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1787 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1788 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1789 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1793 /* if this is an addressof instruction then */
1794 /* put the symbol in the address of list & */
1795 /* delete it from the cseSet */
1796 if (defic->op == ADDRESS_OF)
1798 addSetHead (&ebb->addrOf, IC_LEFT (ic));
1799 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
1803 setToNull ((void **) &ebb->outExprs);
1804 ebb->outExprs = cseSet;
1805 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
1806 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
1810 /*-----------------------------------------------------------------*/
1811 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
1812 /*-----------------------------------------------------------------*/
1814 cseAllBlocks (eBBlock ** ebbs, int count)
1819 /* if optimization turned off */
1821 for (i = 0; i < count; i++)
1822 change += cseBBlock (ebbs[i], FALSE, ebbs, count);