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 IS_ASSOCIATIVE(ic) &&
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)
833 typematch = compareType (operandType (IC_RESULT (ic)),
834 operandType (IC_RIGHT (ic)));
838 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
846 /* for completely different types, preserve the source type */
847 IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
848 setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
851 SET_ISADDR (IC_RESULT (ic), 0);
852 SET_ISADDR (IC_RIGHT (ic), 0);
855 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
856 operandLitValue (IC_RIGHT (ic)) == 0.0)
859 typematch = compareType (operandType (IC_RESULT (ic)),
860 operandType (IC_LEFT (ic)));
864 IC_RIGHT (ic) = IC_LEFT (ic);
865 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
870 IC_RIGHT (ic) = IC_LEFT (ic);
874 /* for completely different types, preserve the source type */
875 IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
876 setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
879 SET_ISADDR (IC_RIGHT (ic), 0);
880 SET_ISADDR (IC_RESULT (ic), 0);
885 /* if subtracting the the same thing then zero */
886 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
889 IC_RIGHT (ic) = operandFromLit (0);
891 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
892 IC_RESULT (ic)->isaddr = 0;
896 /* if subtraction then check if one of the operand */
897 /* is zero then depending on which operand change */
898 /* to assignment or unary minus */
899 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
900 operandLitValue (IC_RIGHT (ic)) == 0.0)
902 /* right size zero change to assignment */
904 IC_RIGHT (ic) = IC_LEFT (ic);
906 SET_ISADDR (IC_RIGHT (ic), 0);
907 SET_ISADDR (IC_RESULT (ic), 0);
910 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
911 operandLitValue (IC_LEFT (ic)) == 0.0)
913 /* left zero turn into an unary minus */
915 IC_LEFT (ic) = IC_RIGHT (ic);
916 IC_RIGHT (ic) = NULL;
920 /* if multiplication then check if either of */
921 /* them is zero then the result is zero */
922 /* if either of them is one then result is */
925 if (IS_OP_LITERAL (IC_LEFT (ic)))
928 if (operandLitValue (IC_LEFT (ic)) == 0.0)
931 IC_RIGHT (ic) = IC_LEFT (ic);
933 SET_RESULT_RIGHT (ic);
936 if (operandLitValue (IC_LEFT (ic)) == 1.0)
938 /* '*' can have two unsigned chars as operands */
939 /* and an unsigned int as result. */
940 if (compareType (operandType (IC_RESULT (ic)),
941 operandType (IC_RIGHT (ic))) == 1)
945 SET_RESULT_RIGHT (ic);
950 IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
951 IC_LEFT (ic)->type = TYPE;
952 IC_LEFT (ic)->isLiteral = 0;
953 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
959 if (IS_OP_LITERAL (IC_RIGHT (ic)))
962 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
966 SET_RESULT_RIGHT (ic);
970 if (operandLitValue (IC_RIGHT (ic)) == 1.0)
972 /* '*' can have two unsigned chars as operands */
973 /* and an unsigned int as result. */
974 if (compareType (operandType (IC_RESULT (ic)),
975 operandType (IC_LEFT (ic))) == 1)
978 IC_RIGHT (ic) = IC_LEFT (ic);
980 SET_RESULT_RIGHT (ic);
988 IC_RIGHT (ic) = IC_LEFT (ic);
989 IC_LEFT (ic) = operandFromOperand (op);
990 IC_LEFT (ic)->type = TYPE;
991 IC_LEFT (ic)->isLiteral = 0;
992 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
999 /* if division by self then 1 */
1000 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
1003 IC_RIGHT (ic) = operandFromLit (1);
1004 IC_LEFT (ic) = NULL;
1005 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
1006 IC_RESULT (ic)->isaddr = 0;
1009 /* if this is a division then check if right */
1010 /* is one then change it to an assignment */
1011 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1012 operandLitValue (IC_RIGHT (ic)) == 1.0)
1016 IC_RIGHT (ic) = IC_LEFT (ic);
1017 IC_LEFT (ic) = NULL;
1018 SET_RESULT_RIGHT (ic);
1022 /* if both are the same for an comparison operators */
1026 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1029 IC_RIGHT (ic) = operandFromLit (1);
1030 IC_LEFT (ic) = NULL;
1031 SET_RESULT_RIGHT (ic);
1037 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1040 IC_RIGHT (ic) = operandFromLit (0);
1041 IC_LEFT (ic) = NULL;
1042 SET_RESULT_RIGHT (ic);
1047 sym_link *otype = operandType(IC_RIGHT(ic));
1048 sym_link *ctype = operandType(IC_LEFT(ic));
1049 /* if this is a cast of a literal value */
1050 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1051 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
1054 operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
1055 operandLitValue (IC_RIGHT (ic))));
1056 IC_LEFT (ic) = NULL;
1057 SET_ISADDR (IC_RESULT (ic), 0);
1059 /* if casting to the same */
1060 if (compareType (operandType (IC_RESULT (ic)),
1061 operandType (IC_RIGHT (ic))) == 1) {
1063 IC_LEFT (ic) = NULL;
1064 SET_ISADDR (IC_RESULT (ic), 0);
1069 if (IS_OP_LITERAL (IC_LEFT (ic)))
1073 (operandLitValue (IC_LEFT (ic)) == 0 ?
1074 operandFromLit (1) : operandFromLit (0));
1075 IC_LEFT (ic) = NULL;
1076 SET_ISADDR (IC_RESULT (ic), 0);
1080 /* if both operands are equal */
1081 /* if yes turn it into assignment */
1082 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1084 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1086 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1087 IC_RESULT (newic) = IC_LEFT (ic);
1088 newic->lineno = ic->lineno;
1089 addiCodeToeBBlock (ebp, newic, ic->next);
1092 IC_LEFT (ic) = NULL;
1093 SET_RESULT_RIGHT (ic);
1096 /* swap literal to right ic */
1097 if (IS_OP_LITERAL (IC_LEFT (ic)))
1102 IC_LEFT (ic) = IC_RIGHT (ic);
1105 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1107 /* if BITWISEAND then check if one of them is a zero */
1108 /* if yes turn it into 0 assignment */
1109 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1111 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1113 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1114 IC_RESULT (newic) = IC_LEFT (ic);
1115 newic->lineno = ic->lineno;
1116 addiCodeToeBBlock (ebp, newic, ic->next);
1119 IC_LEFT (ic) = NULL;
1120 SET_RESULT_RIGHT (ic);
1123 /* if BITWISEAND then check if one of them is 0xff... */
1124 /* if yes turn it into assignment */
1128 switch (getSize (operandType (IC_RIGHT (ic))))
1142 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1145 IC_RIGHT (ic) = IC_LEFT (ic);
1146 IC_LEFT (ic) = NULL;
1147 SET_RESULT_RIGHT (ic);
1154 /* if both operands are equal */
1155 /* if yes turn it into assignment */
1156 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1158 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1160 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1161 IC_RESULT (newic) = IC_LEFT (ic);
1162 newic->lineno = ic->lineno;
1163 addiCodeToeBBlock (ebp, newic, ic->next);
1166 IC_LEFT (ic) = NULL;
1167 SET_RESULT_RIGHT (ic);
1170 /* swap literal to right ic */
1171 if (IS_OP_LITERAL (IC_LEFT (ic)))
1176 IC_LEFT (ic) = IC_RIGHT (ic);
1179 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1181 /* if BITWISEOR then check if one of them is a zero */
1182 /* if yes turn it into assignment */
1183 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1186 IC_RIGHT (ic) = IC_LEFT (ic);
1187 IC_LEFT (ic) = NULL;
1188 SET_RESULT_RIGHT (ic);
1191 /* if BITWISEOR then check if one of them is 0xff... */
1192 /* if yes turn it into 0xff... assignment */
1196 switch (getSize (operandType (IC_RIGHT (ic))))
1210 if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
1212 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1214 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1215 IC_RESULT (newic) = IC_LEFT (ic);
1216 newic->lineno = ic->lineno;
1217 addiCodeToeBBlock (ebp, newic, ic->next);
1220 IC_LEFT (ic) = NULL;
1221 SET_RESULT_RIGHT (ic);
1228 /* if both operands are equal */
1229 /* if yes turn it into 0 assignment */
1230 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1232 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1234 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1235 IC_RESULT (newic) = IC_LEFT (ic);
1236 newic->lineno = ic->lineno;
1237 addiCodeToeBBlock (ebp, newic, ic->next);
1239 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1240 IC_RESULT (newic) = IC_LEFT (ic);
1241 newic->lineno = ic->lineno;
1242 addiCodeToeBBlock (ebp, newic, ic->next);
1245 IC_RIGHT (ic) = operandFromLit (0);
1246 IC_LEFT (ic) = NULL;
1247 SET_RESULT_RIGHT (ic);
1250 /* swap literal to right ic */
1251 if (IS_OP_LITERAL (IC_LEFT (ic)))
1256 IC_LEFT (ic) = IC_RIGHT (ic);
1259 /* if XOR then check if one of them is a zero */
1260 /* if yes turn it into assignment */
1261 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1263 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1266 IC_RIGHT (ic) = IC_LEFT (ic);
1267 IC_LEFT (ic) = NULL;
1268 SET_RESULT_RIGHT (ic);
1277 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1278 /*-----------------------------------------------------------------*/
1279 /* updateSpillLocation - keeps track of register spill location */
1280 /*-----------------------------------------------------------------*/
1282 updateSpillLocation (iCode * ic, int induction)
1286 if (POINTER_SET (ic))
1293 /* for the form true_symbol := iTempNN */
1294 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1295 !SPIL_LOC (IC_RIGHT (ic))) {
1297 setype = getSpec (operandType (IC_RESULT (ic)));
1299 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1300 !IS_VOLATILE (setype) &&
1301 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1302 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1304 wassert(IS_SYMOP(IC_RESULT (ic)));
1305 wassert(IS_SYMOP(IC_RIGHT (ic)));
1306 SPIL_LOC (IC_RIGHT (ic)) =
1307 IC_RESULT (ic)->operand.symOperand;
1313 #if 0 /* this needs furthur investigation can save a lot of code */
1314 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1315 !SPIL_LOC(IC_RESULT(ic))) {
1316 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1317 SPIL_LOC (IC_RESULT (ic)) =
1318 IC_RIGHT (ic)->operand.symOperand;
1321 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1323 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1324 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1325 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1327 setype = getSpec (operandType (IC_RESULT (ic)));
1329 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1330 !IS_VOLATILE (setype) &&
1331 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1332 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) {
1334 SPIL_LOC (IC_RIGHT (ic)) =
1335 SPIL_LOC (IC_RESULT (ic));
1336 OP_SYMBOL (IC_RIGHT (ic))->prereqv =
1337 OP_SYMBOL (IC_RESULT (ic))->prereqv;
1340 /* special case for inductions */
1342 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1343 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1344 !SPIL_LOC(IC_RESULT(ic))) {
1345 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1346 OP_SYMBOL (IC_RESULT (ic))->prereqv =
1347 OP_SYMBOL (IC_RIGHT (ic))->prereqv;
1351 /*-----------------------------------------------------------------*/
1352 /* setUsesDef - sets the uses def bitvector for a given operand */
1353 /*-----------------------------------------------------------------*/
1355 setUsesDefs (operand * op, bitVect * bdefs,
1356 bitVect * idefs, bitVect ** oud)
1358 /* compute the definitions alive at this point */
1359 bitVect *adefs = bitVectUnion (bdefs, idefs);
1361 /* of these definitions find the ones that are */
1362 /* for this operand */
1363 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1365 /* these are the definitions that this operand can use */
1366 op->usesDefs = adefs;
1368 /* the out defs is an union */
1369 *oud = bitVectUnion (*oud, adefs);
1372 /*-----------------------------------------------------------------*/
1373 /* unsetDefsAndUses - clear this operation for the operands */
1374 /*-----------------------------------------------------------------*/
1376 unsetDefsAndUses (iCode * ic)
1378 if (ic->op == JUMPTABLE)
1381 /* take away this definition from the def chain of the */
1382 /* result & take away from use set of the operands */
1385 /* turn off def set */
1386 if (IS_SYMOP (IC_RESULT (ic)))
1388 if (!POINTER_SET (ic))
1389 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1391 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1393 /* turn off the useSet for the operands */
1394 if (IS_SYMOP (IC_LEFT (ic)))
1395 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1397 if (IS_SYMOP (IC_RIGHT (ic)))
1398 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1401 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1402 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1405 /*-----------------------------------------------------------------*/
1406 /* ifxOptimize - changes ifx conditions if it can */
1407 /*-----------------------------------------------------------------*/
1409 ifxOptimize (iCode * ic, set * cseSet,
1411 eBBlock * ebb, int *change,
1417 /* if the condition can be replaced */
1421 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1424 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1429 /* if the conditional is a literal then */
1430 if (IS_OP_LITERAL (IC_COND (ic)))
1433 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1436 /* change to a goto */
1438 IC_LABEL (ic) = IC_TRUE (ic);
1445 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1448 IC_LABEL (ic) = IC_FALSE (ic);
1454 /* then kill this if condition */
1455 remiCodeFromeBBlock (ebb, ic);
1459 /* now we need to recompute the control flow */
1460 /* since the control flow has changed */
1461 /* this is very expensive but it does not happen */
1462 /* too often, if it does happen then the user pays */
1464 computeControlFlow (ebbi);
1465 if (!options.lessPedantic) {
1466 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1471 /* if there is only one successor and that successor
1472 is the same one we are conditionally going to then
1473 we can remove this conditional statement */
1474 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1475 if (elementsInSet (ebb->succList) == 1 &&
1476 isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
1479 if (!options.lessPedantic) {
1480 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1482 if (IS_OP_VOLATILE (IC_COND (ic)))
1484 IC_RIGHT (ic) = IC_COND (ic);
1485 IC_LEFT (ic) = NULL;
1486 IC_RESULT (ic) = NULL;
1487 ic->op = DUMMY_READ_VOLATILE;
1491 remiCodeFromeBBlock (ebb, ic);
1492 computeControlFlow (ebbi);
1498 /* if it remains an IFX the update the use Set */
1501 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1502 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1504 else if (ic->op == DUMMY_READ_VOLATILE)
1506 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1507 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1512 /*-----------------------------------------------------------------*/
1513 /* diCodeForSym - finds the definiting instruction for a symbol */
1514 /*-----------------------------------------------------------------*/
1515 DEFSETFUNC (diCodeForSym)
1518 V_ARG (operand *, sym);
1519 V_ARG (iCode **, dic);
1521 /* if already found */
1525 /* if not if this is the defining iCode */
1526 if (sym->key == cdp->key)
1535 /*-----------------------------------------------------------------*/
1536 /* constFold - does some constant folding */
1537 /*-----------------------------------------------------------------*/
1539 constFold (iCode * ic, set * cseSet)
1543 /* this routine will change
1549 /* deal with only + & - */
1550 if (ic->op != '+' &&
1554 /* this check is a heuristic to prevent live ranges
1555 from becoming too long */
1556 if (IS_PTR (operandType (IC_RESULT (ic))))
1559 /* check if operation with a literal */
1560 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1563 /* check if we can find a definition for the
1565 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1568 /* check that this is also a +/- */
1569 if (dic->op != '+' && dic->op != '-')
1572 /* with a literal */
1573 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1576 /* find the definition of the left operand
1577 of dic.then check if this defined with a
1578 get_pointer return 0 if the pointer size is
1579 less than 2 (MCS51 specific) */
1580 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1583 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1586 /* it is if the operations are the same */
1587 /* the literal parts need to be added */
1588 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1589 if (ic->op == dic->op)
1590 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1591 operandLitValue (IC_RIGHT (dic)));
1593 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1594 operandLitValue (IC_RIGHT (dic)));
1596 if (IS_ITEMP (IC_RESULT (ic)))
1598 SPIL_LOC (IC_RESULT (ic)) = NULL;
1599 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1606 /*-----------------------------------------------------------------*/
1607 /* deleteGetPointers - called when a pointer is passed as parm */
1608 /* will delete from cseSet all get pointers computed from this */
1609 /* pointer. A simple ifOperandsHave is not good enough here */
1610 /*-----------------------------------------------------------------*/
1612 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1614 set *compItems = NULL;
1620 if (!*cseSet && !*pss)
1623 addSet (&compItems, op);
1625 /* Recursively find all items computed from this operand .
1626 This done fairly simply go thru the list and find
1627 those that are computed by arthimetic with these
1629 /* Also check for those computed from our computed
1630 list . This will take care of situations like
1631 iTemp1 = iTemp0 + 8;
1632 iTemp2 = iTemp1 + 8; */
1636 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1638 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1640 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1641 (insetwithFunc)isOperandEqual) ||
1642 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1643 (insetwithFunc)isOperandEqual))
1645 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1646 (insetwithFunc)isOperandEqual))
1648 addSet (&compItems, IC_RESULT (cdp->diCode));
1657 /* now for the computed items */
1658 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1660 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1661 deleteItemIf (cseSet, ifPointerGet, cop);
1662 deleteItemIf (cseSet, ifDefSymIsX, cop);
1663 deleteItemIf (pss, ifPointerSet, cop);
1667 /*-----------------------------------------------------------------*/
1668 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1669 /* dfnum > supplied */
1670 /*-----------------------------------------------------------------*/
1671 DEFSETFUNC (delGetPointerSucc)
1673 eBBlock *ebp = item;
1674 V_ARG (operand *, op);
1681 if (ebp->dfnum > dfnum)
1683 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1686 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1689 /*-----------------------------------------------------------------*/
1690 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1691 /*-----------------------------------------------------------------*/
1693 fixUpTypes (iCode * ic)
1695 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1697 /* if (TARGET_IS_DS390) */
1698 if (options.model == MODEL_FLAT24)
1704 /* for pointer_gets if the types of result & left r the
1705 same then change it type of result to next */
1707 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1709 setOperandType (IC_RESULT (ic), t2->next);
1713 /*-----------------------------------------------------------------*/
1714 /* isSignedOp - will return 1 if sign is important to operation */
1715 /*-----------------------------------------------------------------*/
1716 static int isSignedOp (iCode *ic)
1737 case GET_VALUE_AT_ADDRESS:
1765 dumpCseSet(set *cseSet)
1769 cseDef *item=cseSet->item;
1771 printOperand (item->sym, NULL);
1773 piCode (item->diCode, NULL);
1774 cseSet = cseSet->next;
1779 /*-----------------------------------------------------------------*/
1780 /* cseBBlock - common subexpression elimination for basic blocks */
1781 /* this is the hackiest kludgiest routine in the whole */
1782 /* system. also the most important, since almost all */
1783 /* data flow related information is computed by it */
1784 /*-----------------------------------------------------------------*/
1786 cseBBlock (eBBlock * ebb, int computeOnly,
1789 eBBlock ** ebbs = ebbi->bbOrder;
1790 int count = ebbi->count;
1795 set *ptrSetSet = NULL;
1798 /* if this block is not reachable */
1802 /* set of common subexpressions */
1803 cseSet = setFromSet (ebb->inExprs);
1805 /* these will be computed by this routine */
1806 setToNull ((void *) &ebb->outDefs);
1807 setToNull ((void *) &ebb->defSet);
1808 setToNull ((void *) &ebb->usesDefs);
1809 setToNull ((void *) &ebb->ptrsSet);
1810 setToNull ((void *) &ebb->addrOf);
1811 setToNull ((void *) &ebb->ldefs);
1813 ebb->outDefs = bitVectCopy (ebb->inDefs);
1814 bitVectDefault = iCodeKey;
1815 ebb->defSet = newBitVect (iCodeKey);
1816 ebb->usesDefs = newBitVect (iCodeKey);
1818 /* for all the instructions in this block do */
1819 for (ic = ebb->sch; ic; ic = ic->next)
1826 ic->eBBlockNum = ebb->bbnum;
1831 /* if this is an assignment from true symbol
1832 to a temp then do pointer post inc/dec optimzation */
1833 if (ic->op == '=' && !POINTER_SET (ic) &&
1834 IS_PTR (operandType (IC_RESULT (ic))))
1836 ptrPostIncDecOpt (ic);
1839 /* clear the def & use chains for the operands involved */
1840 /* in this operation . since it can change due to opts */
1841 unsetDefsAndUses (ic);
1843 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1845 /* add to defSet of the symbol */
1846 OP_DEFS(IC_RESULT (ic))=
1847 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1848 /* add to the definition set of this block */
1849 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1850 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1851 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1852 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1853 /* delete global variables from the cseSet
1854 since they can be modified by the function call */
1855 deleteItemIf (&cseSet, ifDefGlobal);
1857 /* and also iTemps derived from globals */
1858 deleteItemIf (&cseSet, ifFromGlobal);
1860 /* Delete iTemps derived from symbols whose address */
1861 /* has been taken */
1862 deleteItemIf (&cseSet, ifFromAddrTaken);
1864 /* delete all getpointer iCodes from cseSet, this should
1865 be done only for global arrays & pointers but at this
1866 point we don't know if globals, so to be safe do all */
1867 deleteItemIf (&cseSet, ifAnyGetPointer);
1869 /* can't cache pointer set/get operations across a call */
1870 deleteSet (&ptrSetSet);
1873 /* for pcall & ipush we need to add to the useSet */
1874 if ((ic->op == PCALL ||
1878 IS_SYMOP (IC_LEFT (ic)))
1881 /* check if they can be replaced */
1885 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1887 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1889 /* the lookup could have changed it */
1890 if (IS_SYMOP (IC_LEFT (ic)))
1892 OP_USES(IC_LEFT (ic))=
1893 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1894 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1895 ebb->outDefs, &ebb->usesDefs);
1899 /* if we a sending a pointer as a parameter
1900 then kill all cse since the pointed to item
1901 might be changed in the function being called */
1902 if ((ic->op == IPUSH || ic->op == SEND) &&
1903 IS_PTR (operandType (IC_LEFT (ic))))
1905 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1906 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1907 for (i = 0; i < count; ebbs[i++]->visited = 0);
1908 applyToSet (ebb->succList, delGetPointerSucc,
1909 IC_LEFT (ic), ebb->dfnum);
1914 /* if jumptable then mark the usage */
1915 if (ic->op == JUMPTABLE)
1917 if (IS_SYMOP (IC_JTCOND (ic)))
1919 OP_USES(IC_JTCOND (ic)) =
1920 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1921 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1922 ebb->outDefs, &ebb->usesDefs);
1932 /* do some algebraic optimizations if possible */
1933 algebraicOpts (ic, ebb);
1934 while (constFold (ic, cseSet));
1938 if (POINTER_GET (ic))
1940 if (!IS_PTR (operandType (IC_LEFT (ic))))
1942 setOperandType (IC_LEFT (ic),
1943 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1944 IC_LEFT (ic)->aggr2ptr = 0;
1947 else if (IC_LEFT (ic)->aggr2ptr)
1948 {/* band aid for kludge */
1949 setOperandType (IC_LEFT (ic),
1950 aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
1951 IC_LEFT (ic)->aggr2ptr = 0;
1956 if (POINTER_SET (ic))
1958 if (!IS_PTR (operandType (IC_RESULT (ic))))
1960 setOperandType (IC_RESULT (ic),
1961 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
1962 IC_RESULT (ic)->aggr2ptr = 0;
1964 else if (IC_RESULT (ic)->aggr2ptr)
1965 {/* band aid for kludge */
1966 setOperandType (IC_RESULT (ic),
1967 aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1968 IC_RESULT (ic)->aggr2ptr = 0;
1972 /* if this is a condition statement then */
1973 /* check if the condition can be replaced */
1976 ifxOptimize (ic, cseSet, computeOnly,
1982 /* if the assignment & result is a temp */
1983 /* see if we can replace it */
1984 if (!computeOnly && ic->op == '=')
1987 /* update the spill location for this */
1988 updateSpillLocation (ic,0);
1990 if (POINTER_SET (ic) &&
1991 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
1994 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
1995 if (pdop && !computeOnly && IS_ITEMP (pdop))
1997 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
1998 if (!IS_PTR (operandType (IC_RESULT (ic))))
2000 setOperandType (IC_RESULT (ic),
2001 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2007 checkSign = isSignedOp(ic);
2009 /* do the operand lookup i.e. for both the */
2010 /* right & left operand : check the cseSet */
2011 /* to see if they have been replaced if yes */
2012 /* then replace them with those from cseSet */
2014 /* and left is a symbol */
2015 if (IS_SYMOP (IC_LEFT (ic)) &&
2016 !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
2017 !computeOnly && ic->op != ADDRESS_OF)
2021 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2024 if (POINTER_GET (ic))
2026 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2028 /* some non dominating block does POINTER_SET with
2029 this variable .. unsafe to remove any POINTER_GETs */
2030 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
2031 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
2032 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2035 /* check if there is a pointer set
2036 for the same pointer visible if yes
2037 then change this into an assignment */
2039 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2040 !bitVectBitValue (ebb->ptrsSet, pdop->key))
2043 IC_LEFT (ic) = NULL;
2044 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2045 SET_ISADDR (IC_RESULT (ic), 0);
2051 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2058 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2062 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2064 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2069 /* if left or right changed then do algebraic */
2070 if (!computeOnly && change)
2072 algebraicOpts (ic, ebb);
2073 while (constFold (ic, cseSet));
2076 /* if after all this it becomes an assignment to self
2077 then delete it and continue */
2078 if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
2080 remiCodeFromeBBlock (ebb, ic);
2084 /* now we will check to see if the entire */
2085 /* operation has been performed before */
2086 /* and is available */
2087 /* don't do assignments they will be killed */
2088 /* by dead code elimination if required do */
2089 /* it only if result is a temporary */
2091 if (!(POINTER_GET (ic) &&
2092 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2093 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2094 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2096 IS_ITEMP (IC_RESULT (ic)) &&
2099 applyToSet (cseSet, findPrevIc, ic, &pdic);
2100 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2101 operandType (IC_RESULT (ic))) != 1)
2103 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2107 /* Alternate code */
2108 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2109 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2110 /* Mmm, found an equivalent pointer get at a lower level.
2111 This could be a loop however with the same pointer set
2114 /* if previous definition found change this to an assignment */
2117 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2118 SET_ISADDR(IC_RESULT(ic),0);
2119 SET_ISADDR(IC_RIGHT (ic),0);
2123 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2125 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2126 csed = newCseDef (IC_RESULT (ic), ic);
2127 updateCseDefAncestors (csed, cseSet);
2128 addSetHead (&cseSet, csed);
2132 /* if assignment to a parameter which is not
2133 mine and type is a pointer then delete
2134 pointerGets to take care of aliasing */
2135 if (ASSIGNMENT (ic) &&
2136 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2137 IS_PTR (operandType (IC_RESULT (ic))))
2139 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2140 for (i = 0; i < count; ebbs[i++]->visited = 0);
2141 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2142 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2145 /* if this is a pointerget then see if we can replace
2146 this with a previously assigned pointer value */
2147 if (POINTER_GET (ic) &&
2148 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2149 isOperandVolatile (IC_LEFT (ic), TRUE)))
2152 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2153 /* if we find it then locally replace all
2154 references to the result with what we assigned */
2157 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2161 /* delete from the cseSet anything that has */
2162 /* operands matching the result of this */
2163 /* except in case of pointer access */
2164 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2166 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2167 /* delete any previous definitions */
2168 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2172 /* add the left & right to the defUse set */
2173 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2175 OP_USES(IC_LEFT (ic))=
2176 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2177 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2181 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2183 OP_USES(IC_RIGHT (ic))=
2184 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2185 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2189 /* for the result it is special case, put the result */
2190 /* in the defuseSet if it a pointer or array access */
2191 if (POINTER_SET (defic))
2193 OP_USES(IC_RESULT (ic))=
2194 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2195 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2196 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2197 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2198 /* delete from inexpressions of all successors which
2199 have dfNum > than this block */
2200 for (i = 0; i < count; ebbs[i++]->visited = 0);
2201 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2203 /* delete from cseSet all other pointer sets
2205 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2206 /* add to the local pointerset set */
2207 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2210 /* add the result to defintion set */ if (IC_RESULT (ic))
2212 OP_DEFS(IC_RESULT (ic))=
2213 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2214 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2215 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2216 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2220 /* if this is an addressof instruction then */
2221 /* put the symbol in the address of list & */
2222 /* delete it from the cseSet */
2223 if (defic->op == ADDRESS_OF)
2225 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2226 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2230 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2231 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2232 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2233 addSetHead (&ebb->killedExprs, expr);
2235 setToNull ((void *) &ebb->outExprs);
2236 ebb->outExprs = cseSet;
2237 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2238 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2242 /*-----------------------------------------------------------------*/
2243 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2244 /*-----------------------------------------------------------------*/
2246 cseAllBlocks (ebbIndex * ebbi, int computeOnly)
2248 eBBlock ** ebbs = ebbi->dfOrder;
2249 int count = ebbi->count;
2253 /* if optimization turned off */
2255 for (i = 0; i < count; i++)
2256 change += cseBBlock (ebbs[i], computeOnly, ebbi);