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);
45 cdp->fromAddrTaken = 0;
47 if (ic->op!=IF && ic->op!=JUMPTABLE)
49 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
51 bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
52 cdp->fromGlobal |= isOperandGlobal (IC_LEFT (ic));
53 cdp->fromAddrTaken |= OP_SYMBOL (IC_LEFT (ic))->addrtaken;
55 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
57 bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
58 cdp->fromGlobal |= isOperandGlobal (IC_RIGHT (ic));
59 cdp->fromAddrTaken |= OP_SYMBOL (IC_RIGHT (ic))->addrtaken;
67 updateCseDefAncestors(cseDef *cdp, set * cseSet)
71 iCode *ic = cdp->diCode;
73 if (ic->op!=IF && ic->op!=JUMPTABLE)
75 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
77 bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
78 for (sl = cseSet; sl; sl = sl->next)
81 if (loop->sym->key == IC_LEFT (ic)->key)
83 cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
84 cdp->fromGlobal |= loop->fromGlobal;
85 cdp->fromAddrTaken |= loop->fromAddrTaken;
90 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
92 bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
93 for (sl = cseSet; sl; sl = sl->next)
96 if (loop->sym->key == IC_RIGHT (ic)->key)
98 cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
99 cdp->fromGlobal |= loop->fromGlobal;
100 cdp->fromAddrTaken |= loop->fromAddrTaken;
109 /*-----------------------------------------------------------------*/
110 /* int isCseDefEqual - two definitions are equal */
111 /*-----------------------------------------------------------------*/
113 isCseDefEqual (void *vsrc, void *vdest)
116 cseDef *dest = vdest;
121 return (src->key == dest->key &&
122 src->diCode == dest->diCode);
126 /*-----------------------------------------------------------------*/
127 /* pcseDef - in the cseDef */
128 /*-----------------------------------------------------------------*/
130 pcseDef (void *item, va_list ap)
138 fprintf (stdout, "**null op**");
139 printOperand (cdp->sym, stdout);
140 icTab = getTableEntry (cdp->diCode->op);
141 icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
145 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
147 printf ("ReplaceOpWithCheaperOp\n\t");
148 printOperand (*op, stdout);
150 printOperand (cop, stdout);
152 // if op is a register equivalent
153 if (IS_ITEMP(cop) && IS_SYMOP((*op)) && OP_SYMBOL((*op))->isreqv) {
154 operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
155 if (isOperandEqual(*rop, *op)) {
158 OP_SYMBOL((*op))->isreqv=0;
159 OP_SYMBOL(cop)->isreqv=1;
169 /*-----------------------------------------------------------------*/
170 /* replaceAllSymBySym - replaces all operands by operand in an */
171 /* instruction chain */
172 /*-----------------------------------------------------------------*/
174 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
178 for (lic = ic; lic; lic = lic->next)
182 /* do the special cases first */
186 IC_COND (lic)->key == from->key)
189 bitVectUnSetBit (OP_USES (from), lic->key);
190 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
191 siaddr = IC_COND (lic)->isaddr;
192 IC_COND (lic) = operandFromOperand (to);
193 IC_COND (lic)->isaddr = siaddr;
199 if (lic->op == JUMPTABLE)
202 IC_JTCOND (lic)->key == from->key)
205 bitVectUnSetBit (OP_USES (from), lic->key);
206 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
207 siaddr = IC_COND (lic)->isaddr;
208 IC_JTCOND (lic) = operandFromOperand (to);
209 IC_JTCOND (lic)->isaddr = siaddr;
216 IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
218 /* maintain du chains */
219 if (POINTER_SET (lic))
221 bitVectUnSetBit (OP_USES (from), lic->key);
222 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
224 /* also check if the "from" was in the non-dominating
225 pointer sets and replace it with "to" in the bitVector */
226 if (bitVectBitValue (*ndpset, from->key))
228 bitVectUnSetBit (*ndpset, from->key);
229 bitVectSetBit (*ndpset, to->key);
235 bitVectUnSetBit (OP_DEFS (from), lic->key);
236 OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
238 siaddr = IC_RESULT (lic)->isaddr;
239 IC_RESULT (lic) = operandFromOperand (to);
240 IC_RESULT (lic)->isaddr = siaddr;
244 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
246 bitVectUnSetBit (OP_USES (from), lic->key);
247 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
248 siaddr = IC_RIGHT (lic)->isaddr;
249 IC_RIGHT (lic) = operandFromOperand (to);
250 IC_RIGHT (lic)->isaddr = siaddr;
254 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
256 bitVectUnSetBit (OP_USES (from), lic->key);
257 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
258 siaddr = IC_LEFT (lic)->isaddr;
259 IC_LEFT (lic) = operandFromOperand (to);
260 IC_LEFT (lic)->isaddr = siaddr;
265 /*-----------------------------------------------------------------*/
266 /* iCodeKeyIs - if the icode keys match then return 1 */
267 /*-----------------------------------------------------------------*/
268 DEFSETFUNC (iCodeKeyIs)
273 if (cdp->diCode->key == key)
279 /*-----------------------------------------------------------------*/
280 /* removeFromInExprs - removes an icode from inexpressions */
281 /*-----------------------------------------------------------------*/
282 DEFSETFUNC (removeFromInExprs)
286 V_ARG (operand *, from);
287 V_ARG (operand *, to);
288 V_ARG (eBBlock *, cbp);
294 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
295 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
296 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
298 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
302 /*-----------------------------------------------------------------*/
303 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
304 /*-----------------------------------------------------------------*/
306 isGlobalInNearSpace (operand * op)
308 sym_link *type = getSpec (operandType (op));
309 /* this is 8051 specific: optimization
310 suggested by Jean-Louis VERN, with 8051s we have no
311 advantage of putting variables in near space into
313 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
314 IN_DIRSPACE (SPEC_OCLS (type)))
320 /*-----------------------------------------------------------------*/
321 /* findCheaperOp - cseBBlock support routine, will check to see if */
322 /* we have a operand previously defined */
323 /*-----------------------------------------------------------------*/
324 DEFSETFUNC (findCheaperOp)
327 V_ARG (operand *, cop);
328 V_ARG (operand **, opp);
329 V_ARG (int, checkSign);
331 /* if we have already found it */
335 /* not found it yet check if this is the one */
336 /* and this is not the defining one */
337 if (cop->key == cdp->key)
340 /* do a special check this will help in */
341 /* constant propagation & dead code elim */
342 /* for assignments only */
343 if (cdp->diCode->op == '=') {
344 /* if the result is volatile then return result */
345 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
346 *opp = IC_RESULT (cdp->diCode);
348 /* if this is a straight assignment and
349 left is a temp then prefer the temporary to the
351 if (!POINTER_SET (cdp->diCode) &&
352 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
353 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
354 *opp = IC_RESULT (cdp->diCode);
356 /* if straight assignement && and both
357 are temps then prefer the one that
358 will not need extra space to spil, also
359 take into consideration if right side
360 an induction variable
362 if (!POINTER_SET (cdp->diCode) &&
363 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
364 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
365 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
366 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
367 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
368 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
369 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
370 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
371 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
372 *opp = IC_RESULT (cdp->diCode);
374 *opp = IC_RIGHT (cdp->diCode);
378 *opp = IC_RESULT (cdp->diCode);
381 /* if this is an assign to a temp. then check
382 if the right side is this then return this */
383 if (IS_TRUE_SYMOP (cop) &&
384 cdp->diCode->op == '=' &&
385 !POINTER_SET (cdp->diCode) &&
386 cop->key == IC_RIGHT (cdp->diCode)->key &&
387 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
388 IS_ITEMP (IC_RESULT (cdp->diCode)))
389 *opp = IC_RESULT (cdp->diCode);
392 (isOperandLiteral(*opp) || !checkSign ||
394 IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
395 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
396 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
399 if ((isGlobalInNearSpace (cop) &&
400 !isOperandLiteral (*opp)) ||
401 isOperandVolatile (*opp, FALSE)
408 if (cop->key == (*opp)->key)
414 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
416 *opp = operandFromOperand (*opp);
417 (*opp)->isaddr = cop->isaddr;
420 /* copy signedness to literal operands */
421 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp))
422 && isOperandLiteral(*opp)
423 && SPEC_NOUN(operandType(*opp)) == SPEC_NOUN(operandType(cop))
424 && SPEC_USIGN(operandType(*opp)) != SPEC_USIGN(operandType(cop)))
426 SPEC_USIGN(operandType(*opp)) = SPEC_USIGN(operandType(cop));
429 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
430 SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
432 // special case: we can make an unsigned char literal
433 // into an int literal with no cost.
434 if (isOperandLiteral(*opp)
435 && SPEC_NOUN(operandType(*opp)) == V_CHAR
436 && SPEC_NOUN(operandType(cop)) == V_INT)
438 *opp = operandFromOperand (*opp);
439 SPEC_NOUN(operandType(*opp)) = V_INT;
457 /*-----------------------------------------------------------------*/
458 /* findPointerSet - finds the right side of a pointer set op */
459 /*-----------------------------------------------------------------*/
460 DEFSETFUNC (findPointerSet)
463 V_ARG (operand *, op);
464 V_ARG (operand **, opp);
465 V_ARG (operand *, rop);
467 if (POINTER_SET (cdp->diCode) &&
468 IC_RESULT (cdp->diCode)->key == op->key &&
469 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
470 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
471 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
472 getSize (operandType (rop)))
474 *opp = IC_RIGHT (cdp->diCode);
481 /*-----------------------------------------------------------------*/
482 /* findPrevIc - cseBBlock support function will return the iCode */
483 /* which matches the current one */
484 /*-----------------------------------------------------------------*/
485 DEFSETFUNC (findPrevIc)
489 V_ARG (iCode **, icp);
491 /* if already found */
495 /* if the iCodes are the same */
496 if (isiCodeEqual (ic, cdp->diCode) &&
497 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
503 /* if iCodes are not the same */
504 /* see the operands maybe interchanged */
505 if (ic->op == cdp->diCode->op &&
506 IS_ASSOCIATIVE(ic) &&
507 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
508 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
517 /*-------------------------------------------------------------------*/
518 /* ifAssignedFromGlobal - if definition is an assignment from global */
519 /*-------------------------------------------------------------------*/
520 DEFSETFUNC (ifAssignedFromGlobal)
523 iCode *dic=cdp->diCode;
525 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
531 /*-------------------------------------------------------------------*/
532 /* ifFromGlobal - if definition is derived from global */
533 /*-------------------------------------------------------------------*/
534 DEFSETFUNC (ifFromGlobal)
538 return cdp->fromGlobal;
541 /*-----------------------------------------------------------------*/
542 /* ifDefGlobal - if definition is global */
543 /*-----------------------------------------------------------------*/
544 DEFSETFUNC (ifDefGlobal)
548 return (isOperandGlobal (cdp->sym));
551 /*-------------------------------------------------------------------*/
552 /* ifFromAddrTaken - if definition is derived from a symbol whose */
553 /* address was taken */
554 /*-------------------------------------------------------------------*/
555 DEFSETFUNC (ifFromAddrTaken)
559 return cdp->fromAddrTaken;
563 /*-----------------------------------------------------------------*/
564 /* ifAnyGetPointer - if get pointer icode */
565 /*-----------------------------------------------------------------*/
566 DEFSETFUNC (ifAnyGetPointer)
570 if (cdp->diCode && POINTER_GET (cdp->diCode))
575 /*-----------------------------------------------------------------*/
576 /* ifOperandsHave - if any of the operand are the same as this */
577 /*-----------------------------------------------------------------*/
578 DEFSETFUNC (ifOperandsHave)
581 V_ARG (operand *, op);
583 if (bitVectBitValue(cdp->ancestors, op->key))
586 if (IC_LEFT (cdp->diCode) &&
587 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
588 IC_LEFT (cdp->diCode)->key == op->key)
591 if (IC_RIGHT (cdp->diCode) &&
592 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
593 IC_RIGHT (cdp->diCode)->key == op->key)
596 /* or if any of the operands are volatile */
597 if (IC_LEFT (cdp->diCode) &&
598 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
601 if (IC_RIGHT (cdp->diCode) &&
602 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
606 if (IC_RESULT (cdp->diCode) &&
607 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
613 /*-----------------------------------------------------------------*/
614 /* ifDefSymIs - if a definition is found in the set */
615 /*-----------------------------------------------------------------*/
617 ifDefSymIs (set * cseSet, operand * sym)
622 if (!sym || !IS_SYMOP (sym))
624 for (sl = cseSet; sl; sl = sl->next)
627 if (loop->sym->key == sym->key)
634 /*-----------------------------------------------------------------*/
635 /* ifDefSymIsX - will return 1 if the symbols match */
636 /*-----------------------------------------------------------------*/
637 DEFSETFUNC (ifDefSymIsX)
640 V_ARG (operand *, op);
644 match = cdp->sym->key == op->key;
646 match = (isOperandEqual (cdp->sym, op));
649 printf("%s ",OP_SYMBOL(cdp->sym)->name);
655 /*-----------------------------------------------------------------*/
656 /* ifDiCodeIs - returns true if diCode is same */
657 /*-----------------------------------------------------------------*/
659 ifDiCodeIs (set * cseSet, iCode * ic)
667 for (sl = cseSet; sl; sl = sl->next)
670 if (loop->diCode == ic)
677 /*-----------------------------------------------------------------*/
678 /* ifPointerGet - returns true if the icode is pointer get sym */
679 /*-----------------------------------------------------------------*/
680 DEFSETFUNC (ifPointerGet)
683 V_ARG (operand *, op);
684 iCode *dic = cdp->diCode;
685 operand *left = IC_LEFT (cdp->diCode);
687 if (POINTER_GET (dic) && left->key == op->key)
693 /*-----------------------------------------------------------------*/
694 /* ifPointerSet - returns true if the icode is pointer set sym */
695 /*-----------------------------------------------------------------*/
696 DEFSETFUNC (ifPointerSet)
699 V_ARG (operand *, op);
701 if (POINTER_SET (cdp->diCode) &&
702 IC_RESULT (cdp->diCode)->key == op->key)
708 /*-----------------------------------------------------------------*/
709 /* ifDiCodeIsX - will return 1 if the symbols match */
710 /*-----------------------------------------------------------------*/
711 DEFSETFUNC (ifDiCodeIsX)
716 return cdp->diCode == ic;
720 /*-----------------------------------------------------------------*/
721 /* findBackwardDef - scan backwards to find deinition of operand */
722 /*-----------------------------------------------------------------*/
723 iCode *findBackwardDef(operand *op,iCode *ic)
727 for (lic = ic; lic ; lic = lic->prev) {
728 if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
734 /*-----------------------------------------------------------------*/
735 /* algebraicOpts - does some algebraic optimizations */
736 /*-----------------------------------------------------------------*/
738 algebraicOpts (iCode * ic, eBBlock * ebp)
740 /* we don't deal with the following iCodes
751 /* if both operands present & ! IFX */
752 /* then if they are both literal we */
753 /* perform the operation right now */
754 if (IC_RESULT (ic) &&
757 IS_OP_LITERAL (IC_LEFT (ic)) &&
758 IS_OP_LITERAL (IC_RIGHT (ic)))
761 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
764 operandType (IC_RESULT (ic)));
767 SET_RESULT_RIGHT (ic);
771 /* if not ifx & only one operand present */
772 if (IC_RESULT (ic) &&
774 IS_OP_LITERAL (IC_LEFT (ic)) &&
778 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
781 operandType (IC_RESULT (ic)));
784 SET_RESULT_RIGHT (ic);
789 /* a special case : or in short a kludgy solution will think
790 about a better solution over a glass of wine someday */
791 if (ic->op == GET_VALUE_AT_ADDRESS)
794 if (IS_ITEMP (IC_RESULT (ic)) &&
795 IS_TRUE_SYMOP (IC_LEFT (ic)))
799 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
800 IC_RIGHT (ic)->isaddr = 0;
802 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
803 IC_RESULT (ic)->isaddr = 0;
804 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
808 if (IS_ITEMP (IC_LEFT (ic)) &&
809 IS_ITEMP (IC_RESULT (ic)) &&
810 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
811 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
812 !IC_LEFT (ic)->isaddr)
815 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
816 IC_RIGHT (ic)->isaddr = 0;
817 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
818 IC_RESULT (ic)->isaddr = 0;
826 /* depending on the operation */
830 /* if adding the same thing change to left shift by 1 */
831 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
832 !(IS_FLOAT (operandType (IC_RESULT (ic)))
833 || IS_FIXED(operandType (IC_RESULT (ic)))))
836 IC_RIGHT (ic) = operandFromLit (1);
839 /* if addition then check if one of them is a zero */
840 /* if yes turn it into assignmnt or cast */
841 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
842 operandLitValue (IC_LEFT (ic)) == 0.0)
845 typematch = compareType (operandType (IC_RESULT (ic)),
846 operandType (IC_RIGHT (ic)));
850 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
858 /* for completely different types, preserve the source type */
859 IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
860 setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
863 SET_ISADDR (IC_RESULT (ic), 0);
864 SET_ISADDR (IC_RIGHT (ic), 0);
867 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
868 operandLitValue (IC_RIGHT (ic)) == 0.0)
871 typematch = compareType (operandType (IC_RESULT (ic)),
872 operandType (IC_LEFT (ic)));
876 IC_RIGHT (ic) = IC_LEFT (ic);
877 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
882 IC_RIGHT (ic) = IC_LEFT (ic);
886 /* for completely different types, preserve the source type */
887 IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
888 setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
891 SET_ISADDR (IC_RIGHT (ic), 0);
892 SET_ISADDR (IC_RESULT (ic), 0);
897 /* if subtracting the the same thing then zero */
898 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
901 IC_RIGHT (ic) = operandFromLit (0);
903 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
904 IC_RESULT (ic)->isaddr = 0;
908 /* if subtraction then check if one of the operand */
909 /* is zero then depending on which operand change */
910 /* to assignment or unary minus */
911 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
912 operandLitValue (IC_RIGHT (ic)) == 0.0)
914 /* right size zero change to assignment */
916 IC_RIGHT (ic) = IC_LEFT (ic);
918 SET_ISADDR (IC_RIGHT (ic), 0);
919 SET_ISADDR (IC_RESULT (ic), 0);
922 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
923 operandLitValue (IC_LEFT (ic)) == 0.0)
925 /* left zero turn into an unary minus */
927 IC_LEFT (ic) = IC_RIGHT (ic);
928 IC_RIGHT (ic) = NULL;
932 /* if multiplication then check if either of */
933 /* them is zero then the result is zero */
934 /* if either of them is one then result is */
937 if (IS_OP_LITERAL (IC_LEFT (ic)))
940 if (operandLitValue (IC_LEFT (ic)) == 0.0)
943 IC_RIGHT (ic) = IC_LEFT (ic);
945 SET_RESULT_RIGHT (ic);
948 if (operandLitValue (IC_LEFT (ic)) == 1.0)
950 /* '*' can have two unsigned chars as operands */
951 /* and an unsigned int as result. */
952 if (compareType (operandType (IC_RESULT (ic)),
953 operandType (IC_RIGHT (ic))) == 1)
957 SET_RESULT_RIGHT (ic);
962 IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
963 IC_LEFT (ic)->type = TYPE;
964 IC_LEFT (ic)->isLiteral = 0;
965 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
971 if (IS_OP_LITERAL (IC_RIGHT (ic)))
974 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
978 SET_RESULT_RIGHT (ic);
982 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
984 /* '*' can have two unsigned chars as operands */
985 /* and an unsigned int as result. */
986 if (compareType (operandType (IC_RESULT (ic)),
987 operandType (IC_LEFT (ic))) == 1)
990 IC_RIGHT (ic) = IC_LEFT (ic);
992 SET_RESULT_RIGHT (ic);
1000 IC_RIGHT (ic) = IC_LEFT (ic);
1001 IC_LEFT (ic) = operandFromOperand (op);
1002 IC_LEFT (ic)->type = TYPE;
1003 IC_LEFT (ic)->isLiteral = 0;
1004 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
1011 /* if division by self then 1 */
1012 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
1015 IC_RIGHT (ic) = operandFromLit (1);
1016 IC_LEFT (ic) = NULL;
1017 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
1018 IC_RESULT (ic)->isaddr = 0;
1021 /* if this is a division then check if right */
1022 /* is one then change it to an assignment */
1023 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1024 operandLitValue (IC_RIGHT (ic)) == 1.0)
1028 IC_RIGHT (ic) = IC_LEFT (ic);
1029 IC_LEFT (ic) = NULL;
1030 SET_RESULT_RIGHT (ic);
1034 /* if both are the same for an comparison operators */
1038 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1041 IC_RIGHT (ic) = operandFromLit (1);
1042 IC_LEFT (ic) = NULL;
1043 SET_RESULT_RIGHT (ic);
1049 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1052 IC_RIGHT (ic) = operandFromLit (0);
1053 IC_LEFT (ic) = NULL;
1054 SET_RESULT_RIGHT (ic);
1059 sym_link *otype = operandType(IC_RIGHT(ic));
1060 sym_link *ctype = operandType(IC_LEFT(ic));
1061 /* if this is a cast of a literal value */
1062 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1063 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
1066 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
1067 operandLitValue (IC_RIGHT (ic))));
1068 IC_LEFT (ic) = NULL;
1069 SET_ISADDR (IC_RESULT (ic), 0);
1071 /* if casting to the same */
1072 if (compareType (operandType (IC_RESULT (ic)),
1073 operandType (IC_RIGHT (ic))) == 1) {
1075 IC_LEFT (ic) = NULL;
1076 SET_ISADDR (IC_RESULT (ic), 0);
1081 if (IS_OP_LITERAL (IC_LEFT (ic)))
1085 (operandLitValue (IC_LEFT (ic)) == 0 ?
1086 operandFromLit (1) : operandFromLit (0));
1087 IC_LEFT (ic) = NULL;
1088 SET_ISADDR (IC_RESULT (ic), 0);
1092 /* if both operands are equal */
1093 /* if yes turn it into assignment */
1094 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1096 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1098 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1099 IC_RESULT (newic) = IC_LEFT (ic);
1100 newic->lineno = ic->lineno;
1101 addiCodeToeBBlock (ebp, newic, ic->next);
1104 IC_LEFT (ic) = NULL;
1105 SET_RESULT_RIGHT (ic);
1108 /* swap literal to right ic */
1109 if (IS_OP_LITERAL (IC_LEFT (ic)))
1114 IC_LEFT (ic) = IC_RIGHT (ic);
1117 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1119 /* if BITWISEAND then check if one of them is a zero */
1120 /* if yes turn it into 0 assignment */
1121 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1123 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1125 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1126 IC_RESULT (newic) = IC_LEFT (ic);
1127 newic->lineno = ic->lineno;
1128 addiCodeToeBBlock (ebp, newic, ic->next);
1131 IC_LEFT (ic) = NULL;
1132 SET_RESULT_RIGHT (ic);
1135 /* if BITWISEAND then check if one of them is 0xff... */
1136 /* if yes turn it into assignment */
1140 switch (getSize (operandType (IC_RIGHT (ic))))
1154 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1157 IC_RIGHT (ic) = IC_LEFT (ic);
1158 IC_LEFT (ic) = NULL;
1159 SET_RESULT_RIGHT (ic);
1166 /* if both operands are equal */
1167 /* if yes turn it into assignment */
1168 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1170 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1172 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1173 IC_RESULT (newic) = IC_LEFT (ic);
1174 newic->lineno = ic->lineno;
1175 addiCodeToeBBlock (ebp, newic, ic->next);
1178 IC_LEFT (ic) = NULL;
1179 SET_RESULT_RIGHT (ic);
1182 /* swap literal to right ic */
1183 if (IS_OP_LITERAL (IC_LEFT (ic)))
1188 IC_LEFT (ic) = IC_RIGHT (ic);
1191 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1193 /* if BITWISEOR then check if one of them is a zero */
1194 /* if yes turn it into assignment */
1195 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1198 IC_RIGHT (ic) = IC_LEFT (ic);
1199 IC_LEFT (ic) = NULL;
1200 SET_RESULT_RIGHT (ic);
1203 /* if BITWISEOR then check if one of them is 0xff... */
1204 /* if yes turn it into 0xff... assignment */
1208 switch (getSize (operandType (IC_RIGHT (ic))))
1222 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1224 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1226 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1227 IC_RESULT (newic) = IC_LEFT (ic);
1228 newic->lineno = ic->lineno;
1229 addiCodeToeBBlock (ebp, newic, ic->next);
1232 IC_LEFT (ic) = NULL;
1233 SET_RESULT_RIGHT (ic);
1240 /* if both operands are equal */
1241 /* if yes turn it into 0 assignment */
1242 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1244 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1246 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1247 IC_RESULT (newic) = IC_LEFT (ic);
1248 newic->lineno = ic->lineno;
1249 addiCodeToeBBlock (ebp, newic, ic->next);
1251 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1252 IC_RESULT (newic) = IC_LEFT (ic);
1253 newic->lineno = ic->lineno;
1254 addiCodeToeBBlock (ebp, newic, ic->next);
1257 IC_RIGHT (ic) = operandFromLit (0);
1258 IC_LEFT (ic) = NULL;
1259 SET_RESULT_RIGHT (ic);
1262 /* swap literal to right ic */
1263 if (IS_OP_LITERAL (IC_LEFT (ic)))
1268 IC_LEFT (ic) = IC_RIGHT (ic);
1271 /* if XOR then check if one of them is a zero */
1272 /* if yes turn it into assignment */
1273 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1275 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1278 IC_RIGHT (ic) = IC_LEFT (ic);
1279 IC_LEFT (ic) = NULL;
1280 SET_RESULT_RIGHT (ic);
1289 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1290 /*-----------------------------------------------------------------*/
1291 /* updateSpillLocation - keeps track of register spill location */
1292 /*-----------------------------------------------------------------*/
1294 updateSpillLocation (iCode * ic, int induction)
1298 if (POINTER_SET (ic))
1305 /* for the form true_symbol := iTempNN */
1306 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1307 !SPIL_LOC (IC_RIGHT (ic))) {
1309 setype = getSpec (operandType (IC_RESULT (ic)));
1311 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1312 !IS_VOLATILE (setype) &&
1313 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1314 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1316 wassert(IS_SYMOP(IC_RESULT (ic)));
1317 wassert(IS_SYMOP(IC_RIGHT (ic)));
1318 SPIL_LOC (IC_RIGHT (ic)) =
1319 IC_RESULT (ic)->operand.symOperand;
1325 #if 0 /* this needs furthur investigation can save a lot of code */
1326 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1327 !SPIL_LOC(IC_RESULT(ic))) {
1328 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1329 SPIL_LOC (IC_RESULT (ic)) =
1330 IC_RIGHT (ic)->operand.symOperand;
1333 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1335 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1336 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1337 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1339 setype = getSpec (operandType (IC_RESULT (ic)));
1341 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1342 !IS_VOLATILE (setype) &&
1343 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1344 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) {
1346 SPIL_LOC (IC_RIGHT (ic)) =
1347 SPIL_LOC (IC_RESULT (ic));
1348 OP_SYMBOL (IC_RIGHT (ic))->prereqv =
1349 OP_SYMBOL (IC_RESULT (ic))->prereqv;
1352 /* special case for inductions */
1354 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1355 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1356 !SPIL_LOC(IC_RESULT(ic))) {
1357 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1358 OP_SYMBOL (IC_RESULT (ic))->prereqv =
1359 OP_SYMBOL (IC_RIGHT (ic))->prereqv;
1363 /*-----------------------------------------------------------------*/
1364 /* setUsesDef - sets the uses def bitvector for a given operand */
1365 /*-----------------------------------------------------------------*/
1367 setUsesDefs (operand * op, bitVect * bdefs,
1368 bitVect * idefs, bitVect ** oud)
1370 /* compute the definitions alive at this point */
1371 bitVect *adefs = bitVectUnion (bdefs, idefs);
1373 /* of these definitions find the ones that are */
1374 /* for this operand */
1375 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1377 /* these are the definitions that this operand can use */
1378 op->usesDefs = adefs;
1380 /* the out defs is an union */
1381 *oud = bitVectUnion (*oud, adefs);
1384 /*-----------------------------------------------------------------*/
1385 /* unsetDefsAndUses - clear this operation for the operands */
1386 /*-----------------------------------------------------------------*/
1388 unsetDefsAndUses (iCode * ic)
1390 if (ic->op == JUMPTABLE)
1393 /* take away this definition from the def chain of the */
1394 /* result & take away from use set of the operands */
1397 /* turn off def set */
1398 if (IS_SYMOP (IC_RESULT (ic)))
1400 if (!POINTER_SET (ic))
1401 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1403 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1405 /* turn off the useSet for the operands */
1406 if (IS_SYMOP (IC_LEFT (ic)))
1407 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1409 if (IS_SYMOP (IC_RIGHT (ic)))
1410 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1413 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1414 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1417 /*-----------------------------------------------------------------*/
1418 /* ifxOptimize - changes ifx conditions if it can */
1419 /*-----------------------------------------------------------------*/
1421 ifxOptimize (iCode * ic, set * cseSet,
1423 eBBlock * ebb, int *change,
1429 /* if the condition can be replaced */
1433 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1436 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1441 /* if the conditional is a literal then */
1442 if (IS_OP_LITERAL (IC_COND (ic)))
1445 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1448 /* change to a goto */
1450 IC_LABEL (ic) = IC_TRUE (ic);
1457 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1460 IC_LABEL (ic) = IC_FALSE (ic);
1466 /* then kill this if condition */
1467 remiCodeFromeBBlock (ebb, ic);
1471 /* now we need to recompute the control flow */
1472 /* since the control flow has changed */
1473 /* this is very expensive but it does not happen */
1474 /* too often, if it does happen then the user pays */
1476 computeControlFlow (ebbi);
1477 if (!options.lessPedantic) {
1478 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1483 /* if there is only one successor and that successor
1484 is the same one we are conditionally going to then
1485 we can remove this conditional statement */
1486 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1487 if (elementsInSet (ebb->succList) == 1 &&
1488 isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
1491 if (!options.lessPedantic) {
1492 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1494 if (IS_OP_VOLATILE (IC_COND (ic)))
1496 IC_RIGHT (ic) = IC_COND (ic);
1497 IC_LEFT (ic) = NULL;
1498 IC_RESULT (ic) = NULL;
1499 ic->op = DUMMY_READ_VOLATILE;
1503 remiCodeFromeBBlock (ebb, ic);
1504 computeControlFlow (ebbi);
1510 /* if it remains an IFX the update the use Set */
1513 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1514 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1516 else if (ic->op == DUMMY_READ_VOLATILE)
1518 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1519 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1524 /*-----------------------------------------------------------------*/
1525 /* diCodeForSym - finds the definiting instruction for a symbol */
1526 /*-----------------------------------------------------------------*/
1527 DEFSETFUNC (diCodeForSym)
1530 V_ARG (operand *, sym);
1531 V_ARG (iCode **, dic);
1533 /* if already found */
1537 /* if not if this is the defining iCode */
1538 if (sym->key == cdp->key)
1547 /*-----------------------------------------------------------------*/
1548 /* constFold - does some constant folding */
1549 /*-----------------------------------------------------------------*/
1551 constFold (iCode * ic, set * cseSet)
1555 /* this routine will change
1561 /* deal with only + & - */
1562 if (ic->op != '+' &&
1566 /* this check is a heuristic to prevent live ranges
1567 from becoming too long */
1568 if (IS_PTR (operandType (IC_RESULT (ic))))
1571 /* check if operation with a literal */
1572 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1575 /* check if we can find a definition for the
1577 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1580 /* check that this is also a +/- */
1581 if (dic->op != '+' && dic->op != '-')
1584 /* with a literal */
1585 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1588 /* find the definition of the left operand
1589 of dic.then check if this defined with a
1590 get_pointer return 0 if the pointer size is
1591 less than 2 (MCS51 specific) */
1592 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1595 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1598 /* it is if the operations are the same */
1599 /* the literal parts need to be added */
1600 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1601 if (ic->op == dic->op)
1602 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1603 operandLitValue (IC_RIGHT (dic)));
1605 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1606 operandLitValue (IC_RIGHT (dic)));
1608 if (IS_ITEMP (IC_RESULT (ic)))
1610 SPIL_LOC (IC_RESULT (ic)) = NULL;
1611 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1618 /*-----------------------------------------------------------------*/
1619 /* deleteGetPointers - called when a pointer is passed as parm */
1620 /* will delete from cseSet all get pointers computed from this */
1621 /* pointer. A simple ifOperandsHave is not good enough here */
1622 /*-----------------------------------------------------------------*/
1624 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1626 set *compItems = NULL;
1632 if (!*cseSet && !*pss)
1635 addSet (&compItems, op);
1637 /* Recursively find all items computed from this operand .
1638 This done fairly simply go thru the list and find
1639 those that are computed by arthimetic with these
1641 /* Also check for those computed from our computed
1642 list . This will take care of situations like
1643 iTemp1 = iTemp0 + 8;
1644 iTemp2 = iTemp1 + 8; */
1648 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1650 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1652 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1653 (insetwithFunc)isOperandEqual) ||
1654 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1655 (insetwithFunc)isOperandEqual))
1657 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1658 (insetwithFunc)isOperandEqual))
1660 addSet (&compItems, IC_RESULT (cdp->diCode));
1669 /* now for the computed items */
1670 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1672 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1673 deleteItemIf (cseSet, ifPointerGet, cop);
1674 deleteItemIf (cseSet, ifDefSymIsX, cop);
1675 deleteItemIf (pss, ifPointerSet, cop);
1679 /*-----------------------------------------------------------------*/
1680 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1681 /* dfnum > supplied */
1682 /*-----------------------------------------------------------------*/
1683 DEFSETFUNC (delGetPointerSucc)
1685 eBBlock *ebp = item;
1686 V_ARG (operand *, op);
1693 if (ebp->dfnum > dfnum)
1695 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1698 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1701 /*-----------------------------------------------------------------*/
1702 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1703 /*-----------------------------------------------------------------*/
1705 fixUpTypes (iCode * ic)
1707 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1709 /* if (TARGET_IS_DS390) */
1710 if (options.model == MODEL_FLAT24)
1716 /* for pointer_gets if the types of result & left r the
1717 same then change it type of result to next */
1719 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1721 setOperandType (IC_RESULT (ic), t2->next);
1725 /*-----------------------------------------------------------------*/
1726 /* isSignedOp - will return 1 if sign is important to operation */
1727 /*-----------------------------------------------------------------*/
1728 static int isSignedOp (iCode *ic)
1749 case GET_VALUE_AT_ADDRESS:
1780 dumpCseSet(set *cseSet)
1784 cseDef *item=cseSet->item;
1786 printOperand (item->sym, NULL);
1788 piCode (item->diCode, NULL);
1789 cseSet = cseSet->next;
1794 /*-----------------------------------------------------------------*/
1795 /* cseBBlock - common subexpression elimination for basic blocks */
1796 /* this is the hackiest kludgiest routine in the whole */
1797 /* system. also the most important, since almost all */
1798 /* data flow related information is computed by it */
1799 /*-----------------------------------------------------------------*/
1801 cseBBlock (eBBlock * ebb, int computeOnly,
1804 eBBlock ** ebbs = ebbi->bbOrder;
1805 int count = ebbi->count;
1810 set *ptrSetSet = NULL;
1813 /* if this block is not reachable */
1817 /* set of common subexpressions */
1818 cseSet = setFromSet (ebb->inExprs);
1820 /* these will be computed by this routine */
1821 setToNull ((void *) &ebb->outDefs);
1822 setToNull ((void *) &ebb->defSet);
1823 setToNull ((void *) &ebb->usesDefs);
1824 setToNull ((void *) &ebb->ptrsSet);
1825 setToNull ((void *) &ebb->addrOf);
1826 setToNull ((void *) &ebb->ldefs);
1828 ebb->outDefs = bitVectCopy (ebb->inDefs);
1829 bitVectDefault = iCodeKey;
1830 ebb->defSet = newBitVect (iCodeKey);
1831 ebb->usesDefs = newBitVect (iCodeKey);
1833 /* for all the instructions in this block do */
1834 for (ic = ebb->sch; ic; ic = ic->next)
1841 ic->eBBlockNum = ebb->bbnum;
1846 /* if this is an assignment from true symbol
1847 to a temp then do pointer post inc/dec optimzation */
1848 if (ic->op == '=' && !POINTER_SET (ic) &&
1849 IS_PTR (operandType (IC_RESULT (ic))))
1851 ptrPostIncDecOpt (ic);
1854 /* clear the def & use chains for the operands involved */
1855 /* in this operation . since it can change due to opts */
1856 unsetDefsAndUses (ic);
1858 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1860 /* add to defSet of the symbol */
1861 OP_DEFS(IC_RESULT (ic))=
1862 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1863 /* add to the definition set of this block */
1864 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1865 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1866 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1867 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1868 /* delete global variables from the cseSet
1869 since they can be modified by the function call */
1870 deleteItemIf (&cseSet, ifDefGlobal);
1872 /* and also iTemps derived from globals */
1873 deleteItemIf (&cseSet, ifFromGlobal);
1875 /* Delete iTemps derived from symbols whose address */
1876 /* has been taken */
1877 deleteItemIf (&cseSet, ifFromAddrTaken);
1879 /* delete all getpointer iCodes from cseSet, this should
1880 be done only for global arrays & pointers but at this
1881 point we don't know if globals, so to be safe do all */
1882 deleteItemIf (&cseSet, ifAnyGetPointer);
1884 /* can't cache pointer set/get operations across a call */
1885 deleteSet (&ptrSetSet);
1888 /* for pcall & ipush we need to add to the useSet */
1889 if ((ic->op == PCALL ||
1893 IS_SYMOP (IC_LEFT (ic)))
1896 /* check if they can be replaced */
1900 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1902 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1904 /* the lookup could have changed it */
1905 if (IS_SYMOP (IC_LEFT (ic)))
1907 OP_USES(IC_LEFT (ic))=
1908 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1909 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1910 ebb->outDefs, &ebb->usesDefs);
1914 /* if we a sending a pointer as a parameter
1915 then kill all cse since the pointed to item
1916 might be changed in the function being called */
1917 if ((ic->op == IPUSH || ic->op == SEND) &&
1918 IS_PTR (operandType (IC_LEFT (ic))))
1920 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1921 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1922 for (i = 0; i < count; ebbs[i++]->visited = 0);
1923 applyToSet (ebb->succList, delGetPointerSucc,
1924 IC_LEFT (ic), ebb->dfnum);
1929 /* if jumptable then mark the usage */
1930 if (ic->op == JUMPTABLE)
1932 if (IS_SYMOP (IC_JTCOND (ic)))
1934 OP_USES(IC_JTCOND (ic)) =
1935 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1936 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1937 ebb->outDefs, &ebb->usesDefs);
1947 /* do some algebraic optimizations if possible */
1948 algebraicOpts (ic, ebb);
1949 while (constFold (ic, cseSet));
1953 if (POINTER_GET (ic))
1955 if (!IS_PTR (operandType (IC_LEFT (ic))))
1957 setOperandType (IC_LEFT (ic),
1958 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1959 IC_LEFT (ic)->aggr2ptr = 0;
1962 else if (IC_LEFT (ic)->aggr2ptr)
1963 {/* band aid for kludge */
1964 setOperandType (IC_LEFT (ic),
1965 aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
1966 IC_LEFT (ic)->aggr2ptr = 0;
1971 if (POINTER_SET (ic))
1973 if (!IS_PTR (operandType (IC_RESULT (ic))))
1975 setOperandType (IC_RESULT (ic),
1976 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1977 IC_RESULT (ic)->aggr2ptr = 0;
1979 else if (IC_RESULT (ic)->aggr2ptr)
1980 {/* band aid for kludge */
1981 setOperandType (IC_RESULT (ic),
1982 aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1983 IC_RESULT (ic)->aggr2ptr = 0;
1987 /* if this is a condition statement then */
1988 /* check if the condition can be replaced */
1991 ifxOptimize (ic, cseSet, computeOnly,
1997 /* if the assignment & result is a temp */
1998 /* see if we can replace it */
1999 if (!computeOnly && ic->op == '=')
2002 /* update the spill location for this */
2003 updateSpillLocation (ic,0);
2005 if (POINTER_SET (ic) &&
2006 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
2009 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
2010 if (pdop && !computeOnly && IS_ITEMP (pdop))
2012 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
2013 if (!IS_PTR (operandType (IC_RESULT (ic))))
2015 setOperandType (IC_RESULT (ic),
2016 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2022 checkSign = isSignedOp(ic);
2024 /* do the operand lookup i.e. for both the */
2025 /* right & left operand : check the cseSet */
2026 /* to see if they have been replaced if yes */
2027 /* then replace them with those from cseSet */
2029 /* and left is a symbol */
2030 if (IS_SYMOP (IC_LEFT (ic)) &&
2031 !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
2032 !computeOnly && ic->op != ADDRESS_OF)
2036 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2039 if (POINTER_GET (ic))
2041 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2043 /* some non dominating block does POINTER_SET with
2044 this variable .. unsafe to remove any POINTER_GETs */
2045 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
2046 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
2047 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2050 /* check if there is a pointer set
2051 for the same pointer visible if yes
2052 then change this into an assignment */
2054 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2055 !bitVectBitValue (ebb->ptrsSet, pdop->key))
2058 IC_LEFT (ic) = NULL;
2059 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2060 SET_ISADDR (IC_RESULT (ic), 0);
2066 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2073 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2077 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2079 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2084 /* if left or right changed then do algebraic */
2085 if (!computeOnly && change)
2087 algebraicOpts (ic, ebb);
2088 while (constFold (ic, cseSet));
2091 /* if after all this it becomes an assignment to self
2092 then delete it and continue */
2093 if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
2095 remiCodeFromeBBlock (ebb, ic);
2099 /* now we will check to see if the entire */
2100 /* operation has been performed before */
2101 /* and is available */
2102 /* don't do assignments they will be killed */
2103 /* by dead code elimination if required do */
2104 /* it only if result is a temporary */
2106 if (!(POINTER_GET (ic) &&
2107 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2108 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2109 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2111 IS_ITEMP (IC_RESULT (ic)) &&
2114 applyToSet (cseSet, findPrevIc, ic, &pdic);
2115 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2116 operandType (IC_RESULT (ic))) != 1)
2118 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2122 /* Alternate code */
2123 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2124 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2125 /* Mmm, found an equivalent pointer get at a lower level.
2126 This could be a loop however with the same pointer set
2129 /* if previous definition found change this to an assignment */
2132 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2133 SET_ISADDR(IC_RESULT(ic),0);
2134 SET_ISADDR(IC_RIGHT (ic),0);
2138 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2140 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2141 csed = newCseDef (IC_RESULT (ic), ic);
2142 updateCseDefAncestors (csed, cseSet);
2143 addSetHead (&cseSet, csed);
2147 /* if assignment to a parameter which is not
2148 mine and type is a pointer then delete
2149 pointerGets to take care of aliasing */
2150 if (ASSIGNMENT (ic) &&
2151 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2152 IS_PTR (operandType (IC_RESULT (ic))))
2154 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2155 for (i = 0; i < count; ebbs[i++]->visited = 0);
2156 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2157 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2160 /* if this is a pointerget then see if we can replace
2161 this with a previously assigned pointer value */
2162 if (POINTER_GET (ic) &&
2163 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2164 isOperandVolatile (IC_LEFT (ic), TRUE)))
2167 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2168 /* if we find it then locally replace all
2169 references to the result with what we assigned */
2172 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2176 /* delete from the cseSet anything that has */
2177 /* operands matching the result of this */
2178 /* except in case of pointer access */
2179 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2181 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2182 /* delete any previous definitions */
2183 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2187 /* add the left & right to the defUse set */
2188 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2190 OP_USES(IC_LEFT (ic))=
2191 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2192 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2196 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2198 OP_USES(IC_RIGHT (ic))=
2199 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2200 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2204 /* for the result it is special case, put the result */
2205 /* in the defuseSet if it a pointer or array access */
2206 if (POINTER_SET (defic))
2208 OP_USES(IC_RESULT (ic))=
2209 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2210 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2211 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2212 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2213 /* delete from inexpressions of all successors which
2214 have dfNum > than this block */
2215 for (i = 0; i < count; ebbs[i++]->visited = 0);
2216 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2218 /* delete from cseSet all other pointer sets
2220 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2221 /* add to the local pointerset set */
2222 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2225 /* add the result to defintion set */ if (IC_RESULT (ic))
2227 OP_DEFS(IC_RESULT (ic))=
2228 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2229 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2230 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2231 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2235 /* if this is an addressof instruction then */
2236 /* put the symbol in the address of list & */
2237 /* delete it from the cseSet */
2238 if (defic->op == ADDRESS_OF)
2240 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2241 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2245 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2246 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2247 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2248 addSetHead (&ebb->killedExprs, expr);
2250 setToNull ((void *) &ebb->outExprs);
2251 ebb->outExprs = cseSet;
2252 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2253 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2257 /*-----------------------------------------------------------------*/
2258 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2259 /*-----------------------------------------------------------------*/
2261 cseAllBlocks (ebbIndex * ebbi, int computeOnly)
2263 eBBlock ** ebbs = ebbi->dfOrder;
2264 int count = ebbi->count;
2268 /* if optimization turned off */
2270 for (i = 0; i < count; i++)
2271 change += cseBBlock (ebbs[i], computeOnly, ebbi);