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)
179 printf ("replaceAllSymBySym\n\t");
180 printOperand (from, stdout);
182 printOperand (to, stdout);
185 for (lic = ic; lic; lic = lic->next)
189 /* do the special cases first */
193 IC_COND (lic)->key == from->key)
196 bitVectUnSetBit (OP_USES (from), lic->key);
197 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
198 siaddr = IC_COND (lic)->isaddr;
199 IC_COND (lic) = operandFromOperand (to);
200 IC_COND (lic)->isaddr = siaddr;
206 if (lic->op == JUMPTABLE)
209 IC_JTCOND (lic)->key == from->key)
212 bitVectUnSetBit (OP_USES (from), lic->key);
213 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
214 siaddr = IC_COND (lic)->isaddr;
215 IC_JTCOND (lic) = operandFromOperand (to);
216 IC_JTCOND (lic)->isaddr = siaddr;
223 IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
225 /* maintain du chains */
226 if (POINTER_SET (lic))
228 bitVectUnSetBit (OP_USES (from), lic->key);
229 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
231 /* also check if the "from" was in the non-dominating
232 pointer sets and replace it with "to" in the bitVector */
233 if (bitVectBitValue (*ndpset, from->key))
235 bitVectUnSetBit (*ndpset, from->key);
236 bitVectSetBit (*ndpset, to->key);
242 bitVectUnSetBit (OP_DEFS (from), lic->key);
243 OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
245 siaddr = IC_RESULT (lic)->isaddr;
246 IC_RESULT (lic) = operandFromOperand (to);
247 IC_RESULT (lic)->isaddr = siaddr;
251 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
253 bitVectUnSetBit (OP_USES (from), lic->key);
254 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
255 siaddr = IC_RIGHT (lic)->isaddr;
256 IC_RIGHT (lic) = operandFromOperand (to);
257 IC_RIGHT (lic)->isaddr = siaddr;
261 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
263 bitVectUnSetBit (OP_USES (from), lic->key);
264 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
265 siaddr = IC_LEFT (lic)->isaddr;
266 IC_LEFT (lic) = operandFromOperand (to);
267 IC_LEFT (lic)->isaddr = siaddr;
272 /*-----------------------------------------------------------------*/
273 /* iCodeKeyIs - if the icode keys match then return 1 */
274 /*-----------------------------------------------------------------*/
275 DEFSETFUNC (iCodeKeyIs)
280 if (cdp->diCode->key == key)
286 /*-----------------------------------------------------------------*/
287 /* removeFromInExprs - removes an icode from inexpressions */
288 /*-----------------------------------------------------------------*/
289 DEFSETFUNC (removeFromInExprs)
293 V_ARG (operand *, from);
294 V_ARG (operand *, to);
295 V_ARG (eBBlock *, cbp);
301 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
302 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
303 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
305 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
309 /*-----------------------------------------------------------------*/
310 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
311 /*-----------------------------------------------------------------*/
313 isGlobalInNearSpace (operand * op)
315 sym_link *type = getSpec (operandType (op));
316 /* this is 8051 specific: optimization
317 suggested by Jean-Louis VERN, with 8051s we have no
318 advantage of putting variables in near space into
320 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
321 IN_DIRSPACE (SPEC_OCLS (type)))
327 /*-----------------------------------------------------------------*/
328 /* findCheaperOp - cseBBlock support routine, will check to see if */
329 /* we have a operand previously defined */
330 /*-----------------------------------------------------------------*/
331 DEFSETFUNC (findCheaperOp)
334 V_ARG (operand *, cop);
335 V_ARG (operand **, opp);
336 V_ARG (int, checkSign);
338 /* if we have already found it */
342 /* not found it yet check if this is the one */
343 /* and this is not the defining one */
344 if (cop->key == cdp->key)
347 /* do a special check this will help in */
348 /* constant propagation & dead code elim */
349 /* for assignments only */
350 if (cdp->diCode->op == '=') {
351 /* if the result is volatile then return result */
352 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
353 *opp = IC_RESULT (cdp->diCode);
355 /* if this is a straight assignment and
356 left is a temp then prefer the temporary to the
358 if (!POINTER_SET (cdp->diCode) &&
359 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
360 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
361 *opp = IC_RESULT (cdp->diCode);
363 /* if straight assignement && and both
364 are temps then prefer the one that
365 will not need extra space to spil, also
366 take into consideration if right side
367 an induction variable
369 if (!POINTER_SET (cdp->diCode) &&
370 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
371 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
372 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
373 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
374 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
375 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
376 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
377 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
378 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
379 *opp = IC_RESULT (cdp->diCode);
381 *opp = IC_RIGHT (cdp->diCode);
385 *opp = IC_RESULT (cdp->diCode);
388 /* if this is an assign to a temp. then check
389 if the right side is this then return this */
390 if (IS_TRUE_SYMOP (cop) &&
391 cdp->diCode->op == '=' &&
392 !POINTER_SET (cdp->diCode) &&
393 cop->key == IC_RIGHT (cdp->diCode)->key &&
394 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
395 IS_ITEMP (IC_RESULT (cdp->diCode)))
396 *opp = IC_RESULT (cdp->diCode);
399 (isOperandLiteral(*opp) || !checkSign ||
401 IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
402 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
403 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
406 if ((isGlobalInNearSpace (cop) &&
407 !isOperandLiteral (*opp)) ||
408 isOperandVolatile (*opp, FALSE)
415 if (cop->key == (*opp)->key)
421 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
423 *opp = operandFromOperand (*opp);
424 (*opp)->isaddr = cop->isaddr;
427 /* copy signedness to literal operands */
428 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp))
429 && isOperandLiteral(*opp)
430 && SPEC_NOUN(operandType(*opp)) == SPEC_NOUN(operandType(cop))
431 && SPEC_USIGN(operandType(*opp)) != SPEC_USIGN(operandType(cop)))
433 SPEC_USIGN(operandType(*opp)) = SPEC_USIGN(operandType(cop));
436 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
437 SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
439 // special case: we can make an unsigned char literal
440 // into an int literal with no cost.
441 if (isOperandLiteral(*opp)
442 && SPEC_NOUN(operandType(*opp)) == V_CHAR
443 && SPEC_NOUN(operandType(cop)) == V_INT)
445 *opp = operandFromOperand (*opp);
446 SPEC_NOUN(operandType(*opp)) = V_INT;
464 /*-----------------------------------------------------------------*/
465 /* findPointerSet - finds the right side of a pointer set op */
466 /*-----------------------------------------------------------------*/
467 DEFSETFUNC (findPointerSet)
470 V_ARG (operand *, op);
471 V_ARG (operand **, opp);
472 V_ARG (operand *, rop);
474 if (POINTER_SET (cdp->diCode) &&
475 IC_RESULT (cdp->diCode)->key == op->key &&
476 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
477 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
478 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
479 getSize (operandType (rop)))
481 if (IS_SPEC (operandType (IC_RIGHT (cdp->diCode))) &&
482 SPEC_USIGN (operandType (IC_RIGHT (cdp->diCode))) !=
483 SPEC_USIGN (operandType (rop)))
486 Reminder for Bernhard: check of signedness
487 could be unnecessary together with 'checkSign', if
488 signedness of operation is stored in ic */
491 *opp = IC_RIGHT (cdp->diCode);
498 /*-----------------------------------------------------------------*/
499 /* findPrevIc - cseBBlock support function will return the iCode */
500 /* which matches the current one */
501 /*-----------------------------------------------------------------*/
502 DEFSETFUNC (findPrevIc)
506 V_ARG (iCode **, icp);
508 /* if already found */
512 /* if the iCodes are the same */
513 if (isiCodeEqual (ic, cdp->diCode) &&
514 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
520 /* if iCodes are not the same */
521 /* see the operands maybe interchanged */
522 if (ic->op == cdp->diCode->op &&
523 IS_ASSOCIATIVE(ic) &&
524 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
525 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
534 /*-------------------------------------------------------------------*/
535 /* ifAssignedFromGlobal - if definition is an assignment from global */
536 /*-------------------------------------------------------------------*/
537 DEFSETFUNC (ifAssignedFromGlobal)
540 iCode *dic=cdp->diCode;
542 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
548 /*-------------------------------------------------------------------*/
549 /* ifFromGlobal - if definition is derived from global */
550 /*-------------------------------------------------------------------*/
551 DEFSETFUNC (ifFromGlobal)
555 return cdp->fromGlobal;
558 /*-----------------------------------------------------------------*/
559 /* ifDefGlobal - if definition is global */
560 /*-----------------------------------------------------------------*/
561 DEFSETFUNC (ifDefGlobal)
565 return (isOperandGlobal (cdp->sym));
568 /*-------------------------------------------------------------------*/
569 /* ifFromAddrTaken - if definition is derived from a symbol whose */
570 /* address was taken */
571 /*-------------------------------------------------------------------*/
572 DEFSETFUNC (ifFromAddrTaken)
576 return cdp->fromAddrTaken;
580 /*-----------------------------------------------------------------*/
581 /* ifAnyGetPointer - if get pointer icode */
582 /*-----------------------------------------------------------------*/
583 DEFSETFUNC (ifAnyGetPointer)
587 if (cdp->diCode && POINTER_GET (cdp->diCode))
592 /*-----------------------------------------------------------------*/
593 /* ifOperandsHave - if any of the operand are the same as this */
594 /*-----------------------------------------------------------------*/
595 DEFSETFUNC (ifOperandsHave)
598 V_ARG (operand *, op);
600 if (bitVectBitValue(cdp->ancestors, op->key))
603 if (IC_LEFT (cdp->diCode) &&
604 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
605 IC_LEFT (cdp->diCode)->key == op->key)
608 if (IC_RIGHT (cdp->diCode) &&
609 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
610 IC_RIGHT (cdp->diCode)->key == op->key)
613 /* or if any of the operands are volatile */
614 if (IC_LEFT (cdp->diCode) &&
615 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
618 if (IC_RIGHT (cdp->diCode) &&
619 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
623 if (IC_RESULT (cdp->diCode) &&
624 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
630 /*-----------------------------------------------------------------*/
631 /* ifDefSymIs - if a definition is found in the set */
632 /*-----------------------------------------------------------------*/
634 ifDefSymIs (set * cseSet, operand * sym)
639 if (!sym || !IS_SYMOP (sym))
641 for (sl = cseSet; sl; sl = sl->next)
644 if (loop->sym->key == sym->key)
651 /*-----------------------------------------------------------------*/
652 /* ifDefSymIsX - will return 1 if the symbols match */
653 /*-----------------------------------------------------------------*/
654 DEFSETFUNC (ifDefSymIsX)
657 V_ARG (operand *, op);
661 match = cdp->sym->key == op->key;
663 match = (isOperandEqual (cdp->sym, op));
666 printf("%s ",OP_SYMBOL(cdp->sym)->name);
672 /*-----------------------------------------------------------------*/
673 /* ifDiCodeIs - returns true if diCode is same */
674 /*-----------------------------------------------------------------*/
676 ifDiCodeIs (set * cseSet, iCode * ic)
684 for (sl = cseSet; sl; sl = sl->next)
687 if (loop->diCode == ic)
694 /*-----------------------------------------------------------------*/
695 /* ifPointerGet - returns true if the icode is pointer get sym */
696 /*-----------------------------------------------------------------*/
697 DEFSETFUNC (ifPointerGet)
700 V_ARG (operand *, op);
701 iCode *dic = cdp->diCode;
702 operand *left = IC_LEFT (cdp->diCode);
704 if (POINTER_GET (dic) && left->key == op->key)
710 /*-----------------------------------------------------------------*/
711 /* ifPointerSet - returns true if the icode is pointer set sym */
712 /*-----------------------------------------------------------------*/
713 DEFSETFUNC (ifPointerSet)
716 V_ARG (operand *, op);
718 if (POINTER_SET (cdp->diCode) &&
719 IC_RESULT (cdp->diCode)->key == op->key)
725 /*-----------------------------------------------------------------*/
726 /* ifDiCodeIsX - will return 1 if the symbols match */
727 /*-----------------------------------------------------------------*/
728 DEFSETFUNC (ifDiCodeIsX)
733 return cdp->diCode == ic;
737 /*-----------------------------------------------------------------*/
738 /* findBackwardDef - scan backwards to find deinition of operand */
739 /*-----------------------------------------------------------------*/
740 iCode *findBackwardDef(operand *op,iCode *ic)
744 for (lic = ic; lic ; lic = lic->prev) {
745 if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
751 /*-----------------------------------------------------------------*/
752 /* algebraicOpts - does some algebraic optimizations */
753 /*-----------------------------------------------------------------*/
755 algebraicOpts (iCode * ic, eBBlock * ebp)
757 /* we don't deal with the following iCodes
768 /* if both operands present & ! IFX */
769 /* then if they are both literal we */
770 /* perform the operation right now */
771 if (IC_RESULT (ic) &&
774 IS_OP_LITERAL (IC_LEFT (ic)) &&
775 IS_OP_LITERAL (IC_RIGHT (ic)))
778 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
781 operandType (IC_RESULT (ic)));
784 SET_RESULT_RIGHT (ic);
788 /* if not ifx & only one operand present */
789 if (IC_RESULT (ic) &&
791 IS_OP_LITERAL (IC_LEFT (ic)) &&
795 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
798 operandType (IC_RESULT (ic)));
801 SET_RESULT_RIGHT (ic);
806 /* a special case : or in short a kludgy solution will think
807 about a better solution over a glass of wine someday */
808 if (ic->op == GET_VALUE_AT_ADDRESS)
811 if (IS_ITEMP (IC_RESULT (ic)) &&
812 IS_TRUE_SYMOP (IC_LEFT (ic)))
816 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
817 IC_RIGHT (ic)->isaddr = 0;
819 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
820 IC_RESULT (ic)->isaddr = 0;
821 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
825 if (IS_ITEMP (IC_LEFT (ic)) &&
826 IS_ITEMP (IC_RESULT (ic)) &&
827 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
828 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
829 !IC_LEFT (ic)->isaddr)
832 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
833 IC_RIGHT (ic)->isaddr = 0;
834 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
835 IC_RESULT (ic)->isaddr = 0;
843 /* depending on the operation */
847 /* if adding the same thing change to left shift by 1 */
848 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
849 !(IS_FLOAT (operandType (IC_RESULT (ic)))
850 || IS_FIXED(operandType (IC_RESULT (ic)))))
853 IC_RIGHT (ic) = operandFromLit (1);
856 /* if addition then check if one of them is a zero */
857 /* if yes turn it into assignmnt or cast */
858 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
859 operandLitValue (IC_LEFT (ic)) == 0.0)
862 typematch = compareType (operandType (IC_RESULT (ic)),
863 operandType (IC_RIGHT (ic)));
867 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
875 /* for completely different types, preserve the source type */
876 IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
877 setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
880 SET_ISADDR (IC_RESULT (ic), 0);
881 SET_ISADDR (IC_RIGHT (ic), 0);
884 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
885 operandLitValue (IC_RIGHT (ic)) == 0.0)
888 typematch = compareType (operandType (IC_RESULT (ic)),
889 operandType (IC_LEFT (ic)));
893 IC_RIGHT (ic) = IC_LEFT (ic);
894 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
899 IC_RIGHT (ic) = IC_LEFT (ic);
903 /* for completely different types, preserve the source type */
904 IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
905 setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
908 SET_ISADDR (IC_RIGHT (ic), 0);
909 SET_ISADDR (IC_RESULT (ic), 0);
914 /* if subtracting the the same thing then zero */
915 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
918 IC_RIGHT (ic) = operandFromLit (0);
920 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
921 IC_RESULT (ic)->isaddr = 0;
925 /* if subtraction then check if one of the operand */
926 /* is zero then depending on which operand change */
927 /* to assignment or unary minus */
928 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
929 operandLitValue (IC_RIGHT (ic)) == 0.0)
931 /* right size zero change to assignment */
933 IC_RIGHT (ic) = IC_LEFT (ic);
935 SET_ISADDR (IC_RIGHT (ic), 0);
936 SET_ISADDR (IC_RESULT (ic), 0);
939 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
940 operandLitValue (IC_LEFT (ic)) == 0.0)
942 /* left zero turn into an unary minus */
944 IC_LEFT (ic) = IC_RIGHT (ic);
945 IC_RIGHT (ic) = NULL;
949 /* if multiplication then check if either of */
950 /* them is zero then the result is zero */
951 /* if either of them is one then result is */
954 if (IS_OP_LITERAL (IC_LEFT (ic)))
957 if (operandLitValue (IC_LEFT (ic)) == 0.0)
960 IC_RIGHT (ic) = IC_LEFT (ic);
962 SET_RESULT_RIGHT (ic);
965 if (operandLitValue (IC_LEFT (ic)) == 1.0)
967 /* '*' can have two unsigned chars as operands */
968 /* and an unsigned int as result. */
969 if (compareType (operandType (IC_RESULT (ic)),
970 operandType (IC_RIGHT (ic))) == 1)
974 SET_RESULT_RIGHT (ic);
979 IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
980 IC_LEFT (ic)->type = TYPE;
981 IC_LEFT (ic)->isLiteral = 0;
982 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
988 if (IS_OP_LITERAL (IC_RIGHT (ic)))
991 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
995 SET_RESULT_RIGHT (ic);
999 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
1001 /* '*' can have two unsigned chars as operands */
1002 /* and an unsigned int as result. */
1003 if (compareType (operandType (IC_RESULT (ic)),
1004 operandType (IC_LEFT (ic))) == 1)
1007 IC_RIGHT (ic) = IC_LEFT (ic);
1008 IC_LEFT (ic) = NULL;
1009 SET_RESULT_RIGHT (ic);
1017 IC_RIGHT (ic) = IC_LEFT (ic);
1018 IC_LEFT (ic) = operandFromOperand (op);
1019 IC_LEFT (ic)->type = TYPE;
1020 IC_LEFT (ic)->isLiteral = 0;
1021 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
1028 /* if division by self then 1 */
1029 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
1032 IC_RIGHT (ic) = operandFromLit (1);
1033 IC_LEFT (ic) = NULL;
1034 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
1035 IC_RESULT (ic)->isaddr = 0;
1038 /* if this is a division then check if right */
1039 /* is one then change it to an assignment */
1040 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1041 operandLitValue (IC_RIGHT (ic)) == 1.0)
1045 IC_RIGHT (ic) = IC_LEFT (ic);
1046 IC_LEFT (ic) = NULL;
1047 SET_RESULT_RIGHT (ic);
1051 /* if both are the same for an comparison operators */
1055 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1058 IC_RIGHT (ic) = operandFromLit (1);
1059 IC_LEFT (ic) = NULL;
1060 SET_RESULT_RIGHT (ic);
1066 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1069 IC_RIGHT (ic) = operandFromLit (0);
1070 IC_LEFT (ic) = NULL;
1071 SET_RESULT_RIGHT (ic);
1076 sym_link *otype = operandType(IC_RIGHT(ic));
1077 sym_link *ctype = operandType(IC_LEFT(ic));
1078 /* if this is a cast of a literal value */
1079 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1080 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
1083 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
1084 operandLitValue (IC_RIGHT (ic))));
1085 IC_LEFT (ic) = NULL;
1086 SET_ISADDR (IC_RESULT (ic), 0);
1088 /* if casting to the same */
1089 if (compareType (operandType (IC_RESULT (ic)),
1090 operandType (IC_RIGHT (ic))) == 1) {
1092 IC_LEFT (ic) = NULL;
1093 SET_ISADDR (IC_RESULT (ic), 0);
1098 if (IS_OP_LITERAL (IC_LEFT (ic)))
1102 (operandLitValue (IC_LEFT (ic)) == 0 ?
1103 operandFromLit (1) : operandFromLit (0));
1104 IC_LEFT (ic) = NULL;
1105 SET_ISADDR (IC_RESULT (ic), 0);
1109 /* if both operands are equal */
1110 /* if yes turn it into assignment */
1111 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1113 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1115 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1116 IC_RESULT (newic) = IC_LEFT (ic);
1117 newic->lineno = ic->lineno;
1118 addiCodeToeBBlock (ebp, newic, ic->next);
1121 IC_LEFT (ic) = NULL;
1122 SET_RESULT_RIGHT (ic);
1125 /* swap literal to right ic */
1126 if (IS_OP_LITERAL (IC_LEFT (ic)))
1131 IC_LEFT (ic) = IC_RIGHT (ic);
1134 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1136 /* if BITWISEAND then check if one of them is a zero */
1137 /* if yes turn it into 0 assignment */
1138 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1140 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1142 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1143 IC_RESULT (newic) = IC_LEFT (ic);
1144 newic->lineno = ic->lineno;
1145 addiCodeToeBBlock (ebp, newic, ic->next);
1148 IC_LEFT (ic) = NULL;
1149 SET_RESULT_RIGHT (ic);
1152 /* if BITWISEAND then check if one of them is 0xff... */
1153 /* if yes turn it into assignment */
1157 switch (getSize (operandType (IC_RIGHT (ic))))
1171 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1174 IC_RIGHT (ic) = IC_LEFT (ic);
1175 IC_LEFT (ic) = NULL;
1176 SET_RESULT_RIGHT (ic);
1183 /* if both operands are equal */
1184 /* if yes turn it into assignment */
1185 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1187 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1189 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1190 IC_RESULT (newic) = IC_LEFT (ic);
1191 newic->lineno = ic->lineno;
1192 addiCodeToeBBlock (ebp, newic, ic->next);
1195 IC_LEFT (ic) = NULL;
1196 SET_RESULT_RIGHT (ic);
1199 /* swap literal to right ic */
1200 if (IS_OP_LITERAL (IC_LEFT (ic)))
1205 IC_LEFT (ic) = IC_RIGHT (ic);
1208 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1210 /* if BITWISEOR then check if one of them is a zero */
1211 /* if yes turn it into assignment */
1212 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1215 IC_RIGHT (ic) = IC_LEFT (ic);
1216 IC_LEFT (ic) = NULL;
1217 SET_RESULT_RIGHT (ic);
1220 /* if BITWISEOR then check if one of them is 0xff... */
1221 /* if yes turn it into 0xff... assignment */
1225 switch (getSize (operandType (IC_RIGHT (ic))))
1239 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1241 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1243 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1244 IC_RESULT (newic) = IC_LEFT (ic);
1245 newic->lineno = ic->lineno;
1246 addiCodeToeBBlock (ebp, newic, ic->next);
1249 IC_LEFT (ic) = NULL;
1250 SET_RESULT_RIGHT (ic);
1257 /* if both operands are equal */
1258 /* if yes turn it into 0 assignment */
1259 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1261 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1263 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1264 IC_RESULT (newic) = IC_LEFT (ic);
1265 newic->lineno = ic->lineno;
1266 addiCodeToeBBlock (ebp, newic, ic->next);
1268 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1269 IC_RESULT (newic) = IC_LEFT (ic);
1270 newic->lineno = ic->lineno;
1271 addiCodeToeBBlock (ebp, newic, ic->next);
1274 IC_RIGHT (ic) = operandFromLit (0);
1275 IC_LEFT (ic) = NULL;
1276 SET_RESULT_RIGHT (ic);
1279 /* swap literal to right ic */
1280 if (IS_OP_LITERAL (IC_LEFT (ic)))
1285 IC_LEFT (ic) = IC_RIGHT (ic);
1288 /* if XOR then check if one of them is a zero */
1289 /* if yes turn it into assignment */
1290 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1292 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1295 IC_RIGHT (ic) = IC_LEFT (ic);
1296 IC_LEFT (ic) = NULL;
1297 SET_RESULT_RIGHT (ic);
1306 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1307 /*-----------------------------------------------------------------*/
1308 /* updateSpillLocation - keeps track of register spill location */
1309 /*-----------------------------------------------------------------*/
1311 updateSpillLocation (iCode * ic, int induction)
1315 if (POINTER_SET (ic))
1322 /* for the form true_symbol := iTempNN */
1323 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1324 !SPIL_LOC (IC_RIGHT (ic))) {
1326 setype = getSpec (operandType (IC_RESULT (ic)));
1328 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1329 !IS_VOLATILE (setype) &&
1330 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1331 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1333 wassert(IS_SYMOP(IC_RESULT (ic)));
1334 wassert(IS_SYMOP(IC_RIGHT (ic)));
1335 SPIL_LOC (IC_RIGHT (ic)) =
1336 IC_RESULT (ic)->operand.symOperand;
1342 #if 0 /* this needs furthur investigation can save a lot of code */
1343 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1344 !SPIL_LOC(IC_RESULT(ic))) {
1345 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1346 SPIL_LOC (IC_RESULT (ic)) =
1347 IC_RIGHT (ic)->operand.symOperand;
1350 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1352 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1353 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1354 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1356 setype = getSpec (operandType (IC_RESULT (ic)));
1358 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1359 !IS_VOLATILE (setype) &&
1360 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1361 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) {
1363 SPIL_LOC (IC_RIGHT (ic)) =
1364 SPIL_LOC (IC_RESULT (ic));
1365 OP_SYMBOL (IC_RIGHT (ic))->prereqv =
1366 OP_SYMBOL (IC_RESULT (ic))->prereqv;
1369 /* special case for inductions */
1371 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1372 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1373 !SPIL_LOC(IC_RESULT(ic))) {
1374 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1375 OP_SYMBOL (IC_RESULT (ic))->prereqv =
1376 OP_SYMBOL (IC_RIGHT (ic))->prereqv;
1380 /*-----------------------------------------------------------------*/
1381 /* setUsesDef - sets the uses def bitvector for a given operand */
1382 /*-----------------------------------------------------------------*/
1384 setUsesDefs (operand * op, bitVect * bdefs,
1385 bitVect * idefs, bitVect ** oud)
1387 /* compute the definitions alive at this point */
1388 bitVect *adefs = bitVectUnion (bdefs, idefs);
1390 /* of these definitions find the ones that are */
1391 /* for this operand */
1392 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1394 /* these are the definitions that this operand can use */
1395 op->usesDefs = adefs;
1397 /* the out defs is an union */
1398 *oud = bitVectUnion (*oud, adefs);
1401 /*-----------------------------------------------------------------*/
1402 /* unsetDefsAndUses - clear this operation for the operands */
1403 /*-----------------------------------------------------------------*/
1405 unsetDefsAndUses (iCode * ic)
1407 if (ic->op == JUMPTABLE)
1410 /* take away this definition from the def chain of the */
1411 /* result & take away from use set of the operands */
1414 /* turn off def set */
1415 if (IS_SYMOP (IC_RESULT (ic)))
1417 if (!POINTER_SET (ic))
1418 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1420 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1422 /* turn off the useSet for the operands */
1423 if (IS_SYMOP (IC_LEFT (ic)))
1424 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1426 if (IS_SYMOP (IC_RIGHT (ic)))
1427 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1430 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1431 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1434 /*-----------------------------------------------------------------*/
1435 /* ifxOptimize - changes ifx conditions if it can */
1436 /*-----------------------------------------------------------------*/
1438 ifxOptimize (iCode * ic, set * cseSet,
1440 eBBlock * ebb, int *change,
1446 /* if the condition can be replaced */
1450 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1453 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1458 /* if the conditional is a literal then */
1459 if (IS_OP_LITERAL (IC_COND (ic)))
1462 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1465 /* change to a goto */
1467 IC_LABEL (ic) = IC_TRUE (ic);
1474 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1477 IC_LABEL (ic) = IC_FALSE (ic);
1483 /* then kill this if condition */
1484 remiCodeFromeBBlock (ebb, ic);
1488 /* now we need to recompute the control flow */
1489 /* since the control flow has changed */
1490 /* this is very expensive but it does not happen */
1491 /* too often, if it does happen then the user pays */
1493 computeControlFlow (ebbi);
1494 if (!options.lessPedantic) {
1495 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1500 /* if there is only one successor and that successor
1501 is the same one we are conditionally going to then
1502 we can remove this conditional statement */
1503 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1504 if (elementsInSet (ebb->succList) == 1 &&
1505 isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
1508 if (!options.lessPedantic) {
1509 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1511 if (IS_OP_VOLATILE (IC_COND (ic)))
1513 IC_RIGHT (ic) = IC_COND (ic);
1514 IC_LEFT (ic) = NULL;
1515 IC_RESULT (ic) = NULL;
1516 ic->op = DUMMY_READ_VOLATILE;
1520 remiCodeFromeBBlock (ebb, ic);
1521 computeControlFlow (ebbi);
1527 /* if it remains an IFX the update the use Set */
1530 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1531 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1533 else if (ic->op == DUMMY_READ_VOLATILE)
1535 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1536 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1541 /*-----------------------------------------------------------------*/
1542 /* diCodeForSym - finds the definiting instruction for a symbol */
1543 /*-----------------------------------------------------------------*/
1544 DEFSETFUNC (diCodeForSym)
1547 V_ARG (operand *, sym);
1548 V_ARG (iCode **, dic);
1550 /* if already found */
1554 /* if not if this is the defining iCode */
1555 if (sym->key == cdp->key)
1564 /*-----------------------------------------------------------------*/
1565 /* constFold - does some constant folding */
1566 /*-----------------------------------------------------------------*/
1568 constFold (iCode * ic, set * cseSet)
1572 /* this routine will change
1578 /* deal with only + & - */
1579 if (ic->op != '+' &&
1583 /* this check is a heuristic to prevent live ranges
1584 from becoming too long */
1585 if (IS_PTR (operandType (IC_RESULT (ic))))
1588 /* check if operation with a literal */
1589 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1592 /* check if we can find a definition for the
1594 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1597 /* check that this is also a +/- */
1598 if (dic->op != '+' && dic->op != '-')
1601 /* with a literal */
1602 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1605 /* find the definition of the left operand
1606 of dic.then check if this defined with a
1607 get_pointer return 0 if the pointer size is
1608 less than 2 (MCS51 specific) */
1609 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1612 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1615 /* it is if the operations are the same */
1616 /* the literal parts need to be added */
1617 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1618 if (ic->op == dic->op)
1619 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1620 operandLitValue (IC_RIGHT (dic)));
1622 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1623 operandLitValue (IC_RIGHT (dic)));
1625 if (IS_ITEMP (IC_RESULT (ic)))
1627 SPIL_LOC (IC_RESULT (ic)) = NULL;
1628 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1635 /*-----------------------------------------------------------------*/
1636 /* deleteGetPointers - called when a pointer is passed as parm */
1637 /* will delete from cseSet all get pointers computed from this */
1638 /* pointer. A simple ifOperandsHave is not good enough here */
1639 /*-----------------------------------------------------------------*/
1641 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1643 set *compItems = NULL;
1649 if (!*cseSet && !*pss)
1652 addSet (&compItems, op);
1654 /* Recursively find all items computed from this operand .
1655 This done fairly simply go thru the list and find
1656 those that are computed by arthimetic with these
1658 /* Also check for those computed from our computed
1659 list . This will take care of situations like
1660 iTemp1 = iTemp0 + 8;
1661 iTemp2 = iTemp1 + 8; */
1665 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1667 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1669 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1670 (insetwithFunc)isOperandEqual) ||
1671 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1672 (insetwithFunc)isOperandEqual))
1674 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1675 (insetwithFunc)isOperandEqual))
1677 addSet (&compItems, IC_RESULT (cdp->diCode));
1686 /* now for the computed items */
1687 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1689 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1690 deleteItemIf (cseSet, ifPointerGet, cop);
1691 deleteItemIf (cseSet, ifDefSymIsX, cop);
1692 deleteItemIf (pss, ifPointerSet, cop);
1696 /*-----------------------------------------------------------------*/
1697 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1698 /* dfnum > supplied */
1699 /*-----------------------------------------------------------------*/
1700 DEFSETFUNC (delGetPointerSucc)
1702 eBBlock *ebp = item;
1703 V_ARG (operand *, op);
1710 if (ebp->dfnum > dfnum)
1712 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1715 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1718 /*-----------------------------------------------------------------*/
1719 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1720 /*-----------------------------------------------------------------*/
1722 fixUpTypes (iCode * ic)
1724 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1726 /* if (TARGET_IS_DS390) */
1727 if (options.model == MODEL_FLAT24)
1733 /* for pointer_gets if the types of result & left r the
1734 same then change it type of result to next */
1736 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1738 setOperandType (IC_RESULT (ic), t2->next);
1742 /*-----------------------------------------------------------------*/
1743 /* isSignedOp - will return 1 if sign is important to operation */
1744 /*-----------------------------------------------------------------*/
1745 static int isSignedOp (iCode *ic)
1766 case GET_VALUE_AT_ADDRESS:
1797 dumpCseSet(set *cseSet)
1801 cseDef *item=cseSet->item;
1803 printOperand (item->sym, NULL);
1805 piCode (item->diCode, NULL);
1806 cseSet = cseSet->next;
1811 /*-----------------------------------------------------------------*/
1812 /* cseBBlock - common subexpression elimination for basic blocks */
1813 /* this is the hackiest kludgiest routine in the whole */
1814 /* system. also the most important, since almost all */
1815 /* data flow related information is computed by it */
1816 /*-----------------------------------------------------------------*/
1818 cseBBlock (eBBlock * ebb, int computeOnly,
1821 eBBlock ** ebbs = ebbi->bbOrder;
1822 int count = ebbi->count;
1827 set *ptrSetSet = NULL;
1830 /* if this block is not reachable */
1834 /* set of common subexpressions */
1835 cseSet = setFromSet (ebb->inExprs);
1837 /* these will be computed by this routine */
1838 setToNull ((void *) &ebb->outDefs);
1839 setToNull ((void *) &ebb->defSet);
1840 setToNull ((void *) &ebb->usesDefs);
1841 setToNull ((void *) &ebb->ptrsSet);
1842 setToNull ((void *) &ebb->addrOf);
1843 setToNull ((void *) &ebb->ldefs);
1845 ebb->outDefs = bitVectCopy (ebb->inDefs);
1846 bitVectDefault = iCodeKey;
1847 ebb->defSet = newBitVect (iCodeKey);
1848 ebb->usesDefs = newBitVect (iCodeKey);
1850 /* for all the instructions in this block do */
1851 for (ic = ebb->sch; ic; ic = ic->next)
1858 ic->eBBlockNum = ebb->bbnum;
1863 /* if this is an assignment from true symbol
1864 to a temp then do pointer post inc/dec optimzation */
1865 if (ic->op == '=' && !POINTER_SET (ic) &&
1866 IS_PTR (operandType (IC_RESULT (ic))))
1868 ptrPostIncDecOpt (ic);
1871 /* clear the def & use chains for the operands involved */
1872 /* in this operation . since it can change due to opts */
1873 unsetDefsAndUses (ic);
1875 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1877 /* add to defSet of the symbol */
1878 OP_DEFS(IC_RESULT (ic))=
1879 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1880 /* add to the definition set of this block */
1881 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1882 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1883 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1884 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1885 /* delete global variables from the cseSet
1886 since they can be modified by the function call */
1887 deleteItemIf (&cseSet, ifDefGlobal);
1889 /* and also iTemps derived from globals */
1890 deleteItemIf (&cseSet, ifFromGlobal);
1892 /* Delete iTemps derived from symbols whose address */
1893 /* has been taken */
1894 deleteItemIf (&cseSet, ifFromAddrTaken);
1896 /* delete all getpointer iCodes from cseSet, this should
1897 be done only for global arrays & pointers but at this
1898 point we don't know if globals, so to be safe do all */
1899 deleteItemIf (&cseSet, ifAnyGetPointer);
1901 /* can't cache pointer set/get operations across a call */
1902 deleteSet (&ptrSetSet);
1905 /* for pcall & ipush we need to add to the useSet */
1906 if ((ic->op == PCALL ||
1910 IS_SYMOP (IC_LEFT (ic)))
1913 /* check if they can be replaced */
1917 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1919 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1921 /* the lookup could have changed it */
1922 if (IS_SYMOP (IC_LEFT (ic)))
1924 OP_USES(IC_LEFT (ic))=
1925 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1926 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1927 ebb->outDefs, &ebb->usesDefs);
1931 /* if we a sending a pointer as a parameter
1932 then kill all cse since the pointed to item
1933 might be changed in the function being called */
1934 if ((ic->op == IPUSH || ic->op == SEND) &&
1935 IS_PTR (operandType (IC_LEFT (ic))))
1937 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1938 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1939 for (i = 0; i < count; ebbs[i++]->visited = 0);
1940 applyToSet (ebb->succList, delGetPointerSucc,
1941 IC_LEFT (ic), ebb->dfnum);
1946 /* if jumptable then mark the usage */
1947 if (ic->op == JUMPTABLE)
1949 if (IS_SYMOP (IC_JTCOND (ic)))
1951 OP_USES(IC_JTCOND (ic)) =
1952 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1953 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1954 ebb->outDefs, &ebb->usesDefs);
1964 /* do some algebraic optimizations if possible */
1965 algebraicOpts (ic, ebb);
1966 while (constFold (ic, cseSet));
1970 if (POINTER_GET (ic))
1972 if (!IS_PTR (operandType (IC_LEFT (ic))))
1974 setOperandType (IC_LEFT (ic),
1975 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1976 IC_LEFT (ic)->aggr2ptr = 0;
1979 else if (IC_LEFT (ic)->aggr2ptr)
1980 {/* band aid for kludge */
1981 setOperandType (IC_LEFT (ic),
1982 aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
1983 IC_LEFT (ic)->aggr2ptr = 0;
1988 if (POINTER_SET (ic))
1990 if (!IS_PTR (operandType (IC_RESULT (ic))))
1992 setOperandType (IC_RESULT (ic),
1993 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1994 IC_RESULT (ic)->aggr2ptr = 0;
1996 else if (IC_RESULT (ic)->aggr2ptr)
1997 {/* band aid for kludge */
1998 setOperandType (IC_RESULT (ic),
1999 aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2000 IC_RESULT (ic)->aggr2ptr = 0;
2004 /* if this is a condition statement then */
2005 /* check if the condition can be replaced */
2008 ifxOptimize (ic, cseSet, computeOnly,
2014 /* if the assignment & result is a temp */
2015 /* see if we can replace it */
2016 if (!computeOnly && ic->op == '=')
2019 /* update the spill location for this */
2020 updateSpillLocation (ic,0);
2022 if (POINTER_SET (ic) &&
2023 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
2026 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
2027 if (pdop && !computeOnly && IS_ITEMP (pdop))
2029 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
2030 if (!IS_PTR (operandType (IC_RESULT (ic))))
2032 setOperandType (IC_RESULT (ic),
2033 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2039 checkSign = isSignedOp(ic);
2041 /* do the operand lookup i.e. for both the */
2042 /* right & left operand : check the cseSet */
2043 /* to see if they have been replaced if yes */
2044 /* then replace them with those from cseSet */
2046 /* and left is a symbol */
2047 if (IS_SYMOP (IC_LEFT (ic)) &&
2048 !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
2049 !computeOnly && ic->op != ADDRESS_OF)
2053 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2056 if (POINTER_GET (ic))
2058 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2060 /* some non dominating block does POINTER_SET with
2061 this variable .. unsafe to remove any POINTER_GETs */
2062 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
2063 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
2064 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2067 /* check if there is a pointer set
2068 for the same pointer visible if yes
2069 then change this into an assignment */
2071 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2072 !bitVectBitValue (ebb->ptrsSet, pdop->key))
2075 IC_LEFT (ic) = NULL;
2076 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2077 SET_ISADDR (IC_RESULT (ic), 0);
2083 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2090 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2094 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2096 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2101 /* if left or right changed then do algebraic */
2102 if (!computeOnly && change)
2104 algebraicOpts (ic, ebb);
2105 while (constFold (ic, cseSet));
2108 /* if after all this it becomes an assignment to self
2109 then delete it and continue */
2110 if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
2112 remiCodeFromeBBlock (ebb, ic);
2116 /* now we will check to see if the entire */
2117 /* operation has been performed before */
2118 /* and is available */
2119 /* don't do assignments they will be killed */
2120 /* by dead code elimination if required do */
2121 /* it only if result is a temporary */
2123 if (!(POINTER_GET (ic) &&
2124 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2125 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2126 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2128 IS_ITEMP (IC_RESULT (ic)) &&
2131 applyToSet (cseSet, findPrevIc, ic, &pdic);
2132 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2133 operandType (IC_RESULT (ic))) != 1)
2135 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2139 /* Alternate code */
2140 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2141 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2142 /* Mmm, found an equivalent pointer get at a lower level.
2143 This could be a loop however with the same pointer set
2146 /* if previous definition found change this to an assignment */
2149 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2150 SET_ISADDR(IC_RESULT(ic),0);
2151 SET_ISADDR(IC_RIGHT (ic),0);
2155 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2157 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2158 csed = newCseDef (IC_RESULT (ic), ic);
2159 updateCseDefAncestors (csed, cseSet);
2160 addSetHead (&cseSet, csed);
2164 /* if assignment to a parameter which is not
2165 mine and type is a pointer then delete
2166 pointerGets to take care of aliasing */
2167 if (ASSIGNMENT (ic) &&
2168 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2169 IS_PTR (operandType (IC_RESULT (ic))))
2171 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2172 for (i = 0; i < count; ebbs[i++]->visited = 0);
2173 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2174 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2177 /* if this is a pointerget then see if we can replace
2178 this with a previously assigned pointer value */
2179 if (POINTER_GET (ic) &&
2180 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2181 isOperandVolatile (IC_LEFT (ic), TRUE)))
2184 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2185 /* if we find it then locally replace all
2186 references to the result with what we assigned */
2189 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2193 /* delete from the cseSet anything that has */
2194 /* operands matching the result of this */
2195 /* except in case of pointer access */
2196 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2198 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2199 /* delete any previous definitions */
2200 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2204 /* add the left & right to the defUse set */
2205 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2207 OP_USES(IC_LEFT (ic))=
2208 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2209 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2213 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2215 OP_USES(IC_RIGHT (ic))=
2216 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2217 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2221 /* for the result it is special case, put the result */
2222 /* in the defuseSet if it a pointer or array access */
2223 if (POINTER_SET (defic))
2225 OP_USES(IC_RESULT (ic))=
2226 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2227 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2228 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2229 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2230 /* delete from inexpressions of all successors which
2231 have dfNum > than this block */
2232 for (i = 0; i < count; ebbs[i++]->visited = 0);
2233 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2235 /* delete from cseSet all other pointer sets
2237 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2238 /* add to the local pointerset set */
2239 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2242 /* add the result to defintion set */ if (IC_RESULT (ic))
2244 OP_DEFS(IC_RESULT (ic))=
2245 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2246 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2247 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2248 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2252 /* if this is an addressof instruction then */
2253 /* put the symbol in the address of list & */
2254 /* delete it from the cseSet */
2255 if (defic->op == ADDRESS_OF)
2257 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2258 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2262 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2263 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2264 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2265 addSetHead (&ebb->killedExprs, expr);
2267 setToNull ((void *) &ebb->outExprs);
2268 ebb->outExprs = cseSet;
2269 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2270 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2274 /*-----------------------------------------------------------------*/
2275 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2276 /*-----------------------------------------------------------------*/
2278 cseAllBlocks (ebbIndex * ebbi, int computeOnly)
2280 eBBlock ** ebbs = ebbi->dfOrder;
2281 int count = ebbi->count;
2285 /* if optimization turned off */
2287 for (i = 0; i < count; i++)
2288 change += cseBBlock (ebbs[i], computeOnly, ebbi);