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 %s with %s: ",
148 IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM",
149 IS_SYMOP(cop) ? OP_SYMBOL(cop)->name : "!SYM");
150 // if op is a register equivalent
151 if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
152 operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
153 if (isOperandEqual(*rop, *op)) {
156 OP_SYMBOL((*op))->isreqv=0;
157 OP_SYMBOL(cop)->isreqv=1;
167 /*-----------------------------------------------------------------*/
168 /* replaceAllSymBySym - replaces all operands by operand in an */
169 /* instruction chain */
170 /*-----------------------------------------------------------------*/
172 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
176 for (lic = ic; lic; lic = lic->next)
180 /* do the special cases first */
184 IC_COND (lic)->key == from->key)
187 bitVectUnSetBit (OP_USES (from), lic->key);
188 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
189 siaddr = IC_COND (lic)->isaddr;
190 IC_COND (lic) = operandFromOperand (to);
191 IC_COND (lic)->isaddr = siaddr;
197 if (lic->op == JUMPTABLE)
200 IC_JTCOND (lic)->key == from->key)
203 bitVectUnSetBit (OP_USES (from), lic->key);
204 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
205 siaddr = IC_COND (lic)->isaddr;
206 IC_JTCOND (lic) = operandFromOperand (to);
207 IC_JTCOND (lic)->isaddr = siaddr;
214 IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
216 /* maintain du chains */
217 if (POINTER_SET (lic))
219 bitVectUnSetBit (OP_USES (from), lic->key);
220 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
222 /* also check if the "from" was in the non-dominating
223 pointer sets and replace it with "to" in the bitVector */
224 if (bitVectBitValue (*ndpset, from->key))
226 bitVectUnSetBit (*ndpset, from->key);
227 bitVectSetBit (*ndpset, to->key);
233 bitVectUnSetBit (OP_DEFS (from), lic->key);
234 OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
236 siaddr = IC_RESULT (lic)->isaddr;
237 IC_RESULT (lic) = operandFromOperand (to);
238 IC_RESULT (lic)->isaddr = siaddr;
242 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
244 bitVectUnSetBit (OP_USES (from), lic->key);
245 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
246 siaddr = IC_RIGHT (lic)->isaddr;
247 IC_RIGHT (lic) = operandFromOperand (to);
248 IC_RIGHT (lic)->isaddr = siaddr;
252 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
254 bitVectUnSetBit (OP_USES (from), lic->key);
255 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
256 siaddr = IC_LEFT (lic)->isaddr;
257 IC_LEFT (lic) = operandFromOperand (to);
258 IC_LEFT (lic)->isaddr = siaddr;
263 /*-----------------------------------------------------------------*/
264 /* iCodeKeyIs - if the icode keys match then return 1 */
265 /*-----------------------------------------------------------------*/
266 DEFSETFUNC (iCodeKeyIs)
271 if (cdp->diCode->key == key)
277 /*-----------------------------------------------------------------*/
278 /* removeFromInExprs - removes an icode from inexpressions */
279 /*-----------------------------------------------------------------*/
280 DEFSETFUNC (removeFromInExprs)
284 V_ARG (operand *, from);
285 V_ARG (operand *, to);
286 V_ARG (eBBlock *, cbp);
292 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
293 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
294 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
296 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
300 /*-----------------------------------------------------------------*/
301 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
302 /*-----------------------------------------------------------------*/
304 isGlobalInNearSpace (operand * op)
306 sym_link *type = getSpec (operandType (op));
307 /* this is 8051 specific: optimization
308 suggested by Jean-Louis VERN, with 8051s we have no
309 advantage of putting variables in near space into
311 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
312 IN_DIRSPACE (SPEC_OCLS (type)))
318 /*-----------------------------------------------------------------*/
319 /* findCheaperOp - cseBBlock support routine, will check to see if */
320 /* we have a operand previously defined */
321 /*-----------------------------------------------------------------*/
322 DEFSETFUNC (findCheaperOp)
325 V_ARG (operand *, cop);
326 V_ARG (operand **, opp);
327 V_ARG (int, checkSign);
329 /* if we have already found it */
333 /* not found it yet check if this is the one */
334 /* and this is not the defining one */
335 if (cop->key == cdp->key)
338 /* do a special check this will help in */
339 /* constant propagation & dead code elim */
340 /* for assignments only */
341 if (cdp->diCode->op == '=') {
342 /* if the result is volatile then return result */
343 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
344 *opp = IC_RESULT (cdp->diCode);
346 /* if this is a straight assignment and
347 left is a temp then prefer the temporary to the
349 if (!POINTER_SET (cdp->diCode) &&
350 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
351 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
352 *opp = IC_RESULT (cdp->diCode);
354 /* if straight assignement && and both
355 are temps then prefer the one that
356 will not need extra space to spil, also
357 take into consideration if right side
358 an induction variable
360 if (!POINTER_SET (cdp->diCode) &&
361 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
362 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
363 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
364 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
365 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
366 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
367 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
368 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
369 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
370 *opp = IC_RESULT (cdp->diCode);
372 *opp = IC_RIGHT (cdp->diCode);
376 *opp = IC_RESULT (cdp->diCode);
379 /* if this is an assign to a temp. then check
380 if the right side is this then return this */
381 if (IS_TRUE_SYMOP (cop) &&
382 cdp->diCode->op == '=' &&
383 !POINTER_SET (cdp->diCode) &&
384 cop->key == IC_RIGHT (cdp->diCode)->key &&
385 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
386 IS_ITEMP (IC_RESULT (cdp->diCode)))
387 *opp = IC_RESULT (cdp->diCode);
390 (isOperandLiteral(*opp) || !checkSign ||
392 IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
393 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
394 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
397 if ((isGlobalInNearSpace (cop) &&
398 !isOperandLiteral (*opp)) ||
399 isOperandVolatile (*opp, FALSE)
406 if (cop->key == (*opp)->key)
412 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
414 *opp = operandFromOperand (*opp);
415 (*opp)->isaddr = cop->isaddr;
418 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
419 SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
421 // special case: we can make an unsigned char literal
422 // into an int literal with no cost.
423 if (isOperandLiteral(*opp)
424 && SPEC_NOUN(operandType(*opp)) == V_CHAR
425 && SPEC_NOUN(operandType(cop)) == V_INT)
427 *opp = operandFromOperand (*opp);
428 SPEC_NOUN(operandType(*opp)) = V_INT;
446 /*-----------------------------------------------------------------*/
447 /* findPointerSet - finds the right side of a pointer set op */
448 /*-----------------------------------------------------------------*/
449 DEFSETFUNC (findPointerSet)
452 V_ARG (operand *, op);
453 V_ARG (operand **, opp);
454 V_ARG (operand *, rop);
456 if (POINTER_SET (cdp->diCode) &&
457 IC_RESULT (cdp->diCode)->key == op->key &&
458 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
459 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
460 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
461 getSize (operandType (rop)))
463 *opp = IC_RIGHT (cdp->diCode);
470 /*-----------------------------------------------------------------*/
471 /* findPrevIc - cseBBlock support function will return the iCode */
472 /* which matches the current one */
473 /*-----------------------------------------------------------------*/
474 DEFSETFUNC (findPrevIc)
478 V_ARG (iCode **, icp);
480 /* if already found */
484 /* if the iCodes are the same */
485 if (isiCodeEqual (ic, cdp->diCode) &&
486 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
492 /* if iCodes are not the same */
493 /* see the operands maybe interchanged */
494 if (ic->op == cdp->diCode->op &&
495 (ic->op == '+' || ic->op == '*') &&
496 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
497 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
506 /*-------------------------------------------------------------------*/
507 /* ifAssignedFromGlobal - if definition is an assignment from global */
508 /*-------------------------------------------------------------------*/
509 DEFSETFUNC (ifAssignedFromGlobal)
512 iCode *dic=cdp->diCode;
514 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
520 /*-------------------------------------------------------------------*/
521 /* ifFromGlobal - if definition is derived from global */
522 /*-------------------------------------------------------------------*/
523 DEFSETFUNC (ifFromGlobal)
527 return cdp->fromGlobal;
530 /*-----------------------------------------------------------------*/
531 /* ifDefGlobal - if definition is global */
532 /*-----------------------------------------------------------------*/
533 DEFSETFUNC (ifDefGlobal)
537 return (isOperandGlobal (cdp->sym));
540 /*-------------------------------------------------------------------*/
541 /* ifFromAddrTaken - if definition is derived from a symbol whose */
542 /* address was taken */
543 /*-------------------------------------------------------------------*/
544 DEFSETFUNC (ifFromAddrTaken)
548 return cdp->fromAddrTaken;
552 /*-----------------------------------------------------------------*/
553 /* ifAnyGetPointer - if get pointer icode */
554 /*-----------------------------------------------------------------*/
555 DEFSETFUNC (ifAnyGetPointer)
559 if (cdp->diCode && POINTER_GET (cdp->diCode))
564 /*-----------------------------------------------------------------*/
565 /* ifOperandsHave - if any of the operand are the same as this */
566 /*-----------------------------------------------------------------*/
567 DEFSETFUNC (ifOperandsHave)
570 V_ARG (operand *, op);
572 if (bitVectBitValue(cdp->ancestors, op->key))
575 if (IC_LEFT (cdp->diCode) &&
576 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
577 IC_LEFT (cdp->diCode)->key == op->key)
580 if (IC_RIGHT (cdp->diCode) &&
581 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
582 IC_RIGHT (cdp->diCode)->key == op->key)
585 /* or if any of the operands are volatile */
586 if (IC_LEFT (cdp->diCode) &&
587 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
590 if (IC_RIGHT (cdp->diCode) &&
591 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
595 if (IC_RESULT (cdp->diCode) &&
596 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
602 /*-----------------------------------------------------------------*/
603 /* ifDefSymIs - if a definition is found in the set */
604 /*-----------------------------------------------------------------*/
606 ifDefSymIs (set * cseSet, operand * sym)
611 if (!sym || !IS_SYMOP (sym))
613 for (sl = cseSet; sl; sl = sl->next)
616 if (loop->sym->key == sym->key)
623 /*-----------------------------------------------------------------*/
624 /* ifDefSymIsX - will return 1 if the symbols match */
625 /*-----------------------------------------------------------------*/
626 DEFSETFUNC (ifDefSymIsX)
629 V_ARG (operand *, op);
633 match = cdp->sym->key == op->key;
635 match = (isOperandEqual (cdp->sym, op));
638 printf("%s ",OP_SYMBOL(cdp->sym)->name);
644 /*-----------------------------------------------------------------*/
645 /* ifDiCodeIs - returns true if diCode is same */
646 /*-----------------------------------------------------------------*/
648 ifDiCodeIs (set * cseSet, iCode * ic)
656 for (sl = cseSet; sl; sl = sl->next)
659 if (loop->diCode == ic)
666 /*-----------------------------------------------------------------*/
667 /* ifPointerGet - returns true if the icode is pointer get sym */
668 /*-----------------------------------------------------------------*/
669 DEFSETFUNC (ifPointerGet)
672 V_ARG (operand *, op);
673 iCode *dic = cdp->diCode;
674 operand *left = IC_LEFT (cdp->diCode);
676 if (POINTER_GET (dic) && left->key == op->key)
682 /*-----------------------------------------------------------------*/
683 /* ifPointerSet - returns true if the icode is pointer set sym */
684 /*-----------------------------------------------------------------*/
685 DEFSETFUNC (ifPointerSet)
688 V_ARG (operand *, op);
690 if (POINTER_SET (cdp->diCode) &&
691 IC_RESULT (cdp->diCode)->key == op->key)
697 /*-----------------------------------------------------------------*/
698 /* ifDiCodeIsX - will return 1 if the symbols match */
699 /*-----------------------------------------------------------------*/
700 DEFSETFUNC (ifDiCodeIsX)
705 return cdp->diCode == ic;
709 /*-----------------------------------------------------------------*/
710 /* findBackwardDef - scan backwards to find deinition of operand */
711 /*-----------------------------------------------------------------*/
712 iCode *findBackwardDef(operand *op,iCode *ic)
716 for (lic = ic; lic ; lic = lic->prev) {
717 if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
723 /*-----------------------------------------------------------------*/
724 /* algebraicOpts - does some algebraic optimizations */
725 /*-----------------------------------------------------------------*/
727 algebraicOpts (iCode * ic, eBBlock * ebp)
729 /* we don't deal with the following iCodes
740 /* if both operands present & ! IFX */
741 /* then if they are both literal we */
742 /* perform the operation right now */
743 if (IC_RESULT (ic) &&
746 IS_OP_LITERAL (IC_LEFT (ic)) &&
747 IS_OP_LITERAL (IC_RIGHT (ic)))
750 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
753 operandType (IC_RESULT (ic)));
756 SET_RESULT_RIGHT (ic);
760 /* if not ifx & only one operand present */
761 if (IC_RESULT (ic) &&
763 IS_OP_LITERAL (IC_LEFT (ic)) &&
767 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
770 operandType (IC_RESULT (ic)));
773 SET_RESULT_RIGHT (ic);
778 /* a special case : or in short a kludgy solution will think
779 about a better solution over a glass of wine someday */
780 if (ic->op == GET_VALUE_AT_ADDRESS)
783 if (IS_ITEMP (IC_RESULT (ic)) &&
784 IS_TRUE_SYMOP (IC_LEFT (ic)))
788 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
789 IC_RIGHT (ic)->isaddr = 0;
791 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
792 IC_RESULT (ic)->isaddr = 0;
793 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
797 if (IS_ITEMP (IC_LEFT (ic)) &&
798 IS_ITEMP (IC_RESULT (ic)) &&
799 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
800 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
801 !IC_LEFT (ic)->isaddr)
804 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
805 IC_RIGHT (ic)->isaddr = 0;
806 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
807 IC_RESULT (ic)->isaddr = 0;
815 /* depending on the operation */
819 /* if adding the same thing change to left shift by 1 */
820 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
821 !IS_FLOAT (operandType (IC_RESULT (ic))))
824 IC_RIGHT (ic) = operandFromLit (1);
827 /* if addition then check if one of them is a zero */
828 /* if yes turn it into assignmnt or cast */
829 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
830 operandLitValue (IC_LEFT (ic)) == 0.0)
832 if (compareType (operandType (IC_RESULT (ic)),
833 operandType (IC_RIGHT (ic)))<0)
836 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
843 SET_ISADDR (IC_RESULT (ic), 0);
844 SET_ISADDR (IC_RIGHT (ic), 0);
847 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
848 operandLitValue (IC_RIGHT (ic)) == 0.0)
850 if (compareType (operandType (IC_RESULT (ic)),
851 operandType (IC_LEFT (ic)))<0)
854 IC_RIGHT (ic) = IC_LEFT (ic);
855 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
860 IC_RIGHT (ic) = IC_LEFT (ic);
863 SET_ISADDR (IC_RIGHT (ic), 0);
864 SET_ISADDR (IC_RESULT (ic), 0);
869 /* if subtracting the the same thing then zero */
870 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
873 IC_RIGHT (ic) = operandFromLit (0);
875 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
876 IC_RESULT (ic)->isaddr = 0;
880 /* if subtraction then check if one of the operand */
881 /* is zero then depending on which operand change */
882 /* to assignment or unary minus */
883 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
884 operandLitValue (IC_RIGHT (ic)) == 0.0)
886 /* right size zero change to assignment */
888 IC_RIGHT (ic) = IC_LEFT (ic);
890 SET_ISADDR (IC_RIGHT (ic), 0);
891 SET_ISADDR (IC_RESULT (ic), 0);
894 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
895 operandLitValue (IC_LEFT (ic)) == 0.0)
897 /* left zero turn into an unary minus */
899 IC_LEFT (ic) = IC_RIGHT (ic);
900 IC_RIGHT (ic) = NULL;
904 /* if multiplication then check if either of */
905 /* them is zero then the result is zero */
906 /* if either of them is one then result is */
909 if (IS_OP_LITERAL (IC_LEFT (ic)))
912 if (operandLitValue (IC_LEFT (ic)) == 0.0)
915 IC_RIGHT (ic) = IC_LEFT (ic);
917 SET_RESULT_RIGHT (ic);
920 if (operandLitValue (IC_LEFT (ic)) == 1.0)
922 /* '*' can have two unsigned chars as operands */
923 /* and an unsigned int as result. */
924 if (compareType (operandType (IC_RESULT (ic)),
925 operandType (IC_RIGHT (ic))) == 1)
929 SET_RESULT_RIGHT (ic);
934 IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
935 IC_LEFT (ic)->type = TYPE;
936 IC_LEFT (ic)->isLiteral = 0;
937 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
943 if (IS_OP_LITERAL (IC_RIGHT (ic)))
946 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
950 SET_RESULT_RIGHT (ic);
954 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
956 /* '*' can have two unsigned chars as operands */
957 /* and an unsigned int as result. */
958 if (compareType (operandType (IC_RESULT (ic)),
959 operandType (IC_LEFT (ic))) == 1)
962 IC_RIGHT (ic) = IC_LEFT (ic);
964 SET_RESULT_RIGHT (ic);
972 IC_RIGHT (ic) = IC_LEFT (ic);
973 IC_LEFT (ic) = operandFromOperand (op);
974 IC_LEFT (ic)->type = TYPE;
975 IC_LEFT (ic)->isLiteral = 0;
976 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
983 /* if division by self then 1 */
984 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
987 IC_RIGHT (ic) = operandFromLit (1);
989 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
990 IC_RESULT (ic)->isaddr = 0;
993 /* if this is a division then check if right */
994 /* is one then change it to an assignment */
995 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
996 operandLitValue (IC_RIGHT (ic)) == 1.0)
1000 IC_RIGHT (ic) = IC_LEFT (ic);
1001 IC_LEFT (ic) = NULL;
1002 SET_RESULT_RIGHT (ic);
1006 /* if both are the same for an comparison operators */
1010 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1013 IC_RIGHT (ic) = operandFromLit (1);
1014 IC_LEFT (ic) = NULL;
1015 SET_RESULT_RIGHT (ic);
1021 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1024 IC_RIGHT (ic) = operandFromLit (0);
1025 IC_LEFT (ic) = NULL;
1026 SET_RESULT_RIGHT (ic);
1031 sym_link *otype = operandType(IC_RIGHT(ic));
1032 sym_link *ctype = operandType(IC_LEFT(ic));
1033 /* if this is a cast of a literal value */
1034 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1035 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
1038 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
1039 operandLitValue (IC_RIGHT (ic))));
1040 IC_LEFT (ic) = NULL;
1041 SET_ISADDR (IC_RESULT (ic), 0);
1043 /* if casting to the same */
1044 if (compareType (operandType (IC_RESULT (ic)),
1045 operandType (IC_RIGHT (ic))) == 1) {
1047 IC_LEFT (ic) = NULL;
1048 SET_ISADDR (IC_RESULT (ic), 0);
1053 if (IS_OP_LITERAL (IC_LEFT (ic)))
1057 (operandLitValue (IC_LEFT (ic)) == 0 ?
1058 operandFromLit (1) : operandFromLit (0));
1059 IC_LEFT (ic) = NULL;
1060 SET_ISADDR (IC_RESULT (ic), 0);
1064 /* if both operands are equal */
1065 /* if yes turn it into assignment */
1066 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1068 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1070 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1071 IC_RESULT (newic) = IC_LEFT (ic);
1072 newic->lineno = ic->lineno;
1073 addiCodeToeBBlock (ebp, newic, ic->next);
1076 IC_LEFT (ic) = NULL;
1077 SET_RESULT_RIGHT (ic);
1080 /* swap literal to right ic */
1081 if (IS_OP_LITERAL (IC_LEFT (ic)))
1086 IC_LEFT (ic) = IC_RIGHT (ic);
1089 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1091 /* if BITWISEAND then check if one of them is a zero */
1092 /* if yes turn it into 0 assignment */
1093 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1095 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1097 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1098 IC_RESULT (newic) = IC_LEFT (ic);
1099 newic->lineno = ic->lineno;
1100 addiCodeToeBBlock (ebp, newic, ic->next);
1103 IC_LEFT (ic) = NULL;
1104 SET_RESULT_RIGHT (ic);
1107 /* if BITWISEAND then check if one of them is 0xff... */
1108 /* if yes turn it into assignment */
1112 switch (getSize (operandType (IC_RIGHT (ic))))
1126 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1129 IC_RIGHT (ic) = IC_LEFT (ic);
1130 IC_LEFT (ic) = NULL;
1131 SET_RESULT_RIGHT (ic);
1138 /* if both operands are equal */
1139 /* if yes turn it into assignment */
1140 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1142 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1144 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1145 IC_RESULT (newic) = IC_LEFT (ic);
1146 newic->lineno = ic->lineno;
1147 addiCodeToeBBlock (ebp, newic, ic->next);
1150 IC_LEFT (ic) = NULL;
1151 SET_RESULT_RIGHT (ic);
1154 /* swap literal to right ic */
1155 if (IS_OP_LITERAL (IC_LEFT (ic)))
1160 IC_LEFT (ic) = IC_RIGHT (ic);
1163 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1165 /* if BITWISEOR then check if one of them is a zero */
1166 /* if yes turn it into assignment */
1167 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1170 IC_RIGHT (ic) = IC_LEFT (ic);
1171 IC_LEFT (ic) = NULL;
1172 SET_RESULT_RIGHT (ic);
1175 /* if BITWISEOR then check if one of them is 0xff... */
1176 /* if yes turn it into 0xff... assignment */
1180 switch (getSize (operandType (IC_RIGHT (ic))))
1194 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1196 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1198 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1199 IC_RESULT (newic) = IC_LEFT (ic);
1200 newic->lineno = ic->lineno;
1201 addiCodeToeBBlock (ebp, newic, ic->next);
1204 IC_LEFT (ic) = NULL;
1205 SET_RESULT_RIGHT (ic);
1212 /* if both operands are equal */
1213 /* if yes turn it into 0 assignment */
1214 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1216 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1218 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1219 IC_RESULT (newic) = IC_LEFT (ic);
1220 newic->lineno = ic->lineno;
1221 addiCodeToeBBlock (ebp, newic, ic->next);
1223 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1224 IC_RESULT (newic) = IC_LEFT (ic);
1225 newic->lineno = ic->lineno;
1226 addiCodeToeBBlock (ebp, newic, ic->next);
1229 IC_RIGHT (ic) = operandFromLit (0);
1230 IC_LEFT (ic) = NULL;
1231 SET_RESULT_RIGHT (ic);
1234 /* swap literal to right ic */
1235 if (IS_OP_LITERAL (IC_LEFT (ic)))
1240 IC_LEFT (ic) = IC_RIGHT (ic);
1243 /* if XOR then check if one of them is a zero */
1244 /* if yes turn it into assignment */
1245 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1247 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1250 IC_RIGHT (ic) = IC_LEFT (ic);
1251 IC_LEFT (ic) = NULL;
1252 SET_RESULT_RIGHT (ic);
1261 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1262 /*-----------------------------------------------------------------*/
1263 /* updateSpillLocation - keeps track of register spill location */
1264 /*-----------------------------------------------------------------*/
1266 updateSpillLocation (iCode * ic, int induction)
1270 if (POINTER_SET (ic))
1277 /* for the form true_symbol := iTempNN */
1278 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1279 !SPIL_LOC (IC_RIGHT (ic))) {
1281 setype = getSpec (operandType (IC_RESULT (ic)));
1283 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1284 !IS_VOLATILE (setype) &&
1285 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1286 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1288 wassert(IS_SYMOP(IC_RESULT (ic)));
1289 wassert(IS_SYMOP(IC_RIGHT (ic)));
1290 SPIL_LOC (IC_RIGHT (ic)) =
1291 IC_RESULT (ic)->operand.symOperand;
1297 #if 0 /* this needs furthur investigation can save a lot of code */
1298 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1299 !SPIL_LOC(IC_RESULT(ic))) {
1300 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1301 SPIL_LOC (IC_RESULT (ic)) =
1302 IC_RIGHT (ic)->operand.symOperand;
1305 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1307 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1308 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1309 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1311 setype = getSpec (operandType (IC_RESULT (ic)));
1313 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1314 !IS_VOLATILE (setype) &&
1315 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1316 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) {
1318 SPIL_LOC (IC_RIGHT (ic)) =
1319 SPIL_LOC (IC_RESULT (ic));
1320 OP_SYMBOL (IC_RIGHT (ic))->prereqv =
1321 OP_SYMBOL (IC_RESULT (ic))->prereqv;
1324 /* special case for inductions */
1326 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1327 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1328 !SPIL_LOC(IC_RESULT(ic))) {
1329 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1330 OP_SYMBOL (IC_RESULT (ic))->prereqv =
1331 OP_SYMBOL (IC_RIGHT (ic))->prereqv;
1335 /*-----------------------------------------------------------------*/
1336 /* setUsesDef - sets the uses def bitvector for a given operand */
1337 /*-----------------------------------------------------------------*/
1339 setUsesDefs (operand * op, bitVect * bdefs,
1340 bitVect * idefs, bitVect ** oud)
1342 /* compute the definitions alive at this point */
1343 bitVect *adefs = bitVectUnion (bdefs, idefs);
1345 /* of these definitions find the ones that are */
1346 /* for this operand */
1347 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1349 /* these are the definitions that this operand can use */
1350 op->usesDefs = adefs;
1352 /* the out defs is an union */
1353 *oud = bitVectUnion (*oud, adefs);
1356 /*-----------------------------------------------------------------*/
1357 /* unsetDefsAndUses - clear this operation for the operands */
1358 /*-----------------------------------------------------------------*/
1360 unsetDefsAndUses (iCode * ic)
1362 if (ic->op == JUMPTABLE)
1365 /* take away this definition from the def chain of the */
1366 /* result & take away from use set of the operands */
1369 /* turn off def set */
1370 if (IS_SYMOP (IC_RESULT (ic)))
1372 if (!POINTER_SET (ic))
1373 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1375 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1377 /* turn off the useSet for the operands */
1378 if (IS_SYMOP (IC_LEFT (ic)))
1379 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1381 if (IS_SYMOP (IC_RIGHT (ic)))
1382 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1385 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1386 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1389 /*-----------------------------------------------------------------*/
1390 /* ifxOptimize - changes ifx conditions if it can */
1391 /*-----------------------------------------------------------------*/
1393 ifxOptimize (iCode * ic, set * cseSet,
1395 eBBlock * ebb, int *change,
1396 eBBlock ** ebbs, int count)
1401 /* if the condition can be replaced */
1405 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1408 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1413 /* if the conditional is a literal then */
1414 if (IS_OP_LITERAL (IC_COND (ic)))
1417 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1420 /* change to a goto */
1422 IC_LABEL (ic) = IC_TRUE (ic);
1429 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1432 IC_LABEL (ic) = IC_FALSE (ic);
1438 /* then kill this if condition */
1439 remiCodeFromeBBlock (ebb, ic);
1443 /* now we need to recompute the control flow */
1444 /* since the control flow has changed */
1445 /* this is very expensive but it does not happen */
1446 /* too often, if it does happen then the user pays */
1448 computeControlFlow (ebbs, count, 1);
1449 if (!options.lessPedantic) {
1450 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1455 /* if there is only one successor and that successor
1456 is the same one we are conditionally going to then
1457 we can remove this conditional statement */
1458 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1459 if (elementsInSet (ebb->succList) == 1 &&
1460 isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
1463 if (!options.lessPedantic) {
1464 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1466 if (IS_OP_VOLATILE (IC_COND (ic)))
1468 IC_RIGHT (ic) = IC_COND (ic);
1469 IC_LEFT (ic) = NULL;
1470 IC_RESULT (ic) = NULL;
1471 ic->op = DUMMY_READ_VOLATILE;
1475 remiCodeFromeBBlock (ebb, ic);
1476 computeControlFlow (ebbs, count, 1);
1482 /* if it remains an IFX the update the use Set */
1485 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1486 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1488 else if (ic->op == DUMMY_READ_VOLATILE)
1490 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1491 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1496 /*-----------------------------------------------------------------*/
1497 /* diCodeForSym - finds the definiting instruction for a symbol */
1498 /*-----------------------------------------------------------------*/
1499 DEFSETFUNC (diCodeForSym)
1502 V_ARG (operand *, sym);
1503 V_ARG (iCode **, dic);
1505 /* if already found */
1509 /* if not if this is the defining iCode */
1510 if (sym->key == cdp->key)
1519 /*-----------------------------------------------------------------*/
1520 /* constFold - does some constant folding */
1521 /*-----------------------------------------------------------------*/
1523 constFold (iCode * ic, set * cseSet)
1527 /* this routine will change
1533 /* deal with only + & - */
1534 if (ic->op != '+' &&
1538 /* this check is a hueristic to prevent live ranges
1539 from becoming too long */
1540 if (IS_PTR (operandType (IC_RESULT (ic))))
1543 /* check if operation with a literal */
1544 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1547 /* check if we can find a definition for the
1549 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1552 /* check that this is also a +/- */
1553 if (dic->op != '+' && dic->op != '-')
1556 /* with a literal */
1557 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1560 /* find the definition of the left operand
1561 of dic.then check if this defined with a
1562 get_pointer return 0 if the pointer size is
1563 less than 2 (MCS51 specific) */
1564 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1567 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1570 /* it is if the operations are the same */
1571 /* the literal parts need to be added */
1572 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1573 if (ic->op == dic->op)
1574 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1575 operandLitValue (IC_RIGHT (dic)));
1577 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1578 operandLitValue (IC_RIGHT (dic)));
1580 if (IS_ITEMP (IC_RESULT (ic)))
1582 SPIL_LOC (IC_RESULT (ic)) = NULL;
1583 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1590 /*-----------------------------------------------------------------*/
1591 /* deleteGetPointers - called when a pointer is passed as parm */
1592 /* will delete from cseSet all get pointers computed from this */
1593 /* pointer. A simple ifOperandsHave is not good enough here */
1594 /*-----------------------------------------------------------------*/
1596 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1598 set *compItems = NULL;
1604 if (!*cseSet && !*pss)
1607 addSet (&compItems, op);
1609 /* Recursively find all items computed from this operand .
1610 This done fairly simply go thru the list and find
1611 those that are computed by arthimetic with these
1613 /* Also check for those computed from our computed
1614 list . This will take care of situations like
1615 iTemp1 = iTemp0 + 8;
1616 iTemp2 = iTemp1 + 8; */
1620 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1622 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1624 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1625 (insetwithFunc)isOperandEqual) ||
1626 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1627 (insetwithFunc)isOperandEqual))
1629 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1630 (insetwithFunc)isOperandEqual))
1632 addSet (&compItems, IC_RESULT (cdp->diCode));
1641 /* now for the computed items */
1642 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1644 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1645 deleteItemIf (cseSet, ifPointerGet, cop);
1646 deleteItemIf (cseSet, ifDefSymIsX, cop);
1647 deleteItemIf (pss, ifPointerSet, cop);
1651 /*-----------------------------------------------------------------*/
1652 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1653 /* dfnum > supplied */
1654 /*-----------------------------------------------------------------*/
1655 DEFSETFUNC (delGetPointerSucc)
1657 eBBlock *ebp = item;
1658 V_ARG (operand *, op);
1665 if (ebp->dfnum > dfnum)
1667 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1670 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1673 /*-----------------------------------------------------------------*/
1674 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1675 /*-----------------------------------------------------------------*/
1677 fixUpTypes (iCode * ic)
1679 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1681 /* if (TARGET_IS_DS390) */
1682 if (options.model == MODEL_FLAT24)
1688 /* for pointer_gets if the types of result & left r the
1689 same then change it type of result to next */
1691 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1693 setOperandType (IC_RESULT (ic), t2->next);
1697 /*-----------------------------------------------------------------*/
1698 /* isSignedOp - will return 1 if sign is important to operation */
1699 /*-----------------------------------------------------------------*/
1700 static int isSignedOp (iCode *ic)
1721 case GET_VALUE_AT_ADDRESS:
1749 dumpCseSet(set *cseSet)
1753 cseDef *item=cseSet->item;
1755 printOperand (item->sym, NULL);
1757 piCode (item->diCode, NULL);
1758 cseSet = cseSet->next;
1763 /*-----------------------------------------------------------------*/
1764 /* cseBBlock - common subexpression elimination for basic blocks */
1765 /* this is the hackiest kludgiest routine in the whole */
1766 /* system. also the most important, since almost all */
1767 /* data flow related information is computed by it */
1768 /*-----------------------------------------------------------------*/
1770 cseBBlock (eBBlock * ebb, int computeOnly,
1771 eBBlock ** ebbs, int count)
1777 set *ptrSetSet = NULL;
1780 /* if this block is not reachable */
1784 /* set of common subexpressions */
1785 cseSet = setFromSet (ebb->inExprs);
1787 /* these will be computed by this routine */
1788 setToNull ((void *) &ebb->outDefs);
1789 setToNull ((void *) &ebb->defSet);
1790 setToNull ((void *) &ebb->usesDefs);
1791 setToNull ((void *) &ebb->ptrsSet);
1792 setToNull ((void *) &ebb->addrOf);
1793 setToNull ((void *) &ebb->ldefs);
1795 ebb->outDefs = bitVectCopy (ebb->inDefs);
1796 bitVectDefault = iCodeKey;
1797 ebb->defSet = newBitVect (iCodeKey);
1798 ebb->usesDefs = newBitVect (iCodeKey);
1800 /* for all the instructions in this block do */
1801 for (ic = ebb->sch; ic; ic = ic->next)
1808 ic->eBBlockNum = ebb->bbnum;
1813 /* if this is an assignment from true symbol
1814 to a temp then do pointer post inc/dec optimzation */
1815 if (ic->op == '=' && !POINTER_SET (ic) &&
1816 IS_PTR (operandType (IC_RESULT (ic))))
1818 ptrPostIncDecOpt (ic);
1821 /* clear the def & use chains for the operands involved */
1822 /* in this operation . since it can change due to opts */
1823 unsetDefsAndUses (ic);
1825 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1827 /* add to defSet of the symbol */
1828 OP_DEFS(IC_RESULT (ic))=
1829 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1830 /* add to the definition set of this block */
1831 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1832 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1833 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1834 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1835 /* delete global variables from the cseSet
1836 since they can be modified by the function call */
1837 deleteItemIf (&cseSet, ifDefGlobal);
1839 /* and also iTemps derived from globals */
1840 deleteItemIf (&cseSet, ifFromGlobal);
1842 /* Delete iTemps derived from symbols whose address */
1843 /* has been taken */
1844 deleteItemIf (&cseSet, ifFromAddrTaken);
1846 /* delete all getpointer iCodes from cseSet, this should
1847 be done only for global arrays & pointers but at this
1848 point we don't know if globals, so to be safe do all */
1849 deleteItemIf (&cseSet, ifAnyGetPointer);
1851 /* can't cache pointer set/get operations across a call */
1852 deleteSet (&ptrSetSet);
1855 /* for pcall & ipush we need to add to the useSet */
1856 if ((ic->op == PCALL ||
1860 IS_SYMOP (IC_LEFT (ic)))
1863 /* check if they can be replaced */
1867 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1869 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1871 /* the lookup could have changed it */
1872 if (IS_SYMOP (IC_LEFT (ic)))
1874 OP_USES(IC_LEFT (ic))=
1875 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1876 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1877 ebb->outDefs, &ebb->usesDefs);
1881 /* if we a sending a pointer as a parameter
1882 then kill all cse since the pointed to item
1883 might be changed in the function being called */
1884 if ((ic->op == IPUSH || ic->op == SEND) &&
1885 IS_PTR (operandType (IC_LEFT (ic))))
1887 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1888 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1889 for (i = 0; i < count; ebbs[i++]->visited = 0);
1890 applyToSet (ebb->succList, delGetPointerSucc,
1891 IC_LEFT (ic), ebb->dfnum);
1896 /* if jumptable then mark the usage */
1897 if (ic->op == JUMPTABLE)
1899 if (IS_SYMOP (IC_JTCOND (ic)))
1901 OP_USES(IC_JTCOND (ic)) =
1902 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1903 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1904 ebb->outDefs, &ebb->usesDefs);
1914 /* do some algebraic optimizations if possible */
1915 algebraicOpts (ic, ebb);
1916 while (constFold (ic, cseSet));
1920 if (POINTER_GET (ic))
1922 if (!IS_PTR (operandType (IC_LEFT (ic))))
1924 setOperandType (IC_LEFT (ic),
1925 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1926 IC_LEFT (ic)->aggr2ptr = 0;
1929 else if (IC_LEFT (ic)->aggr2ptr)
1930 {/* band aid for kludge */
1931 setOperandType (IC_LEFT (ic),
1932 aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
1933 IC_LEFT (ic)->aggr2ptr = 0;
1938 if (POINTER_SET (ic))
1940 if (!IS_PTR (operandType (IC_RESULT (ic))))
1942 setOperandType (IC_RESULT (ic),
1943 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1944 IC_RESULT (ic)->aggr2ptr = 0;
1946 else if (IC_RESULT (ic)->aggr2ptr)
1947 {/* band aid for kludge */
1948 setOperandType (IC_RESULT (ic),
1949 aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1950 IC_RESULT (ic)->aggr2ptr = 0;
1954 /* if this is a condition statement then */
1955 /* check if the condition can be replaced */
1958 ifxOptimize (ic, cseSet, computeOnly,
1964 /* if the assignment & result is a temp */
1965 /* see if we can replace it */
1966 if (!computeOnly && ic->op == '=')
1969 /* update the spill location for this */
1970 updateSpillLocation (ic,0);
1972 if (POINTER_SET (ic) &&
1973 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1976 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1977 if (pdop && !computeOnly && IS_ITEMP (pdop))
1979 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1980 if (!IS_PTR (operandType (IC_RESULT (ic))))
1982 setOperandType (IC_RESULT (ic),
1983 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1989 checkSign = isSignedOp(ic);
1991 /* do the operand lookup i.e. for both the */
1992 /* right & left operand : check the cseSet */
1993 /* to see if they have been replaced if yes */
1994 /* then replace them with those from cseSet */
1996 /* and left is a symbol */
1997 if (IS_SYMOP (IC_LEFT (ic)) &&
1998 !computeOnly && ic->op != ADDRESS_OF)
2002 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2005 if (POINTER_GET (ic))
2007 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2009 /* some non dominating block does POINTER_SET with
2010 this variable .. unsafe to remove any POINTER_GETs */
2011 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
2012 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
2013 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2016 /* check if there is a pointer set
2017 for the same pointer visible if yes
2018 then change this into an assignment */
2020 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2021 !bitVectBitValue (ebb->ptrsSet, pdop->key))
2024 IC_LEFT (ic) = NULL;
2025 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2026 SET_ISADDR (IC_RESULT (ic), 0);
2032 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2039 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2043 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2045 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2050 /* if left or right changed then do algebraic */
2051 if (!computeOnly && change)
2053 algebraicOpts (ic, ebb);
2054 while (constFold (ic, cseSet));
2057 /* if after all this it becomes an assignment to self
2058 then delete it and continue */
2059 if (ASSIGNMENT_TO_SELF (ic))
2061 remiCodeFromeBBlock (ebb, ic);
2065 /* now we will check to see if the entire */
2066 /* operation has been performed before */
2067 /* and is available */
2068 /* don't do assignments they will be killed */
2069 /* by dead code elimination if required do */
2070 /* it only if result is a temporary */
2072 if (!(POINTER_GET (ic) &&
2073 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2074 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2075 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2077 IS_ITEMP (IC_RESULT (ic)) &&
2080 applyToSet (cseSet, findPrevIc, ic, &pdic);
2081 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2082 operandType (IC_RESULT (ic))) != 1)
2084 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2088 /* Alternate code */
2089 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2090 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2091 /* Mmm, found an equivalent pointer get at a lower level.
2092 This could be a loop however with the same pointer set
2095 /* if previous definition found change this to an assignment */
2098 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2099 SET_ISADDR(IC_RESULT(ic),0);
2100 SET_ISADDR(IC_RIGHT (ic),0);
2104 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2106 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2107 csed = newCseDef (IC_RESULT (ic), ic);
2108 updateCseDefAncestors (csed, cseSet);
2109 addSetHead (&cseSet, csed);
2113 /* if assignment to a parameter which is not
2114 mine and type is a pointer then delete
2115 pointerGets to take care of aliasing */
2116 if (ASSIGNMENT (ic) &&
2117 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2118 IS_PTR (operandType (IC_RESULT (ic))))
2120 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2121 for (i = 0; i < count; ebbs[i++]->visited = 0);
2122 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2123 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2126 /* if this is a pointerget then see if we can replace
2127 this with a previously assigned pointer value */
2128 if (POINTER_GET (ic) &&
2129 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2130 isOperandVolatile (IC_LEFT (ic), TRUE)))
2133 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2134 /* if we find it then locally replace all
2135 references to the result with what we assigned */
2138 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2142 /* delete from the cseSet anything that has */
2143 /* operands matching the result of this */
2144 /* except in case of pointer access */
2145 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2147 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2148 /* delete any previous definitions */
2149 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2153 /* add the left & right to the defUse set */
2154 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2156 OP_USES(IC_LEFT (ic))=
2157 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2158 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2162 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2164 OP_USES(IC_RIGHT (ic))=
2165 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2166 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2170 /* for the result it is special case, put the result */
2171 /* in the defuseSet if it a pointer or array access */
2172 if (POINTER_SET (defic))
2174 OP_USES(IC_RESULT (ic))=
2175 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2176 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2177 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2178 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2179 /* delete from inexpressions of all successors which
2180 have dfNum > than this block */
2181 for (i = 0; i < count; ebbs[i++]->visited = 0);
2182 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2184 /* delete from cseSet all other pointer sets
2186 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2187 /* add to the local pointerset set */
2188 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2191 /* add the result to defintion set */ if (IC_RESULT (ic))
2193 OP_DEFS(IC_RESULT (ic))=
2194 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2195 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2196 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2197 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2201 /* if this is an addressof instruction then */
2202 /* put the symbol in the address of list & */
2203 /* delete it from the cseSet */
2204 if (defic->op == ADDRESS_OF)
2206 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2207 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2211 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2212 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2213 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2214 addSetHead (&ebb->killedExprs, expr);
2216 setToNull ((void *) &ebb->outExprs);
2217 ebb->outExprs = cseSet;
2218 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2219 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2223 /*-----------------------------------------------------------------*/
2224 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2225 /*-----------------------------------------------------------------*/
2227 cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
2232 /* if optimization turned off */
2234 for (i = 0; i < count; i++)
2235 change += cseBBlock (ebbs[i], computeOnly, ebbs, count);