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 == '*') && // MB: why not check for &, &&, |, ||, ^ ???
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,
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 (ebbi);
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 (ebbi, label)))
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 (ebbi);
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 heuristic 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,
1773 eBBlock ** ebbs = ebbi->bbOrder;
1774 int count = ebbi->count;
1779 set *ptrSetSet = NULL;
1782 /* if this block is not reachable */
1786 /* set of common subexpressions */
1787 cseSet = setFromSet (ebb->inExprs);
1789 /* these will be computed by this routine */
1790 setToNull ((void *) &ebb->outDefs);
1791 setToNull ((void *) &ebb->defSet);
1792 setToNull ((void *) &ebb->usesDefs);
1793 setToNull ((void *) &ebb->ptrsSet);
1794 setToNull ((void *) &ebb->addrOf);
1795 setToNull ((void *) &ebb->ldefs);
1797 ebb->outDefs = bitVectCopy (ebb->inDefs);
1798 bitVectDefault = iCodeKey;
1799 ebb->defSet = newBitVect (iCodeKey);
1800 ebb->usesDefs = newBitVect (iCodeKey);
1802 /* for all the instructions in this block do */
1803 for (ic = ebb->sch; ic; ic = ic->next)
1810 ic->eBBlockNum = ebb->bbnum;
1815 /* if this is an assignment from true symbol
1816 to a temp then do pointer post inc/dec optimzation */
1817 if (ic->op == '=' && !POINTER_SET (ic) &&
1818 IS_PTR (operandType (IC_RESULT (ic))))
1820 ptrPostIncDecOpt (ic);
1823 /* clear the def & use chains for the operands involved */
1824 /* in this operation . since it can change due to opts */
1825 unsetDefsAndUses (ic);
1827 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1829 /* add to defSet of the symbol */
1830 OP_DEFS(IC_RESULT (ic))=
1831 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1832 /* add to the definition set of this block */
1833 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1834 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1835 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1836 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1837 /* delete global variables from the cseSet
1838 since they can be modified by the function call */
1839 deleteItemIf (&cseSet, ifDefGlobal);
1841 /* and also iTemps derived from globals */
1842 deleteItemIf (&cseSet, ifFromGlobal);
1844 /* Delete iTemps derived from symbols whose address */
1845 /* has been taken */
1846 deleteItemIf (&cseSet, ifFromAddrTaken);
1848 /* delete all getpointer iCodes from cseSet, this should
1849 be done only for global arrays & pointers but at this
1850 point we don't know if globals, so to be safe do all */
1851 deleteItemIf (&cseSet, ifAnyGetPointer);
1853 /* can't cache pointer set/get operations across a call */
1854 deleteSet (&ptrSetSet);
1857 /* for pcall & ipush we need to add to the useSet */
1858 if ((ic->op == PCALL ||
1862 IS_SYMOP (IC_LEFT (ic)))
1865 /* check if they can be replaced */
1869 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1871 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1873 /* the lookup could have changed it */
1874 if (IS_SYMOP (IC_LEFT (ic)))
1876 OP_USES(IC_LEFT (ic))=
1877 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1878 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1879 ebb->outDefs, &ebb->usesDefs);
1883 /* if we a sending a pointer as a parameter
1884 then kill all cse since the pointed to item
1885 might be changed in the function being called */
1886 if ((ic->op == IPUSH || ic->op == SEND) &&
1887 IS_PTR (operandType (IC_LEFT (ic))))
1889 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1890 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1891 for (i = 0; i < count; ebbs[i++]->visited = 0);
1892 applyToSet (ebb->succList, delGetPointerSucc,
1893 IC_LEFT (ic), ebb->dfnum);
1898 /* if jumptable then mark the usage */
1899 if (ic->op == JUMPTABLE)
1901 if (IS_SYMOP (IC_JTCOND (ic)))
1903 OP_USES(IC_JTCOND (ic)) =
1904 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1905 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1906 ebb->outDefs, &ebb->usesDefs);
1916 /* do some algebraic optimizations if possible */
1917 algebraicOpts (ic, ebb);
1918 while (constFold (ic, cseSet));
1922 if (POINTER_GET (ic))
1924 if (!IS_PTR (operandType (IC_LEFT (ic))))
1926 setOperandType (IC_LEFT (ic),
1927 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1928 IC_LEFT (ic)->aggr2ptr = 0;
1931 else if (IC_LEFT (ic)->aggr2ptr)
1932 {/* band aid for kludge */
1933 setOperandType (IC_LEFT (ic),
1934 aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
1935 IC_LEFT (ic)->aggr2ptr = 0;
1940 if (POINTER_SET (ic))
1942 if (!IS_PTR (operandType (IC_RESULT (ic))))
1944 setOperandType (IC_RESULT (ic),
1945 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1946 IC_RESULT (ic)->aggr2ptr = 0;
1948 else if (IC_RESULT (ic)->aggr2ptr)
1949 {/* band aid for kludge */
1950 setOperandType (IC_RESULT (ic),
1951 aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1952 IC_RESULT (ic)->aggr2ptr = 0;
1956 /* if this is a condition statement then */
1957 /* check if the condition can be replaced */
1960 ifxOptimize (ic, cseSet, computeOnly,
1966 /* if the assignment & result is a temp */
1967 /* see if we can replace it */
1968 if (!computeOnly && ic->op == '=')
1971 /* update the spill location for this */
1972 updateSpillLocation (ic,0);
1974 if (POINTER_SET (ic) &&
1975 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1978 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1979 if (pdop && !computeOnly && IS_ITEMP (pdop))
1981 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1982 if (!IS_PTR (operandType (IC_RESULT (ic))))
1984 setOperandType (IC_RESULT (ic),
1985 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1991 checkSign = isSignedOp(ic);
1993 /* do the operand lookup i.e. for both the */
1994 /* right & left operand : check the cseSet */
1995 /* to see if they have been replaced if yes */
1996 /* then replace them with those from cseSet */
1998 /* and left is a symbol */
1999 if (IS_SYMOP (IC_LEFT (ic)) &&
2000 !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
2001 !computeOnly && ic->op != ADDRESS_OF)
2005 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2008 if (POINTER_GET (ic))
2010 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2012 /* some non dominating block does POINTER_SET with
2013 this variable .. unsafe to remove any POINTER_GETs */
2014 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
2015 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
2016 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2019 /* check if there is a pointer set
2020 for the same pointer visible if yes
2021 then change this into an assignment */
2023 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2024 !bitVectBitValue (ebb->ptrsSet, pdop->key))
2027 IC_LEFT (ic) = NULL;
2028 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2029 SET_ISADDR (IC_RESULT (ic), 0);
2035 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2042 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2046 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2048 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2053 /* if left or right changed then do algebraic */
2054 if (!computeOnly && change)
2056 algebraicOpts (ic, ebb);
2057 while (constFold (ic, cseSet));
2060 /* if after all this it becomes an assignment to self
2061 then delete it and continue */
2062 if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
2064 remiCodeFromeBBlock (ebb, ic);
2068 /* now we will check to see if the entire */
2069 /* operation has been performed before */
2070 /* and is available */
2071 /* don't do assignments they will be killed */
2072 /* by dead code elimination if required do */
2073 /* it only if result is a temporary */
2075 if (!(POINTER_GET (ic) &&
2076 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2077 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2078 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2080 IS_ITEMP (IC_RESULT (ic)) &&
2083 applyToSet (cseSet, findPrevIc, ic, &pdic);
2084 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2085 operandType (IC_RESULT (ic))) != 1)
2087 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2091 /* Alternate code */
2092 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2093 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2094 /* Mmm, found an equivalent pointer get at a lower level.
2095 This could be a loop however with the same pointer set
2098 /* if previous definition found change this to an assignment */
2101 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2102 SET_ISADDR(IC_RESULT(ic),0);
2103 SET_ISADDR(IC_RIGHT (ic),0);
2107 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2109 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2110 csed = newCseDef (IC_RESULT (ic), ic);
2111 updateCseDefAncestors (csed, cseSet);
2112 addSetHead (&cseSet, csed);
2116 /* if assignment to a parameter which is not
2117 mine and type is a pointer then delete
2118 pointerGets to take care of aliasing */
2119 if (ASSIGNMENT (ic) &&
2120 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2121 IS_PTR (operandType (IC_RESULT (ic))))
2123 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2124 for (i = 0; i < count; ebbs[i++]->visited = 0);
2125 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2126 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2129 /* if this is a pointerget then see if we can replace
2130 this with a previously assigned pointer value */
2131 if (POINTER_GET (ic) &&
2132 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2133 isOperandVolatile (IC_LEFT (ic), TRUE)))
2136 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2137 /* if we find it then locally replace all
2138 references to the result with what we assigned */
2141 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2145 /* delete from the cseSet anything that has */
2146 /* operands matching the result of this */
2147 /* except in case of pointer access */
2148 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2150 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2151 /* delete any previous definitions */
2152 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2156 /* add the left & right to the defUse set */
2157 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2159 OP_USES(IC_LEFT (ic))=
2160 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2161 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2165 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2167 OP_USES(IC_RIGHT (ic))=
2168 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2169 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2173 /* for the result it is special case, put the result */
2174 /* in the defuseSet if it a pointer or array access */
2175 if (POINTER_SET (defic))
2177 OP_USES(IC_RESULT (ic))=
2178 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2179 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2180 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2181 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2182 /* delete from inexpressions of all successors which
2183 have dfNum > than this block */
2184 for (i = 0; i < count; ebbs[i++]->visited = 0);
2185 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2187 /* delete from cseSet all other pointer sets
2189 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2190 /* add to the local pointerset set */
2191 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2194 /* add the result to defintion set */ if (IC_RESULT (ic))
2196 OP_DEFS(IC_RESULT (ic))=
2197 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2198 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2199 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2200 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2204 /* if this is an addressof instruction then */
2205 /* put the symbol in the address of list & */
2206 /* delete it from the cseSet */
2207 if (defic->op == ADDRESS_OF)
2209 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2210 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2214 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2215 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2216 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2217 addSetHead (&ebb->killedExprs, expr);
2219 setToNull ((void *) &ebb->outExprs);
2220 ebb->outExprs = cseSet;
2221 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2222 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2226 /*-----------------------------------------------------------------*/
2227 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2228 /*-----------------------------------------------------------------*/
2230 cseAllBlocks (ebbIndex * ebbi, int computeOnly)
2232 eBBlock ** ebbs = ebbi->dfOrder;
2233 int count = ebbi->count;
2237 /* if optimization turned off */
2239 for (i = 0; i < count; i++)
2240 change += cseBBlock (ebbs[i], computeOnly, ebbi);