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 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* newCseDef - new cseDef */
31 /*-----------------------------------------------------------------*/
33 newCseDef (operand * sym, iCode * ic)
38 cdp = Safe_alloc (sizeof (cseDef));
49 /*-----------------------------------------------------------------*/
50 /* int isCseDefEqual - two definitions are equal */
51 /*-----------------------------------------------------------------*/
53 isCseDefEqual (void *vsrc, void *vdest)
61 return (src->key == dest->key &&
62 src->diCode == dest->diCode);
66 /*-----------------------------------------------------------------*/
67 /* pcseDef - in the cseDef */
68 /*-----------------------------------------------------------------*/
70 pcseDef (void *item, va_list ap)
78 fprintf (stdout, "**null op**");
79 printOperand (cdp->sym, stdout);
80 icTab = getTableEntry (cdp->diCode->op);
81 icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
85 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
87 printf ("ReplaceOpWithCheaperOp %s with %s: ",
88 IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM",
89 IS_SYMOP(cop) ? OP_SYMBOL(cop)->name : "!SYM");
90 // if op is a register equivalent
91 if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
92 operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
93 if (isOperandEqual(*rop, *op)) {
96 OP_SYMBOL((*op))->isreqv=0;
97 OP_SYMBOL(cop)->isreqv=1;
107 /*-----------------------------------------------------------------*/
108 /* replaceAllSymBySym - replaces all operands by operand in an */
109 /* instruction chain */
110 /*-----------------------------------------------------------------*/
112 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
116 for (lic = ic; lic; lic = lic->next)
120 /* do the special cases first */
124 IC_COND (lic)->key == from->key)
127 bitVectUnSetBit (OP_USES (from), lic->key);
128 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
129 siaddr = IC_COND (lic)->isaddr;
130 IC_COND (lic) = operandFromOperand (to);
131 IC_COND (lic)->isaddr = siaddr;
137 if (lic->op == JUMPTABLE)
140 IC_JTCOND (lic)->key == from->key)
143 bitVectUnSetBit (OP_USES (from), lic->key);
144 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
145 siaddr = IC_COND (lic)->isaddr;
146 IC_JTCOND (lic) = operandFromOperand (to);
147 IC_JTCOND (lic)->isaddr = siaddr;
154 IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
156 /* maintain du chains */
157 if (POINTER_SET (lic))
159 bitVectUnSetBit (OP_USES (from), lic->key);
160 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
162 /* also check if the "from" was in the non-dominating
163 pointer sets and replace it with "to" in the bitVector */
164 if (bitVectBitValue (*ndpset, from->key))
166 bitVectUnSetBit (*ndpset, from->key);
167 bitVectSetBit (*ndpset, to->key);
173 bitVectUnSetBit (OP_DEFS (from), lic->key);
174 OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
176 siaddr = IC_RESULT (lic)->isaddr;
177 IC_RESULT (lic) = operandFromOperand (to);
178 IC_RESULT (lic)->isaddr = siaddr;
182 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
184 bitVectUnSetBit (OP_USES (from), lic->key);
185 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
186 siaddr = IC_RIGHT (lic)->isaddr;
187 IC_RIGHT (lic) = operandFromOperand (to);
188 IC_RIGHT (lic)->isaddr = siaddr;
192 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
194 bitVectUnSetBit (OP_USES (from), lic->key);
195 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
196 siaddr = IC_LEFT (lic)->isaddr;
197 IC_LEFT (lic) = operandFromOperand (to);
198 IC_LEFT (lic)->isaddr = siaddr;
203 /*-----------------------------------------------------------------*/
204 /* iCodeKeyIs - if the icode keys match then return 1 */
205 /*-----------------------------------------------------------------*/
206 DEFSETFUNC (iCodeKeyIs)
211 if (cdp->diCode->key == key)
217 /*-----------------------------------------------------------------*/
218 /* removeFromInExprs - removes an icode from inexpressions */
219 /*-----------------------------------------------------------------*/
220 DEFSETFUNC (removeFromInExprs)
224 V_ARG (operand *, from);
225 V_ARG (operand *, to);
226 V_ARG (eBBlock *, cbp);
232 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
233 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
234 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
236 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
240 /*-----------------------------------------------------------------*/
241 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
242 /*-----------------------------------------------------------------*/
244 isGlobalInNearSpace (operand * op)
246 sym_link *type = getSpec (operandType (op));
247 /* this is 8051 specific: optimization
248 suggested by Jean-Louis VERN, with 8051s we have no
249 advantage of putting variables in near space into
251 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
252 IN_DIRSPACE (SPEC_OCLS (type)))
258 /*-----------------------------------------------------------------*/
259 /* findCheaperOp - cseBBlock support routine, will check to see if */
260 /* we have a operand previously defined */
261 /*-----------------------------------------------------------------*/
262 DEFSETFUNC (findCheaperOp)
265 V_ARG (operand *, cop);
266 V_ARG (operand **, opp);
267 V_ARG (int, checkSign);
269 /* if we have already found it */
273 /* not found it yet check if this is the one */
274 /* and this is not the defining one */
275 if (cop->key == cdp->key)
278 /* do a special check this will help in */
279 /* constant propagation & dead code elim */
280 /* for assignments only */
281 if (cdp->diCode->op == '=') {
282 /* if the result is volatile then return result */
283 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
284 *opp = IC_RESULT (cdp->diCode);
286 /* if this is a straight assignment and
287 left is a temp then prefer the temporary to the
289 if (!POINTER_SET (cdp->diCode) &&
290 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
291 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
292 *opp = IC_RESULT (cdp->diCode);
294 /* if straight assignement && and both
295 are temps then prefer the one that
296 will not need extra space to spil, also
297 take into consideration if right side
298 an induction variable
300 if (!POINTER_SET (cdp->diCode) &&
301 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
302 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
303 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
304 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
305 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
306 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
307 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
308 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
309 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
310 *opp = IC_RESULT (cdp->diCode);
312 *opp = IC_RIGHT (cdp->diCode);
316 *opp = IC_RESULT (cdp->diCode);
319 /* if this is an assign to a temp. then check
320 if the right side is this then return this */
321 if (IS_TRUE_SYMOP (cop) &&
322 cdp->diCode->op == '=' &&
323 !POINTER_SET (cdp->diCode) &&
324 cop->key == IC_RIGHT (cdp->diCode)->key &&
325 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
326 IS_ITEMP (IC_RESULT (cdp->diCode)))
327 *opp = IC_RESULT (cdp->diCode);
330 (isOperandLiteral(*opp) || !checkSign ||
332 IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
333 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
334 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
337 if ((isGlobalInNearSpace (cop) &&
338 !isOperandLiteral (*opp)) ||
339 isOperandVolatile (*opp, FALSE)
346 if (cop->key == (*opp)->key)
352 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
354 *opp = operandFromOperand (*opp);
355 (*opp)->isaddr = cop->isaddr;
358 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
359 SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
361 // special case: we can make an unsigned char literal
362 // into an int literal with no cost.
363 if (isOperandLiteral(*opp)
364 && SPEC_NOUN(operandType(*opp)) == V_CHAR
365 && SPEC_NOUN(operandType(cop)) == V_INT)
367 *opp = operandFromOperand (*opp);
368 SPEC_NOUN(operandType(*opp)) = V_INT;
386 /*-----------------------------------------------------------------*/
387 /* findPointerSet - finds the right side of a pointer set op */
388 /*-----------------------------------------------------------------*/
389 DEFSETFUNC (findPointerSet)
392 V_ARG (operand *, op);
393 V_ARG (operand **, opp);
394 V_ARG (operand *, rop);
396 if (POINTER_SET (cdp->diCode) &&
397 IC_RESULT (cdp->diCode)->key == op->key &&
398 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
399 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
400 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
401 getSize (operandType (rop)))
403 *opp = IC_RIGHT (cdp->diCode);
410 /*-----------------------------------------------------------------*/
411 /* findPrevIc - cseBBlock support function will return the iCode */
412 /* which matches the current one */
413 /*-----------------------------------------------------------------*/
414 DEFSETFUNC (findPrevIc)
418 V_ARG (iCode **, icp);
420 /* if already found */
424 /* if the iCodes are the same */
425 if (isiCodeEqual (ic, cdp->diCode) &&
426 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
432 /* if iCodes are not the same */
433 /* see the operands maybe interchanged */
434 if (ic->op == cdp->diCode->op &&
435 (ic->op == '+' || ic->op == '*') &&
436 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
437 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
446 /*-------------------------------------------------------------------*/
447 /* ifAssignedFromGlobal - if definition is an assignment from global */
448 /*-------------------------------------------------------------------*/
449 DEFSETFUNC (ifAssignedFromGlobal)
452 iCode *dic=cdp->diCode;
454 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
460 /*-----------------------------------------------------------------*/
461 /* ifDefGlobal - if definition is global */
462 /*-----------------------------------------------------------------*/
463 DEFSETFUNC (ifDefGlobal)
467 return (isOperandGlobal (cdp->sym));
470 /*-----------------------------------------------------------------*/
471 /* ifAnyGetPointer - if get pointer icode */
472 /*-----------------------------------------------------------------*/
473 DEFSETFUNC (ifAnyGetPointer)
477 if (cdp->diCode && POINTER_GET (cdp->diCode))
482 /*-----------------------------------------------------------------*/
483 /* ifOperandsHave - if any of the operand are the same as this */
484 /*-----------------------------------------------------------------*/
485 DEFSETFUNC (ifOperandsHave)
488 V_ARG (operand *, op);
491 if (IC_LEFT (cdp->diCode) &&
492 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
493 IC_LEFT (cdp->diCode)->key == op->key)
496 if (IC_RIGHT (cdp->diCode) &&
497 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
498 IC_RIGHT (cdp->diCode)->key == op->key)
501 /* or if any of the operands are volatile */
502 if (IC_LEFT (cdp->diCode) &&
503 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
506 if (IC_RIGHT (cdp->diCode) &&
507 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
511 if (IC_RESULT (cdp->diCode) &&
512 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
518 /*-----------------------------------------------------------------*/
519 /* ifDefSymIs - if a definition is found in the set */
520 /*-----------------------------------------------------------------*/
522 ifDefSymIs (set * cseSet, operand * sym)
527 if (!sym || !IS_SYMOP (sym))
529 for (sl = cseSet; sl; sl = sl->next)
532 if (loop->sym->key == sym->key)
539 /*-----------------------------------------------------------------*/
540 /* ifDefSymIsX - will return 1 if the symbols match */
541 /*-----------------------------------------------------------------*/
542 DEFSETFUNC (ifDefSymIsX)
545 V_ARG (operand *, op);
548 return cdp->sym->key == op->key;
550 return (isOperandEqual (cdp->sym, op));
555 /*-----------------------------------------------------------------*/
556 /* ifDiCodeIs - returns truw if diCode is same */
557 /*-----------------------------------------------------------------*/
559 ifDiCodeIs (set * cseSet, iCode * ic)
567 for (sl = cseSet; sl; sl = sl->next)
570 if (loop->diCode == ic)
577 /*-----------------------------------------------------------------*/
578 /* ifPointerGet - returns true if the icode is pointer get sym */
579 /*-----------------------------------------------------------------*/
580 DEFSETFUNC (ifPointerGet)
583 V_ARG (operand *, op);
584 iCode *dic = cdp->diCode;
585 operand *left = IC_LEFT (cdp->diCode);
587 if (POINTER_GET (dic) && left->key == op->key)
593 /*-----------------------------------------------------------------*/
594 /* ifPointerSet - returns true if the icode is pointer set sym */
595 /*-----------------------------------------------------------------*/
596 DEFSETFUNC (ifPointerSet)
599 V_ARG (operand *, op);
601 if (POINTER_SET (cdp->diCode) &&
602 IC_RESULT (cdp->diCode)->key == op->key)
608 /*-----------------------------------------------------------------*/
609 /* ifDiCodeIsX - will return 1 if the symbols match */
610 /*-----------------------------------------------------------------*/
611 DEFSETFUNC (ifDiCodeIsX)
616 return cdp->diCode == ic;
620 /*-----------------------------------------------------------------*/
621 /* findBackwardDef - scan backwards to find deinition of operand */
622 /*-----------------------------------------------------------------*/
623 iCode *findBackwardDef(operand *op,iCode *ic)
627 for (lic = ic; lic ; lic = lic->prev) {
628 if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
634 /*-----------------------------------------------------------------*/
635 /* algebraicOpts - does some algebraic optimizations */
636 /*-----------------------------------------------------------------*/
638 algebraicOpts (iCode * ic, eBBlock * ebp)
640 /* we don't deal with the following iCodes
651 /* if both operands present & ! IFX */
652 /* then if they are both literal we */
653 /* perform the operation right now */
654 if (IC_RESULT (ic) &&
657 IS_OP_LITERAL (IC_LEFT (ic)) &&
658 IS_OP_LITERAL (IC_RIGHT (ic)))
661 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
664 operandType (IC_RESULT (ic)));
667 SET_RESULT_RIGHT (ic);
671 /* if not ifx & only one operand present */
672 if (IC_RESULT (ic) &&
674 IS_OP_LITERAL (IC_LEFT (ic)) &&
678 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
681 operandType (IC_RESULT (ic)));
684 SET_RESULT_RIGHT (ic);
689 /* a special case : or in short a kludgy solution will think
690 about a better solution over a glass of wine someday */
691 if (ic->op == GET_VALUE_AT_ADDRESS)
694 if (IS_ITEMP (IC_RESULT (ic)) &&
695 IS_TRUE_SYMOP (IC_LEFT (ic)))
699 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
700 IC_RIGHT (ic)->isaddr = 0;
702 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
703 IC_RESULT (ic)->isaddr = 0;
704 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
708 if (IS_ITEMP (IC_LEFT (ic)) &&
709 IS_ITEMP (IC_RESULT (ic)) &&
710 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
711 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
712 !IC_LEFT (ic)->isaddr)
715 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
716 IC_RIGHT (ic)->isaddr = 0;
717 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
718 IC_RESULT (ic)->isaddr = 0;
726 /* depending on the operation */
730 /* if adding the same thing change to left shift by 1 */
731 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
732 !IS_FLOAT (operandType (IC_RESULT (ic))))
735 IC_RIGHT (ic) = operandFromLit (1);
738 /* if addition then check if one of them is a zero */
739 /* if yes turn it into assignmnt or cast */
740 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
741 operandLitValue (IC_LEFT (ic)) == 0.0)
743 if (compareType (operandType (IC_RESULT (ic)),
744 operandType (IC_RIGHT (ic)))<0)
747 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
754 SET_ISADDR (IC_RESULT (ic), 0);
755 SET_ISADDR (IC_RIGHT (ic), 0);
758 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
759 operandLitValue (IC_RIGHT (ic)) == 0.0)
761 if (compareType (operandType (IC_RESULT (ic)),
762 operandType (IC_LEFT (ic)))<0)
765 IC_RIGHT (ic) = IC_LEFT (ic);
766 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
771 IC_RIGHT (ic) = IC_LEFT (ic);
774 SET_ISADDR (IC_RIGHT (ic), 0);
775 SET_ISADDR (IC_RESULT (ic), 0);
780 /* if subtracting the the same thing then zero */
781 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
784 IC_RIGHT (ic) = operandFromLit (0);
786 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
787 IC_RESULT (ic)->isaddr = 0;
791 /* if subtraction then check if one of the operand */
792 /* is zero then depending on which operand change */
793 /* to assignment or unary minus */
794 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
795 operandLitValue (IC_RIGHT (ic)) == 0.0)
797 /* right size zero change to assignment */
799 IC_RIGHT (ic) = IC_LEFT (ic);
801 SET_ISADDR (IC_RIGHT (ic), 0);
802 SET_ISADDR (IC_RESULT (ic), 0);
805 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
806 operandLitValue (IC_LEFT (ic)) == 0.0)
808 /* left zero turn into an unary minus */
810 IC_LEFT (ic) = IC_RIGHT (ic);
811 IC_RIGHT (ic) = NULL;
815 /* if multiplication then check if either of */
816 /* them is zero then the result is zero */
817 /* if either of them is one then result is */
820 if (IS_OP_LITERAL (IC_LEFT (ic)))
823 if (operandLitValue (IC_LEFT (ic)) == 0.0)
826 IC_RIGHT (ic) = IC_LEFT (ic);
828 SET_RESULT_RIGHT (ic);
831 if (operandLitValue (IC_LEFT (ic)) == 1.0)
833 /* '*' can have two unsigned chars as operands */
834 /* and an unsigned int as result. */
835 if (compareType (operandType (IC_RESULT (ic)),
836 operandType (IC_RIGHT (ic))) == 1)
840 SET_RESULT_RIGHT (ic);
845 IC_LEFT (ic)->type = TYPE;
846 IC_LEFT (ic)->isLiteral = 0;
847 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
853 if (IS_OP_LITERAL (IC_RIGHT (ic)))
856 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
860 SET_RESULT_RIGHT (ic);
864 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
866 /* '*' can have two unsigned chars as operands */
867 /* and an unsigned int as result. */
868 if (compareType (operandType (IC_RESULT (ic)),
869 operandType (IC_LEFT (ic))) == 1)
872 IC_RIGHT (ic) = IC_LEFT (ic);
874 SET_RESULT_RIGHT (ic);
882 IC_RIGHT (ic) = IC_LEFT (ic);
884 IC_LEFT (ic)->type = TYPE;
885 IC_LEFT (ic)->isLiteral = 0;
886 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
893 /* if division by self then 1 */
894 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
897 IC_RIGHT (ic) = operandFromLit (1);
899 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
900 IC_RESULT (ic)->isaddr = 0;
903 /* if this is a division then check if right */
904 /* is one then change it to an assignment */
905 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
906 operandLitValue (IC_RIGHT (ic)) == 1.0)
910 IC_RIGHT (ic) = IC_LEFT (ic);
912 SET_RESULT_RIGHT (ic);
916 /* if both are the same for an comparison operators */
920 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
923 IC_RIGHT (ic) = operandFromLit (1);
925 SET_RESULT_RIGHT (ic);
931 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
934 IC_RIGHT (ic) = operandFromLit (0);
936 SET_RESULT_RIGHT (ic);
941 sym_link *otype = operandType(IC_RIGHT(ic));
942 sym_link *ctype = operandType(IC_LEFT(ic));
943 /* if this is a cast of a literal value */
944 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
945 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
948 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
949 operandLitValue (IC_RIGHT (ic))));
951 SET_ISADDR (IC_RESULT (ic), 0);
953 /* if casting to the same */
954 if (compareType (operandType (IC_RESULT (ic)),
955 operandType (IC_RIGHT (ic))) == 1) {
958 SET_ISADDR (IC_RESULT (ic), 0);
963 if (IS_OP_LITERAL (IC_LEFT (ic)))
967 (operandLitValue (IC_LEFT (ic)) == 0 ?
968 operandFromLit (1) : operandFromLit (0));
970 SET_ISADDR (IC_RESULT (ic), 0);
974 /* if both operands are equal */
975 /* if yes turn it into assignment */
976 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
978 if (IS_OP_VOLATILE (IC_LEFT (ic)))
980 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
981 IC_RESULT (newic) = IC_LEFT (ic);
982 newic->lineno = ic->lineno;
983 addiCodeToeBBlock (ebp, newic, ic->next);
987 SET_RESULT_RIGHT (ic);
990 /* swap literal to right ic */
991 if (IS_OP_LITERAL (IC_LEFT (ic)))
996 IC_LEFT (ic) = IC_RIGHT (ic);
999 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1001 /* if BITWISEAND then check if one of them is a zero */
1002 /* if yes turn it into 0 assignment */
1003 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1005 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1007 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1008 IC_RESULT (newic) = IC_LEFT (ic);
1009 newic->lineno = ic->lineno;
1010 addiCodeToeBBlock (ebp, newic, ic->next);
1013 IC_LEFT (ic) = NULL;
1014 SET_RESULT_RIGHT (ic);
1017 /* if BITWISEAND then check if one of them is 0xff... */
1018 /* if yes turn it into assignment */
1022 switch (getSize (operandType (IC_RIGHT (ic))))
1036 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1039 IC_RIGHT (ic) = IC_LEFT (ic);
1040 IC_LEFT (ic) = NULL;
1041 SET_RESULT_RIGHT (ic);
1048 /* if both operands are equal */
1049 /* if yes turn it into assignment */
1050 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1052 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1054 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1055 IC_RESULT (newic) = IC_LEFT (ic);
1056 newic->lineno = ic->lineno;
1057 addiCodeToeBBlock (ebp, newic, ic->next);
1060 IC_LEFT (ic) = NULL;
1061 SET_RESULT_RIGHT (ic);
1064 /* swap literal to right ic */
1065 if (IS_OP_LITERAL (IC_LEFT (ic)))
1070 IC_LEFT (ic) = IC_RIGHT (ic);
1073 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1075 /* if BITWISEOR then check if one of them is a zero */
1076 /* if yes turn it into assignment */
1077 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1080 IC_RIGHT (ic) = IC_LEFT (ic);
1081 IC_LEFT (ic) = NULL;
1082 SET_RESULT_RIGHT (ic);
1085 /* if BITWISEOR then check if one of them is 0xff... */
1086 /* if yes turn it into 0xff... assignment */
1090 switch (getSize (operandType (IC_RIGHT (ic))))
1104 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1106 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1108 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1109 IC_RESULT (newic) = IC_LEFT (ic);
1110 newic->lineno = ic->lineno;
1111 addiCodeToeBBlock (ebp, newic, ic->next);
1114 IC_LEFT (ic) = NULL;
1115 SET_RESULT_RIGHT (ic);
1122 /* if both operands are equal */
1123 /* if yes turn it into 0 assignment */
1124 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1126 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1128 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1129 IC_RESULT (newic) = IC_LEFT (ic);
1130 newic->lineno = ic->lineno;
1131 addiCodeToeBBlock (ebp, newic, ic->next);
1133 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1134 IC_RESULT (newic) = IC_LEFT (ic);
1135 newic->lineno = ic->lineno;
1136 addiCodeToeBBlock (ebp, newic, ic->next);
1139 IC_RIGHT (ic) = operandFromLit (0);
1140 IC_LEFT (ic) = NULL;
1141 SET_RESULT_RIGHT (ic);
1144 /* swap literal to right ic */
1145 if (IS_OP_LITERAL (IC_LEFT (ic)))
1150 IC_LEFT (ic) = IC_RIGHT (ic);
1153 /* if XOR then check if one of them is a zero */
1154 /* if yes turn it into assignment */
1155 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1157 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1160 IC_RIGHT (ic) = IC_LEFT (ic);
1161 IC_LEFT (ic) = NULL;
1162 SET_RESULT_RIGHT (ic);
1171 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1172 /*-----------------------------------------------------------------*/
1173 /* updateSpillLocation - keeps track of register spill location */
1174 /*-----------------------------------------------------------------*/
1176 updateSpillLocation (iCode * ic, int induction)
1180 if (POINTER_SET (ic))
1187 /* for the form true_symbol := iTempNN */
1188 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1189 !SPIL_LOC (IC_RIGHT (ic))) {
1191 setype = getSpec (operandType (IC_RESULT (ic)));
1193 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1194 !IS_VOLATILE (setype) &&
1195 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1196 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1198 wassert(IS_SYMOP(IC_RESULT (ic)));
1199 wassert(IS_SYMOP(IC_RIGHT (ic)));
1200 SPIL_LOC (IC_RIGHT (ic)) =
1201 IC_RESULT (ic)->operand.symOperand;
1207 #if 0 /* this needs furthur investigation can save a lot of code */
1208 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1209 !SPIL_LOC(IC_RESULT(ic))) {
1210 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1211 SPIL_LOC (IC_RESULT (ic)) =
1212 IC_RIGHT (ic)->operand.symOperand;
1215 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1217 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1218 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1219 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1221 setype = getSpec (operandType (IC_RESULT (ic)));
1223 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1224 !IS_VOLATILE (setype) &&
1225 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1226 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1228 SPIL_LOC (IC_RIGHT (ic)) =
1229 SPIL_LOC (IC_RESULT (ic));
1231 /* special case for inductions */
1233 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1234 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1235 !SPIL_LOC(IC_RESULT(ic))) {
1236 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1240 /*-----------------------------------------------------------------*/
1241 /* setUsesDef - sets the uses def bitvector for a given operand */
1242 /*-----------------------------------------------------------------*/
1244 setUsesDefs (operand * op, bitVect * bdefs,
1245 bitVect * idefs, bitVect ** oud)
1247 /* compute the definitions alive at this point */
1248 bitVect *adefs = bitVectUnion (bdefs, idefs);
1250 /* of these definitions find the ones that are */
1251 /* for this operand */
1252 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1254 /* these are the definitions that this operand can use */
1255 op->usesDefs = adefs;
1257 /* the out defs is an union */
1258 *oud = bitVectUnion (*oud, adefs);
1261 /*-----------------------------------------------------------------*/
1262 /* unsetDefsAndUses - clear this operation for the operands */
1263 /*-----------------------------------------------------------------*/
1265 unsetDefsAndUses (iCode * ic)
1267 if (ic->op == JUMPTABLE)
1270 /* take away this definition from the def chain of the */
1271 /* result & take away from use set of the operands */
1274 /* turn off def set */
1275 if (IS_SYMOP (IC_RESULT (ic)))
1277 if (!POINTER_SET (ic))
1278 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1280 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1282 /* turn off the useSet for the operands */
1283 if (IS_SYMOP (IC_LEFT (ic)))
1284 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1286 if (IS_SYMOP (IC_RIGHT (ic)))
1287 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1290 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1291 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1294 /*-----------------------------------------------------------------*/
1295 /* ifxOptimize - changes ifx conditions if it can */
1296 /*-----------------------------------------------------------------*/
1298 ifxOptimize (iCode * ic, set * cseSet,
1300 eBBlock * ebb, int *change,
1301 eBBlock ** ebbs, int count)
1306 /* if the condition can be replaced */
1310 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1313 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1318 /* if the conditional is a literal then */
1319 if (IS_OP_LITERAL (IC_COND (ic)))
1322 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1325 /* change to a goto */
1327 IC_LABEL (ic) = IC_TRUE (ic);
1334 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1337 IC_LABEL (ic) = IC_FALSE (ic);
1343 /* then kill this if condition */
1344 remiCodeFromeBBlock (ebb, ic);
1348 /* now we need to recompute the control flow */
1349 /* since the control flow has changed */
1350 /* this is very expensive but it does not happen */
1351 /* too often, if it does happen then the user pays */
1353 computeControlFlow (ebbs, count, 1);
1354 if (!options.lessPedantic) {
1355 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1360 /* if there is only one successor and that successor
1361 is the same one we are conditionally going to then
1362 we can remove this conditional statement */
1363 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1364 if (elementsInSet (ebb->succList) == 1 &&
1365 isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1368 if (!options.lessPedantic) {
1369 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1371 if (IS_OP_VOLATILE (IC_COND (ic)))
1373 IC_RIGHT (ic) = IC_COND (ic);
1374 IC_LEFT (ic) = NULL;
1375 IC_RESULT (ic) = NULL;
1376 ic->op = DUMMY_READ_VOLATILE;
1380 remiCodeFromeBBlock (ebb, ic);
1381 computeControlFlow (ebbs, count, 1);
1387 /* if it remains an IFX the update the use Set */
1390 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1391 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1393 else if (ic->op == DUMMY_READ_VOLATILE)
1395 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1396 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1401 /*-----------------------------------------------------------------*/
1402 /* diCodeForSym - finds the definiting instruction for a symbol */
1403 /*-----------------------------------------------------------------*/
1404 DEFSETFUNC (diCodeForSym)
1407 V_ARG (operand *, sym);
1408 V_ARG (iCode **, dic);
1410 /* if already found */
1414 /* if not if this is the defining iCode */
1415 if (sym->key == cdp->key)
1424 /*-----------------------------------------------------------------*/
1425 /* constFold - does some constant folding */
1426 /*-----------------------------------------------------------------*/
1428 constFold (iCode * ic, set * cseSet)
1432 /* this routine will change
1438 /* deal with only + & - */
1439 if (ic->op != '+' &&
1443 /* this check is a hueristic to prevent live ranges
1444 from becoming too long */
1445 if (IS_PTR (operandType (IC_RESULT (ic))))
1448 /* check if operation with a literal */
1449 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1452 /* check if we can find a definition for the
1454 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1457 /* check that this is also a +/- */
1458 if (dic->op != '+' && dic->op != '-')
1461 /* with a literal */
1462 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1465 /* find the definition of the left operand
1466 of dic.then check if this defined with a
1467 get_pointer return 0 if the pointer size is
1468 less than 2 (MCS51 specific) */
1469 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1472 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1475 /* it is if the operations are the same */
1476 /* the literal parts need to be added */
1477 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1478 if (ic->op == dic->op)
1479 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1480 operandLitValue (IC_RIGHT (dic)));
1482 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1483 operandLitValue (IC_RIGHT (dic)));
1485 if (IS_ITEMP (IC_RESULT (ic)))
1487 SPIL_LOC (IC_RESULT (ic)) = NULL;
1488 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1495 /*-----------------------------------------------------------------*/
1496 /* deleteGetPointers - called when a pointer is passed as parm */
1497 /* will delete from cseSet all get pointers computed from this */
1498 /* pointer. A simple ifOperandsHave is not good enough here */
1499 /*-----------------------------------------------------------------*/
1501 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1503 set *compItems = NULL;
1509 if (!*cseSet && !*pss)
1512 addSet (&compItems, op);
1514 /* Recursively find all items computed from this operand .
1515 This done fairly simply go thru the list and find
1516 those that are computed by arthimetic with these
1518 /* Also check for those computed from our computed
1519 list . This will take care of situations like
1520 iTemp1 = iTemp0 + 8;
1521 iTemp2 = iTemp1 + 8; */
1525 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1527 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1529 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1530 (insetwithFunc)isOperandEqual) ||
1531 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1532 (insetwithFunc)isOperandEqual))
1534 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1535 (insetwithFunc)isOperandEqual))
1537 addSet (&compItems, IC_RESULT (cdp->diCode));
1546 /* now for the computed items */
1547 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1549 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1550 deleteItemIf (cseSet, ifPointerGet, cop);
1551 deleteItemIf (pss, ifPointerSet, cop);
1555 /*-----------------------------------------------------------------*/
1556 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1557 /* dfnum > supplied */
1558 /*-----------------------------------------------------------------*/
1559 DEFSETFUNC (delGetPointerSucc)
1561 eBBlock *ebp = item;
1562 V_ARG (operand *, op);
1569 if (ebp->dfnum > dfnum)
1571 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1574 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1577 /*-----------------------------------------------------------------*/
1578 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1579 /*-----------------------------------------------------------------*/
1581 fixUpTypes (iCode * ic)
1583 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1585 /* if (TARGET_IS_DS390) */
1586 if (options.model == MODEL_FLAT24)
1592 /* for pointer_gets if the types of result & left r the
1593 same then change it type of result to next */
1595 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1597 setOperandType (IC_RESULT (ic), t2->next);
1601 /*-----------------------------------------------------------------*/
1602 /* isSignedOp - will return 1 if sign is important to operation */
1603 /*-----------------------------------------------------------------*/
1604 static int isSignedOp (iCode *ic)
1625 case GET_VALUE_AT_ADDRESS:
1653 dumpCseSet(set *cseSet)
1657 cseDef *item=cseSet->item;
1659 printOperand (item->sym, NULL);
1661 piCode (item->diCode, NULL);
1662 cseSet = cseSet->next;
1667 /*-----------------------------------------------------------------*/
1668 /* cseBBlock - common subexpression elimination for basic blocks */
1669 /* this is the hackiest kludgiest routine in the whole */
1670 /* system. also the most important, since almost all */
1671 /* data flow related information is computed by it */
1672 /*-----------------------------------------------------------------*/
1674 cseBBlock (eBBlock * ebb, int computeOnly,
1675 eBBlock ** ebbs, int count)
1681 set *ptrSetSet = NULL;
1683 /* if this block is not reachable */
1687 /* set of common subexpressions */
1688 cseSet = setFromSet (ebb->inExprs);
1690 /* these will be computed by this routine */
1691 setToNull ((void *) &ebb->outDefs);
1692 setToNull ((void *) &ebb->defSet);
1693 setToNull ((void *) &ebb->usesDefs);
1694 setToNull ((void *) &ebb->ptrsSet);
1695 setToNull ((void *) &ebb->addrOf);
1696 setToNull ((void *) &ebb->ldefs);
1698 ebb->outDefs = bitVectCopy (ebb->inDefs);
1699 bitVectDefault = iCodeKey;
1700 ebb->defSet = newBitVect (iCodeKey);
1701 ebb->usesDefs = newBitVect (iCodeKey);
1703 /* for all the instructions in this block do */
1704 for (ic = ebb->sch; ic; ic = ic->next)
1711 ic->eBBlockNum = ebb->bbnum;
1716 /* if this is an assignment from true symbol
1717 to a temp then do pointer post inc/dec optimzation */
1718 if (ic->op == '=' && !POINTER_SET (ic) &&
1719 IS_PTR (operandType (IC_RESULT (ic))))
1721 ptrPostIncDecOpt (ic);
1724 /* clear the def & use chains for the operands involved */
1725 /* in this operation . since it can change due to opts */
1726 unsetDefsAndUses (ic);
1728 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1730 /* add to defSet of the symbol */
1731 OP_DEFS(IC_RESULT (ic))=
1732 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1733 /* add to the definition set of this block */
1734 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1735 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1736 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1737 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1738 /* delete global variables from the cseSet
1739 since they can be modified by the function call */
1740 deleteItemIf (&cseSet, ifDefGlobal);
1742 /* and also itemps assigned from globals */
1743 deleteItemIf (&cseSet, ifAssignedFromGlobal);
1745 /* delete all getpointer iCodes from cseSet, this should
1746 be done only for global arrays & pointers but at this
1747 point we don't know if globals, so to be safe do all */
1748 deleteItemIf (&cseSet, ifAnyGetPointer);
1750 /* can't cache pointer set/get operations across a call */
1751 deleteSet (&ptrSetSet);
1754 /* for pcall & ipush we need to add to the useSet */
1755 if ((ic->op == PCALL ||
1759 IS_SYMOP (IC_LEFT (ic)))
1762 /* check if they can be replaced */
1766 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1768 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1770 /* the lookup could have changed it */
1771 if (IS_SYMOP (IC_LEFT (ic)))
1773 OP_USES(IC_LEFT (ic))=
1774 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1775 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1776 ebb->outDefs, &ebb->usesDefs);
1780 /* if we a sending a pointer as a parameter
1781 then kill all cse since the pointed to item
1782 might be changed in the function being called */
1783 if ((ic->op == IPUSH || ic->op == SEND) &&
1784 IS_PTR (operandType (IC_LEFT (ic))))
1786 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1787 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1788 for (i = 0; i < count; ebbs[i++]->visited = 0);
1789 applyToSet (ebb->succList, delGetPointerSucc,
1790 IC_LEFT (ic), ebb->dfnum);
1795 /* if jumptable then mark the usage */
1796 if (ic->op == JUMPTABLE)
1798 if (IS_SYMOP (IC_JTCOND (ic)))
1800 OP_USES(IC_JTCOND (ic)) =
1801 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1802 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1803 ebb->outDefs, &ebb->usesDefs);
1812 /* do some algebraic optimizations if possible */
1813 algebraicOpts (ic, ebb);
1814 while (constFold (ic, cseSet));
1818 if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1820 setOperandType (IC_LEFT (ic),
1821 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1825 if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1827 setOperandType (IC_RESULT (ic),
1828 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1831 /* if this is a condition statement then */
1832 /* check if the condition can be replaced */
1835 ifxOptimize (ic, cseSet, computeOnly,
1841 /* if the assignment & result is a temp */
1842 /* see if we can replace it */
1843 if (!computeOnly && ic->op == '=')
1846 /* update the spill location for this */
1847 updateSpillLocation (ic,0);
1849 if (POINTER_SET (ic) &&
1850 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1853 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1854 if (pdop && !computeOnly &&
1855 IS_ITEMP (pdop) && IS_PTR(operandType(pdop)))
1856 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1860 checkSign = isSignedOp(ic);
1862 /* do the operand lookup i.e. for both the */
1863 /* right & left operand : check the cseSet */
1864 /* to see if they have been replaced if yes */
1865 /* then replace them with those from cseSet */
1867 /* and left is a symbol */
1868 if (IS_SYMOP (IC_LEFT (ic)) &&
1869 !computeOnly && ic->op != ADDRESS_OF)
1873 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1876 if (POINTER_GET (ic))
1878 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1880 /* some non dominating block does POINTER_SET with
1881 this variable .. unsafe to remove any POINTER_GETs */
1882 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1883 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1884 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1887 /* check if there is a pointer set
1888 for the same pointer visible if yes
1889 then change this into an assignment */
1891 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1892 !bitVectBitValue (ebb->ptrsSet, pdop->key))
1895 IC_LEFT (ic) = NULL;
1896 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1897 SET_ISADDR (IC_RESULT (ic), 0);
1903 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1910 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1914 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1916 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1921 /* if left or right changed then do algebraic */
1922 if (!computeOnly && change)
1924 algebraicOpts (ic, ebb);
1925 while (constFold (ic, cseSet));
1928 /* if after all this it becomes an assignment to self
1929 then delete it and continue */
1930 if (ASSIGNMENT_TO_SELF (ic))
1932 remiCodeFromeBBlock (ebb, ic);
1936 /* now we will check to see if the entire */
1937 /* operation has been performed before */
1938 /* and is available */
1939 /* don't do assignments they will be killed */
1940 /* by dead code elimination if required do */
1941 /* it only if result is a temporary */
1943 if (!(POINTER_GET (ic) &&
1944 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1945 isOperandVolatile (IC_LEFT (ic), TRUE) ||
1946 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
1948 IS_ITEMP (IC_RESULT (ic)) &&
1951 applyToSet (cseSet, findPrevIc, ic, &pdic);
1952 if (pdic && compareType (operandType (IC_RESULT (pdic)),
1953 operandType (IC_RESULT (ic))) != 1)
1955 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
1959 /* Alternate code */
1960 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
1961 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
1962 /* Mmm, found an equivalent pointer get at a lower level.
1963 This could be a loop however with the same pointer set
1966 /* if previous definition found change this to an assignment */
1969 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
1970 SET_ISADDR(IC_RESULT(ic),0);
1971 SET_ISADDR(IC_RIGHT (ic),0);
1975 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
1976 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
1977 addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
1981 /* if assignment to a parameter which is not
1982 mine and type is a pointer then delete
1983 pointerGets to take care of aliasing */
1984 if (ASSIGNMENT (ic) &&
1985 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
1986 IS_PTR (operandType (IC_RESULT (ic))))
1988 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
1989 for (i = 0; i < count; ebbs[i++]->visited = 0);
1990 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
1991 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
1994 /* if this is a pointerget then see if we can replace
1995 this with a previously assigned pointer value */
1996 if (POINTER_GET (ic) &&
1997 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
1998 isOperandVolatile (IC_LEFT (ic), TRUE)))
2001 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2002 /* if we find it then locally replace all
2003 references to the result with what we assigned */
2006 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2010 /* delete from the cseSet anything that has */
2011 /* operands matching the result of this */
2012 /* except in case of pointer access */
2013 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2015 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2016 /* delete any previous definitions */
2017 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2021 /* add the left & right to the defUse set */
2022 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2024 OP_USES(IC_LEFT (ic))=
2025 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2026 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2030 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2032 OP_USES(IC_RIGHT (ic))=
2033 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2034 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2038 /* for the result it is special case, put the result */
2039 /* in the defuseSet if it a pointer or array access */
2040 if (POINTER_SET (defic))
2042 OP_USES(IC_RESULT (ic))=
2043 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2044 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2045 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2046 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2047 /* delete from inexpressions of all successors which
2048 have dfNum > than this block */
2049 for (i = 0; i < count; ebbs[i++]->visited = 0);
2050 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2052 /* delete from cseSet all other pointer sets
2054 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2055 /* add to the local pointerset set */
2056 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2059 /* add the result to defintion set */ if (IC_RESULT (ic))
2061 OP_DEFS(IC_RESULT (ic))=
2062 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2063 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2064 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2065 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2069 /* if this is an addressof instruction then */
2070 /* put the symbol in the address of list & */
2071 /* delete it from the cseSet */
2072 if (defic->op == ADDRESS_OF)
2074 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2075 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2079 setToNull ((void *) &ebb->outExprs);
2080 ebb->outExprs = cseSet;
2081 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2082 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2086 /*-----------------------------------------------------------------*/
2087 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2088 /*-----------------------------------------------------------------*/
2090 cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
2095 /* if optimization turned off */
2097 for (i = 0; i < count; i++)
2098 change += cseBBlock (ebbs[i], computeOnly, ebbs, count);