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 /*-----------------------------------------------------------------*/
85 /* replaceAllSymBySym - replaces all operands by operand in an */
86 /* instruction chain */
87 /*-----------------------------------------------------------------*/
89 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
93 for (lic = ic; lic; lic = lic->next)
97 /* do the special cases first */
101 IC_COND (lic)->key == from->key)
104 bitVectUnSetBit (OP_USES (from), lic->key);
105 OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key);
106 siaddr = IC_COND (lic)->isaddr;
107 IC_COND (lic) = operandFromOperand (to);
108 IC_COND (lic)->isaddr = siaddr;
114 if (lic->op == JUMPTABLE)
117 IC_JTCOND (lic)->key == from->key)
120 bitVectUnSetBit (OP_USES (from), lic->key);
121 OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key);
122 siaddr = IC_COND (lic)->isaddr;
123 IC_JTCOND (lic) = operandFromOperand (to);
124 IC_JTCOND (lic)->isaddr = siaddr;
130 if (IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
132 /* maintain du chains */
133 if (POINTER_SET (lic))
135 bitVectUnSetBit (OP_USES (from), lic->key);
136 OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key);
138 /* also check if the "from" was in the non-dominating
139 pointer sets and replace it with "to" in the bitVector */
140 if (bitVectBitValue (*ndpset, from->key))
142 bitVectUnSetBit (*ndpset, from->key);
143 bitVectSetBit (*ndpset, to->key);
149 bitVectUnSetBit (OP_DEFS (from), lic->key);
150 OP_DEFS (to) = bitVectSetBit (OP_DEFS (to), lic->key);
152 siaddr = IC_RESULT (lic)->isaddr;
153 IC_RESULT (lic) = operandFromOperand (to);
154 IC_RESULT (lic)->isaddr = siaddr;
158 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
160 bitVectUnSetBit (OP_USES (from), lic->key);
161 OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key);
162 siaddr = IC_RIGHT (lic)->isaddr;
163 IC_RIGHT (lic) = operandFromOperand (to);
164 IC_RIGHT (lic)->isaddr = siaddr;
168 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
170 bitVectUnSetBit (OP_USES (from), lic->key);
171 OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key);
172 siaddr = IC_LEFT (lic)->isaddr;
173 IC_LEFT (lic) = operandFromOperand (to);
174 IC_LEFT (lic)->isaddr = siaddr;
179 /*-----------------------------------------------------------------*/
180 /* iCodeKeyIs - if the icode keys match then return 1 */
181 /*-----------------------------------------------------------------*/
182 DEFSETFUNC (iCodeKeyIs)
187 if (cdp->diCode->key == key)
193 /*-----------------------------------------------------------------*/
194 /* removeFromInExprs - removes an icode from inexpressions */
195 /*-----------------------------------------------------------------*/
196 DEFSETFUNC (removeFromInExprs)
200 V_ARG (operand *, from);
201 V_ARG (operand *, to);
202 V_ARG (eBBlock *, cbp);
208 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
209 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
210 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
212 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
216 /*-----------------------------------------------------------------*/
217 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
218 /*-----------------------------------------------------------------*/
220 isGlobalInNearSpace (operand * op)
222 sym_link *type = getSpec (operandType (op));
223 /* this is 8051 specific: optimization
224 suggested by Jean-Louis VERN, with 8051s we have no
225 advantage of putting variables in near space into
227 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
228 IN_DIRSPACE (SPEC_OCLS (type)))
234 /*-----------------------------------------------------------------*/
235 /* findCheaperOp - cseBBlock support routine, will check to see if */
236 /* we have a operand previously defined */
237 /*-----------------------------------------------------------------*/
238 DEFSETFUNC (findCheaperOp)
241 V_ARG (operand *, cop);
242 V_ARG (operand **, opp);
244 /* if we have already found it */
248 /* not found it yet check if this is the one */
249 /* and this is not the defining one */
250 if (cop->key == cdp->key)
253 /* do a special check this will help in */
254 /* constant propagation & dead code elim */
255 /* for assignments only */
256 if (cdp->diCode->op == '=') {
257 /* if the result is volatile then return result */
258 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
259 *opp = IC_RESULT (cdp->diCode);
261 /* if this is a straight assignment and
262 left is a temp then prefer the temporary to the
264 if (!POINTER_SET (cdp->diCode) &&
265 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
266 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
267 *opp = IC_RESULT (cdp->diCode);
269 /* if straight assignement && and both
270 are temps then prefer the one that
271 will not need extra space to spil, also
272 take into consideration if right side
273 an induction variable
275 if (!POINTER_SET (cdp->diCode) &&
276 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
277 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
278 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
279 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
280 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
281 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
282 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
283 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
284 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
285 *opp = IC_RESULT (cdp->diCode);
287 *opp = IC_RIGHT (cdp->diCode);
291 *opp = IC_RESULT (cdp->diCode);
294 /* if this is an assign to a temp. then check
295 if the right side is this then return this */
296 if (IS_TRUE_SYMOP (cop) &&
297 cdp->diCode->op == '=' &&
298 !POINTER_SET (cdp->diCode) &&
299 cop->key == IC_RIGHT (cdp->diCode)->key &&
300 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
301 IS_ITEMP (IC_RESULT (cdp->diCode)))
302 *opp = IC_RESULT (cdp->diCode);
305 (isOperandLiteral(*opp) ||
306 getSize(operandType(*opp)) == getSize(operandType(cop)) ||
307 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
308 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp))))))
311 if ((isGlobalInNearSpace (cop) &&
312 !isOperandLiteral (*opp)) ||
313 isOperandVolatile (*opp, FALSE)
320 if (cop->key == (*opp)->key)
326 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
328 *opp = operandFromOperand (*opp);
329 (*opp)->isaddr = cop->isaddr;
339 /*-----------------------------------------------------------------*/
340 /* findPointerSet - finds the right side of a pointer set op */
341 /*-----------------------------------------------------------------*/
342 DEFSETFUNC (findPointerSet)
345 V_ARG (operand *, op);
346 V_ARG (operand **, opp);
347 V_ARG (operand *, rop);
349 if (POINTER_SET (cdp->diCode) &&
350 IC_RESULT (cdp->diCode)->key == op->key &&
351 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
352 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
353 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
354 getSize (operandType (rop)))
356 *opp = IC_RIGHT (cdp->diCode);
363 /*-----------------------------------------------------------------*/
364 /* findPrevIc - cseBBlock support function will return the iCode */
365 /* which matches the current one */
366 /*-----------------------------------------------------------------*/
367 DEFSETFUNC (findPrevIc)
371 V_ARG (iCode **, icp);
373 /* if already found */
377 /* if the iCodes are the same */
378 if (isiCodeEqual (ic, cdp->diCode) &&
379 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
385 /* if iCodes are not the same */
386 /* see the operands maybe interchanged */
387 if (ic->op == cdp->diCode->op &&
388 (ic->op == '+' || ic->op == '*') &&
389 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
390 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
399 /*-------------------------------------------------------------------*/
400 /* ifAssignedFromGlobal - if definition is an assignment from global */
401 /*-------------------------------------------------------------------*/
402 DEFSETFUNC (ifAssignedFromGlobal)
405 iCode *dic=cdp->diCode;
407 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
413 /*-----------------------------------------------------------------*/
414 /* ifDefGlobal - if definition is global */
415 /*-----------------------------------------------------------------*/
416 DEFSETFUNC (ifDefGlobal)
420 return (isOperandGlobal (cdp->sym));
423 /*-----------------------------------------------------------------*/
424 /* ifAnyGetPointer - if get pointer icode */
425 /*-----------------------------------------------------------------*/
426 DEFSETFUNC (ifAnyGetPointer)
430 if (cdp->diCode && POINTER_GET (cdp->diCode))
435 /*-----------------------------------------------------------------*/
436 /* ifOperandsHave - if any of the operand are the same as this */
437 /*-----------------------------------------------------------------*/
438 DEFSETFUNC (ifOperandsHave)
441 V_ARG (operand *, op);
444 if (IC_LEFT (cdp->diCode) &&
445 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
446 IC_LEFT (cdp->diCode)->key == op->key)
449 if (IC_RIGHT (cdp->diCode) &&
450 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
451 IC_RIGHT (cdp->diCode)->key == op->key)
454 /* or if any of the operands are volatile */
455 if (IC_LEFT (cdp->diCode) &&
456 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
459 if (IC_RIGHT (cdp->diCode) &&
460 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
464 if (IC_RESULT (cdp->diCode) &&
465 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
471 /*-----------------------------------------------------------------*/
472 /* ifDefSymIs - if a definition is found in the set */
473 /*-----------------------------------------------------------------*/
475 ifDefSymIs (set * cseSet, operand * sym)
480 if (!sym || !IS_SYMOP (sym))
482 for (sl = cseSet; sl; sl = sl->next)
485 if (loop->sym->key == sym->key)
492 /*-----------------------------------------------------------------*/
493 /* ifDefSymIsX - will return 1 if the symbols match */
494 /*-----------------------------------------------------------------*/
495 DEFSETFUNC (ifDefSymIsX)
498 V_ARG (operand *, op);
501 return cdp->sym->key == op->key;
503 return (isOperandEqual (cdp->sym, op));
508 /*-----------------------------------------------------------------*/
509 /* ifDiCodeIs - returns truw if diCode is same */
510 /*-----------------------------------------------------------------*/
512 ifDiCodeIs (set * cseSet, iCode * ic)
520 for (sl = cseSet; sl; sl = sl->next)
523 if (loop->diCode == ic)
530 /*-----------------------------------------------------------------*/
531 /* ifPointerGet - returns true if the icode is pointer get sym */
532 /*-----------------------------------------------------------------*/
533 DEFSETFUNC (ifPointerGet)
536 V_ARG (operand *, op);
537 iCode *dic = cdp->diCode;
538 operand *left = IC_LEFT (cdp->diCode);
540 if (POINTER_GET (dic) && left->key == op->key)
546 /*-----------------------------------------------------------------*/
547 /* ifPointerSet - returns true if the icode is pointer set sym */
548 /*-----------------------------------------------------------------*/
549 DEFSETFUNC (ifPointerSet)
552 V_ARG (operand *, op);
554 if (POINTER_SET (cdp->diCode) &&
555 IC_RESULT (cdp->diCode)->key == op->key)
561 /*-----------------------------------------------------------------*/
562 /* ifDiCodeIsX - will return 1 if the symbols match */
563 /*-----------------------------------------------------------------*/
564 DEFSETFUNC (ifDiCodeIsX)
569 return cdp->diCode == ic;
573 /*-----------------------------------------------------------------*/
574 /* algebraicOpts - does some algebraic optimizations */
575 /*-----------------------------------------------------------------*/
577 algebraicOpts (iCode * ic)
579 /* we don't deal with the following iCodes
590 /* if both operands present & ! IFX */
591 /* then if they are both literal we */
592 /* perform the operation right now */
593 if (IC_RESULT (ic) &&
596 IS_OP_LITERAL (IC_LEFT (ic)) &&
597 IS_OP_LITERAL (IC_RIGHT (ic)))
600 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
603 operandType (IC_RESULT (ic)));
606 SET_RESULT_RIGHT (ic);
610 /* if not ifx & only one operand present */
611 if (IC_RESULT (ic) &&
613 IS_OP_LITERAL (IC_LEFT (ic)) &&
617 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
620 operandType (IC_RESULT (ic)));
623 SET_RESULT_RIGHT (ic);
628 /* a special case : or in short a kludgy solution will think
629 about a better solution over a glass of wine someday */
630 if (ic->op == GET_VALUE_AT_ADDRESS)
633 if (IS_ITEMP (IC_RESULT (ic)) &&
634 IS_TRUE_SYMOP (IC_LEFT (ic)))
638 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
639 IC_RIGHT (ic)->isaddr = 0;
641 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
642 IC_RESULT (ic)->isaddr = 0;
643 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
647 if (IS_ITEMP (IC_LEFT (ic)) &&
648 IS_ITEMP (IC_RESULT (ic)) &&
649 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
650 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
651 !IC_LEFT (ic)->isaddr)
654 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
655 IC_RIGHT (ic)->isaddr = 0;
656 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
657 IC_RESULT (ic)->isaddr = 0;
665 /* depending on the operation */
669 /* if adding the same thing change to left shift by 1 */
670 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
671 !IS_FLOAT (operandType (IC_RESULT (ic))))
674 IC_RIGHT (ic) = operandFromLit (1);
677 /* if addition then check if one of them is a zero */
678 /* if yes turn it into assignmnt */
679 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
680 operandLitValue (IC_LEFT (ic)) == 0.0)
685 SET_ISADDR (IC_RESULT (ic), 0);
686 SET_ISADDR (IC_RIGHT (ic), 0);
689 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
690 operandLitValue (IC_RIGHT (ic)) == 0.0)
694 IC_RIGHT (ic) = IC_LEFT (ic);
696 SET_ISADDR (IC_RIGHT (ic), 0);
697 SET_ISADDR (IC_RESULT (ic), 0);
702 /* if subtracting the the same thing then zero */
703 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
706 IC_RIGHT (ic) = operandFromLit (0);
708 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
709 IC_RESULT (ic)->isaddr = 0;
713 /* if subtraction then check if one of the operand */
714 /* is zero then depending on which operand change */
715 /* to assignment or unary minus */
716 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
717 operandLitValue (IC_RIGHT (ic)) == 0.0)
719 /* right size zero change to assignment */
721 IC_RIGHT (ic) = IC_LEFT (ic);
723 SET_ISADDR (IC_RIGHT (ic), 0);
724 SET_ISADDR (IC_RESULT (ic), 0);
727 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
728 operandLitValue (IC_LEFT (ic)) == 0.0)
730 /* left zero turn into an unary minus */
732 IC_LEFT (ic) = IC_RIGHT (ic);
733 IC_RIGHT (ic) = NULL;
737 /* if multiplication then check if either of */
738 /* them is zero then the result is zero */
739 /* if either of them is one then result is */
742 if (IS_OP_LITERAL (IC_LEFT (ic)))
745 if (operandLitValue (IC_LEFT (ic)) == 0.0)
748 IC_RIGHT (ic) = IC_LEFT (ic);
750 SET_RESULT_RIGHT (ic);
753 if (operandLitValue (IC_LEFT (ic)) == 1.0)
757 SET_RESULT_RIGHT (ic);
762 if (IS_OP_LITERAL (IC_RIGHT (ic)))
765 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
769 SET_RESULT_RIGHT (ic);
773 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
776 IC_RIGHT (ic) = IC_LEFT (ic);
778 SET_RESULT_RIGHT (ic);
784 /* if division by self then 1 */
785 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
788 IC_RIGHT (ic) = operandFromLit (1);
790 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
791 IC_RESULT (ic)->isaddr = 0;
793 /* if this is a division then check if right */
794 /* is one then change it to an assignment */
795 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
796 operandLitValue (IC_RIGHT (ic)) == 1.0)
800 IC_RIGHT (ic) = IC_LEFT (ic);
802 SET_RESULT_RIGHT (ic);
806 /* if both are the same for an comparison operators */
810 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
813 IC_RIGHT (ic) = operandFromLit (1);
815 SET_RESULT_RIGHT (ic);
821 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
824 IC_RIGHT (ic) = operandFromLit (0);
826 SET_RESULT_RIGHT (ic);
831 sym_link *otype = operandType(IC_RIGHT(ic));
832 sym_link *ctype = operandType(IC_LEFT(ic));
833 /* if this is a cast of a literal value */
834 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
835 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
838 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
839 operandLitValue (IC_RIGHT (ic))));
841 SET_ISADDR (IC_RESULT (ic), 0);
843 /* if casting to the same */
844 if (compareType (operandType (IC_RESULT (ic)),
845 operandType (IC_RIGHT (ic))) == 1) {
848 SET_ISADDR (IC_RESULT (ic), 0);
853 if (IS_OP_LITERAL (IC_LEFT (ic)))
857 (operandLitValue (IC_LEFT (ic)) == 0 ?
858 operandFromLit (1) : operandFromLit (0));
860 SET_ISADDR (IC_RESULT (ic), 0);
866 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
867 /*-----------------------------------------------------------------*/
868 /* updateSpillLocation - keeps track of register spill location */
869 /*-----------------------------------------------------------------*/
871 updateSpillLocation (iCode * ic, int induction)
876 if (POINTER_SET (ic))
882 /* for the form true_symbol := iTempNN */
883 if (ASSIGN_ITEMP_TO_SYM (ic) &&
884 !SPIL_LOC (IC_RIGHT (ic))) {
886 setype = getSpec (operandType (IC_RESULT (ic)));
888 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
889 !IS_VOLATILE (setype) &&
890 !IN_FARSPACE (SPEC_OCLS (setype)) &&
891 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
893 SPIL_LOC (IC_RIGHT (ic)) =
894 IC_RESULT (ic)->operand.symOperand;
897 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
899 if (!SPIL_LOC (IC_RIGHT (ic)) &&
900 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
901 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
903 setype = getSpec (operandType (IC_RESULT (ic)));
905 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
906 !IS_VOLATILE (setype) &&
907 !IN_FARSPACE (SPEC_OCLS (setype)) &&
908 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
910 SPIL_LOC (IC_RIGHT (ic)) =
911 SPIL_LOC (IC_RESULT (ic));
913 /* special case for inductions */
915 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
916 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
917 !SPIL_LOC(IC_RESULT(ic))) {
918 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
922 /*-----------------------------------------------------------------*/
923 /* setUsesDef - sets the uses def bitvector for a given operand */
924 /*-----------------------------------------------------------------*/
926 setUsesDefs (operand * op, bitVect * bdefs,
927 bitVect * idefs, bitVect ** oud)
929 /* compute the definitions alive at this point */
930 bitVect *adefs = bitVectUnion (bdefs, idefs);
932 /* of these definitions find the ones that are */
933 /* for this operand */
934 adefs = bitVectIntersect (adefs, OP_DEFS (op));
936 /* these are the definitions that this operand can use */
937 op->usesDefs = adefs;
939 /* the out defs is an union */
940 *oud = bitVectUnion (*oud, adefs);
943 /*-----------------------------------------------------------------*/
944 /* unsetDefsAndUses - clear this operation for the operands */
945 /*-----------------------------------------------------------------*/
947 unsetDefsAndUses (iCode * ic)
949 if (ic->op == JUMPTABLE)
952 /* take away this definition from the def chain of the */
953 /* result & take away from use set of the operands */
956 /* turn off def set */
957 if (IS_SYMOP (IC_RESULT (ic)))
959 if (!POINTER_SET (ic))
960 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
962 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
964 /* turn off the useSet for the operands */
965 if (IS_SYMOP (IC_LEFT (ic)))
966 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
968 if (IS_SYMOP (IC_RIGHT (ic)))
969 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
972 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
973 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
976 /*-----------------------------------------------------------------*/
977 /* ifxOptimize - changes ifx conditions if it can */
978 /*-----------------------------------------------------------------*/
980 ifxOptimize (iCode * ic, set * cseSet,
982 eBBlock * ebb, int *change,
983 eBBlock ** ebbs, int count)
988 /* if the condition can be replaced */
992 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop);
1000 /* if the conditional is a literal then */
1001 if (IS_OP_LITERAL (IC_COND (ic)))
1004 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1007 /* change to a goto */
1009 IC_LABEL (ic) = IC_TRUE (ic);
1016 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1019 IC_LABEL (ic) = IC_FALSE (ic);
1025 /* then kill this if condition */
1026 remiCodeFromeBBlock (ebb, ic);
1030 /* now we need to recompute the control flow */
1031 /* since the control flow has changed */
1032 /* this is very expensive but it does not happen */
1033 /* too often, if it does happen then the user pays */
1035 computeControlFlow (ebbs, count, 1);
1036 if (!options.lessPedantic) {
1037 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1042 /* if there is only one successor and that successor
1043 is the same one we are conditionally going to then
1044 we can remove this conditional statement */
1045 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1046 if (elementsInSet (ebb->succList) == 1 &&
1047 isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1050 remiCodeFromeBBlock (ebb, ic);
1051 computeControlFlow (ebbs, count, 1);
1052 if (!options.lessPedantic) {
1053 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1059 /* if it remains an IFX the update the use Set */
1060 OP_USES (IC_COND (ic)) = bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1061 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1065 /*-----------------------------------------------------------------*/
1066 /* diCodeForSym - finds the definiting instruction for a symbol */
1067 /*-----------------------------------------------------------------*/
1068 DEFSETFUNC (diCodeForSym)
1071 V_ARG (operand *, sym);
1072 V_ARG (iCode **, dic);
1074 /* if already found */
1078 /* if not if this is the defining iCode */
1079 if (sym->key == cdp->key)
1088 /*-----------------------------------------------------------------*/
1089 /* constFold - does some constant folding */
1090 /*-----------------------------------------------------------------*/
1092 constFold (iCode * ic, set * cseSet)
1096 /* this routine will change
1102 /* deal with only + & - */
1103 if (ic->op != '+' &&
1107 /* this check is a hueristic to prevent live ranges
1108 from becoming too long */
1109 if (IS_PTR (operandType (IC_RESULT (ic))))
1112 /* check if operation with a literal */
1113 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1116 /* check if we can find a definition for the
1118 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1121 /* check that this is also a +/- */
1122 if (dic->op != '+' && dic->op != '-')
1125 /* with a literal */
1126 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1129 /* find the definition of the left operand
1130 of dic.then check if this defined with a
1131 get_pointer return 0 if the pointer size is
1132 less than 2 (MCS51 specific) */
1133 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1136 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1139 /* it is if the operations are the same */
1140 /* the literal parts need to be added */
1141 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1142 if (ic->op == dic->op)
1143 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1144 operandLitValue (IC_RIGHT (dic)));
1146 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1147 operandLitValue (IC_RIGHT (dic)));
1149 if (IS_ITEMP (IC_RESULT (ic)))
1151 SPIL_LOC (IC_RESULT (ic)) = NULL;
1152 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1159 /*-----------------------------------------------------------------*/
1160 /* deleteGetPointers - called when a pointer is passed as parm */
1161 /* will delete from cseSet all get pointers computed from this */
1162 /* pointer. A simple ifOperandsHave is not good enough here */
1163 /*-----------------------------------------------------------------*/
1165 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1167 set *compItems = NULL;
1172 if (!*cseSet && !*pss)
1175 /* first find all items computed from this operand .
1176 This done fairly simply go thru the list and find
1177 those that are computed by arthimetic with this
1179 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1181 if (IS_ARITHMETIC_OP (cdp->diCode))
1183 if (isOperandEqual (IC_LEFT (cdp->diCode), op) ||
1184 isOperandEqual (IC_RIGHT (cdp->diCode), op))
1186 /* save it in our list of items */
1187 addSet (&compItems, IC_RESULT (cdp->diCode));
1189 /* also check for those computed from our computed
1190 list . This will take care of situations like
1191 iTemp1 = iTemp0 + 8;
1192 iTemp2 = iTemp1 + 8; */
1193 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1194 (insetwithFunc)isOperandEqual) ||
1195 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1196 (insetwithFunc)isOperandEqual))
1198 addSet (&compItems, IC_RESULT (cdp->diCode));
1203 /* now delete all pointer gets with this op */
1204 deleteItemIf (cseSet, ifPointerGet, op);
1205 deleteItemIf (pss, ifPointerSet, op);
1207 /* set the bit vector used by dataFlow computation later */
1208 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key);
1209 /* now for the computed items */
1210 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1212 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1213 deleteItemIf (cseSet, ifPointerGet, cop);
1214 deleteItemIf (pss, ifPointerSet, cop);
1218 /*-----------------------------------------------------------------*/
1219 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1220 /* dfnum > supplied */
1221 /*-----------------------------------------------------------------*/
1222 DEFSETFUNC (delGetPointerSucc)
1224 eBBlock *ebp = item;
1225 V_ARG (operand *, op);
1232 if (ebp->dfnum > dfnum)
1234 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1237 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1240 /*-----------------------------------------------------------------*/
1241 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1242 /*-----------------------------------------------------------------*/
1244 fixUpTypes (iCode * ic)
1246 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1248 /* if (TARGET_IS_DS390) */
1249 if (options.model == MODEL_FLAT24)
1255 /* for pointer_gets if the types of result & left r the
1256 same then change it type of result to next */
1258 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1260 setOperandType (IC_RESULT (ic), t2->next);
1264 /*-----------------------------------------------------------------*/
1265 /* cseBBlock - common subexpression elimination for basic blocks */
1266 /* this is the hackiest kludgiest routine in the whole */
1267 /* system. also the most important, since almost all */
1268 /* data flow related information is computed by it */
1269 /*-----------------------------------------------------------------*/
1271 cseBBlock (eBBlock * ebb, int computeOnly,
1272 eBBlock ** ebbs, int count)
1278 set *ptrSetSet = NULL;
1280 /* if this block is not reachable */
1284 /* set of common subexpressions */
1285 cseSet = setFromSet (ebb->inExprs);
1287 /* these will be computed by this routine */
1288 setToNull ((void **) &ebb->outDefs);
1289 setToNull ((void **) &ebb->defSet);
1290 setToNull ((void **) &ebb->usesDefs);
1291 setToNull ((void **) &ebb->ptrsSet);
1292 setToNull ((void **) &ebb->addrOf);
1293 setToNull ((void **) &ebb->ldefs);
1295 ebb->outDefs = bitVectCopy (ebb->inDefs);
1296 bitVectDefault = iCodeKey;
1297 ebb->defSet = newBitVect (iCodeKey);
1298 ebb->usesDefs = newBitVect (iCodeKey);
1300 /* for all the instructions in this block do */
1301 for (ic = ebb->sch; ic; ic = ic->next)
1308 ic->eBBlockNum = ebb->bbnum;
1313 /* if this is an assignment from true symbol
1314 to a temp then do pointer post inc/dec optimzation */
1315 if (ic->op == '=' && !POINTER_SET (ic) &&
1316 IS_PTR (operandType (IC_RESULT (ic))))
1318 ptrPostIncDecOpt (ic);
1321 /* clear the def & use chains for the operands involved */
1322 /* in this operation . since it can change due to opts */
1323 unsetDefsAndUses (ic);
1325 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1327 /* add to defSet of the symbol */
1328 OP_DEFS (IC_RESULT (ic)) =
1329 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1330 /* add to the definition set of this block */
1331 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1332 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1333 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1334 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1335 /* delete global variables from the cseSet
1336 since they can be modified by the function call */
1337 deleteItemIf (&cseSet, ifDefGlobal);
1339 /* and also itemps assigned from globals */
1340 deleteItemIf (&cseSet, ifAssignedFromGlobal);
1342 /* delete all getpointer iCodes from cseSet, this should
1343 be done only for global arrays & pointers but at this
1344 point we don't know if globals, so to be safe do all */
1345 deleteItemIf (&cseSet, ifAnyGetPointer);
1348 /* for pcall & ipush we need to add to the useSet */
1349 if ((ic->op == PCALL ||
1353 IS_SYMOP (IC_LEFT (ic)))
1356 /* check if they can be replaced */
1360 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop);
1362 IC_LEFT (ic) = pdop;
1364 /* the lookup could have changed it */
1365 if (IS_SYMOP (IC_LEFT (ic)))
1367 OP_USES (IC_LEFT (ic)) =
1368 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1369 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1370 ebb->outDefs, &ebb->usesDefs);
1374 /* if we a sending a pointer as a parameter
1375 then kill all cse since the pointed to item
1376 might be changed in the function being called */
1377 if ((ic->op == IPUSH || ic->op == SEND) &&
1378 IS_PTR (operandType (IC_LEFT (ic))))
1380 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1381 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1382 for (i = 0; i < count; ebbs[i++]->visited = 0);
1383 applyToSet (ebb->succList, delGetPointerSucc,
1384 IC_LEFT (ic), ebb->dfnum);
1389 /* if jumptable then mark the usage */
1390 if (ic->op == JUMPTABLE)
1392 OP_USES (IC_JTCOND (ic)) =
1393 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1394 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1395 ebb->outDefs, &ebb->usesDefs);
1402 /* do some algebraic optimizations if possible */
1404 while (constFold (ic, cseSet));
1407 if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1409 setOperandType (IC_LEFT (ic),
1410 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1414 if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1416 setOperandType (IC_RESULT (ic),
1417 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1420 /* if this is a condition statment then */
1421 /* check if the condition can be replaced */
1424 ifxOptimize (ic, cseSet, computeOnly,
1430 /* if the assignment & result is a temp */
1431 /* see if we can replace it */
1435 /* update the spill location for this */
1436 updateSpillLocation (ic,0);
1438 if (POINTER_SET (ic) &&
1439 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1442 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop);
1443 if (pdop && IS_ITEMP (pdop) && !computeOnly)
1444 IC_RESULT (ic) = pdop;
1448 /* do the operand lookup i.e. for both the */
1449 /* right & left operand : check the cseSet */
1450 /* to see if they have been replaced if yes */
1451 /* then replace them with those from cseSet */
1453 /* and left is a symbol */
1454 if (IS_SYMOP (IC_LEFT (ic)) &&
1455 !computeOnly && ic->op != ADDRESS_OF)
1459 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop);
1462 if (POINTER_GET (ic))
1464 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1466 IC_LEFT (ic) = pdop;
1469 /* check if there is a pointer set
1470 for the same pointer visible if yes
1471 then change this into an assignment */
1473 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1474 !bitVectBitValue (ebb->ptrsSet, pdop->key))
1477 IC_LEFT (ic) = NULL;
1478 IC_RIGHT (ic) = pdop;
1479 SET_ISADDR (IC_RESULT (ic), 0);
1485 IC_LEFT (ic) = pdop;
1492 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1496 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop);
1499 IC_RIGHT (ic) = pdop;
1504 /* if left or right changed then do algebraic */
1508 while (constFold (ic, cseSet));
1511 /* if after all this it becomes a assignment to self
1512 then delete it and continue */
1513 if (ASSIGNMENT_TO_SELF (ic))
1515 remiCodeFromeBBlock (ebb, ic);
1519 /* now we will check to see if the entire */
1520 /* operation has been performed before */
1521 /* and is available */
1522 /* don't do assignments they will be killed */
1523 /* by dead code elimination if required do */
1524 /* it only if result is a temporary */
1526 if (!(POINTER_GET (ic) &&
1527 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1528 isOperandVolatile (IC_LEFT (ic), TRUE) ||
1529 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
1531 IS_ITEMP (IC_RESULT (ic)) &&
1534 applyToSet (cseSet, findPrevIc, ic, &pdic);
1535 if (pdic && compareType (operandType (IC_RESULT (pdic)),
1536 operandType (IC_RESULT (ic))) != 1)
1538 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
1542 /* Alternate code */
1543 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
1544 /* if previous definition found change this to an assignment */
1547 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
1548 SET_ISADDR(IC_RESULT(ic),0);
1549 SET_ISADDR(IC_RIGHT (ic),0);
1552 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
1553 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
1554 addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
1558 /* if assignment to a parameter which is not
1559 mine and type is a pointer then delete
1560 pointerGets to take care of aliasing */
1561 if (ASSIGNMENT (ic) &&
1562 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1563 IS_PTR (operandType (IC_RESULT (ic))))
1565 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1566 for (i = 0; i < count; ebbs[i++]->visited = 0);
1567 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1568 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1571 /* if this is a pointerget then see if we can replace
1572 this with a previously assigned pointer value */
1573 if (POINTER_GET (ic) &&
1574 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1575 isOperandVolatile (IC_LEFT (ic), TRUE)))
1578 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
1579 /* if we find it then locally replace all
1580 references to the result with what we assigned */
1583 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
1587 /* delete from the cseSet anything that has */
1588 /* operands matching the result of this */
1589 /* except in case of pointer access */
1590 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
1592 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
1593 /* delete any previous definitions */
1594 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
1598 /* add the left & right to the defUse set */
1599 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
1601 OP_USES (IC_LEFT (ic)) =
1602 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1603 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1607 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
1609 OP_USES (IC_RIGHT (ic)) =
1610 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1611 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1615 /* for the result it is special case, put the result */
1616 /* in the defuseSet if it a pointer or array access */
1617 if (POINTER_SET (defic))
1619 OP_USES (IC_RESULT (ic)) =
1620 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1621 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1622 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
1623 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
1624 /* delete from inexpressions of all successors which
1625 have dfNum > than this block */
1626 for (i = 0; i < count; ebbs[i++]->visited = 0);
1627 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
1629 /* delete from cseSet all other pointer sets
1631 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
1632 /* add to the local pointerset set */
1633 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
1636 /* add the result to defintion set */ if (IC_RESULT (ic))
1638 OP_DEFS (IC_RESULT (ic)) =
1639 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1640 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1641 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1642 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1646 /* if this is an addressof instruction then */
1647 /* put the symbol in the address of list & */
1648 /* delete it from the cseSet */
1649 if (defic->op == ADDRESS_OF)
1651 addSetHead (&ebb->addrOf, IC_LEFT (ic));
1652 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
1656 setToNull ((void **) &ebb->outExprs);
1657 ebb->outExprs = cseSet;
1658 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
1659 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
1663 /*-----------------------------------------------------------------*/
1664 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
1665 /*-----------------------------------------------------------------*/
1667 cseAllBlocks (eBBlock ** ebbs, int count)
1672 /* if optimization turned off */
1674 for (i = 0; i < count; i++)
1675 change += cseBBlock (ebbs[i], FALSE, ebbs, count);