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));
43 cdp->ancestors = newBitVect(iCodeKey);
46 if (ic->op!=IF && ic->op!=JUMPTABLE)
48 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
50 bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
51 cdp->fromGlobal |= isOperandGlobal (IC_LEFT (ic));
53 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
55 bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
56 cdp->fromGlobal |= isOperandGlobal (IC_RIGHT (ic));
64 updateCseDefAncestors(cseDef *cdp, set * cseSet)
68 iCode *ic = cdp->diCode;
70 if (ic->op!=IF && ic->op!=JUMPTABLE)
72 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
74 bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
75 for (sl = cseSet; sl; sl = sl->next)
78 if (loop->sym->key == IC_LEFT (ic)->key)
80 cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
81 cdp->fromGlobal |= loop->fromGlobal;
86 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
88 bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
89 for (sl = cseSet; sl; sl = sl->next)
92 if (loop->sym->key == IC_RIGHT (ic)->key)
94 cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
95 cdp->fromGlobal |= loop->fromGlobal;
104 /*-----------------------------------------------------------------*/
105 /* int isCseDefEqual - two definitions are equal */
106 /*-----------------------------------------------------------------*/
108 isCseDefEqual (void *vsrc, void *vdest)
111 cseDef *dest = vdest;
116 return (src->key == dest->key &&
117 src->diCode == dest->diCode);
121 /*-----------------------------------------------------------------*/
122 /* pcseDef - in the cseDef */
123 /*-----------------------------------------------------------------*/
125 pcseDef (void *item, va_list ap)
133 fprintf (stdout, "**null op**");
134 printOperand (cdp->sym, stdout);
135 icTab = getTableEntry (cdp->diCode->op);
136 icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
140 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
142 printf ("ReplaceOpWithCheaperOp %s with %s: ",
143 IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM",
144 IS_SYMOP(cop) ? OP_SYMBOL(cop)->name : "!SYM");
145 // if op is a register equivalent
146 if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
147 operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
148 if (isOperandEqual(*rop, *op)) {
151 OP_SYMBOL((*op))->isreqv=0;
152 OP_SYMBOL(cop)->isreqv=1;
162 /*-----------------------------------------------------------------*/
163 /* replaceAllSymBySym - replaces all operands by operand in an */
164 /* instruction chain */
165 /*-----------------------------------------------------------------*/
167 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
171 for (lic = ic; lic; lic = lic->next)
175 /* do the special cases first */
179 IC_COND (lic)->key == from->key)
182 bitVectUnSetBit (OP_USES (from), lic->key);
183 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
184 siaddr = IC_COND (lic)->isaddr;
185 IC_COND (lic) = operandFromOperand (to);
186 IC_COND (lic)->isaddr = siaddr;
192 if (lic->op == JUMPTABLE)
195 IC_JTCOND (lic)->key == from->key)
198 bitVectUnSetBit (OP_USES (from), lic->key);
199 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
200 siaddr = IC_COND (lic)->isaddr;
201 IC_JTCOND (lic) = operandFromOperand (to);
202 IC_JTCOND (lic)->isaddr = siaddr;
209 IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
211 /* maintain du chains */
212 if (POINTER_SET (lic))
214 bitVectUnSetBit (OP_USES (from), lic->key);
215 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
217 /* also check if the "from" was in the non-dominating
218 pointer sets and replace it with "to" in the bitVector */
219 if (bitVectBitValue (*ndpset, from->key))
221 bitVectUnSetBit (*ndpset, from->key);
222 bitVectSetBit (*ndpset, to->key);
228 bitVectUnSetBit (OP_DEFS (from), lic->key);
229 OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
231 siaddr = IC_RESULT (lic)->isaddr;
232 IC_RESULT (lic) = operandFromOperand (to);
233 IC_RESULT (lic)->isaddr = siaddr;
237 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
239 bitVectUnSetBit (OP_USES (from), lic->key);
240 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
241 siaddr = IC_RIGHT (lic)->isaddr;
242 IC_RIGHT (lic) = operandFromOperand (to);
243 IC_RIGHT (lic)->isaddr = siaddr;
247 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
249 bitVectUnSetBit (OP_USES (from), lic->key);
250 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
251 siaddr = IC_LEFT (lic)->isaddr;
252 IC_LEFT (lic) = operandFromOperand (to);
253 IC_LEFT (lic)->isaddr = siaddr;
258 /*-----------------------------------------------------------------*/
259 /* iCodeKeyIs - if the icode keys match then return 1 */
260 /*-----------------------------------------------------------------*/
261 DEFSETFUNC (iCodeKeyIs)
266 if (cdp->diCode->key == key)
272 /*-----------------------------------------------------------------*/
273 /* removeFromInExprs - removes an icode from inexpressions */
274 /*-----------------------------------------------------------------*/
275 DEFSETFUNC (removeFromInExprs)
279 V_ARG (operand *, from);
280 V_ARG (operand *, to);
281 V_ARG (eBBlock *, cbp);
287 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
288 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
289 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
291 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
295 /*-----------------------------------------------------------------*/
296 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
297 /*-----------------------------------------------------------------*/
299 isGlobalInNearSpace (operand * op)
301 sym_link *type = getSpec (operandType (op));
302 /* this is 8051 specific: optimization
303 suggested by Jean-Louis VERN, with 8051s we have no
304 advantage of putting variables in near space into
306 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
307 IN_DIRSPACE (SPEC_OCLS (type)))
313 /*-----------------------------------------------------------------*/
314 /* findCheaperOp - cseBBlock support routine, will check to see if */
315 /* we have a operand previously defined */
316 /*-----------------------------------------------------------------*/
317 DEFSETFUNC (findCheaperOp)
320 V_ARG (operand *, cop);
321 V_ARG (operand **, opp);
322 V_ARG (int, checkSign);
324 /* if we have already found it */
328 /* not found it yet check if this is the one */
329 /* and this is not the defining one */
330 if (cop->key == cdp->key)
333 /* do a special check this will help in */
334 /* constant propagation & dead code elim */
335 /* for assignments only */
336 if (cdp->diCode->op == '=') {
337 /* if the result is volatile then return result */
338 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
339 *opp = IC_RESULT (cdp->diCode);
341 /* if this is a straight assignment and
342 left is a temp then prefer the temporary to the
344 if (!POINTER_SET (cdp->diCode) &&
345 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
346 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
347 *opp = IC_RESULT (cdp->diCode);
349 /* if straight assignement && and both
350 are temps then prefer the one that
351 will not need extra space to spil, also
352 take into consideration if right side
353 an induction variable
355 if (!POINTER_SET (cdp->diCode) &&
356 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
357 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
358 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
359 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
360 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
361 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
362 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
363 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
364 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
365 *opp = IC_RESULT (cdp->diCode);
367 *opp = IC_RIGHT (cdp->diCode);
371 *opp = IC_RESULT (cdp->diCode);
374 /* if this is an assign to a temp. then check
375 if the right side is this then return this */
376 if (IS_TRUE_SYMOP (cop) &&
377 cdp->diCode->op == '=' &&
378 !POINTER_SET (cdp->diCode) &&
379 cop->key == IC_RIGHT (cdp->diCode)->key &&
380 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
381 IS_ITEMP (IC_RESULT (cdp->diCode)))
382 *opp = IC_RESULT (cdp->diCode);
385 (isOperandLiteral(*opp) || !checkSign ||
387 IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
388 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
389 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
392 if ((isGlobalInNearSpace (cop) &&
393 !isOperandLiteral (*opp)) ||
394 isOperandVolatile (*opp, FALSE)
401 if (cop->key == (*opp)->key)
407 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
409 *opp = operandFromOperand (*opp);
410 (*opp)->isaddr = cop->isaddr;
413 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
414 SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
416 // special case: we can make an unsigned char literal
417 // into an int literal with no cost.
418 if (isOperandLiteral(*opp)
419 && SPEC_NOUN(operandType(*opp)) == V_CHAR
420 && SPEC_NOUN(operandType(cop)) == V_INT)
422 *opp = operandFromOperand (*opp);
423 SPEC_NOUN(operandType(*opp)) = V_INT;
441 /*-----------------------------------------------------------------*/
442 /* findPointerSet - finds the right side of a pointer set op */
443 /*-----------------------------------------------------------------*/
444 DEFSETFUNC (findPointerSet)
447 V_ARG (operand *, op);
448 V_ARG (operand **, opp);
449 V_ARG (operand *, rop);
451 if (POINTER_SET (cdp->diCode) &&
452 IC_RESULT (cdp->diCode)->key == op->key &&
453 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
454 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
455 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
456 getSize (operandType (rop)))
458 *opp = IC_RIGHT (cdp->diCode);
465 /*-----------------------------------------------------------------*/
466 /* findPrevIc - cseBBlock support function will return the iCode */
467 /* which matches the current one */
468 /*-----------------------------------------------------------------*/
469 DEFSETFUNC (findPrevIc)
473 V_ARG (iCode **, icp);
475 /* if already found */
479 /* if the iCodes are the same */
480 if (isiCodeEqual (ic, cdp->diCode) &&
481 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
487 /* if iCodes are not the same */
488 /* see the operands maybe interchanged */
489 if (ic->op == cdp->diCode->op &&
490 (ic->op == '+' || ic->op == '*') &&
491 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
492 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
501 /*-------------------------------------------------------------------*/
502 /* ifAssignedFromGlobal - if definition is an assignment from global */
503 /*-------------------------------------------------------------------*/
504 DEFSETFUNC (ifAssignedFromGlobal)
507 iCode *dic=cdp->diCode;
509 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
515 /*-------------------------------------------------------------------*/
516 /* ifFromGlobal - if definition is derived from global */
517 /*-------------------------------------------------------------------*/
518 DEFSETFUNC (ifFromGlobal)
522 return cdp->fromGlobal;
525 /*-----------------------------------------------------------------*/
526 /* ifDefGlobal - if definition is global */
527 /*-----------------------------------------------------------------*/
528 DEFSETFUNC (ifDefGlobal)
532 return (isOperandGlobal (cdp->sym));
535 /*-----------------------------------------------------------------*/
536 /* ifAnyGetPointer - if get pointer icode */
537 /*-----------------------------------------------------------------*/
538 DEFSETFUNC (ifAnyGetPointer)
542 if (cdp->diCode && POINTER_GET (cdp->diCode))
547 /*-----------------------------------------------------------------*/
548 /* ifOperandsHave - if any of the operand are the same as this */
549 /*-----------------------------------------------------------------*/
550 DEFSETFUNC (ifOperandsHave)
553 V_ARG (operand *, op);
555 if (bitVectBitValue(cdp->ancestors, op->key))
558 if (IC_LEFT (cdp->diCode) &&
559 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
560 IC_LEFT (cdp->diCode)->key == op->key)
563 if (IC_RIGHT (cdp->diCode) &&
564 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
565 IC_RIGHT (cdp->diCode)->key == op->key)
568 /* or if any of the operands are volatile */
569 if (IC_LEFT (cdp->diCode) &&
570 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
573 if (IC_RIGHT (cdp->diCode) &&
574 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
578 if (IC_RESULT (cdp->diCode) &&
579 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
585 /*-----------------------------------------------------------------*/
586 /* ifDefSymIs - if a definition is found in the set */
587 /*-----------------------------------------------------------------*/
589 ifDefSymIs (set * cseSet, operand * sym)
594 if (!sym || !IS_SYMOP (sym))
596 for (sl = cseSet; sl; sl = sl->next)
599 if (loop->sym->key == sym->key)
606 /*-----------------------------------------------------------------*/
607 /* ifDefSymIsX - will return 1 if the symbols match */
608 /*-----------------------------------------------------------------*/
609 DEFSETFUNC (ifDefSymIsX)
612 V_ARG (operand *, op);
616 match = cdp->sym->key == op->key;
618 match = (isOperandEqual (cdp->sym, op));
621 printf("%s ",OP_SYMBOL(cdp->sym)->name);
627 /*-----------------------------------------------------------------*/
628 /* ifDiCodeIs - returns truw if diCode is same */
629 /*-----------------------------------------------------------------*/
631 ifDiCodeIs (set * cseSet, iCode * ic)
639 for (sl = cseSet; sl; sl = sl->next)
642 if (loop->diCode == ic)
649 /*-----------------------------------------------------------------*/
650 /* ifPointerGet - returns true if the icode is pointer get sym */
651 /*-----------------------------------------------------------------*/
652 DEFSETFUNC (ifPointerGet)
655 V_ARG (operand *, op);
656 iCode *dic = cdp->diCode;
657 operand *left = IC_LEFT (cdp->diCode);
659 if (POINTER_GET (dic) && left->key == op->key)
665 /*-----------------------------------------------------------------*/
666 /* ifPointerSet - returns true if the icode is pointer set sym */
667 /*-----------------------------------------------------------------*/
668 DEFSETFUNC (ifPointerSet)
671 V_ARG (operand *, op);
673 if (POINTER_SET (cdp->diCode) &&
674 IC_RESULT (cdp->diCode)->key == op->key)
680 /*-----------------------------------------------------------------*/
681 /* ifDiCodeIsX - will return 1 if the symbols match */
682 /*-----------------------------------------------------------------*/
683 DEFSETFUNC (ifDiCodeIsX)
688 return cdp->diCode == ic;
692 /*-----------------------------------------------------------------*/
693 /* findBackwardDef - scan backwards to find deinition of operand */
694 /*-----------------------------------------------------------------*/
695 iCode *findBackwardDef(operand *op,iCode *ic)
699 for (lic = ic; lic ; lic = lic->prev) {
700 if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
706 /*-----------------------------------------------------------------*/
707 /* algebraicOpts - does some algebraic optimizations */
708 /*-----------------------------------------------------------------*/
710 algebraicOpts (iCode * ic, eBBlock * ebp)
712 /* we don't deal with the following iCodes
723 /* if both operands present & ! IFX */
724 /* then if they are both literal we */
725 /* perform the operation right now */
726 if (IC_RESULT (ic) &&
729 IS_OP_LITERAL (IC_LEFT (ic)) &&
730 IS_OP_LITERAL (IC_RIGHT (ic)))
733 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
736 operandType (IC_RESULT (ic)));
739 SET_RESULT_RIGHT (ic);
743 /* if not ifx & only one operand present */
744 if (IC_RESULT (ic) &&
746 IS_OP_LITERAL (IC_LEFT (ic)) &&
750 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
753 operandType (IC_RESULT (ic)));
756 SET_RESULT_RIGHT (ic);
761 /* a special case : or in short a kludgy solution will think
762 about a better solution over a glass of wine someday */
763 if (ic->op == GET_VALUE_AT_ADDRESS)
766 if (IS_ITEMP (IC_RESULT (ic)) &&
767 IS_TRUE_SYMOP (IC_LEFT (ic)))
771 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
772 IC_RIGHT (ic)->isaddr = 0;
774 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
775 IC_RESULT (ic)->isaddr = 0;
776 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
780 if (IS_ITEMP (IC_LEFT (ic)) &&
781 IS_ITEMP (IC_RESULT (ic)) &&
782 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
783 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
784 !IC_LEFT (ic)->isaddr)
787 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
788 IC_RIGHT (ic)->isaddr = 0;
789 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
790 IC_RESULT (ic)->isaddr = 0;
798 /* depending on the operation */
802 /* if adding the same thing change to left shift by 1 */
803 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
804 !IS_FLOAT (operandType (IC_RESULT (ic))))
807 IC_RIGHT (ic) = operandFromLit (1);
810 /* if addition then check if one of them is a zero */
811 /* if yes turn it into assignmnt or cast */
812 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
813 operandLitValue (IC_LEFT (ic)) == 0.0)
815 if (compareType (operandType (IC_RESULT (ic)),
816 operandType (IC_RIGHT (ic)))<0)
819 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
826 SET_ISADDR (IC_RESULT (ic), 0);
827 SET_ISADDR (IC_RIGHT (ic), 0);
830 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
831 operandLitValue (IC_RIGHT (ic)) == 0.0)
833 if (compareType (operandType (IC_RESULT (ic)),
834 operandType (IC_LEFT (ic)))<0)
837 IC_RIGHT (ic) = IC_LEFT (ic);
838 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
843 IC_RIGHT (ic) = IC_LEFT (ic);
846 SET_ISADDR (IC_RIGHT (ic), 0);
847 SET_ISADDR (IC_RESULT (ic), 0);
852 /* if subtracting the the same thing then zero */
853 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
856 IC_RIGHT (ic) = operandFromLit (0);
858 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
859 IC_RESULT (ic)->isaddr = 0;
863 /* if subtraction then check if one of the operand */
864 /* is zero then depending on which operand change */
865 /* to assignment or unary minus */
866 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
867 operandLitValue (IC_RIGHT (ic)) == 0.0)
869 /* right size zero change to assignment */
871 IC_RIGHT (ic) = IC_LEFT (ic);
873 SET_ISADDR (IC_RIGHT (ic), 0);
874 SET_ISADDR (IC_RESULT (ic), 0);
877 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
878 operandLitValue (IC_LEFT (ic)) == 0.0)
880 /* left zero turn into an unary minus */
882 IC_LEFT (ic) = IC_RIGHT (ic);
883 IC_RIGHT (ic) = NULL;
887 /* if multiplication then check if either of */
888 /* them is zero then the result is zero */
889 /* if either of them is one then result is */
892 if (IS_OP_LITERAL (IC_LEFT (ic)))
895 if (operandLitValue (IC_LEFT (ic)) == 0.0)
898 IC_RIGHT (ic) = IC_LEFT (ic);
900 SET_RESULT_RIGHT (ic);
903 if (operandLitValue (IC_LEFT (ic)) == 1.0)
905 /* '*' can have two unsigned chars as operands */
906 /* and an unsigned int as result. */
907 if (compareType (operandType (IC_RESULT (ic)),
908 operandType (IC_RIGHT (ic))) == 1)
912 SET_RESULT_RIGHT (ic);
917 IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
918 IC_LEFT (ic)->type = TYPE;
919 IC_LEFT (ic)->isLiteral = 0;
920 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
926 if (IS_OP_LITERAL (IC_RIGHT (ic)))
929 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
933 SET_RESULT_RIGHT (ic);
937 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
939 /* '*' can have two unsigned chars as operands */
940 /* and an unsigned int as result. */
941 if (compareType (operandType (IC_RESULT (ic)),
942 operandType (IC_LEFT (ic))) == 1)
945 IC_RIGHT (ic) = IC_LEFT (ic);
947 SET_RESULT_RIGHT (ic);
955 IC_RIGHT (ic) = IC_LEFT (ic);
956 IC_LEFT (ic) = operandFromOperand (op);
957 IC_LEFT (ic)->type = TYPE;
958 IC_LEFT (ic)->isLiteral = 0;
959 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
966 /* if division by self then 1 */
967 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
970 IC_RIGHT (ic) = operandFromLit (1);
972 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
973 IC_RESULT (ic)->isaddr = 0;
976 /* if this is a division then check if right */
977 /* is one then change it to an assignment */
978 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
979 operandLitValue (IC_RIGHT (ic)) == 1.0)
983 IC_RIGHT (ic) = IC_LEFT (ic);
985 SET_RESULT_RIGHT (ic);
989 /* if both are the same for an comparison operators */
993 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
996 IC_RIGHT (ic) = operandFromLit (1);
998 SET_RESULT_RIGHT (ic);
1004 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1007 IC_RIGHT (ic) = operandFromLit (0);
1008 IC_LEFT (ic) = NULL;
1009 SET_RESULT_RIGHT (ic);
1014 sym_link *otype = operandType(IC_RIGHT(ic));
1015 sym_link *ctype = operandType(IC_LEFT(ic));
1016 /* if this is a cast of a literal value */
1017 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1018 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
1021 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
1022 operandLitValue (IC_RIGHT (ic))));
1023 IC_LEFT (ic) = NULL;
1024 SET_ISADDR (IC_RESULT (ic), 0);
1026 /* if casting to the same */
1027 if (compareType (operandType (IC_RESULT (ic)),
1028 operandType (IC_RIGHT (ic))) == 1) {
1030 IC_LEFT (ic) = NULL;
1031 SET_ISADDR (IC_RESULT (ic), 0);
1036 if (IS_OP_LITERAL (IC_LEFT (ic)))
1040 (operandLitValue (IC_LEFT (ic)) == 0 ?
1041 operandFromLit (1) : operandFromLit (0));
1042 IC_LEFT (ic) = NULL;
1043 SET_ISADDR (IC_RESULT (ic), 0);
1047 /* if both operands are equal */
1048 /* if yes turn it into assignment */
1049 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1051 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1053 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1054 IC_RESULT (newic) = IC_LEFT (ic);
1055 newic->lineno = ic->lineno;
1056 addiCodeToeBBlock (ebp, newic, ic->next);
1059 IC_LEFT (ic) = NULL;
1060 SET_RESULT_RIGHT (ic);
1063 /* swap literal to right ic */
1064 if (IS_OP_LITERAL (IC_LEFT (ic)))
1069 IC_LEFT (ic) = IC_RIGHT (ic);
1072 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1074 /* if BITWISEAND then check if one of them is a zero */
1075 /* if yes turn it into 0 assignment */
1076 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1078 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1080 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1081 IC_RESULT (newic) = IC_LEFT (ic);
1082 newic->lineno = ic->lineno;
1083 addiCodeToeBBlock (ebp, newic, ic->next);
1086 IC_LEFT (ic) = NULL;
1087 SET_RESULT_RIGHT (ic);
1090 /* if BITWISEAND then check if one of them is 0xff... */
1091 /* if yes turn it into assignment */
1095 switch (getSize (operandType (IC_RIGHT (ic))))
1109 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1112 IC_RIGHT (ic) = IC_LEFT (ic);
1113 IC_LEFT (ic) = NULL;
1114 SET_RESULT_RIGHT (ic);
1121 /* if both operands are equal */
1122 /* if yes turn it into assignment */
1123 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1125 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1127 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1128 IC_RESULT (newic) = IC_LEFT (ic);
1129 newic->lineno = ic->lineno;
1130 addiCodeToeBBlock (ebp, newic, ic->next);
1133 IC_LEFT (ic) = NULL;
1134 SET_RESULT_RIGHT (ic);
1137 /* swap literal to right ic */
1138 if (IS_OP_LITERAL (IC_LEFT (ic)))
1143 IC_LEFT (ic) = IC_RIGHT (ic);
1146 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1148 /* if BITWISEOR then check if one of them is a zero */
1149 /* if yes turn it into assignment */
1150 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1153 IC_RIGHT (ic) = IC_LEFT (ic);
1154 IC_LEFT (ic) = NULL;
1155 SET_RESULT_RIGHT (ic);
1158 /* if BITWISEOR then check if one of them is 0xff... */
1159 /* if yes turn it into 0xff... assignment */
1163 switch (getSize (operandType (IC_RIGHT (ic))))
1177 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1179 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1181 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1182 IC_RESULT (newic) = IC_LEFT (ic);
1183 newic->lineno = ic->lineno;
1184 addiCodeToeBBlock (ebp, newic, ic->next);
1187 IC_LEFT (ic) = NULL;
1188 SET_RESULT_RIGHT (ic);
1195 /* if both operands are equal */
1196 /* if yes turn it into 0 assignment */
1197 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1199 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1201 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1202 IC_RESULT (newic) = IC_LEFT (ic);
1203 newic->lineno = ic->lineno;
1204 addiCodeToeBBlock (ebp, newic, ic->next);
1206 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1207 IC_RESULT (newic) = IC_LEFT (ic);
1208 newic->lineno = ic->lineno;
1209 addiCodeToeBBlock (ebp, newic, ic->next);
1212 IC_RIGHT (ic) = operandFromLit (0);
1213 IC_LEFT (ic) = NULL;
1214 SET_RESULT_RIGHT (ic);
1217 /* swap literal to right ic */
1218 if (IS_OP_LITERAL (IC_LEFT (ic)))
1223 IC_LEFT (ic) = IC_RIGHT (ic);
1226 /* if XOR then check if one of them is a zero */
1227 /* if yes turn it into assignment */
1228 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1230 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1233 IC_RIGHT (ic) = IC_LEFT (ic);
1234 IC_LEFT (ic) = NULL;
1235 SET_RESULT_RIGHT (ic);
1244 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1245 /*-----------------------------------------------------------------*/
1246 /* updateSpillLocation - keeps track of register spill location */
1247 /*-----------------------------------------------------------------*/
1249 updateSpillLocation (iCode * ic, int induction)
1253 if (POINTER_SET (ic))
1260 /* for the form true_symbol := iTempNN */
1261 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1262 !SPIL_LOC (IC_RIGHT (ic))) {
1264 setype = getSpec (operandType (IC_RESULT (ic)));
1266 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1267 !IS_VOLATILE (setype) &&
1268 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1269 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1271 wassert(IS_SYMOP(IC_RESULT (ic)));
1272 wassert(IS_SYMOP(IC_RIGHT (ic)));
1273 SPIL_LOC (IC_RIGHT (ic)) =
1274 IC_RESULT (ic)->operand.symOperand;
1280 #if 0 /* this needs furthur investigation can save a lot of code */
1281 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1282 !SPIL_LOC(IC_RESULT(ic))) {
1283 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1284 SPIL_LOC (IC_RESULT (ic)) =
1285 IC_RIGHT (ic)->operand.symOperand;
1288 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1290 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1291 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1292 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1294 setype = getSpec (operandType (IC_RESULT (ic)));
1296 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1297 !IS_VOLATILE (setype) &&
1298 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1299 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1301 SPIL_LOC (IC_RIGHT (ic)) =
1302 SPIL_LOC (IC_RESULT (ic));
1304 /* special case for inductions */
1306 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1307 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1308 !SPIL_LOC(IC_RESULT(ic))) {
1309 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1313 /*-----------------------------------------------------------------*/
1314 /* setUsesDef - sets the uses def bitvector for a given operand */
1315 /*-----------------------------------------------------------------*/
1317 setUsesDefs (operand * op, bitVect * bdefs,
1318 bitVect * idefs, bitVect ** oud)
1320 /* compute the definitions alive at this point */
1321 bitVect *adefs = bitVectUnion (bdefs, idefs);
1323 /* of these definitions find the ones that are */
1324 /* for this operand */
1325 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1327 /* these are the definitions that this operand can use */
1328 op->usesDefs = adefs;
1330 /* the out defs is an union */
1331 *oud = bitVectUnion (*oud, adefs);
1334 /*-----------------------------------------------------------------*/
1335 /* unsetDefsAndUses - clear this operation for the operands */
1336 /*-----------------------------------------------------------------*/
1338 unsetDefsAndUses (iCode * ic)
1340 if (ic->op == JUMPTABLE)
1343 /* take away this definition from the def chain of the */
1344 /* result & take away from use set of the operands */
1347 /* turn off def set */
1348 if (IS_SYMOP (IC_RESULT (ic)))
1350 if (!POINTER_SET (ic))
1351 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1353 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1355 /* turn off the useSet for the operands */
1356 if (IS_SYMOP (IC_LEFT (ic)))
1357 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1359 if (IS_SYMOP (IC_RIGHT (ic)))
1360 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1363 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1364 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1367 /*-----------------------------------------------------------------*/
1368 /* ifxOptimize - changes ifx conditions if it can */
1369 /*-----------------------------------------------------------------*/
1371 ifxOptimize (iCode * ic, set * cseSet,
1373 eBBlock * ebb, int *change,
1374 eBBlock ** ebbs, int count)
1379 /* if the condition can be replaced */
1383 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1386 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1391 /* if the conditional is a literal then */
1392 if (IS_OP_LITERAL (IC_COND (ic)))
1395 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1398 /* change to a goto */
1400 IC_LABEL (ic) = IC_TRUE (ic);
1407 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1410 IC_LABEL (ic) = IC_FALSE (ic);
1416 /* then kill this if condition */
1417 remiCodeFromeBBlock (ebb, ic);
1421 /* now we need to recompute the control flow */
1422 /* since the control flow has changed */
1423 /* this is very expensive but it does not happen */
1424 /* too often, if it does happen then the user pays */
1426 computeControlFlow (ebbs, count, 1);
1427 if (!options.lessPedantic) {
1428 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1433 /* if there is only one successor and that successor
1434 is the same one we are conditionally going to then
1435 we can remove this conditional statement */
1436 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1437 if (elementsInSet (ebb->succList) == 1 &&
1438 isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1441 if (!options.lessPedantic) {
1442 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1444 if (IS_OP_VOLATILE (IC_COND (ic)))
1446 IC_RIGHT (ic) = IC_COND (ic);
1447 IC_LEFT (ic) = NULL;
1448 IC_RESULT (ic) = NULL;
1449 ic->op = DUMMY_READ_VOLATILE;
1453 remiCodeFromeBBlock (ebb, ic);
1454 computeControlFlow (ebbs, count, 1);
1460 /* if it remains an IFX the update the use Set */
1463 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1464 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1466 else if (ic->op == DUMMY_READ_VOLATILE)
1468 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1469 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1474 /*-----------------------------------------------------------------*/
1475 /* diCodeForSym - finds the definiting instruction for a symbol */
1476 /*-----------------------------------------------------------------*/
1477 DEFSETFUNC (diCodeForSym)
1480 V_ARG (operand *, sym);
1481 V_ARG (iCode **, dic);
1483 /* if already found */
1487 /* if not if this is the defining iCode */
1488 if (sym->key == cdp->key)
1497 /*-----------------------------------------------------------------*/
1498 /* constFold - does some constant folding */
1499 /*-----------------------------------------------------------------*/
1501 constFold (iCode * ic, set * cseSet)
1505 /* this routine will change
1511 /* deal with only + & - */
1512 if (ic->op != '+' &&
1516 /* this check is a hueristic to prevent live ranges
1517 from becoming too long */
1518 if (IS_PTR (operandType (IC_RESULT (ic))))
1521 /* check if operation with a literal */
1522 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1525 /* check if we can find a definition for the
1527 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1530 /* check that this is also a +/- */
1531 if (dic->op != '+' && dic->op != '-')
1534 /* with a literal */
1535 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1538 /* find the definition of the left operand
1539 of dic.then check if this defined with a
1540 get_pointer return 0 if the pointer size is
1541 less than 2 (MCS51 specific) */
1542 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1545 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1548 /* it is if the operations are the same */
1549 /* the literal parts need to be added */
1550 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1551 if (ic->op == dic->op)
1552 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1553 operandLitValue (IC_RIGHT (dic)));
1555 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1556 operandLitValue (IC_RIGHT (dic)));
1558 if (IS_ITEMP (IC_RESULT (ic)))
1560 SPIL_LOC (IC_RESULT (ic)) = NULL;
1561 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1568 /*-----------------------------------------------------------------*/
1569 /* deleteGetPointers - called when a pointer is passed as parm */
1570 /* will delete from cseSet all get pointers computed from this */
1571 /* pointer. A simple ifOperandsHave is not good enough here */
1572 /*-----------------------------------------------------------------*/
1574 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1576 set *compItems = NULL;
1582 if (!*cseSet && !*pss)
1585 addSet (&compItems, op);
1587 /* Recursively find all items computed from this operand .
1588 This done fairly simply go thru the list and find
1589 those that are computed by arthimetic with these
1591 /* Also check for those computed from our computed
1592 list . This will take care of situations like
1593 iTemp1 = iTemp0 + 8;
1594 iTemp2 = iTemp1 + 8; */
1598 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1600 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1602 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1603 (insetwithFunc)isOperandEqual) ||
1604 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1605 (insetwithFunc)isOperandEqual))
1607 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1608 (insetwithFunc)isOperandEqual))
1610 addSet (&compItems, IC_RESULT (cdp->diCode));
1619 /* now for the computed items */
1620 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1622 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1623 deleteItemIf (cseSet, ifPointerGet, cop);
1624 deleteItemIf (cseSet, ifDefSymIsX, cop);
1625 deleteItemIf (pss, ifPointerSet, cop);
1629 /*-----------------------------------------------------------------*/
1630 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1631 /* dfnum > supplied */
1632 /*-----------------------------------------------------------------*/
1633 DEFSETFUNC (delGetPointerSucc)
1635 eBBlock *ebp = item;
1636 V_ARG (operand *, op);
1643 if (ebp->dfnum > dfnum)
1645 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1648 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1651 /*-----------------------------------------------------------------*/
1652 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1653 /*-----------------------------------------------------------------*/
1655 fixUpTypes (iCode * ic)
1657 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1659 /* if (TARGET_IS_DS390) */
1660 if (options.model == MODEL_FLAT24)
1666 /* for pointer_gets if the types of result & left r the
1667 same then change it type of result to next */
1669 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1671 setOperandType (IC_RESULT (ic), t2->next);
1675 /*-----------------------------------------------------------------*/
1676 /* isSignedOp - will return 1 if sign is important to operation */
1677 /*-----------------------------------------------------------------*/
1678 static int isSignedOp (iCode *ic)
1699 case GET_VALUE_AT_ADDRESS:
1727 dumpCseSet(set *cseSet)
1731 cseDef *item=cseSet->item;
1733 printOperand (item->sym, NULL);
1735 piCode (item->diCode, NULL);
1736 cseSet = cseSet->next;
1741 /*-----------------------------------------------------------------*/
1742 /* cseBBlock - common subexpression elimination for basic blocks */
1743 /* this is the hackiest kludgiest routine in the whole */
1744 /* system. also the most important, since almost all */
1745 /* data flow related information is computed by it */
1746 /*-----------------------------------------------------------------*/
1748 cseBBlock (eBBlock * ebb, int computeOnly,
1749 eBBlock ** ebbs, int count)
1755 set *ptrSetSet = NULL;
1758 /* if this block is not reachable */
1762 /* set of common subexpressions */
1763 cseSet = setFromSet (ebb->inExprs);
1765 /* these will be computed by this routine */
1766 setToNull ((void *) &ebb->outDefs);
1767 setToNull ((void *) &ebb->defSet);
1768 setToNull ((void *) &ebb->usesDefs);
1769 setToNull ((void *) &ebb->ptrsSet);
1770 setToNull ((void *) &ebb->addrOf);
1771 setToNull ((void *) &ebb->ldefs);
1773 ebb->outDefs = bitVectCopy (ebb->inDefs);
1774 bitVectDefault = iCodeKey;
1775 ebb->defSet = newBitVect (iCodeKey);
1776 ebb->usesDefs = newBitVect (iCodeKey);
1778 /* for all the instructions in this block do */
1779 for (ic = ebb->sch; ic; ic = ic->next)
1786 ic->eBBlockNum = ebb->bbnum;
1791 /* if this is an assignment from true symbol
1792 to a temp then do pointer post inc/dec optimzation */
1793 if (ic->op == '=' && !POINTER_SET (ic) &&
1794 IS_PTR (operandType (IC_RESULT (ic))))
1796 ptrPostIncDecOpt (ic);
1799 /* clear the def & use chains for the operands involved */
1800 /* in this operation . since it can change due to opts */
1801 unsetDefsAndUses (ic);
1803 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1805 /* add to defSet of the symbol */
1806 OP_DEFS(IC_RESULT (ic))=
1807 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1808 /* add to the definition set of this block */
1809 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1810 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1811 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1812 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1813 /* delete global variables from the cseSet
1814 since they can be modified by the function call */
1815 deleteItemIf (&cseSet, ifDefGlobal);
1817 /* and also itemps derived from globals */
1818 deleteItemIf (&cseSet, ifFromGlobal);
1820 /* delete all getpointer iCodes from cseSet, this should
1821 be done only for global arrays & pointers but at this
1822 point we don't know if globals, so to be safe do all */
1823 deleteItemIf (&cseSet, ifAnyGetPointer);
1825 /* can't cache pointer set/get operations across a call */
1826 deleteSet (&ptrSetSet);
1829 /* for pcall & ipush we need to add to the useSet */
1830 if ((ic->op == PCALL ||
1834 IS_SYMOP (IC_LEFT (ic)))
1837 /* check if they can be replaced */
1841 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1843 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1845 /* the lookup could have changed it */
1846 if (IS_SYMOP (IC_LEFT (ic)))
1848 OP_USES(IC_LEFT (ic))=
1849 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1850 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1851 ebb->outDefs, &ebb->usesDefs);
1855 /* if we a sending a pointer as a parameter
1856 then kill all cse since the pointed to item
1857 might be changed in the function being called */
1858 if ((ic->op == IPUSH || ic->op == SEND) &&
1859 IS_PTR (operandType (IC_LEFT (ic))))
1861 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1862 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1863 for (i = 0; i < count; ebbs[i++]->visited = 0);
1864 applyToSet (ebb->succList, delGetPointerSucc,
1865 IC_LEFT (ic), ebb->dfnum);
1870 /* if jumptable then mark the usage */
1871 if (ic->op == JUMPTABLE)
1873 if (IS_SYMOP (IC_JTCOND (ic)))
1875 OP_USES(IC_JTCOND (ic)) =
1876 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1877 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1878 ebb->outDefs, &ebb->usesDefs);
1887 /* do some algebraic optimizations if possible */
1888 algebraicOpts (ic, ebb);
1889 while (constFold (ic, cseSet));
1893 if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1895 setOperandType (IC_LEFT (ic),
1896 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1900 if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1902 setOperandType (IC_RESULT (ic),
1903 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1906 /* if this is a condition statement then */
1907 /* check if the condition can be replaced */
1910 ifxOptimize (ic, cseSet, computeOnly,
1916 /* if the assignment & result is a temp */
1917 /* see if we can replace it */
1918 if (!computeOnly && ic->op == '=')
1921 /* update the spill location for this */
1922 updateSpillLocation (ic,0);
1924 if (POINTER_SET (ic) &&
1925 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1928 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1929 if (pdop && !computeOnly &&
1930 IS_ITEMP (pdop) && IS_PTR(operandType(pdop)))
1931 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1935 checkSign = isSignedOp(ic);
1937 /* do the operand lookup i.e. for both the */
1938 /* right & left operand : check the cseSet */
1939 /* to see if they have been replaced if yes */
1940 /* then replace them with those from cseSet */
1942 /* and left is a symbol */
1943 if (IS_SYMOP (IC_LEFT (ic)) &&
1944 !computeOnly && ic->op != ADDRESS_OF)
1948 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1951 if (POINTER_GET (ic))
1953 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1955 /* some non dominating block does POINTER_SET with
1956 this variable .. unsafe to remove any POINTER_GETs */
1957 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1958 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1959 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1962 /* check if there is a pointer set
1963 for the same pointer visible if yes
1964 then change this into an assignment */
1966 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1967 !bitVectBitValue (ebb->ptrsSet, pdop->key))
1970 IC_LEFT (ic) = NULL;
1971 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1972 SET_ISADDR (IC_RESULT (ic), 0);
1978 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1985 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1989 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1991 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1996 /* if left or right changed then do algebraic */
1997 if (!computeOnly && change)
1999 algebraicOpts (ic, ebb);
2000 while (constFold (ic, cseSet));
2003 /* if after all this it becomes an assignment to self
2004 then delete it and continue */
2005 if (ASSIGNMENT_TO_SELF (ic))
2007 remiCodeFromeBBlock (ebb, ic);
2011 /* now we will check to see if the entire */
2012 /* operation has been performed before */
2013 /* and is available */
2014 /* don't do assignments they will be killed */
2015 /* by dead code elimination if required do */
2016 /* it only if result is a temporary */
2018 if (!(POINTER_GET (ic) &&
2019 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2020 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2021 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2023 IS_ITEMP (IC_RESULT (ic)) &&
2026 applyToSet (cseSet, findPrevIc, ic, &pdic);
2027 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2028 operandType (IC_RESULT (ic))) != 1)
2030 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2034 /* Alternate code */
2035 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2036 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2037 /* Mmm, found an equivalent pointer get at a lower level.
2038 This could be a loop however with the same pointer set
2041 /* if previous definition found change this to an assignment */
2044 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2045 SET_ISADDR(IC_RESULT(ic),0);
2046 SET_ISADDR(IC_RIGHT (ic),0);
2050 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2052 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2053 csed = newCseDef (IC_RESULT (ic), ic);
2054 updateCseDefAncestors (csed, cseSet);
2055 addSetHead (&cseSet, csed);
2059 /* if assignment to a parameter which is not
2060 mine and type is a pointer then delete
2061 pointerGets to take care of aliasing */
2062 if (ASSIGNMENT (ic) &&
2063 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2064 IS_PTR (operandType (IC_RESULT (ic))))
2066 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2067 for (i = 0; i < count; ebbs[i++]->visited = 0);
2068 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2069 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2072 /* if this is a pointerget then see if we can replace
2073 this with a previously assigned pointer value */
2074 if (POINTER_GET (ic) &&
2075 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2076 isOperandVolatile (IC_LEFT (ic), TRUE)))
2079 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2080 /* if we find it then locally replace all
2081 references to the result with what we assigned */
2084 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2088 /* delete from the cseSet anything that has */
2089 /* operands matching the result of this */
2090 /* except in case of pointer access */
2091 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2093 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2094 /* delete any previous definitions */
2095 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2099 /* add the left & right to the defUse set */
2100 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2102 OP_USES(IC_LEFT (ic))=
2103 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2104 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2108 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2110 OP_USES(IC_RIGHT (ic))=
2111 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2112 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2116 /* for the result it is special case, put the result */
2117 /* in the defuseSet if it a pointer or array access */
2118 if (POINTER_SET (defic))
2120 OP_USES(IC_RESULT (ic))=
2121 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2122 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2123 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2124 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2125 /* delete from inexpressions of all successors which
2126 have dfNum > than this block */
2127 for (i = 0; i < count; ebbs[i++]->visited = 0);
2128 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2130 /* delete from cseSet all other pointer sets
2132 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2133 /* add to the local pointerset set */
2134 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2137 /* add the result to defintion set */ if (IC_RESULT (ic))
2139 OP_DEFS(IC_RESULT (ic))=
2140 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2141 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2142 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2143 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2147 /* if this is an addressof instruction then */
2148 /* put the symbol in the address of list & */
2149 /* delete it from the cseSet */
2150 if (defic->op == ADDRESS_OF)
2152 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2153 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2157 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2158 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2159 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2160 addSetHead (&ebb->killedExprs, expr);
2162 setToNull ((void *) &ebb->outExprs);
2163 ebb->outExprs = cseSet;
2164 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2165 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2169 /*-----------------------------------------------------------------*/
2170 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2171 /*-----------------------------------------------------------------*/
2173 cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
2178 /* if optimization turned off */
2180 for (i = 0; i < count; i++)
2181 change += cseBBlock (ebbs[i], computeOnly, ebbs, count);