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)->type = TYPE;
918 IC_LEFT (ic)->isLiteral = 0;
919 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
925 if (IS_OP_LITERAL (IC_RIGHT (ic)))
928 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
932 SET_RESULT_RIGHT (ic);
936 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
938 /* '*' can have two unsigned chars as operands */
939 /* and an unsigned int as result. */
940 if (compareType (operandType (IC_RESULT (ic)),
941 operandType (IC_LEFT (ic))) == 1)
944 IC_RIGHT (ic) = IC_LEFT (ic);
946 SET_RESULT_RIGHT (ic);
954 IC_RIGHT (ic) = IC_LEFT (ic);
956 IC_LEFT (ic)->type = TYPE;
957 IC_LEFT (ic)->isLiteral = 0;
958 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
965 /* if division by self then 1 */
966 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
969 IC_RIGHT (ic) = operandFromLit (1);
971 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
972 IC_RESULT (ic)->isaddr = 0;
975 /* if this is a division then check if right */
976 /* is one then change it to an assignment */
977 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
978 operandLitValue (IC_RIGHT (ic)) == 1.0)
982 IC_RIGHT (ic) = IC_LEFT (ic);
984 SET_RESULT_RIGHT (ic);
988 /* if both are the same for an comparison operators */
992 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
995 IC_RIGHT (ic) = operandFromLit (1);
997 SET_RESULT_RIGHT (ic);
1003 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1006 IC_RIGHT (ic) = operandFromLit (0);
1007 IC_LEFT (ic) = NULL;
1008 SET_RESULT_RIGHT (ic);
1013 sym_link *otype = operandType(IC_RIGHT(ic));
1014 sym_link *ctype = operandType(IC_LEFT(ic));
1015 /* if this is a cast of a literal value */
1016 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1017 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
1020 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
1021 operandLitValue (IC_RIGHT (ic))));
1022 IC_LEFT (ic) = NULL;
1023 SET_ISADDR (IC_RESULT (ic), 0);
1025 /* if casting to the same */
1026 if (compareType (operandType (IC_RESULT (ic)),
1027 operandType (IC_RIGHT (ic))) == 1) {
1029 IC_LEFT (ic) = NULL;
1030 SET_ISADDR (IC_RESULT (ic), 0);
1035 if (IS_OP_LITERAL (IC_LEFT (ic)))
1039 (operandLitValue (IC_LEFT (ic)) == 0 ?
1040 operandFromLit (1) : operandFromLit (0));
1041 IC_LEFT (ic) = NULL;
1042 SET_ISADDR (IC_RESULT (ic), 0);
1046 /* if both operands are equal */
1047 /* if yes turn it into assignment */
1048 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1050 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1052 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1053 IC_RESULT (newic) = IC_LEFT (ic);
1054 newic->lineno = ic->lineno;
1055 addiCodeToeBBlock (ebp, newic, ic->next);
1058 IC_LEFT (ic) = NULL;
1059 SET_RESULT_RIGHT (ic);
1062 /* swap literal to right ic */
1063 if (IS_OP_LITERAL (IC_LEFT (ic)))
1068 IC_LEFT (ic) = IC_RIGHT (ic);
1071 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1073 /* if BITWISEAND then check if one of them is a zero */
1074 /* if yes turn it into 0 assignment */
1075 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1077 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1079 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1080 IC_RESULT (newic) = IC_LEFT (ic);
1081 newic->lineno = ic->lineno;
1082 addiCodeToeBBlock (ebp, newic, ic->next);
1085 IC_LEFT (ic) = NULL;
1086 SET_RESULT_RIGHT (ic);
1089 /* if BITWISEAND then check if one of them is 0xff... */
1090 /* if yes turn it into assignment */
1094 switch (getSize (operandType (IC_RIGHT (ic))))
1108 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1111 IC_RIGHT (ic) = IC_LEFT (ic);
1112 IC_LEFT (ic) = NULL;
1113 SET_RESULT_RIGHT (ic);
1120 /* if both operands are equal */
1121 /* if yes turn it into assignment */
1122 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1124 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1126 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1127 IC_RESULT (newic) = IC_LEFT (ic);
1128 newic->lineno = ic->lineno;
1129 addiCodeToeBBlock (ebp, newic, ic->next);
1132 IC_LEFT (ic) = NULL;
1133 SET_RESULT_RIGHT (ic);
1136 /* swap literal to right ic */
1137 if (IS_OP_LITERAL (IC_LEFT (ic)))
1142 IC_LEFT (ic) = IC_RIGHT (ic);
1145 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1147 /* if BITWISEOR then check if one of them is a zero */
1148 /* if yes turn it into assignment */
1149 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1152 IC_RIGHT (ic) = IC_LEFT (ic);
1153 IC_LEFT (ic) = NULL;
1154 SET_RESULT_RIGHT (ic);
1157 /* if BITWISEOR then check if one of them is 0xff... */
1158 /* if yes turn it into 0xff... assignment */
1162 switch (getSize (operandType (IC_RIGHT (ic))))
1176 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1178 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1180 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1181 IC_RESULT (newic) = IC_LEFT (ic);
1182 newic->lineno = ic->lineno;
1183 addiCodeToeBBlock (ebp, newic, ic->next);
1186 IC_LEFT (ic) = NULL;
1187 SET_RESULT_RIGHT (ic);
1194 /* if both operands are equal */
1195 /* if yes turn it into 0 assignment */
1196 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1198 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1200 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1201 IC_RESULT (newic) = IC_LEFT (ic);
1202 newic->lineno = ic->lineno;
1203 addiCodeToeBBlock (ebp, newic, ic->next);
1205 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1206 IC_RESULT (newic) = IC_LEFT (ic);
1207 newic->lineno = ic->lineno;
1208 addiCodeToeBBlock (ebp, newic, ic->next);
1211 IC_RIGHT (ic) = operandFromLit (0);
1212 IC_LEFT (ic) = NULL;
1213 SET_RESULT_RIGHT (ic);
1216 /* swap literal to right ic */
1217 if (IS_OP_LITERAL (IC_LEFT (ic)))
1222 IC_LEFT (ic) = IC_RIGHT (ic);
1225 /* if XOR then check if one of them is a zero */
1226 /* if yes turn it into assignment */
1227 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1229 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1232 IC_RIGHT (ic) = IC_LEFT (ic);
1233 IC_LEFT (ic) = NULL;
1234 SET_RESULT_RIGHT (ic);
1243 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1244 /*-----------------------------------------------------------------*/
1245 /* updateSpillLocation - keeps track of register spill location */
1246 /*-----------------------------------------------------------------*/
1248 updateSpillLocation (iCode * ic, int induction)
1252 if (POINTER_SET (ic))
1259 /* for the form true_symbol := iTempNN */
1260 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1261 !SPIL_LOC (IC_RIGHT (ic))) {
1263 setype = getSpec (operandType (IC_RESULT (ic)));
1265 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1266 !IS_VOLATILE (setype) &&
1267 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1268 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1270 wassert(IS_SYMOP(IC_RESULT (ic)));
1271 wassert(IS_SYMOP(IC_RIGHT (ic)));
1272 SPIL_LOC (IC_RIGHT (ic)) =
1273 IC_RESULT (ic)->operand.symOperand;
1279 #if 0 /* this needs furthur investigation can save a lot of code */
1280 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1281 !SPIL_LOC(IC_RESULT(ic))) {
1282 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1283 SPIL_LOC (IC_RESULT (ic)) =
1284 IC_RIGHT (ic)->operand.symOperand;
1287 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1289 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1290 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1291 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1293 setype = getSpec (operandType (IC_RESULT (ic)));
1295 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1296 !IS_VOLATILE (setype) &&
1297 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1298 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1300 SPIL_LOC (IC_RIGHT (ic)) =
1301 SPIL_LOC (IC_RESULT (ic));
1303 /* special case for inductions */
1305 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1306 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1307 !SPIL_LOC(IC_RESULT(ic))) {
1308 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1312 /*-----------------------------------------------------------------*/
1313 /* setUsesDef - sets the uses def bitvector for a given operand */
1314 /*-----------------------------------------------------------------*/
1316 setUsesDefs (operand * op, bitVect * bdefs,
1317 bitVect * idefs, bitVect ** oud)
1319 /* compute the definitions alive at this point */
1320 bitVect *adefs = bitVectUnion (bdefs, idefs);
1322 /* of these definitions find the ones that are */
1323 /* for this operand */
1324 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1326 /* these are the definitions that this operand can use */
1327 op->usesDefs = adefs;
1329 /* the out defs is an union */
1330 *oud = bitVectUnion (*oud, adefs);
1333 /*-----------------------------------------------------------------*/
1334 /* unsetDefsAndUses - clear this operation for the operands */
1335 /*-----------------------------------------------------------------*/
1337 unsetDefsAndUses (iCode * ic)
1339 if (ic->op == JUMPTABLE)
1342 /* take away this definition from the def chain of the */
1343 /* result & take away from use set of the operands */
1346 /* turn off def set */
1347 if (IS_SYMOP (IC_RESULT (ic)))
1349 if (!POINTER_SET (ic))
1350 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1352 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1354 /* turn off the useSet for the operands */
1355 if (IS_SYMOP (IC_LEFT (ic)))
1356 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1358 if (IS_SYMOP (IC_RIGHT (ic)))
1359 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1362 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1363 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1366 /*-----------------------------------------------------------------*/
1367 /* ifxOptimize - changes ifx conditions if it can */
1368 /*-----------------------------------------------------------------*/
1370 ifxOptimize (iCode * ic, set * cseSet,
1372 eBBlock * ebb, int *change,
1373 eBBlock ** ebbs, int count)
1378 /* if the condition can be replaced */
1382 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1385 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1390 /* if the conditional is a literal then */
1391 if (IS_OP_LITERAL (IC_COND (ic)))
1394 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1397 /* change to a goto */
1399 IC_LABEL (ic) = IC_TRUE (ic);
1406 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1409 IC_LABEL (ic) = IC_FALSE (ic);
1415 /* then kill this if condition */
1416 remiCodeFromeBBlock (ebb, ic);
1420 /* now we need to recompute the control flow */
1421 /* since the control flow has changed */
1422 /* this is very expensive but it does not happen */
1423 /* too often, if it does happen then the user pays */
1425 computeControlFlow (ebbs, count, 1);
1426 if (!options.lessPedantic) {
1427 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1432 /* if there is only one successor and that successor
1433 is the same one we are conditionally going to then
1434 we can remove this conditional statement */
1435 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1436 if (elementsInSet (ebb->succList) == 1 &&
1437 isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1440 if (!options.lessPedantic) {
1441 werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
1443 if (IS_OP_VOLATILE (IC_COND (ic)))
1445 IC_RIGHT (ic) = IC_COND (ic);
1446 IC_LEFT (ic) = NULL;
1447 IC_RESULT (ic) = NULL;
1448 ic->op = DUMMY_READ_VOLATILE;
1452 remiCodeFromeBBlock (ebb, ic);
1453 computeControlFlow (ebbs, count, 1);
1459 /* if it remains an IFX the update the use Set */
1462 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1463 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1465 else if (ic->op == DUMMY_READ_VOLATILE)
1467 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1468 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1473 /*-----------------------------------------------------------------*/
1474 /* diCodeForSym - finds the definiting instruction for a symbol */
1475 /*-----------------------------------------------------------------*/
1476 DEFSETFUNC (diCodeForSym)
1479 V_ARG (operand *, sym);
1480 V_ARG (iCode **, dic);
1482 /* if already found */
1486 /* if not if this is the defining iCode */
1487 if (sym->key == cdp->key)
1496 /*-----------------------------------------------------------------*/
1497 /* constFold - does some constant folding */
1498 /*-----------------------------------------------------------------*/
1500 constFold (iCode * ic, set * cseSet)
1504 /* this routine will change
1510 /* deal with only + & - */
1511 if (ic->op != '+' &&
1515 /* this check is a hueristic to prevent live ranges
1516 from becoming too long */
1517 if (IS_PTR (operandType (IC_RESULT (ic))))
1520 /* check if operation with a literal */
1521 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1524 /* check if we can find a definition for the
1526 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1529 /* check that this is also a +/- */
1530 if (dic->op != '+' && dic->op != '-')
1533 /* with a literal */
1534 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1537 /* find the definition of the left operand
1538 of dic.then check if this defined with a
1539 get_pointer return 0 if the pointer size is
1540 less than 2 (MCS51 specific) */
1541 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1544 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1547 /* it is if the operations are the same */
1548 /* the literal parts need to be added */
1549 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1550 if (ic->op == dic->op)
1551 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1552 operandLitValue (IC_RIGHT (dic)));
1554 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1555 operandLitValue (IC_RIGHT (dic)));
1557 if (IS_ITEMP (IC_RESULT (ic)))
1559 SPIL_LOC (IC_RESULT (ic)) = NULL;
1560 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1567 /*-----------------------------------------------------------------*/
1568 /* deleteGetPointers - called when a pointer is passed as parm */
1569 /* will delete from cseSet all get pointers computed from this */
1570 /* pointer. A simple ifOperandsHave is not good enough here */
1571 /*-----------------------------------------------------------------*/
1573 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1575 set *compItems = NULL;
1581 if (!*cseSet && !*pss)
1584 addSet (&compItems, op);
1586 /* Recursively find all items computed from this operand .
1587 This done fairly simply go thru the list and find
1588 those that are computed by arthimetic with these
1590 /* Also check for those computed from our computed
1591 list . This will take care of situations like
1592 iTemp1 = iTemp0 + 8;
1593 iTemp2 = iTemp1 + 8; */
1597 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1599 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1601 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1602 (insetwithFunc)isOperandEqual) ||
1603 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1604 (insetwithFunc)isOperandEqual))
1606 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1607 (insetwithFunc)isOperandEqual))
1609 addSet (&compItems, IC_RESULT (cdp->diCode));
1618 /* now for the computed items */
1619 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1621 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1622 deleteItemIf (cseSet, ifPointerGet, cop);
1623 deleteItemIf (cseSet, ifDefSymIsX, cop);
1624 deleteItemIf (pss, ifPointerSet, cop);
1628 /*-----------------------------------------------------------------*/
1629 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1630 /* dfnum > supplied */
1631 /*-----------------------------------------------------------------*/
1632 DEFSETFUNC (delGetPointerSucc)
1634 eBBlock *ebp = item;
1635 V_ARG (operand *, op);
1642 if (ebp->dfnum > dfnum)
1644 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1647 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1650 /*-----------------------------------------------------------------*/
1651 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1652 /*-----------------------------------------------------------------*/
1654 fixUpTypes (iCode * ic)
1656 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1658 /* if (TARGET_IS_DS390) */
1659 if (options.model == MODEL_FLAT24)
1665 /* for pointer_gets if the types of result & left r the
1666 same then change it type of result to next */
1668 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1670 setOperandType (IC_RESULT (ic), t2->next);
1674 /*-----------------------------------------------------------------*/
1675 /* isSignedOp - will return 1 if sign is important to operation */
1676 /*-----------------------------------------------------------------*/
1677 static int isSignedOp (iCode *ic)
1698 case GET_VALUE_AT_ADDRESS:
1726 dumpCseSet(set *cseSet)
1730 cseDef *item=cseSet->item;
1732 printOperand (item->sym, NULL);
1734 piCode (item->diCode, NULL);
1735 cseSet = cseSet->next;
1740 /*-----------------------------------------------------------------*/
1741 /* cseBBlock - common subexpression elimination for basic blocks */
1742 /* this is the hackiest kludgiest routine in the whole */
1743 /* system. also the most important, since almost all */
1744 /* data flow related information is computed by it */
1745 /*-----------------------------------------------------------------*/
1747 cseBBlock (eBBlock * ebb, int computeOnly,
1748 eBBlock ** ebbs, int count)
1754 set *ptrSetSet = NULL;
1757 /* if this block is not reachable */
1761 /* set of common subexpressions */
1762 cseSet = setFromSet (ebb->inExprs);
1764 /* these will be computed by this routine */
1765 setToNull ((void *) &ebb->outDefs);
1766 setToNull ((void *) &ebb->defSet);
1767 setToNull ((void *) &ebb->usesDefs);
1768 setToNull ((void *) &ebb->ptrsSet);
1769 setToNull ((void *) &ebb->addrOf);
1770 setToNull ((void *) &ebb->ldefs);
1772 ebb->outDefs = bitVectCopy (ebb->inDefs);
1773 bitVectDefault = iCodeKey;
1774 ebb->defSet = newBitVect (iCodeKey);
1775 ebb->usesDefs = newBitVect (iCodeKey);
1777 /* for all the instructions in this block do */
1778 for (ic = ebb->sch; ic; ic = ic->next)
1785 ic->eBBlockNum = ebb->bbnum;
1790 /* if this is an assignment from true symbol
1791 to a temp then do pointer post inc/dec optimzation */
1792 if (ic->op == '=' && !POINTER_SET (ic) &&
1793 IS_PTR (operandType (IC_RESULT (ic))))
1795 ptrPostIncDecOpt (ic);
1798 /* clear the def & use chains for the operands involved */
1799 /* in this operation . since it can change due to opts */
1800 unsetDefsAndUses (ic);
1802 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1804 /* add to defSet of the symbol */
1805 OP_DEFS(IC_RESULT (ic))=
1806 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1807 /* add to the definition set of this block */
1808 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1809 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1810 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1811 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1812 /* delete global variables from the cseSet
1813 since they can be modified by the function call */
1814 deleteItemIf (&cseSet, ifDefGlobal);
1816 /* and also itemps derived from globals */
1817 deleteItemIf (&cseSet, ifFromGlobal);
1819 /* delete all getpointer iCodes from cseSet, this should
1820 be done only for global arrays & pointers but at this
1821 point we don't know if globals, so to be safe do all */
1822 deleteItemIf (&cseSet, ifAnyGetPointer);
1824 /* can't cache pointer set/get operations across a call */
1825 deleteSet (&ptrSetSet);
1828 /* for pcall & ipush we need to add to the useSet */
1829 if ((ic->op == PCALL ||
1833 IS_SYMOP (IC_LEFT (ic)))
1836 /* check if they can be replaced */
1840 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1842 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1844 /* the lookup could have changed it */
1845 if (IS_SYMOP (IC_LEFT (ic)))
1847 OP_USES(IC_LEFT (ic))=
1848 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1849 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1850 ebb->outDefs, &ebb->usesDefs);
1854 /* if we a sending a pointer as a parameter
1855 then kill all cse since the pointed to item
1856 might be changed in the function being called */
1857 if ((ic->op == IPUSH || ic->op == SEND) &&
1858 IS_PTR (operandType (IC_LEFT (ic))))
1860 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1861 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1862 for (i = 0; i < count; ebbs[i++]->visited = 0);
1863 applyToSet (ebb->succList, delGetPointerSucc,
1864 IC_LEFT (ic), ebb->dfnum);
1869 /* if jumptable then mark the usage */
1870 if (ic->op == JUMPTABLE)
1872 if (IS_SYMOP (IC_JTCOND (ic)))
1874 OP_USES(IC_JTCOND (ic)) =
1875 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1876 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1877 ebb->outDefs, &ebb->usesDefs);
1886 /* do some algebraic optimizations if possible */
1887 algebraicOpts (ic, ebb);
1888 while (constFold (ic, cseSet));
1892 if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
1894 setOperandType (IC_LEFT (ic),
1895 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1899 if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
1901 setOperandType (IC_RESULT (ic),
1902 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1905 /* if this is a condition statement then */
1906 /* check if the condition can be replaced */
1909 ifxOptimize (ic, cseSet, computeOnly,
1915 /* if the assignment & result is a temp */
1916 /* see if we can replace it */
1917 if (!computeOnly && ic->op == '=')
1920 /* update the spill location for this */
1921 updateSpillLocation (ic,0);
1923 if (POINTER_SET (ic) &&
1924 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1927 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1928 if (pdop && !computeOnly &&
1929 IS_ITEMP (pdop) && IS_PTR(operandType(pdop)))
1930 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1934 checkSign = isSignedOp(ic);
1936 /* do the operand lookup i.e. for both the */
1937 /* right & left operand : check the cseSet */
1938 /* to see if they have been replaced if yes */
1939 /* then replace them with those from cseSet */
1941 /* and left is a symbol */
1942 if (IS_SYMOP (IC_LEFT (ic)) &&
1943 !computeOnly && ic->op != ADDRESS_OF)
1947 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
1950 if (POINTER_GET (ic))
1952 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
1954 /* some non dominating block does POINTER_SET with
1955 this variable .. unsafe to remove any POINTER_GETs */
1956 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
1957 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
1958 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1961 /* check if there is a pointer set
1962 for the same pointer visible if yes
1963 then change this into an assignment */
1965 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
1966 !bitVectBitValue (ebb->ptrsSet, pdop->key))
1969 IC_LEFT (ic) = NULL;
1970 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1971 SET_ISADDR (IC_RESULT (ic), 0);
1977 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1984 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
1988 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
1990 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
1995 /* if left or right changed then do algebraic */
1996 if (!computeOnly && change)
1998 algebraicOpts (ic, ebb);
1999 while (constFold (ic, cseSet));
2002 /* if after all this it becomes an assignment to self
2003 then delete it and continue */
2004 if (ASSIGNMENT_TO_SELF (ic))
2006 remiCodeFromeBBlock (ebb, ic);
2010 /* now we will check to see if the entire */
2011 /* operation has been performed before */
2012 /* and is available */
2013 /* don't do assignments they will be killed */
2014 /* by dead code elimination if required do */
2015 /* it only if result is a temporary */
2017 if (!(POINTER_GET (ic) &&
2018 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2019 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2020 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2022 IS_ITEMP (IC_RESULT (ic)) &&
2025 applyToSet (cseSet, findPrevIc, ic, &pdic);
2026 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2027 operandType (IC_RESULT (ic))) != 1)
2029 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2033 /* Alternate code */
2034 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2035 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2036 /* Mmm, found an equivalent pointer get at a lower level.
2037 This could be a loop however with the same pointer set
2040 /* if previous definition found change this to an assignment */
2043 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2044 SET_ISADDR(IC_RESULT(ic),0);
2045 SET_ISADDR(IC_RIGHT (ic),0);
2049 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2051 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2052 csed = newCseDef (IC_RESULT (ic), ic);
2053 updateCseDefAncestors (csed, cseSet);
2054 addSetHead (&cseSet, csed);
2058 /* if assignment to a parameter which is not
2059 mine and type is a pointer then delete
2060 pointerGets to take care of aliasing */
2061 if (ASSIGNMENT (ic) &&
2062 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2063 IS_PTR (operandType (IC_RESULT (ic))))
2065 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2066 for (i = 0; i < count; ebbs[i++]->visited = 0);
2067 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2068 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2071 /* if this is a pointerget then see if we can replace
2072 this with a previously assigned pointer value */
2073 if (POINTER_GET (ic) &&
2074 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2075 isOperandVolatile (IC_LEFT (ic), TRUE)))
2078 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2079 /* if we find it then locally replace all
2080 references to the result with what we assigned */
2083 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2087 /* delete from the cseSet anything that has */
2088 /* operands matching the result of this */
2089 /* except in case of pointer access */
2090 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2092 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2093 /* delete any previous definitions */
2094 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2098 /* add the left & right to the defUse set */
2099 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2101 OP_USES(IC_LEFT (ic))=
2102 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2103 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2107 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2109 OP_USES(IC_RIGHT (ic))=
2110 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2111 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2115 /* for the result it is special case, put the result */
2116 /* in the defuseSet if it a pointer or array access */
2117 if (POINTER_SET (defic))
2119 OP_USES(IC_RESULT (ic))=
2120 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2121 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2122 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2123 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2124 /* delete from inexpressions of all successors which
2125 have dfNum > than this block */
2126 for (i = 0; i < count; ebbs[i++]->visited = 0);
2127 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2129 /* delete from cseSet all other pointer sets
2131 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2132 /* add to the local pointerset set */
2133 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2136 /* add the result to defintion set */ if (IC_RESULT (ic))
2138 OP_DEFS(IC_RESULT (ic))=
2139 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2140 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2141 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2142 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2146 /* if this is an addressof instruction then */
2147 /* put the symbol in the address of list & */
2148 /* delete it from the cseSet */
2149 if (defic->op == ADDRESS_OF)
2151 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2152 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2156 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2157 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2158 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2159 addSetHead (&ebb->killedExprs, expr);
2161 setToNull ((void *) &ebb->outExprs);
2162 ebb->outExprs = cseSet;
2163 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2164 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2168 /*-----------------------------------------------------------------*/
2169 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2170 /*-----------------------------------------------------------------*/
2172 cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
2177 /* if optimization turned off */
2179 for (i = 0; i < count; i++)
2180 change += cseBBlock (ebbs[i], computeOnly, ebbs, count);