1 /*-------------------------------------------------------------------------
2 SDCCcse.c - source file for Common Subexpressions and other utility
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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
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.
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.
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 -------------------------------------------------------------------------*/
28 /*-----------------------------------------------------------------*/
29 /* newCseDef - new cseDef */
30 /*-----------------------------------------------------------------*/
32 newCseDef (operand * sym, iCode * ic)
37 cdp = Safe_alloc (sizeof (cseDef));
48 /*-----------------------------------------------------------------*/
49 /* int isCseDefEqual - two definitions are equal */
50 /*-----------------------------------------------------------------*/
52 isCseDefEqual (void *vsrc, void *vdest)
60 return (src->key == dest->key &&
61 src->diCode == dest->diCode);
65 /*-----------------------------------------------------------------*/
66 /* pcseDef - in the cseDef */
67 /*-----------------------------------------------------------------*/
69 pcseDef (void *item, va_list ap)
77 fprintf (stdout, "**null op**");
78 printOperand (cdp->sym, stdout);
79 icTab = getTableEntry (cdp->diCode->op);
80 icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
84 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
86 printf ("ReplaceOpWithCheaperOp (%s:%d with %s:%d): ",
87 OP_SYMBOL((*op))->name, OP_SYMBOL((*op))->isreqv,
88 OP_SYMBOL(cop)->name, OP_SYMBOL(cop)->isreqv);
89 // if op is a register equivalent
90 if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
91 operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
92 if (isOperandEqual(*rop, *op)) {
95 OP_SYMBOL((*op))->isreqv=0;
96 OP_SYMBOL(cop)->isreqv=1;
106 /*-----------------------------------------------------------------*/
107 /* replaceAllSymBySym - replaces all operands by operand in an */
108 /* instruction chain */
109 /*-----------------------------------------------------------------*/
111 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
115 for (lic = ic; lic; lic = lic->next)
119 /* do the special cases first */
123 IC_COND (lic)->key == from->key)
126 bitVectUnSetBit (OP_USES (from), lic->key);
127 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
128 siaddr = IC_COND (lic)->isaddr;
129 IC_COND (lic) = operandFromOperand (to);
130 IC_COND (lic)->isaddr = siaddr;
136 if (lic->op == JUMPTABLE)
139 IC_JTCOND (lic)->key == from->key)
142 bitVectUnSetBit (OP_USES (from), lic->key);
143 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
144 siaddr = IC_COND (lic)->isaddr;
145 IC_JTCOND (lic) = operandFromOperand (to);
146 IC_JTCOND (lic)->isaddr = siaddr;
153 IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
155 /* maintain du chains */
156 if (POINTER_SET (lic))
158 bitVectUnSetBit (OP_USES (from), lic->key);
159 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
161 /* also check if the "from" was in the non-dominating
162 pointer sets and replace it with "to" in the bitVector */
163 if (bitVectBitValue (*ndpset, from->key))
165 bitVectUnSetBit (*ndpset, from->key);
166 bitVectSetBit (*ndpset, to->key);
172 bitVectUnSetBit (OP_DEFS (from), lic->key);
173 OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
175 siaddr = IC_RESULT (lic)->isaddr;
176 IC_RESULT (lic) = operandFromOperand (to);
177 IC_RESULT (lic)->isaddr = siaddr;
181 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
183 bitVectUnSetBit (OP_USES (from), lic->key);
184 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
185 siaddr = IC_RIGHT (lic)->isaddr;
186 IC_RIGHT (lic) = operandFromOperand (to);
187 IC_RIGHT (lic)->isaddr = siaddr;
191 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
193 bitVectUnSetBit (OP_USES (from), lic->key);
194 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
195 siaddr = IC_LEFT (lic)->isaddr;
196 IC_LEFT (lic) = operandFromOperand (to);
197 IC_LEFT (lic)->isaddr = siaddr;
202 /*-----------------------------------------------------------------*/
203 /* iCodeKeyIs - if the icode keys match then return 1 */
204 /*-----------------------------------------------------------------*/
205 DEFSETFUNC (iCodeKeyIs)
210 if (cdp->diCode->key == key)
216 /*-----------------------------------------------------------------*/
217 /* removeFromInExprs - removes an icode from inexpressions */
218 /*-----------------------------------------------------------------*/
219 DEFSETFUNC (removeFromInExprs)
223 V_ARG (operand *, from);
224 V_ARG (operand *, to);
225 V_ARG (eBBlock *, cbp);
231 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
232 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
233 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
235 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
239 /*-----------------------------------------------------------------*/
240 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
241 /*-----------------------------------------------------------------*/
243 isGlobalInNearSpace (operand * op)
245 sym_link *type = getSpec (operandType (op));
246 /* this is 8051 specific: optimization
247 suggested by Jean-Louis VERN, with 8051s we have no
248 advantage of putting variables in near space into
250 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
251 IN_DIRSPACE (SPEC_OCLS (type)))
257 /*-----------------------------------------------------------------*/
258 /* findCheaperOp - cseBBlock support routine, will check to see if */
259 /* we have a operand previously defined */
260 /*-----------------------------------------------------------------*/
261 DEFSETFUNC (findCheaperOp)
264 V_ARG (operand *, cop);
265 V_ARG (operand **, opp);
266 V_ARG (int, checkSign);
268 /* if we have already found it */
272 /* not found it yet check if this is the one */
273 /* and this is not the defining one */
274 if (cop->key == cdp->key)
277 /* do a special check this will help in */
278 /* constant propagation & dead code elim */
279 /* for assignments only */
280 if (cdp->diCode->op == '=') {
281 /* if the result is volatile then return result */
282 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
283 *opp = IC_RESULT (cdp->diCode);
285 /* if this is a straight assignment and
286 left is a temp then prefer the temporary to the
288 if (!POINTER_SET (cdp->diCode) &&
289 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
290 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
291 *opp = IC_RESULT (cdp->diCode);
293 /* if straight assignement && and both
294 are temps then prefer the one that
295 will not need extra space to spil, also
296 take into consideration if right side
297 an induction variable
299 if (!POINTER_SET (cdp->diCode) &&
300 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
301 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
302 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
303 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
304 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
305 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
306 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
307 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
308 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
309 *opp = IC_RESULT (cdp->diCode);
311 *opp = IC_RIGHT (cdp->diCode);
315 *opp = IC_RESULT (cdp->diCode);
318 /* if this is an assign to a temp. then check
319 if the right side is this then return this */
320 if (IS_TRUE_SYMOP (cop) &&
321 cdp->diCode->op == '=' &&
322 !POINTER_SET (cdp->diCode) &&
323 cop->key == IC_RIGHT (cdp->diCode)->key &&
324 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
325 IS_ITEMP (IC_RESULT (cdp->diCode)))
326 *opp = IC_RESULT (cdp->diCode);
329 (isOperandLiteral(*opp) || !checkSign ||
331 IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
332 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
333 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
336 if ((isGlobalInNearSpace (cop) &&
337 !isOperandLiteral (*opp)) ||
338 isOperandVolatile (*opp, FALSE)
345 if (cop->key == (*opp)->key)
351 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
353 *opp = operandFromOperand (*opp);
354 (*opp)->isaddr = cop->isaddr;
357 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
358 SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
360 // special case: we can make an unsigned char literal
361 // into an int literal with no cost.
362 if (isOperandLiteral(*opp)
363 && SPEC_NOUN(operandType(*opp)) == V_CHAR
364 && SPEC_NOUN(operandType(cop)) == V_INT)
366 *opp = operandFromOperand (*opp);
367 SPEC_NOUN(operandType(*opp)) = V_INT;
385 /*-----------------------------------------------------------------*/
386 /* findPointerSet - finds the right side of a pointer set op */
387 /*-----------------------------------------------------------------*/
388 DEFSETFUNC (findPointerSet)
391 V_ARG (operand *, op);
392 V_ARG (operand **, opp);
393 V_ARG (operand *, rop);
395 if (POINTER_SET (cdp->diCode) &&
396 IC_RESULT (cdp->diCode)->key == op->key &&
397 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
398 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
399 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
400 getSize (operandType (rop)))
402 *opp = IC_RIGHT (cdp->diCode);
409 /*-----------------------------------------------------------------*/
410 /* findPrevIc - cseBBlock support function will return the iCode */
411 /* which matches the current one */
412 /*-----------------------------------------------------------------*/
413 DEFSETFUNC (findPrevIc)
417 V_ARG (iCode **, icp);
419 /* if already found */
423 /* if the iCodes are the same */
424 if (isiCodeEqual (ic, cdp->diCode) &&
425 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
430 /* if iCodes are not the same */
431 /* see the operands maybe interchanged */
432 if (ic->op == cdp->diCode->op &&
433 (ic->op == '+' || ic->op == '*') &&
434 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
435 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
443 /*-------------------------------------------------------------------*/
444 /* ifAssignedFromGlobal - if definition is an assignment from global */
445 /*-------------------------------------------------------------------*/
446 DEFSETFUNC (ifAssignedFromGlobal)
449 iCode *dic=cdp->diCode;
451 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
457 /*-----------------------------------------------------------------*/
458 /* ifDefGlobal - if definition is global */
459 /*-----------------------------------------------------------------*/
460 DEFSETFUNC (ifDefGlobal)
464 return (isOperandGlobal (cdp->sym));
467 /*-----------------------------------------------------------------*/
468 /* ifAnyGetPointer - if get pointer icode */
469 /*-----------------------------------------------------------------*/
470 DEFSETFUNC (ifAnyGetPointer)
474 if (cdp->diCode && POINTER_GET (cdp->diCode))
479 /*-----------------------------------------------------------------*/
480 /* ifOperandsHave - if any of the operand are the same as this */
481 /*-----------------------------------------------------------------*/
482 DEFSETFUNC (ifOperandsHave)
485 V_ARG (operand *, op);
488 if (IC_LEFT (cdp->diCode) &&
489 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
490 IC_LEFT (cdp->diCode)->key == op->key)
493 if (IC_RIGHT (cdp->diCode) &&
494 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
495 IC_RIGHT (cdp->diCode)->key == op->key)
498 /* or if any of the operands are volatile */
499 if (IC_LEFT (cdp->diCode) &&
500 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
503 if (IC_RIGHT (cdp->diCode) &&
504 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
508 if (IC_RESULT (cdp->diCode) &&
509 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
515 /*-----------------------------------------------------------------*/
516 /* ifDefSymIs - if a definition is found in the set */
517 /*-----------------------------------------------------------------*/
519 ifDefSymIs (set * cseSet, operand * sym)
524 if (!sym || !IS_SYMOP (sym))
526 for (sl = cseSet; sl; sl = sl->next)
529 if (loop->sym->key == sym->key)
536 /*-----------------------------------------------------------------*/
537 /* ifDefSymIsX - will return 1 if the symbols match */
538 /*-----------------------------------------------------------------*/
539 DEFSETFUNC (ifDefSymIsX)
542 V_ARG (operand *, op);
545 return cdp->sym->key == op->key;
547 return (isOperandEqual (cdp->sym, op));
552 /*-----------------------------------------------------------------*/
553 /* ifDiCodeIs - returns truw if diCode is same */
554 /*-----------------------------------------------------------------*/
556 ifDiCodeIs (set * cseSet, iCode * ic)
564 for (sl = cseSet; sl; sl = sl->next)
567 if (loop->diCode == ic)
574 /*-----------------------------------------------------------------*/
575 /* ifPointerGet - returns true if the icode is pointer get sym */
576 /*-----------------------------------------------------------------*/
577 DEFSETFUNC (ifPointerGet)
580 V_ARG (operand *, op);
581 iCode *dic = cdp->diCode;
582 operand *left = IC_LEFT (cdp->diCode);
584 if (POINTER_GET (dic) && left->key == op->key)
590 /*-----------------------------------------------------------------*/
591 /* ifPointerSet - returns true if the icode is pointer set sym */
592 /*-----------------------------------------------------------------*/
593 DEFSETFUNC (ifPointerSet)
596 V_ARG (operand *, op);
598 if (POINTER_SET (cdp->diCode) &&
599 IC_RESULT (cdp->diCode)->key == op->key)
605 /*-----------------------------------------------------------------*/
606 /* ifDiCodeIsX - will return 1 if the symbols match */
607 /*-----------------------------------------------------------------*/
608 DEFSETFUNC (ifDiCodeIsX)
613 return cdp->diCode == ic;
617 /*-----------------------------------------------------------------*/
618 /* findBackwardDef - scan backwards to find deinition of operand */
619 /*-----------------------------------------------------------------*/
620 iCode *findBackwardDef(operand *op,iCode *ic)
624 for (lic = ic; lic ; lic = lic->prev) {
625 if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
631 /*-----------------------------------------------------------------*/
632 /* algebraicOpts - does some algebraic optimizations */
633 /*-----------------------------------------------------------------*/
635 algebraicOpts (iCode * ic)
637 /* we don't deal with the following iCodes
648 /* if both operands present & ! IFX */
649 /* then if they are both literal we */
650 /* perform the operation right now */
651 if (IC_RESULT (ic) &&
654 IS_OP_LITERAL (IC_LEFT (ic)) &&
655 IS_OP_LITERAL (IC_RIGHT (ic)))
658 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
661 operandType (IC_RESULT (ic)));
664 SET_RESULT_RIGHT (ic);
668 /* if not ifx & only one operand present */
669 if (IC_RESULT (ic) &&
671 IS_OP_LITERAL (IC_LEFT (ic)) &&
675 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
678 operandType (IC_RESULT (ic)));
681 SET_RESULT_RIGHT (ic);
686 /* a special case : or in short a kludgy solution will think
687 about a better solution over a glass of wine someday */
688 if (ic->op == GET_VALUE_AT_ADDRESS)
691 if (IS_ITEMP (IC_RESULT (ic)) &&
692 IS_TRUE_SYMOP (IC_LEFT (ic)))
696 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
697 IC_RIGHT (ic)->isaddr = 0;
699 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
700 IC_RESULT (ic)->isaddr = 0;
701 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
705 if (IS_ITEMP (IC_LEFT (ic)) &&
706 IS_ITEMP (IC_RESULT (ic)) &&
707 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
708 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
709 !IC_LEFT (ic)->isaddr)
712 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
713 IC_RIGHT (ic)->isaddr = 0;
714 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
715 IC_RESULT (ic)->isaddr = 0;
723 /* depending on the operation */
727 /* if adding the same thing change to left shift by 1 */
728 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
729 !IS_FLOAT (operandType (IC_RESULT (ic))))
732 IC_RIGHT (ic) = operandFromLit (1);
735 /* if addition then check if one of them is a zero */
736 /* if yes turn it into assignmnt */
737 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
738 operandLitValue (IC_LEFT (ic)) == 0.0)
743 SET_ISADDR (IC_RESULT (ic), 0);
744 SET_ISADDR (IC_RIGHT (ic), 0);
747 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
748 operandLitValue (IC_RIGHT (ic)) == 0.0)
752 IC_RIGHT (ic) = IC_LEFT (ic);
754 SET_ISADDR (IC_RIGHT (ic), 0);
755 SET_ISADDR (IC_RESULT (ic), 0);
760 /* if subtracting the the same thing then zero */
761 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
764 IC_RIGHT (ic) = operandFromLit (0);
766 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
767 IC_RESULT (ic)->isaddr = 0;
771 /* if subtraction then check if one of the operand */
772 /* is zero then depending on which operand change */
773 /* to assignment or unary minus */
774 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
775 operandLitValue (IC_RIGHT (ic)) == 0.0)
777 /* right size zero change to assignment */
779 IC_RIGHT (ic) = IC_LEFT (ic);
781 SET_ISADDR (IC_RIGHT (ic), 0);
782 SET_ISADDR (IC_RESULT (ic), 0);
785 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
786 operandLitValue (IC_LEFT (ic)) == 0.0)
788 /* left zero turn into an unary minus */
790 IC_LEFT (ic) = IC_RIGHT (ic);
791 IC_RIGHT (ic) = NULL;
795 /* if multiplication then check if either of */
796 /* them is zero then the result is zero */
797 /* if either of them is one then result is */
800 if (IS_OP_LITERAL (IC_LEFT (ic)))
803 if (operandLitValue (IC_LEFT (ic)) == 0.0)
806 IC_RIGHT (ic) = IC_LEFT (ic);
808 SET_RESULT_RIGHT (ic);
811 if (operandLitValue (IC_LEFT (ic)) == 1.0)
815 SET_RESULT_RIGHT (ic);
820 if (IS_OP_LITERAL (IC_RIGHT (ic)))
823 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
827 SET_RESULT_RIGHT (ic);
831 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
834 IC_RIGHT (ic) = IC_LEFT (ic);
836 SET_RESULT_RIGHT (ic);
842 /* if division by self then 1 */
843 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
846 IC_RIGHT (ic) = operandFromLit (1);
848 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
849 IC_RESULT (ic)->isaddr = 0;
852 /* if this is a division then check if right */
853 /* is one then change it to an assignment */
854 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
855 operandLitValue (IC_RIGHT (ic)) == 1.0)
859 IC_RIGHT (ic) = IC_LEFT (ic);
861 SET_RESULT_RIGHT (ic);
865 /* if both are the same for an comparison operators */
869 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
872 IC_RIGHT (ic) = operandFromLit (1);
874 SET_RESULT_RIGHT (ic);
880 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
883 IC_RIGHT (ic) = operandFromLit (0);
885 SET_RESULT_RIGHT (ic);
890 sym_link *otype = operandType(IC_RIGHT(ic));
891 sym_link *ctype = operandType(IC_LEFT(ic));
892 /* if this is a cast of a literal value */
893 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
894 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
897 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
898 operandLitValue (IC_RIGHT (ic))));
900 SET_ISADDR (IC_RESULT (ic), 0);
902 /* if casting to the same */
903 if (compareType (operandType (IC_RESULT (ic)),
904 operandType (IC_RIGHT (ic))) == 1) {
907 SET_ISADDR (IC_RESULT (ic), 0);
912 if (IS_OP_LITERAL (IC_LEFT (ic)))
916 (operandLitValue (IC_LEFT (ic)) == 0 ?
917 operandFromLit (1) : operandFromLit (0));
919 SET_ISADDR (IC_RESULT (ic), 0);
925 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
926 /*-----------------------------------------------------------------*/
927 /* updateSpillLocation - keeps track of register spill location */
928 /*-----------------------------------------------------------------*/
930 updateSpillLocation (iCode * ic, int induction)
934 if (POINTER_SET (ic))
940 /* for the form true_symbol := iTempNN */
941 if (ASSIGN_ITEMP_TO_SYM (ic) &&
942 !SPIL_LOC (IC_RIGHT (ic))) {
944 setype = getSpec (operandType (IC_RESULT (ic)));
946 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
947 !IS_VOLATILE (setype) &&
948 !IN_FARSPACE (SPEC_OCLS (setype)) &&
949 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
951 wassert(IS_SYMOP(IC_RESULT (ic)));
952 wassert(IS_SYMOP(IC_RIGHT (ic)));
953 SPIL_LOC (IC_RIGHT (ic)) =
954 IC_RESULT (ic)->operand.symOperand;
959 #if 0 /* this needs furthur investigation can save a lot of code */
960 if (ASSIGN_SYM_TO_ITEMP(ic) &&
961 !SPIL_LOC(IC_RESULT(ic))) {
962 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
963 SPIL_LOC (IC_RESULT (ic)) =
964 IC_RIGHT (ic)->operand.symOperand;
967 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
969 if (!SPIL_LOC (IC_RIGHT (ic)) &&
970 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
971 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
973 setype = getSpec (operandType (IC_RESULT (ic)));
975 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
976 !IS_VOLATILE (setype) &&
977 !IN_FARSPACE (SPEC_OCLS (setype)) &&
978 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
980 SPIL_LOC (IC_RIGHT (ic)) =
981 SPIL_LOC (IC_RESULT (ic));
983 /* special case for inductions */
985 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
986 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
987 !SPIL_LOC(IC_RESULT(ic))) {
988 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
992 /*-----------------------------------------------------------------*/
993 /* setUsesDef - sets the uses def bitvector for a given operand */
994 /*-----------------------------------------------------------------*/
996 setUsesDefs (operand * op, bitVect * bdefs,
997 bitVect * idefs, bitVect ** oud)
999 /* compute the definitions alive at this point */
1000 bitVect *adefs = bitVectUnion (bdefs, idefs);
1002 /* of these definitions find the ones that are */
1003 /* for this operand */
1004 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1006 /* these are the definitions that this operand can use */
1007 op->usesDefs = adefs;
1009 /* the out defs is an union */
1010 *oud = bitVectUnion (*oud, adefs);
1013 /*-----------------------------------------------------------------*/
1014 /* unsetDefsAndUses - clear this operation for the operands */
1015 /*-----------------------------------------------------------------*/
1017 unsetDefsAndUses (iCode * ic)
1019 if (ic->op == JUMPTABLE)
1022 /* take away this definition from the def chain of the */
1023 /* result & take away from use set of the operands */
1026 /* turn off def set */
1027 if (IS_SYMOP (IC_RESULT (ic)))
1029 if (!POINTER_SET (ic))
1030 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1032 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1034 /* turn off the useSet for the operands */
1035 if (IS_SYMOP (IC_LEFT (ic)))
1036 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1038 if (IS_SYMOP (IC_RIGHT (ic)))
1039 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1042 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1043 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1046 /*-----------------------------------------------------------------*/
1047 /* ifxOptimize - changes ifx conditions if it can */
1048 /*-----------------------------------------------------------------*/
1050 ifxOptimize (iCode * ic, set * cseSet,
1052 eBBlock * ebb, int *change,
1053 eBBlock ** ebbs, int count)
1058 /* if the condition can be replaced */
1062 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1065 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1070 /* if the conditional is a literal then */
1071 if (IS_OP_LITERAL (IC_COND (ic)))
1074 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1077 /* change to a goto */
1079 IC_LABEL (ic) = IC_TRUE (ic);
1086 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1089 IC_LABEL (ic) = IC_FALSE (ic);
1095 /* then kill this if condition */
1096 remiCodeFromeBBlock (ebb, ic);
1100 /* now we need to recompute the control flow */
1101 /* since the control flow has changed */
1102 /* this is very expensive but it does not happen */
1103 /* too often, if it does happen then the user pays */
1105 computeControlFlow (ebbs, count, 1);
1106 if (!options.lessPedantic) {
1107 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1112 /* if there is only one successor and that successor
1113 is the same one we are conditionally going to then
1114 we can remove this conditional statement */
1115 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1116 if (elementsInSet (ebb->succList) == 1 &&
1117 isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1120 remiCodeFromeBBlock (ebb, ic);
1121 computeControlFlow (ebbs, count, 1);
1122 if (!options.lessPedantic) {
1123 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1129 /* if it remains an IFX the update the use Set */
1130 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1131 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1135 /*-----------------------------------------------------------------*/
1136 /* diCodeForSym - finds the definiting instruction for a symbol */
1137 /*-----------------------------------------------------------------*/
1138 DEFSETFUNC (diCodeForSym)
1141 V_ARG (operand *, sym);
1142 V_ARG (iCode **, dic);
1144 /* if already found */
1148 /* if not if this is the defining iCode */
1149 if (sym->key == cdp->key)
1158 /*-----------------------------------------------------------------*/
1159 /* constFold - does some constant folding */
1160 /*-----------------------------------------------------------------*/
1162 constFold (iCode * ic, set * cseSet)
1166 /* this routine will change
1172 /* deal with only + & - */
1173 if (ic->op != '+' &&
1177 /* this check is a hueristic to prevent live ranges
1178 from becoming too long */
1179 if (IS_PTR (operandType (IC_RESULT (ic))))
1182 /* check if operation with a literal */
1183 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1186 /* check if we can find a definition for the
1188 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1191 /* check that this is also a +/- */
1192 if (dic->op != '+' && dic->op != '-')
1195 /* with a literal */
1196 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1199 /* find the definition of the left operand
1200 of dic.then check if this defined with a
1201 get_pointer return 0 if the pointer size is
1202 less than 2 (MCS51 specific) */
1203 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1206 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1209 /* it is if the operations are the same */
1210 /* the literal parts need to be added */
1211 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1212 if (ic->op == dic->op)
1213 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1214 operandLitValue (IC_RIGHT (dic)));
1216 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1217 operandLitValue (IC_RIGHT (dic)));
1219 if (IS_ITEMP (IC_RESULT (ic)))
1221 SPIL_LOC (IC_RESULT (ic)) = NULL;
1222 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1229 /*-----------------------------------------------------------------*/
1230 /* deleteGetPointers - called when a pointer is passed as parm */
1231 /* will delete from cseSet all get pointers computed from this */
1232 /* pointer. A simple ifOperandsHave is not good enough here */
1233 /*-----------------------------------------------------------------*/
1235 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1237 set *compItems = NULL;
1242 if (!*cseSet && !*pss)
1245 /* first find all items computed from this operand .
1246 This done fairly simply go thru the list and find
1247 those that are computed by arthimetic with this
1249 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1251 if (IS_ARITHMETIC_OP (cdp->diCode))
1253 if (isOperandEqual (IC_LEFT (cdp->diCode), op) ||
1254 isOperandEqual (IC_RIGHT (cdp->diCode), op))
1256 /* save it in our list of items */
1257 addSet (&compItems, IC_RESULT (cdp->diCode));
1259 /* also check for those computed from our computed
1260 list . This will take care of situations like
1261 iTemp1 = iTemp0 + 8;
1262 iTemp2 = iTemp1 + 8; */
1263 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1264 (insetwithFunc)isOperandEqual) ||
1265 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1266 (insetwithFunc)isOperandEqual))
1268 addSet (&compItems, IC_RESULT (cdp->diCode));
1273 /* now delete all pointer gets with this op */
1274 deleteItemIf (cseSet, ifPointerGet, op);
1275 deleteItemIf (pss, ifPointerSet, op);
1277 /* set the bit vector used by dataFlow computation later */
1278 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key);
1279 /* now for the computed items */
1280 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1282 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1283 deleteItemIf (cseSet, ifPointerGet, cop);
1284 deleteItemIf (pss, ifPointerSet, cop);
1288 /*-----------------------------------------------------------------*/
1289 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1290 /* dfnum > supplied */
1291 /*-----------------------------------------------------------------*/
1292 DEFSETFUNC (delGetPointerSucc)
1294 eBBlock *ebp = item;
1295 V_ARG (operand *, op);
1302 if (ebp->dfnum > dfnum)
1304 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1307 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1310 /*-----------------------------------------------------------------*/
1311 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1312 /*-----------------------------------------------------------------*/
1314 fixUpTypes (iCode * ic)
1316 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1318 /* if (TARGET_IS_DS390) */
1319 if (options.model == MODEL_FLAT24)
1325 /* for pointer_gets if the types of result & left r the
1326 same then change it type of result to next */
1328 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1330 setOperandType (IC_RESULT (ic), t2->next);
1334 /*-----------------------------------------------------------------*/
1335 /* isSignedOp - will return 1 if sign is important to operation */
1336 /*-----------------------------------------------------------------*/
1337 static int isSignedOp (iCode *ic)
1358 case GET_VALUE_AT_ADDRESS:
1384 /*-----------------------------------------------------------------*/
1385 /* cseBBlock - common subexpression elimination for basic blocks */
1386 /* this is the hackiest kludgiest routine in the whole */
1387 /* system. also the most important, since almost all */
1388 /* data flow related information is computed by it */
1389 /*-----------------------------------------------------------------*/
1391 cseBBlock (eBBlock * ebb, int computeOnly,
1392 eBBlock ** ebbs, int count)
1398 set *ptrSetSet = NULL;
1400 /* if this block is not reachable */
1404 /* set of common subexpressions */
1405 cseSet = setFromSet (ebb->inExprs);
1407 /* these will be computed by this routine */
1408 setToNull ((void **) &ebb->outDefs);
1409 setToNull ((void **) &ebb->defSet);
1410 setToNull ((void **) &ebb->usesDefs);
1411 setToNull ((void **) &ebb->ptrsSet);
1412 setToNull ((void **) &ebb->addrOf);
1413 setToNull ((void **) &ebb->ldefs);
1415 ebb->outDefs = bitVectCopy (ebb->inDefs);
1416 bitVectDefault = iCodeKey;
1417 ebb->defSet = newBitVect (iCodeKey);
1418 ebb->usesDefs = newBitVect (iCodeKey);
1420 /* for all the instructions in this block do */
1421 for (ic = ebb->sch; ic; ic = ic->next)
1428 ic->eBBlockNum = ebb->bbnum;
1433 /* if this is an assignment from true symbol
1434 to a temp then do pointer post inc/dec optimzation */
1435 if (ic->op == '=' && !POINTER_SET (ic) &&
1436 IS_PTR (operandType (IC_RESULT (ic))))
1438 ptrPostIncDecOpt (ic);
1441 /* clear the def & use chains for the operands involved */
1442 /* in this operation . since it can change due to opts */
1443 unsetDefsAndUses (ic);
1445 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1447 /* add to defSet of the symbol */
1448 OP_DEFS(IC_RESULT (ic))=
1449 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1450 /* add to the definition set of this block */
1451 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1452 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1453 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1454 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1455 /* delete global variables from the cseSet
1456 since they can be modified by the function call */
1457 deleteItemIf (&cseSet, ifDefGlobal);
1459 /* and also itemps assigned from globals */
1460 deleteItemIf (&cseSet, ifAssignedFromGlobal);
1462 /* delete all getpointer iCodes from cseSet, this should
1463 be done only for global arrays & pointers but at this
1464 point we don't know if globals, so to be safe do all */
1465 deleteItemIf (&cseSet, ifAnyGetPointer);
1468 /* for pcall & ipush we need to add to the useSet */
1469 if ((ic->op == PCALL ||
1473 IS_SYMOP (IC_LEFT (ic)))
1476 /* check if they can be replaced */
1480 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1482 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1484 /* the lookup could have changed it */
1485 if (IS_SYMOP (IC_LEFT (ic)))
1487 OP_USES(IC_LEFT (ic))=
1488 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1489 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1490 ebb->outDefs, &ebb->usesDefs);
1494 /* if we a sending a pointer as a parameter
1495 then kill all cse since the pointed to item
1496 might be changed in the function being called */
1497 if ((ic->op == IPUSH || ic->op == SEND) &&
1498 IS_PTR (operandType (IC_LEFT (ic))))
1500 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1501 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1502 for (i = 0; i < count; ebbs[i++]->visited = 0);
1503 applyToSet (ebb->succList, delGetPointerSucc,
1504 IC_LEFT (ic), ebb->dfnum);
1509 /* if jumptable then mark the usage */
1510 if (ic->op == JUMPTABLE)
1512 OP_USES(IC_JTCOND (ic))=
1513 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1514 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1515 ebb->outDefs, &ebb->usesDefs);
1522 /* do some algebraic optimizations if possible */
1524 while (constFold (ic, cseSet));
1527 if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1529 setOperandType (IC_LEFT (ic),
1530 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1534 if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1536 setOperandType (IC_RESULT (ic),
1537 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1540 /* if this is a condition statment then */
1541 /* check if the condition can be replaced */
1544 ifxOptimize (ic, cseSet, computeOnly,
1550 /* if the assignment & result is a temp */
1551 /* see if we can replace it */
1555 /* update the spill location for this */
1556 updateSpillLocation (ic,0);
1558 if (POINTER_SET (ic) &&
1559 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1562 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1563 if (pdop && IS_ITEMP (pdop) && !computeOnly)
1564 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1568 checkSign = isSignedOp(ic);
1570 /* do the operand lookup i.e. for both the */
1571 /* right & left operand : check the cseSet */
1572 /* to see if they have been replaced if yes */
1573 /* then replace them with those from cseSet */
1575 /* and left is a symbol */
1576 if (IS_SYMOP (IC_LEFT (ic)) &&
1577 !computeOnly && ic->op != ADDRESS_OF)
1581 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1584 if (POINTER_GET (ic))
1586 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1588 /* some non dominating block does POINTER_SET with
1589 this variable .. unsafe to remove any POINTER_GETs */
1590 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1591 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1592 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1595 /* check if there is a pointer set
1596 for the same pointer visible if yes
1597 then change this into an assignment */
1599 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1600 !bitVectBitValue (ebb->ptrsSet, pdop->key))
1603 IC_LEFT (ic) = NULL;
1604 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1605 SET_ISADDR (IC_RESULT (ic), 0);
1611 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1618 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1622 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1624 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1629 /* if left or right changed then do algebraic */
1633 while (constFold (ic, cseSet));
1636 /* if after all this it becomes a assignment to self
1637 then delete it and continue */
1638 if (ASSIGNMENT_TO_SELF (ic))
1640 remiCodeFromeBBlock (ebb, ic);
1644 /* now we will check to see if the entire */
1645 /* operation has been performed before */
1646 /* and is available */
1647 /* don't do assignments they will be killed */
1648 /* by dead code elimination if required do */
1649 /* it only if result is a temporary */
1651 if (!(POINTER_GET (ic) &&
1652 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1653 isOperandVolatile (IC_LEFT (ic), TRUE) ||
1654 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
1656 IS_ITEMP (IC_RESULT (ic)) &&
1659 applyToSet (cseSet, findPrevIc, ic, &pdic);
1660 if (pdic && compareType (operandType (IC_RESULT (pdic)),
1661 operandType (IC_RESULT (ic))) != 1)
1663 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
1667 /* Alternate code */
1668 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
1669 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
1670 /* Mmm, found an equivalent pointer get at a lower level.
1671 This could be a loop however with the same pointer set
1674 /* if previous definition found change this to an assignment */
1677 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
1678 SET_ISADDR(IC_RESULT(ic),0);
1679 SET_ISADDR(IC_RIGHT (ic),0);
1683 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
1684 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
1685 addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
1689 /* if assignment to a parameter which is not
1690 mine and type is a pointer then delete
1691 pointerGets to take care of aliasing */
1692 if (ASSIGNMENT (ic) &&
1693 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1694 IS_PTR (operandType (IC_RESULT (ic))))
1696 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1697 for (i = 0; i < count; ebbs[i++]->visited = 0);
1698 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1699 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1702 /* if this is a pointerget then see if we can replace
1703 this with a previously assigned pointer value */
1704 if (POINTER_GET (ic) &&
1705 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1706 isOperandVolatile (IC_LEFT (ic), TRUE)))
1709 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
1710 /* if we find it then locally replace all
1711 references to the result with what we assigned */
1714 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
1718 /* delete from the cseSet anything that has */
1719 /* operands matching the result of this */
1720 /* except in case of pointer access */
1721 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1723 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
1724 /* delete any previous definitions */
1725 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
1729 /* add the left & right to the defUse set */
1730 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
1732 OP_USES(IC_LEFT (ic))=
1733 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1734 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1738 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
1740 OP_USES(IC_RIGHT (ic))=
1741 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1742 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1746 /* for the result it is special case, put the result */
1747 /* in the defuseSet if it a pointer or array access */
1748 if (POINTER_SET (defic))
1750 OP_USES(IC_RESULT (ic))=
1751 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1752 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1753 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
1754 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
1755 /* delete from inexpressions of all successors which
1756 have dfNum > than this block */
1757 for (i = 0; i < count; ebbs[i++]->visited = 0);
1758 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
1760 /* delete from cseSet all other pointer sets
1762 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
1763 /* add to the local pointerset set */
1764 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
1767 /* add the result to defintion set */ if (IC_RESULT (ic))
1769 OP_DEFS(IC_RESULT (ic))=
1770 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1771 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1772 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1773 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1777 /* if this is an addressof instruction then */
1778 /* put the symbol in the address of list & */
1779 /* delete it from the cseSet */
1780 if (defic->op == ADDRESS_OF)
1782 addSetHead (&ebb->addrOf, IC_LEFT (ic));
1783 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
1787 setToNull ((void **) &ebb->outExprs);
1788 ebb->outExprs = cseSet;
1789 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
1790 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
1794 /*-----------------------------------------------------------------*/
1795 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
1796 /*-----------------------------------------------------------------*/
1798 cseAllBlocks (eBBlock ** ebbs, int count)
1803 /* if optimization turned off */
1805 for (i = 0; i < count; i++)
1806 change += cseBBlock (ebbs[i], FALSE, ebbs, count);