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));
1303 OP_SYMBOL (IC_RIGHT (ic))->prereqv =
1304 OP_SYMBOL (IC_RESULT (ic))->prereqv;
1307 /* special case for inductions */
1309 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1310 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1311 !SPIL_LOC(IC_RESULT(ic))) {
1312 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1313 OP_SYMBOL (IC_RESULT (ic))->prereqv =
1314 OP_SYMBOL (IC_RIGHT (ic))->prereqv;
1318 /*-----------------------------------------------------------------*/
1319 /* setUsesDef - sets the uses def bitvector for a given operand */
1320 /*-----------------------------------------------------------------*/
1322 setUsesDefs (operand * op, bitVect * bdefs,
1323 bitVect * idefs, bitVect ** oud)
1325 /* compute the definitions alive at this point */
1326 bitVect *adefs = bitVectUnion (bdefs, idefs);
1328 /* of these definitions find the ones that are */
1329 /* for this operand */
1330 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1332 /* these are the definitions that this operand can use */
1333 op->usesDefs = adefs;
1335 /* the out defs is an union */
1336 *oud = bitVectUnion (*oud, adefs);
1339 /*-----------------------------------------------------------------*/
1340 /* unsetDefsAndUses - clear this operation for the operands */
1341 /*-----------------------------------------------------------------*/
1343 unsetDefsAndUses (iCode * ic)
1345 if (ic->op == JUMPTABLE)
1348 /* take away this definition from the def chain of the */
1349 /* result & take away from use set of the operands */
1352 /* turn off def set */
1353 if (IS_SYMOP (IC_RESULT (ic)))
1355 if (!POINTER_SET (ic))
1356 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1358 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1360 /* turn off the useSet for the operands */
1361 if (IS_SYMOP (IC_LEFT (ic)))
1362 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1364 if (IS_SYMOP (IC_RIGHT (ic)))
1365 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1368 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1369 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1372 /*-----------------------------------------------------------------*/
1373 /* ifxOptimize - changes ifx conditions if it can */
1374 /*-----------------------------------------------------------------*/
1376 ifxOptimize (iCode * ic, set * cseSet,
1378 eBBlock * ebb, int *change,
1379 eBBlock ** ebbs, int count)
1384 /* if the condition can be replaced */
1388 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1391 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1396 /* if the conditional is a literal then */
1397 if (IS_OP_LITERAL (IC_COND (ic)))
1400 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1403 /* change to a goto */
1405 IC_LABEL (ic) = IC_TRUE (ic);
1412 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1415 IC_LABEL (ic) = IC_FALSE (ic);
1421 /* then kill this if condition */
1422 remiCodeFromeBBlock (ebb, ic);
1426 /* now we need to recompute the control flow */
1427 /* since the control flow has changed */
1428 /* this is very expensive but it does not happen */
1429 /* too often, if it does happen then the user pays */
1431 computeControlFlow (ebbs, count, 1);
1432 if (!options.lessPedantic) {
1433 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1438 /* if there is only one successor and that successor
1439 is the same one we are conditionally going to then
1440 we can remove this conditional statement */
1441 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1442 if (elementsInSet (ebb->succList) == 1 &&
1443 isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1446 if (!options.lessPedantic) {
1447 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1449 if (IS_OP_VOLATILE (IC_COND (ic)))
1451 IC_RIGHT (ic) = IC_COND (ic);
1452 IC_LEFT (ic) = NULL;
1453 IC_RESULT (ic) = NULL;
1454 ic->op = DUMMY_READ_VOLATILE;
1458 remiCodeFromeBBlock (ebb, ic);
1459 computeControlFlow (ebbs, count, 1);
1465 /* if it remains an IFX the update the use Set */
1468 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1469 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1471 else if (ic->op == DUMMY_READ_VOLATILE)
1473 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1474 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1479 /*-----------------------------------------------------------------*/
1480 /* diCodeForSym - finds the definiting instruction for a symbol */
1481 /*-----------------------------------------------------------------*/
1482 DEFSETFUNC (diCodeForSym)
1485 V_ARG (operand *, sym);
1486 V_ARG (iCode **, dic);
1488 /* if already found */
1492 /* if not if this is the defining iCode */
1493 if (sym->key == cdp->key)
1502 /*-----------------------------------------------------------------*/
1503 /* constFold - does some constant folding */
1504 /*-----------------------------------------------------------------*/
1506 constFold (iCode * ic, set * cseSet)
1510 /* this routine will change
1516 /* deal with only + & - */
1517 if (ic->op != '+' &&
1521 /* this check is a hueristic to prevent live ranges
1522 from becoming too long */
1523 if (IS_PTR (operandType (IC_RESULT (ic))))
1526 /* check if operation with a literal */
1527 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1530 /* check if we can find a definition for the
1532 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1535 /* check that this is also a +/- */
1536 if (dic->op != '+' && dic->op != '-')
1539 /* with a literal */
1540 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1543 /* find the definition of the left operand
1544 of dic.then check if this defined with a
1545 get_pointer return 0 if the pointer size is
1546 less than 2 (MCS51 specific) */
1547 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1550 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1553 /* it is if the operations are the same */
1554 /* the literal parts need to be added */
1555 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1556 if (ic->op == dic->op)
1557 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1558 operandLitValue (IC_RIGHT (dic)));
1560 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1561 operandLitValue (IC_RIGHT (dic)));
1563 if (IS_ITEMP (IC_RESULT (ic)))
1565 SPIL_LOC (IC_RESULT (ic)) = NULL;
1566 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1573 /*-----------------------------------------------------------------*/
1574 /* deleteGetPointers - called when a pointer is passed as parm */
1575 /* will delete from cseSet all get pointers computed from this */
1576 /* pointer. A simple ifOperandsHave is not good enough here */
1577 /*-----------------------------------------------------------------*/
1579 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1581 set *compItems = NULL;
1587 if (!*cseSet && !*pss)
1590 addSet (&compItems, op);
1592 /* Recursively find all items computed from this operand .
1593 This done fairly simply go thru the list and find
1594 those that are computed by arthimetic with these
1596 /* Also check for those computed from our computed
1597 list . This will take care of situations like
1598 iTemp1 = iTemp0 + 8;
1599 iTemp2 = iTemp1 + 8; */
1603 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1605 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1607 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1608 (insetwithFunc)isOperandEqual) ||
1609 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1610 (insetwithFunc)isOperandEqual))
1612 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1613 (insetwithFunc)isOperandEqual))
1615 addSet (&compItems, IC_RESULT (cdp->diCode));
1624 /* now for the computed items */
1625 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1627 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1628 deleteItemIf (cseSet, ifPointerGet, cop);
1629 deleteItemIf (cseSet, ifDefSymIsX, cop);
1630 deleteItemIf (pss, ifPointerSet, cop);
1634 /*-----------------------------------------------------------------*/
1635 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1636 /* dfnum > supplied */
1637 /*-----------------------------------------------------------------*/
1638 DEFSETFUNC (delGetPointerSucc)
1640 eBBlock *ebp = item;
1641 V_ARG (operand *, op);
1648 if (ebp->dfnum > dfnum)
1650 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1653 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1656 /*-----------------------------------------------------------------*/
1657 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1658 /*-----------------------------------------------------------------*/
1660 fixUpTypes (iCode * ic)
1662 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1664 /* if (TARGET_IS_DS390) */
1665 if (options.model == MODEL_FLAT24)
1671 /* for pointer_gets if the types of result & left r the
1672 same then change it type of result to next */
1674 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1676 setOperandType (IC_RESULT (ic), t2->next);
1680 /*-----------------------------------------------------------------*/
1681 /* isSignedOp - will return 1 if sign is important to operation */
1682 /*-----------------------------------------------------------------*/
1683 static int isSignedOp (iCode *ic)
1704 case GET_VALUE_AT_ADDRESS:
1732 dumpCseSet(set *cseSet)
1736 cseDef *item=cseSet->item;
1738 printOperand (item->sym, NULL);
1740 piCode (item->diCode, NULL);
1741 cseSet = cseSet->next;
1746 /*-----------------------------------------------------------------*/
1747 /* cseBBlock - common subexpression elimination for basic blocks */
1748 /* this is the hackiest kludgiest routine in the whole */
1749 /* system. also the most important, since almost all */
1750 /* data flow related information is computed by it */
1751 /*-----------------------------------------------------------------*/
1753 cseBBlock (eBBlock * ebb, int computeOnly,
1754 eBBlock ** ebbs, int count)
1760 set *ptrSetSet = NULL;
1763 /* if this block is not reachable */
1767 /* set of common subexpressions */
1768 cseSet = setFromSet (ebb->inExprs);
1770 /* these will be computed by this routine */
1771 setToNull ((void *) &ebb->outDefs);
1772 setToNull ((void *) &ebb->defSet);
1773 setToNull ((void *) &ebb->usesDefs);
1774 setToNull ((void *) &ebb->ptrsSet);
1775 setToNull ((void *) &ebb->addrOf);
1776 setToNull ((void *) &ebb->ldefs);
1778 ebb->outDefs = bitVectCopy (ebb->inDefs);
1779 bitVectDefault = iCodeKey;
1780 ebb->defSet = newBitVect (iCodeKey);
1781 ebb->usesDefs = newBitVect (iCodeKey);
1783 /* for all the instructions in this block do */
1784 for (ic = ebb->sch; ic; ic = ic->next)
1791 ic->eBBlockNum = ebb->bbnum;
1796 /* if this is an assignment from true symbol
1797 to a temp then do pointer post inc/dec optimzation */
1798 if (ic->op == '=' && !POINTER_SET (ic) &&
1799 IS_PTR (operandType (IC_RESULT (ic))))
1801 ptrPostIncDecOpt (ic);
1804 /* clear the def & use chains for the operands involved */
1805 /* in this operation . since it can change due to opts */
1806 unsetDefsAndUses (ic);
1808 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1810 /* add to defSet of the symbol */
1811 OP_DEFS(IC_RESULT (ic))=
1812 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1813 /* add to the definition set of this block */
1814 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1815 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1816 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1817 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1818 /* delete global variables from the cseSet
1819 since they can be modified by the function call */
1820 deleteItemIf (&cseSet, ifDefGlobal);
1822 /* and also itemps derived from globals */
1823 deleteItemIf (&cseSet, ifFromGlobal);
1825 /* delete all getpointer iCodes from cseSet, this should
1826 be done only for global arrays & pointers but at this
1827 point we don't know if globals, so to be safe do all */
1828 deleteItemIf (&cseSet, ifAnyGetPointer);
1830 /* can't cache pointer set/get operations across a call */
1831 deleteSet (&ptrSetSet);
1834 /* for pcall & ipush we need to add to the useSet */
1835 if ((ic->op == PCALL ||
1839 IS_SYMOP (IC_LEFT (ic)))
1842 /* check if they can be replaced */
1846 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1848 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1850 /* the lookup could have changed it */
1851 if (IS_SYMOP (IC_LEFT (ic)))
1853 OP_USES(IC_LEFT (ic))=
1854 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1855 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1856 ebb->outDefs, &ebb->usesDefs);
1860 /* if we a sending a pointer as a parameter
1861 then kill all cse since the pointed to item
1862 might be changed in the function being called */
1863 if ((ic->op == IPUSH || ic->op == SEND) &&
1864 IS_PTR (operandType (IC_LEFT (ic))))
1866 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1867 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1868 for (i = 0; i < count; ebbs[i++]->visited = 0);
1869 applyToSet (ebb->succList, delGetPointerSucc,
1870 IC_LEFT (ic), ebb->dfnum);
1875 /* if jumptable then mark the usage */
1876 if (ic->op == JUMPTABLE)
1878 if (IS_SYMOP (IC_JTCOND (ic)))
1880 OP_USES(IC_JTCOND (ic)) =
1881 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1882 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1883 ebb->outDefs, &ebb->usesDefs);
1892 /* do some algebraic optimizations if possible */
1893 algebraicOpts (ic, ebb);
1894 while (constFold (ic, cseSet));
1898 if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1900 setOperandType (IC_LEFT (ic),
1901 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1905 if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1907 setOperandType (IC_RESULT (ic),
1908 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1911 /* if this is a condition statement then */
1912 /* check if the condition can be replaced */
1915 ifxOptimize (ic, cseSet, computeOnly,
1921 /* if the assignment & result is a temp */
1922 /* see if we can replace it */
1923 if (!computeOnly && ic->op == '=')
1926 /* update the spill location for this */
1927 updateSpillLocation (ic,0);
1929 if (POINTER_SET (ic) &&
1930 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1933 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1934 if (pdop && !computeOnly && IS_ITEMP (pdop))
1936 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1937 if (!IS_PTR (operandType (IC_RESULT (ic))))
1939 setOperandType (IC_RESULT (ic),
1940 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1946 checkSign = isSignedOp(ic);
1948 /* do the operand lookup i.e. for both the */
1949 /* right & left operand : check the cseSet */
1950 /* to see if they have been replaced if yes */
1951 /* then replace them with those from cseSet */
1953 /* and left is a symbol */
1954 if (IS_SYMOP (IC_LEFT (ic)) &&
1955 !computeOnly && ic->op != ADDRESS_OF)
1959 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1962 if (POINTER_GET (ic))
1964 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1966 /* some non dominating block does POINTER_SET with
1967 this variable .. unsafe to remove any POINTER_GETs */
1968 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1969 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1970 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1973 /* check if there is a pointer set
1974 for the same pointer visible if yes
1975 then change this into an assignment */
1977 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1978 !bitVectBitValue (ebb->ptrsSet, pdop->key))
1981 IC_LEFT (ic) = NULL;
1982 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1983 SET_ISADDR (IC_RESULT (ic), 0);
1989 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1996 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2000 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2002 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2007 /* if left or right changed then do algebraic */
2008 if (!computeOnly && change)
2010 algebraicOpts (ic, ebb);
2011 while (constFold (ic, cseSet));
2014 /* if after all this it becomes an assignment to self
2015 then delete it and continue */
2016 if (ASSIGNMENT_TO_SELF (ic))
2018 remiCodeFromeBBlock (ebb, ic);
2022 /* now we will check to see if the entire */
2023 /* operation has been performed before */
2024 /* and is available */
2025 /* don't do assignments they will be killed */
2026 /* by dead code elimination if required do */
2027 /* it only if result is a temporary */
2029 if (!(POINTER_GET (ic) &&
2030 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2031 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2032 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2034 IS_ITEMP (IC_RESULT (ic)) &&
2037 applyToSet (cseSet, findPrevIc, ic, &pdic);
2038 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2039 operandType (IC_RESULT (ic))) != 1)
2041 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2045 /* Alternate code */
2046 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2047 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2048 /* Mmm, found an equivalent pointer get at a lower level.
2049 This could be a loop however with the same pointer set
2052 /* if previous definition found change this to an assignment */
2055 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2056 SET_ISADDR(IC_RESULT(ic),0);
2057 SET_ISADDR(IC_RIGHT (ic),0);
2061 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2063 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2064 csed = newCseDef (IC_RESULT (ic), ic);
2065 updateCseDefAncestors (csed, cseSet);
2066 addSetHead (&cseSet, csed);
2070 /* if assignment to a parameter which is not
2071 mine and type is a pointer then delete
2072 pointerGets to take care of aliasing */
2073 if (ASSIGNMENT (ic) &&
2074 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2075 IS_PTR (operandType (IC_RESULT (ic))))
2077 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2078 for (i = 0; i < count; ebbs[i++]->visited = 0);
2079 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2080 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2083 /* if this is a pointerget then see if we can replace
2084 this with a previously assigned pointer value */
2085 if (POINTER_GET (ic) &&
2086 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2087 isOperandVolatile (IC_LEFT (ic), TRUE)))
2090 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2091 /* if we find it then locally replace all
2092 references to the result with what we assigned */
2095 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2099 /* delete from the cseSet anything that has */
2100 /* operands matching the result of this */
2101 /* except in case of pointer access */
2102 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2104 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2105 /* delete any previous definitions */
2106 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2110 /* add the left & right to the defUse set */
2111 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2113 OP_USES(IC_LEFT (ic))=
2114 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2115 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2119 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2121 OP_USES(IC_RIGHT (ic))=
2122 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2123 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2127 /* for the result it is special case, put the result */
2128 /* in the defuseSet if it a pointer or array access */
2129 if (POINTER_SET (defic))
2131 OP_USES(IC_RESULT (ic))=
2132 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2133 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2134 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2135 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2136 /* delete from inexpressions of all successors which
2137 have dfNum > than this block */
2138 for (i = 0; i < count; ebbs[i++]->visited = 0);
2139 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2141 /* delete from cseSet all other pointer sets
2143 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2144 /* add to the local pointerset set */
2145 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2148 /* add the result to defintion set */ if (IC_RESULT (ic))
2150 OP_DEFS(IC_RESULT (ic))=
2151 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2152 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2153 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2154 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2158 /* if this is an addressof instruction then */
2159 /* put the symbol in the address of list & */
2160 /* delete it from the cseSet */
2161 if (defic->op == ADDRESS_OF)
2163 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2164 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2168 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2169 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2170 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2171 addSetHead (&ebb->killedExprs, expr);
2173 setToNull ((void *) &ebb->outExprs);
2174 ebb->outExprs = cseSet;
2175 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2176 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2180 /*-----------------------------------------------------------------*/
2181 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2182 /*-----------------------------------------------------------------*/
2184 cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
2189 /* if optimization turned off */
2191 for (i = 0; i < count; i++)
2192 change += cseBBlock (ebbs[i], computeOnly, ebbs, count);