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 -------------------------------------------------------------------------*/
27 #include "dbuf_string.h"
30 /*-----------------------------------------------------------------*/
31 /* newCseDef - new cseDef */
32 /*-----------------------------------------------------------------*/
34 newCseDef (operand * sym, iCode * ic)
39 cdp = Safe_alloc (sizeof (cseDef));
44 cdp->ancestors = newBitVect(iCodeKey);
46 cdp->fromAddrTaken = 0;
48 if (ic->op!=IF && ic->op!=JUMPTABLE)
50 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
52 bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
53 cdp->fromGlobal |= isOperandGlobal (IC_LEFT (ic));
54 cdp->fromAddrTaken |= OP_SYMBOL (IC_LEFT (ic))->addrtaken;
56 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
58 bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
59 cdp->fromGlobal |= isOperandGlobal (IC_RIGHT (ic));
60 cdp->fromAddrTaken |= OP_SYMBOL (IC_RIGHT (ic))->addrtaken;
68 updateCseDefAncestors(cseDef *cdp, set * cseSet)
72 iCode *ic = cdp->diCode;
74 if (ic->op!=IF && ic->op!=JUMPTABLE)
76 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
78 bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
79 for (sl = cseSet; sl; sl = sl->next)
82 if (loop->sym->key == IC_LEFT (ic)->key)
84 cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
85 cdp->fromGlobal |= loop->fromGlobal;
86 cdp->fromAddrTaken |= loop->fromAddrTaken;
91 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
93 bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
94 for (sl = cseSet; sl; sl = sl->next)
97 if (loop->sym->key == IC_RIGHT (ic)->key)
99 cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
100 cdp->fromGlobal |= loop->fromGlobal;
101 cdp->fromAddrTaken |= loop->fromAddrTaken;
110 /*-----------------------------------------------------------------*/
111 /* int isCseDefEqual - two definitions are equal */
112 /*-----------------------------------------------------------------*/
114 isCseDefEqual (void *vsrc, void *vdest)
117 cseDef *dest = vdest;
122 return (src->key == dest->key &&
123 src->diCode == dest->diCode);
127 /*-----------------------------------------------------------------*/
128 /* pcseDef - in the cseDef */
129 /*-----------------------------------------------------------------*/
131 pcseDef (void *item, va_list ap)
140 fprintf (stdout, "**null op**");
141 printOperand (cdp->sym, stdout);
142 icTab = getTableEntry (cdp->diCode->op);
143 dbuf_init (&dbuf, 1024);
144 icTab->iCodePrint (&dbuf, cdp->diCode, icTab->printName);
145 dbuf_write_and_destroy (&dbuf, stdout);
149 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
151 printf ("ReplaceOpWithCheaperOp\n\t");
152 printOperand (*op, stdout);
154 printOperand (cop, stdout);
156 // if op is a register equivalent
157 if (IS_ITEMP(cop) && IS_SYMOP((*op)) && OP_SYMBOL((*op))->isreqv) {
158 operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
159 if (isOperandEqual(*rop, *op)) {
162 OP_SYMBOL((*op))->isreqv=0;
163 OP_SYMBOL(cop)->isreqv=1;
173 /*-----------------------------------------------------------------*/
174 /* replaceAllSymBySym - replaces all operands by operand in an */
175 /* instruction chain */
176 /*-----------------------------------------------------------------*/
178 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
183 printf ("replaceAllSymBySym\n\t");
184 printOperand (from, stdout);
186 printOperand (to, stdout);
189 for (lic = ic; lic; lic = lic->next)
193 /* do the special cases first */
197 IC_COND (lic)->key == from->key)
200 bitVectUnSetBit (OP_USES (from), lic->key);
201 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
202 isaddr = IC_COND (lic)->isaddr;
203 IC_COND (lic) = operandFromOperand (to);
204 IC_COND (lic)->isaddr = isaddr;
210 if (lic->op == JUMPTABLE)
213 IC_JTCOND (lic)->key == from->key)
216 bitVectUnSetBit (OP_USES (from), lic->key);
217 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
218 isaddr = IC_COND (lic)->isaddr;
219 IC_JTCOND (lic) = operandFromOperand (to);
220 IC_JTCOND (lic)->isaddr = isaddr;
227 IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
229 /* maintain du chains */
230 if (POINTER_SET (lic))
232 bitVectUnSetBit (OP_USES (from), lic->key);
233 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
235 /* also check if the "from" was in the non-dominating
236 pointer sets and replace it with "to" in the bitVector */
237 if (bitVectBitValue (*ndpset, from->key))
239 bitVectUnSetBit (*ndpset, from->key);
240 bitVectSetBit (*ndpset, to->key);
246 bitVectUnSetBit (OP_DEFS (from), lic->key);
247 OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
249 isaddr = IC_RESULT (lic)->isaddr;
250 IC_RESULT (lic) = operandFromOperand (to);
251 IC_RESULT (lic)->isaddr = isaddr;
255 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
257 bitVectUnSetBit (OP_USES (from), lic->key);
258 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
259 isaddr = IC_RIGHT (lic)->isaddr;
260 IC_RIGHT (lic) = operandFromOperand (to);
261 IC_RIGHT (lic)->isaddr = isaddr;
265 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
267 bitVectUnSetBit (OP_USES (from), lic->key);
268 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
269 isaddr = IC_LEFT (lic)->isaddr;
270 IC_LEFT (lic) = operandFromOperand (to);
271 IC_LEFT (lic)->isaddr = isaddr;
276 /*-----------------------------------------------------------------*/
277 /* iCodeKeyIs - if the icode keys match then return 1 */
278 /*-----------------------------------------------------------------*/
279 DEFSETFUNC (iCodeKeyIs)
284 if (cdp->diCode->key == key)
290 /*-----------------------------------------------------------------*/
291 /* removeFromInExprs - removes an icode from inexpressions */
292 /*-----------------------------------------------------------------*/
293 DEFSETFUNC (removeFromInExprs)
297 V_ARG (operand *, from);
298 V_ARG (operand *, to);
299 V_ARG (eBBlock *, cbp);
305 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
306 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
307 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
309 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
313 /*-----------------------------------------------------------------*/
314 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
315 /*-----------------------------------------------------------------*/
317 isGlobalInNearSpace (operand * op)
319 sym_link *type = getSpec (operandType (op));
320 /* this is 8051 specific: optimization
321 suggested by Jean-Louis VERN, with 8051s we have no
322 advantage of putting variables in near space into
324 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
325 IN_DIRSPACE (SPEC_OCLS (type)))
331 /*-----------------------------------------------------------------*/
332 /* findCheaperOp - cseBBlock support routine, will check to see if */
333 /* we have a operand previously defined */
334 /*-----------------------------------------------------------------*/
335 DEFSETFUNC (findCheaperOp)
338 V_ARG (operand *, cop);
339 V_ARG (operand **, opp);
340 V_ARG (int, checkSign);
342 /* if we have already found it */
346 /* not found it yet check if this is the one */
347 /* and this is not the defining one */
348 if (cop->key == cdp->key)
351 /* do a special check this will help in */
352 /* constant propagation & dead code elim */
353 /* for assignments only */
354 if (cdp->diCode->op == '=') {
355 /* if the result is volatile then return result */
356 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
357 *opp = IC_RESULT (cdp->diCode);
359 /* if this is a straight assignment and
360 left is a temp then prefer the temporary to the
362 if (!POINTER_SET (cdp->diCode) &&
363 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
364 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
365 *opp = IC_RESULT (cdp->diCode);
367 /* if straight assignment and both
368 are temps then prefer the one that
369 will not need extra space to spil, also
370 take into consideration if right side
371 is an induction variable
373 if (!POINTER_SET (cdp->diCode) &&
374 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
375 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
376 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
377 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
378 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
379 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
380 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
381 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
382 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
383 *opp = IC_RESULT (cdp->diCode);
385 *opp = IC_RIGHT (cdp->diCode);
389 *opp = IC_RESULT (cdp->diCode);
392 /* if this is an assign to a temp. then check
393 if the right side is this then return this */
394 if (IS_TRUE_SYMOP (cop) &&
395 cdp->diCode->op == '=' &&
396 !POINTER_SET (cdp->diCode) &&
397 cop->key == IC_RIGHT (cdp->diCode)->key &&
398 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
399 IS_ITEMP (IC_RESULT (cdp->diCode)))
400 *opp = IC_RESULT (cdp->diCode);
403 (isOperandLiteral(*opp) || !checkSign ||
405 IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
406 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
407 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
410 if ((isGlobalInNearSpace (cop) &&
411 !isOperandLiteral (*opp)) ||
412 isOperandVolatile (*opp, FALSE)
419 if (cop->key == (*opp)->key)
425 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
427 *opp = operandFromOperand (*opp);
428 (*opp)->isaddr = cop->isaddr;
431 /* copy signedness to literal operands */
432 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp))
433 && isOperandLiteral(*opp)
434 && SPEC_NOUN(operandType(*opp)) == SPEC_NOUN(operandType(cop))
435 && SPEC_USIGN(operandType(*opp)) != SPEC_USIGN(operandType(cop)))
437 SPEC_USIGN(operandType(*opp)) = SPEC_USIGN(operandType(cop));
440 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
441 SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
443 // special case: we can make an unsigned char literal
444 // into an int literal with no cost.
445 if (isOperandLiteral(*opp)
446 && SPEC_NOUN(operandType(*opp)) == V_CHAR
447 && SPEC_NOUN(operandType(cop)) == V_INT)
449 *opp = operandFromOperand (*opp);
450 SPEC_NOUN(operandType(*opp)) = V_INT;
468 /*-----------------------------------------------------------------*/
469 /* findPointerSet - finds the right side of a pointer set op */
470 /*-----------------------------------------------------------------*/
471 DEFSETFUNC (findPointerSet)
474 V_ARG (operand *, op);
475 V_ARG (operand **, opp);
476 V_ARG (operand *, rop);
478 if (POINTER_SET (cdp->diCode) &&
479 IC_RESULT (cdp->diCode)->key == op->key &&
480 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
481 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
482 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
483 getSize (operandType (rop)))
485 if (IS_SPEC (operandType (IC_RIGHT (cdp->diCode))) &&
486 SPEC_USIGN (operandType (IC_RIGHT (cdp->diCode))) !=
487 SPEC_USIGN (operandType (rop)))
490 Reminder for Bernhard: check of signedness
491 could be unnecessary together with 'checkSign', if
492 signedness of operation is stored in ic */
495 *opp = IC_RIGHT (cdp->diCode);
502 /*-----------------------------------------------------------------*/
503 /* findPrevIc - cseBBlock support function will return the iCode */
504 /* which matches the current one */
505 /*-----------------------------------------------------------------*/
506 DEFSETFUNC (findPrevIc)
510 V_ARG (iCode **, icp);
512 /* if already found */
516 /* if the iCodes are the same */
517 if (isiCodeEqual (ic, cdp->diCode) &&
518 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
524 /* if iCodes are not the same */
525 /* see the operands maybe interchanged */
526 if (ic->op == cdp->diCode->op &&
527 IS_ASSOCIATIVE(ic) &&
528 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
529 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
538 /*-------------------------------------------------------------------*/
539 /* ifAssignedFromGlobal - if definition is an assignment from global */
540 /*-------------------------------------------------------------------*/
541 DEFSETFUNC (ifAssignedFromGlobal)
544 iCode *dic=cdp->diCode;
546 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
552 /*-------------------------------------------------------------------*/
553 /* ifFromGlobal - if definition is derived from global */
554 /*-------------------------------------------------------------------*/
555 DEFSETFUNC (ifFromGlobal)
559 return cdp->fromGlobal;
562 /*-----------------------------------------------------------------*/
563 /* ifDefGlobal - if definition is global */
564 /*-----------------------------------------------------------------*/
565 DEFSETFUNC (ifDefGlobal)
569 return (isOperandGlobal (cdp->sym));
572 /*-------------------------------------------------------------------*/
573 /* ifFromAddrTaken - if definition is derived from a symbol whose */
574 /* address was taken */
575 /*-------------------------------------------------------------------*/
576 DEFSETFUNC (ifFromAddrTaken)
580 return cdp->fromAddrTaken;
584 /*-----------------------------------------------------------------*/
585 /* ifAnyGetPointer - if get pointer icode */
586 /*-----------------------------------------------------------------*/
587 DEFSETFUNC (ifAnyGetPointer)
591 if (cdp->diCode && POINTER_GET (cdp->diCode))
596 /*-----------------------------------------------------------------*/
597 /* ifOperandsHave - if any of the operand are the same as this */
598 /*-----------------------------------------------------------------*/
599 DEFSETFUNC (ifOperandsHave)
602 V_ARG (operand *, op);
604 if (bitVectBitValue(cdp->ancestors, op->key))
607 if (IC_LEFT (cdp->diCode) &&
608 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
609 IC_LEFT (cdp->diCode)->key == op->key)
612 if (IC_RIGHT (cdp->diCode) &&
613 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
614 IC_RIGHT (cdp->diCode)->key == op->key)
617 /* or if any of the operands are volatile */
618 if (IC_LEFT (cdp->diCode) &&
619 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
622 if (IC_RIGHT (cdp->diCode) &&
623 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
627 if (IC_RESULT (cdp->diCode) &&
628 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
634 /*-----------------------------------------------------------------*/
635 /* ifDefSymIs - if a definition is found in the set */
636 /*-----------------------------------------------------------------*/
638 ifDefSymIs (set * cseSet, operand * sym)
643 if (!sym || !IS_SYMOP (sym))
645 for (sl = cseSet; sl; sl = sl->next)
648 if (loop->sym->key == sym->key)
655 /*-----------------------------------------------------------------*/
656 /* ifDefSymIsX - will return 1 if the symbols match */
657 /*-----------------------------------------------------------------*/
658 DEFSETFUNC (ifDefSymIsX)
661 V_ARG (operand *, op);
665 match = cdp->sym->key == op->key;
667 match = (isOperandEqual (cdp->sym, op));
670 printf("%s ",OP_SYMBOL(cdp->sym)->name);
676 /*-----------------------------------------------------------------*/
677 /* ifDiCodeIs - returns true if diCode is same */
678 /*-----------------------------------------------------------------*/
680 ifDiCodeIs (set * cseSet, iCode * ic)
688 for (sl = cseSet; sl; sl = sl->next)
691 if (loop->diCode == ic)
698 /*-----------------------------------------------------------------*/
699 /* ifPointerGet - returns true if the icode is pointer get sym */
700 /*-----------------------------------------------------------------*/
701 DEFSETFUNC (ifPointerGet)
704 V_ARG (operand *, op);
705 iCode *dic = cdp->diCode;
706 operand *left = IC_LEFT (cdp->diCode);
708 if (POINTER_GET (dic) && left->key == op->key)
714 /*-----------------------------------------------------------------*/
715 /* ifPointerSet - returns true if the icode is pointer set sym */
716 /*-----------------------------------------------------------------*/
717 DEFSETFUNC (ifPointerSet)
720 V_ARG (operand *, op);
722 if (POINTER_SET (cdp->diCode) &&
723 IC_RESULT (cdp->diCode)->key == op->key)
729 /*-----------------------------------------------------------------*/
730 /* ifDiCodeIsX - will return 1 if the symbols match */
731 /*-----------------------------------------------------------------*/
732 DEFSETFUNC (ifDiCodeIsX)
737 return cdp->diCode == ic;
741 /*-----------------------------------------------------------------*/
742 /* findBackwardDef - scan backwards to find deinition of operand */
743 /*-----------------------------------------------------------------*/
744 iCode *findBackwardDef(operand *op,iCode *ic)
748 for (lic = ic; lic ; lic = lic->prev) {
749 if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
755 /*-----------------------------------------------------------------*/
756 /* algebraicOpts - does some algebraic optimizations */
757 /*-----------------------------------------------------------------*/
759 algebraicOpts (iCode * ic, eBBlock * ebp)
761 /* we don't deal with the following iCodes
772 /* if both operands present & ! IFX */
773 /* then if they are both literal we */
774 /* perform the operation right now */
775 if (IC_RESULT (ic) &&
778 IS_OP_LITERAL (IC_LEFT (ic)) &&
779 IS_OP_LITERAL (IC_RIGHT (ic)))
782 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
785 operandType (IC_RESULT (ic)));
788 SET_RESULT_RIGHT (ic);
792 /* if not ifx & only one operand present */
793 if (IC_RESULT (ic) &&
795 IS_OP_LITERAL (IC_LEFT (ic)) &&
799 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
802 operandType (IC_RESULT (ic)));
805 SET_RESULT_RIGHT (ic);
810 /* a special case : or in short a kludgy solution will think
811 about a better solution over a glass of wine someday */
812 if (ic->op == GET_VALUE_AT_ADDRESS)
815 if (IS_ITEMP (IC_RESULT (ic)) &&
816 IS_TRUE_SYMOP (IC_LEFT (ic)))
820 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
821 IC_RIGHT (ic)->isaddr = 0;
823 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
824 IC_RESULT (ic)->isaddr = 0;
825 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
829 if (IS_ITEMP (IC_LEFT (ic)) &&
830 IS_ITEMP (IC_RESULT (ic)) &&
831 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
832 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
833 !IC_LEFT (ic)->isaddr)
836 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
837 IC_RIGHT (ic)->isaddr = 0;
838 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
839 IC_RESULT (ic)->isaddr = 0;
847 /* depending on the operation */
851 /* if adding the same thing change to left shift by 1 */
852 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
853 !(IS_FLOAT (operandType (IC_RESULT (ic)))
854 || IS_FIXED(operandType (IC_RESULT (ic)))))
857 IC_RIGHT (ic) = operandFromLit (1);
860 /* if addition then check if one of them is a zero */
861 /* if yes turn it into assignment or cast */
862 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
863 operandLitValue (IC_LEFT (ic)) == 0.0)
866 typematch = compareType (operandType (IC_RESULT (ic)),
867 operandType (IC_RIGHT (ic)));
868 if ((typematch<0) || (IS_TRUE_SYMOP (IC_RIGHT (ic))))
871 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
879 /* for completely different types, preserve the source type */
880 IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
881 setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
884 SET_ISADDR (IC_RESULT (ic), 0);
885 SET_ISADDR (IC_RIGHT (ic), 0);
888 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
889 operandLitValue (IC_RIGHT (ic)) == 0.0)
892 typematch = compareType (operandType (IC_RESULT (ic)),
893 operandType (IC_LEFT (ic)));
894 if ((typematch<0) || (IS_TRUE_SYMOP (IC_LEFT (ic))))
897 IC_RIGHT (ic) = IC_LEFT (ic);
898 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
903 IC_RIGHT (ic) = IC_LEFT (ic);
907 /* for completely different types, preserve the source type */
908 IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
909 setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
912 SET_ISADDR (IC_RIGHT (ic), 0);
913 SET_ISADDR (IC_RESULT (ic), 0);
918 /* if subtracting the same thing then zero */
919 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
922 IC_RIGHT (ic) = operandFromLit (0);
924 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
925 IC_RESULT (ic)->isaddr = 0;
929 /* if subtraction then check if one of the operand */
930 /* is zero then depending on which operand change */
931 /* to assignment or unary minus */
932 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
933 operandLitValue (IC_RIGHT (ic)) == 0.0)
935 /* right size zero change to assignment */
937 IC_RIGHT (ic) = IC_LEFT (ic);
939 SET_ISADDR (IC_RIGHT (ic), 0);
940 SET_ISADDR (IC_RESULT (ic), 0);
943 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
944 operandLitValue (IC_LEFT (ic)) == 0.0)
946 /* left zero turn into an unary minus */
948 IC_LEFT (ic) = IC_RIGHT (ic);
949 IC_RIGHT (ic) = NULL;
953 /* if multiplication then check if either of */
954 /* them is zero then the result is zero */
955 /* if either of them is one then result is */
958 if (IS_OP_LITERAL (IC_LEFT (ic)))
960 double leftValue = operandLitValue (IC_LEFT (ic));
962 if (leftValue == 0.0)
965 IC_RIGHT (ic) = IC_LEFT (ic);
967 SET_RESULT_RIGHT (ic);
970 if (leftValue == 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_RIGHT (ic))) == 1)
979 SET_RESULT_RIGHT (ic);
984 IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
985 IC_LEFT (ic)->type = TYPE;
986 IC_LEFT (ic)->isLiteral = 0;
987 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
991 if (leftValue == -1.0)
993 /* convert -1 * x to -x */
995 IC_LEFT (ic) = IC_RIGHT (ic);
996 IC_RIGHT (ic) = NULL;
1001 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1003 double rightValue = operandLitValue (IC_RIGHT (ic));
1005 if (rightValue == 0.0)
1008 IC_LEFT (ic) = NULL;
1009 SET_RESULT_RIGHT (ic);
1013 if (rightValue == 1.0)
1015 /* '*' can have two unsigned chars as operands */
1016 /* and an unsigned int as result. */
1017 if (compareType (operandType (IC_RESULT (ic)),
1018 operandType (IC_LEFT (ic))) == 1)
1021 IC_RIGHT (ic) = IC_LEFT (ic);
1022 IC_LEFT (ic) = NULL;
1023 SET_RESULT_RIGHT (ic);
1031 IC_RIGHT (ic) = IC_LEFT (ic);
1032 IC_LEFT (ic) = operandFromOperand (op);
1033 IC_LEFT (ic)->type = TYPE;
1034 IC_LEFT (ic)->isLiteral = 0;
1035 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
1039 if (rightValue == -1.0)
1041 /* convert x * -1 to -x */
1042 ic->op = UNARYMINUS;
1043 IC_RIGHT (ic) = NULL;
1049 /* if division by self then 1 */
1050 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
1053 IC_RIGHT (ic) = operandFromLit (1);
1054 IC_LEFT (ic) = NULL;
1055 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
1056 IC_RESULT (ic)->isaddr = 0;
1059 /* if this is a division then check if right */
1060 /* is one then change it to an assignment */
1061 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1062 operandLitValue (IC_RIGHT (ic)) == 1.0)
1066 IC_RIGHT (ic) = IC_LEFT (ic);
1067 IC_LEFT (ic) = NULL;
1068 SET_RESULT_RIGHT (ic);
1072 /* if both are the same for an comparison operators */
1076 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1079 IC_RIGHT (ic) = operandFromLit (1);
1080 IC_LEFT (ic) = NULL;
1081 SET_RESULT_RIGHT (ic);
1087 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1090 IC_RIGHT (ic) = operandFromLit (0);
1091 IC_LEFT (ic) = NULL;
1092 SET_RESULT_RIGHT (ic);
1097 sym_link *otype = operandType(IC_RIGHT(ic));
1098 sym_link *ctype = operandType(IC_LEFT(ic));
1099 /* if this is a cast of a literal value */
1100 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1101 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype))))
1104 IC_RIGHT (ic) = operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
1105 operandLitValue (IC_RIGHT (ic))));
1106 IC_LEFT (ic) = NULL;
1107 SET_ISADDR (IC_RESULT (ic), 0);
1109 /* if casting to the same */
1110 if (compareType (operandType (IC_RESULT (ic)), operandType (IC_RIGHT (ic))) == 1)
1113 IC_LEFT (ic) = NULL;
1114 SET_ISADDR (IC_RESULT (ic), 0);
1119 if (IS_OP_LITERAL (IC_LEFT (ic)))
1123 (operandLitValue (IC_LEFT (ic)) == 0 ?
1124 operandFromLit (1) : operandFromLit (0));
1125 IC_LEFT (ic) = NULL;
1126 SET_ISADDR (IC_RESULT (ic), 0);
1130 /* if both operands are equal */
1131 /* if yes turn it into assignment */
1132 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1134 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1136 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1137 IC_RESULT (newic) = IC_LEFT (ic);
1138 newic->filename = ic->filename;
1139 newic->lineno = ic->lineno;
1140 addiCodeToeBBlock (ebp, newic, ic->next);
1143 IC_LEFT (ic) = NULL;
1144 SET_RESULT_RIGHT (ic);
1147 /* swap literal to right ic */
1148 if (IS_OP_LITERAL (IC_LEFT (ic)))
1153 IC_LEFT (ic) = IC_RIGHT (ic);
1156 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1158 /* if BITWISEAND then check if one of them is a zero */
1159 /* if yes turn it into 0 assignment */
1160 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1162 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1164 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1165 IC_RESULT (newic) = IC_LEFT (ic);
1166 newic->filename = ic->filename;
1167 newic->lineno = ic->lineno;
1168 addiCodeToeBBlock (ebp, newic, ic->next);
1171 IC_LEFT (ic) = NULL;
1172 SET_RESULT_RIGHT (ic);
1175 /* if BITWISEAND then check if one of them is 0xff... */
1176 /* if yes turn it into assignment */
1180 switch (getSize (operandType (IC_RIGHT (ic))))
1194 if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
1197 IC_RIGHT (ic) = IC_LEFT (ic);
1198 IC_LEFT (ic) = NULL;
1199 SET_RESULT_RIGHT (ic);
1206 /* if both operands are equal */
1207 /* if yes turn it into assignment */
1208 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1210 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1212 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1213 IC_RESULT (newic) = IC_LEFT (ic);
1214 newic->filename = ic->filename;
1215 newic->lineno = ic->lineno;
1216 addiCodeToeBBlock (ebp, newic, ic->next);
1219 IC_LEFT (ic) = NULL;
1220 SET_RESULT_RIGHT (ic);
1223 /* swap literal to right ic */
1224 if (IS_OP_LITERAL (IC_LEFT (ic)))
1229 IC_LEFT (ic) = IC_RIGHT (ic);
1232 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1234 /* if BITWISEOR then check if one of them is a zero */
1235 /* if yes turn it into assignment */
1236 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1239 IC_RIGHT (ic) = IC_LEFT (ic);
1240 IC_LEFT (ic) = NULL;
1241 SET_RESULT_RIGHT (ic);
1244 /* if BITWISEOR then check if one of them is 0xff... */
1245 /* if yes turn it into 0xff... assignment */
1249 switch (getSize (operandType (IC_RIGHT (ic))))
1263 if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
1265 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1267 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1268 IC_RESULT (newic) = IC_LEFT (ic);
1269 newic->filename = ic->filename;
1270 newic->lineno = ic->lineno;
1271 addiCodeToeBBlock (ebp, newic, ic->next);
1274 IC_LEFT (ic) = NULL;
1275 SET_RESULT_RIGHT (ic);
1282 /* if both operands are equal */
1283 /* if yes turn it into 0 assignment */
1284 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1286 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1288 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1289 IC_RESULT (newic) = IC_LEFT (ic);
1290 newic->filename = ic->filename;
1291 newic->lineno = ic->lineno;
1292 addiCodeToeBBlock (ebp, newic, ic->next);
1294 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1295 IC_RESULT (newic) = IC_LEFT (ic);
1296 newic->filename = ic->filename;
1297 newic->lineno = ic->lineno;
1298 addiCodeToeBBlock (ebp, newic, ic->next);
1301 IC_RIGHT (ic) = operandFromLit (0);
1302 IC_LEFT (ic) = NULL;
1303 SET_RESULT_RIGHT (ic);
1306 /* swap literal to right ic */
1307 if (IS_OP_LITERAL (IC_LEFT (ic)))
1312 IC_LEFT (ic) = IC_RIGHT (ic);
1315 /* if XOR then check if one of them is a zero */
1316 /* if yes turn it into assignment */
1317 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1319 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1322 IC_RIGHT (ic) = IC_LEFT (ic);
1323 IC_LEFT (ic) = NULL;
1324 SET_RESULT_RIGHT (ic);
1333 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1334 /*-----------------------------------------------------------------*/
1335 /* updateSpillLocation - keeps track of register spill location */
1336 /*-----------------------------------------------------------------*/
1338 updateSpillLocation (iCode * ic, int induction)
1342 if (POINTER_SET (ic))
1349 /* for the form true_symbol := iTempNN */
1350 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1351 !SPIL_LOC (IC_RIGHT (ic))) {
1353 setype = getSpec (operandType (IC_RESULT (ic)));
1355 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1356 !IS_VOLATILE (setype) &&
1357 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1358 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1360 wassert(IS_SYMOP(IC_RESULT (ic)));
1361 wassert(IS_SYMOP(IC_RIGHT (ic)));
1362 SPIL_LOC (IC_RIGHT (ic)) =
1363 IC_RESULT (ic)->operand.symOperand;
1369 #if 0 /* this needs furthur investigation can save a lot of code */
1370 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1371 !SPIL_LOC(IC_RESULT(ic))) {
1372 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1373 SPIL_LOC (IC_RESULT (ic)) =
1374 IC_RIGHT (ic)->operand.symOperand;
1377 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1379 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1380 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1381 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1383 setype = getSpec (operandType (IC_RESULT (ic)));
1385 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1386 !IS_VOLATILE (setype) &&
1387 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1388 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) {
1390 SPIL_LOC (IC_RIGHT (ic)) =
1391 SPIL_LOC (IC_RESULT (ic));
1392 OP_SYMBOL (IC_RIGHT (ic))->prereqv =
1393 OP_SYMBOL (IC_RESULT (ic))->prereqv;
1396 /* special case for inductions */
1398 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1399 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1400 !SPIL_LOC(IC_RESULT(ic))) {
1401 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1402 OP_SYMBOL (IC_RESULT (ic))->prereqv =
1403 OP_SYMBOL (IC_RIGHT (ic))->prereqv;
1407 /*-----------------------------------------------------------------*/
1408 /* setUsesDef - sets the uses def bitvector for a given operand */
1409 /*-----------------------------------------------------------------*/
1411 setUsesDefs (operand * op, bitVect * bdefs,
1412 bitVect * idefs, bitVect ** oud)
1414 /* compute the definitions alive at this point */
1415 bitVect *adefs = bitVectUnion (bdefs, idefs);
1417 /* of these definitions find the ones that are */
1418 /* for this operand */
1419 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1421 /* these are the definitions that this operand can use */
1422 op->usesDefs = adefs;
1424 /* the out defs is an union */
1425 *oud = bitVectUnion (*oud, adefs);
1428 /*-----------------------------------------------------------------*/
1429 /* unsetDefsAndUses - clear this operation for the operands */
1430 /*-----------------------------------------------------------------*/
1432 unsetDefsAndUses (iCode * ic)
1434 if (ic->op == JUMPTABLE)
1437 /* take away this definition from the def chain of the */
1438 /* result & take away from use set of the operands */
1441 /* turn off def set */
1442 if (IS_SYMOP (IC_RESULT (ic)))
1444 if (!POINTER_SET (ic))
1445 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1447 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1449 /* turn off the useSet for the operands */
1450 if (IS_SYMOP (IC_LEFT (ic)))
1451 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1453 if (IS_SYMOP (IC_RIGHT (ic)))
1454 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1457 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1458 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1461 /*-----------------------------------------------------------------*/
1462 /* ifxOptimize - changes ifx conditions if it can */
1463 /*-----------------------------------------------------------------*/
1465 ifxOptimize (iCode * ic, set * cseSet,
1467 eBBlock * ebb, int *change,
1473 /* if the condition can be replaced */
1477 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1480 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1485 /* if the conditional is a literal then */
1486 if (IS_OP_LITERAL (IC_COND (ic)))
1488 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1490 /* change to a goto */
1492 IC_LABEL (ic) = IC_TRUE (ic);
1497 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1500 IC_LABEL (ic) = IC_FALSE (ic);
1505 /* then kill this if condition */
1506 remiCodeFromeBBlock (ebb, ic);
1510 /* now we need to recompute the control flow */
1511 /* since the control flow has changed */
1512 /* this is very expensive but it does not happen */
1513 /* too often, if it does happen then the user pays */
1515 computeControlFlow (ebbi);
1516 if (!options.lessPedantic)
1518 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1523 /* if there is only one successor and that successor
1524 is the same one we are conditionally going to then
1525 we can remove this conditional statement */
1526 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1527 if (elementsInSet (ebb->succList) == 1 &&
1528 isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
1530 if (!options.lessPedantic)
1532 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1534 if (IS_OP_VOLATILE (IC_COND (ic)))
1536 IC_RIGHT (ic) = IC_COND (ic);
1537 IC_LEFT (ic) = NULL;
1538 IC_RESULT (ic) = NULL;
1539 ic->op = DUMMY_READ_VOLATILE;
1543 remiCodeFromeBBlock (ebb, ic);
1544 computeControlFlow (ebbi);
1549 /* if it remains an IFX then update the use Set */
1552 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1553 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1555 else if (ic->op == DUMMY_READ_VOLATILE)
1557 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1558 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1563 /*-----------------------------------------------------------------*/
1564 /* diCodeForSym - finds the definiting instruction for a symbol */
1565 /*-----------------------------------------------------------------*/
1566 DEFSETFUNC (diCodeForSym)
1569 V_ARG (operand *, sym);
1570 V_ARG (iCode **, dic);
1572 /* if already found */
1576 /* if not if this is the defining iCode */
1577 if (sym->key == cdp->key)
1586 /*-----------------------------------------------------------------*/
1587 /* constFold - does some constant folding */
1588 /*-----------------------------------------------------------------*/
1590 constFold (iCode * ic, set * cseSet)
1594 /* this routine will change
1600 /* deal with only + & - */
1601 if (ic->op != '+' &&
1605 /* this check is a heuristic to prevent live ranges
1606 from becoming too long */
1607 if (IS_PTR (operandType (IC_RESULT (ic))))
1610 /* check if operation with a literal */
1611 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1614 /* check if we can find a definition for the
1616 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1619 /* check that this is also a +/- */
1620 if (dic->op != '+' && dic->op != '-')
1623 /* with a literal */
1624 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1627 /* find the definition of the left operand
1628 of dic.then check if this defined with a
1629 get_pointer return 0 if the pointer size is
1630 less than 2 (MCS51 specific) */
1631 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1634 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1637 /* it is if the operations are the same */
1638 /* the literal parts need to be added */
1639 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1640 if (ic->op == dic->op)
1641 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1642 operandLitValue (IC_RIGHT (dic)));
1644 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1645 operandLitValue (IC_RIGHT (dic)));
1647 if (IS_ITEMP (IC_RESULT (ic)))
1649 SPIL_LOC (IC_RESULT (ic)) = NULL;
1650 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1657 /*-----------------------------------------------------------------*/
1658 /* deleteGetPointers - called when a pointer is passed as parm */
1659 /* will delete from cseSet all get pointers computed from this */
1660 /* pointer. A simple ifOperandsHave is not good enough here */
1661 /*-----------------------------------------------------------------*/
1663 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1665 set *compItems = NULL;
1671 if (!*cseSet && !*pss)
1674 addSet (&compItems, op);
1676 /* Recursively find all items computed from this operand .
1677 This done fairly simply go thru the list and find
1678 those that are computed by arthimetic with these
1680 /* Also check for those computed from our computed
1681 list . This will take care of situations like
1682 iTemp1 = iTemp0 + 8;
1683 iTemp2 = iTemp1 + 8; */
1687 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1689 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1691 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1692 (insetwithFunc)isOperandEqual) ||
1693 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1694 (insetwithFunc)isOperandEqual))
1696 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1697 (insetwithFunc)isOperandEqual))
1699 addSet (&compItems, IC_RESULT (cdp->diCode));
1708 /* now for the computed items */
1709 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1711 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1712 deleteItemIf (cseSet, ifPointerGet, cop);
1713 deleteItemIf (cseSet, ifDefSymIsX, cop);
1714 deleteItemIf (pss, ifPointerSet, cop);
1718 /*-----------------------------------------------------------------*/
1719 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1720 /* dfnum > supplied */
1721 /*-----------------------------------------------------------------*/
1722 DEFSETFUNC (delGetPointerSucc)
1724 eBBlock *ebp = item;
1725 V_ARG (operand *, op);
1732 if (ebp->dfnum > dfnum)
1734 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1737 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1740 /*-----------------------------------------------------------------*/
1741 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1742 /*-----------------------------------------------------------------*/
1744 fixUpTypes (iCode * ic)
1746 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1748 /* if (TARGET_IS_DS390) */
1749 if (options.model == MODEL_FLAT24)
1755 /* for pointer_gets if the types of result & left r the
1756 same then change it type of result to next */
1758 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1760 setOperandType (IC_RESULT (ic), t2->next);
1764 /*-----------------------------------------------------------------*/
1765 /* isSignedOp - will return 1 if sign is important to operation */
1766 /*-----------------------------------------------------------------*/
1767 static int isSignedOp (iCode *ic)
1788 case GET_VALUE_AT_ADDRESS:
1819 dumpCseSet(set *cseSet)
1823 cseDef *item=cseSet->item;
1825 printOperand (item->sym, NULL);
1827 piCode (item->diCode, NULL);
1828 cseSet = cseSet->next;
1833 /*-----------------------------------------------------------------*/
1834 /* cseBBlock - common subexpression elimination for basic blocks */
1835 /* this is the hackiest kludgiest routine in the whole */
1836 /* system. also the most important, since almost all */
1837 /* data flow related information is computed by it */
1838 /*-----------------------------------------------------------------*/
1840 cseBBlock (eBBlock * ebb, int computeOnly,
1843 eBBlock ** ebbs = ebbi->bbOrder;
1844 int count = ebbi->count;
1849 set *ptrSetSet = NULL;
1852 /* if this block is not reachable */
1856 /* set of common subexpressions */
1857 cseSet = setFromSet (ebb->inExprs);
1859 /* these will be computed by this routine */
1860 setToNull ((void *) &ebb->outDefs);
1861 setToNull ((void *) &ebb->defSet);
1862 setToNull ((void *) &ebb->usesDefs);
1863 setToNull ((void *) &ebb->ptrsSet);
1864 setToNull ((void *) &ebb->addrOf);
1865 setToNull ((void *) &ebb->ldefs);
1867 ebb->outDefs = bitVectCopy (ebb->inDefs);
1868 bitVectDefault = iCodeKey;
1869 ebb->defSet = newBitVect (iCodeKey);
1870 ebb->usesDefs = newBitVect (iCodeKey);
1872 /* for all the instructions in this block do */
1873 for (ic = ebb->sch; ic; ic = ic->next)
1880 ic->eBBlockNum = ebb->bbnum;
1885 /* if this is an assignment from true symbol
1886 to a temp then do pointer post inc/dec optimization */
1887 if (ic->op == '=' && !POINTER_SET (ic) &&
1888 IS_PTR (operandType (IC_RESULT (ic))))
1890 ptrPostIncDecOpt (ic);
1893 /* clear the def & use chains for the operands involved */
1894 /* in this operation . since it can change due to opts */
1895 unsetDefsAndUses (ic);
1897 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1899 /* add to defSet of the symbol */
1900 OP_DEFS(IC_RESULT (ic))=
1901 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1902 /* add to the definition set of this block */
1903 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1904 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1905 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1906 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1907 /* delete global variables from the cseSet
1908 since they can be modified by the function call */
1909 deleteItemIf (&cseSet, ifDefGlobal);
1911 /* and also iTemps derived from globals */
1912 deleteItemIf (&cseSet, ifFromGlobal);
1914 /* Delete iTemps derived from symbols whose address */
1915 /* has been taken */
1916 deleteItemIf (&cseSet, ifFromAddrTaken);
1918 /* delete all getpointer iCodes from cseSet, this should
1919 be done only for global arrays & pointers but at this
1920 point we don't know if globals, so to be safe do all */
1921 deleteItemIf (&cseSet, ifAnyGetPointer);
1923 /* can't cache pointer set/get operations across a call */
1924 deleteSet (&ptrSetSet);
1927 /* for pcall & ipush we need to add to the useSet */
1928 if ((ic->op == PCALL ||
1932 IS_SYMOP (IC_LEFT (ic)))
1935 /* check if they can be replaced */
1939 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1941 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1943 /* the lookup could have changed it */
1944 if (IS_SYMOP (IC_LEFT (ic)))
1946 OP_USES(IC_LEFT (ic))=
1947 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1948 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1949 ebb->outDefs, &ebb->usesDefs);
1953 /* if we a sending a pointer as a parameter
1954 then kill all cse since the pointed to item
1955 might be changed in the function being called */
1956 if ((ic->op == IPUSH || ic->op == SEND) &&
1957 IS_PTR (operandType (IC_LEFT (ic))))
1959 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1960 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1961 for (i = 0; i < count; ebbs[i++]->visited = 0);
1962 applyToSet (ebb->succList, delGetPointerSucc,
1963 IC_LEFT (ic), ebb->dfnum);
1968 /* if jumptable then mark the usage */
1969 if (ic->op == JUMPTABLE)
1971 if (IS_SYMOP (IC_JTCOND (ic)))
1973 OP_USES(IC_JTCOND (ic)) =
1974 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1975 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1976 ebb->outDefs, &ebb->usesDefs);
1986 /* do some algebraic optimizations if possible */
1987 algebraicOpts (ic, ebb);
1988 while (constFold (ic, cseSet));
1992 if (POINTER_GET (ic))
1994 if (!IS_PTR (operandType (IC_LEFT (ic))))
1996 setOperandType (IC_LEFT (ic),
1997 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1998 IC_LEFT (ic)->aggr2ptr = 0;
2001 else if (IC_LEFT (ic)->aggr2ptr == 1)
2002 {/* band aid for kludge */
2003 setOperandType (IC_LEFT (ic),
2004 aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
2005 IC_LEFT (ic)->aggr2ptr++;
2010 if (POINTER_SET (ic))
2012 if (!IS_PTR (operandType (IC_RESULT (ic))))
2014 setOperandType (IC_RESULT (ic),
2015 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2016 IC_RESULT (ic)->aggr2ptr = 0;
2018 else if (IC_RESULT (ic)->aggr2ptr == 1)
2019 {/* band aid for kludge */
2020 setOperandType (IC_RESULT (ic),
2021 aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2022 IC_RESULT (ic)->aggr2ptr++;
2026 /* if this is a condition statement then */
2027 /* check if the condition can be replaced */
2030 ifxOptimize (ic, cseSet, computeOnly,
2036 /* if the assignment & result is a temp */
2037 /* see if we can replace it */
2038 if (!computeOnly && ic->op == '=')
2041 /* update the spill location for this */
2042 updateSpillLocation (ic,0);
2044 if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)) &&
2045 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
2048 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
2049 if (pdop && !computeOnly && IS_ITEMP (pdop))
2051 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
2052 if (!IS_PTR (operandType (IC_RESULT (ic))))
2054 setOperandType (IC_RESULT (ic),
2055 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2061 checkSign = isSignedOp(ic);
2063 /* do the operand lookup i.e. for both the */
2064 /* right & left operand : check the cseSet */
2065 /* to see if they have been replaced if yes */
2066 /* then replace them with those from cseSet */
2068 /* and left is a symbol */
2069 if (IS_SYMOP (IC_LEFT (ic)) &&
2070 !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
2071 !computeOnly && ic->op != ADDRESS_OF)
2075 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2078 if (POINTER_GET (ic))
2080 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2082 /* some non dominating block does POINTER_SET with
2083 this variable .. unsafe to remove any POINTER_GETs */
2084 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
2085 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
2086 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2089 /* check if there is a pointer set
2090 for the same pointer visible if yes
2091 then change this into an assignment */
2093 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2094 !bitVectBitValue (ebb->ptrsSet, pdop->key))
2097 IC_LEFT (ic) = NULL;
2098 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2099 SET_ISADDR (IC_RESULT (ic), 0);
2105 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2112 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2116 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2118 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2123 /* if left or right changed then do algebraic */
2124 if (!computeOnly && change)
2126 algebraicOpts (ic, ebb);
2127 while (constFold (ic, cseSet));
2130 /* if after all this it becomes an assignment to self
2131 then delete it and continue */
2132 if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
2134 remiCodeFromeBBlock (ebb, ic);
2138 /* now we will check to see if the entire */
2139 /* operation has been performed before */
2140 /* and is available */
2141 /* don't do assignments they will be killed */
2142 /* by dead code elimination if required do */
2143 /* it only if result is a temporary */
2145 if (!(POINTER_GET (ic) &&
2146 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2147 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2148 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2150 IS_ITEMP (IC_RESULT (ic)) &&
2153 applyToSet (cseSet, findPrevIc, ic, &pdic);
2154 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2155 operandType (IC_RESULT (ic))) != 1)
2157 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2161 /* Alternate code */
2162 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2163 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2164 /* Mmm, found an equivalent pointer get at a lower level.
2165 This could be a loop however with the same pointer set
2168 /* if previous definition found change this to an assignment */
2171 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2172 SET_ISADDR(IC_RESULT(ic),0);
2173 SET_ISADDR(IC_RIGHT (ic),0);
2177 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2179 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2180 csed = newCseDef (IC_RESULT (ic), ic);
2181 updateCseDefAncestors (csed, cseSet);
2182 addSetHead (&cseSet, csed);
2186 /* if assignment to a parameter which is not
2187 mine and type is a pointer then delete
2188 pointerGets to take care of aliasing */
2189 if (ASSIGNMENT (ic) &&
2190 IS_SYMOP (IC_RESULT (ic)) &&
2191 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2192 IS_PTR (operandType (IC_RESULT (ic))))
2194 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2195 for (i = 0; i < count; ebbs[i++]->visited = 0);
2196 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2197 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2200 /* if this is a pointerget then see if we can replace
2201 this with a previously assigned pointer value */
2202 if (POINTER_GET (ic) &&
2203 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2204 isOperandVolatile (IC_LEFT (ic), TRUE)))
2207 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2208 /* if we find it then locally replace all
2209 references to the result with what we assigned */
2212 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2216 /* delete from the cseSet anything that has */
2217 /* operands matching the result of this */
2218 /* except in case of pointer access */
2219 if (!(POINTER_SET (ic)) && IS_SYMOP (IC_RESULT (ic)))
2221 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2222 /* delete any previous definitions */
2223 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2226 /* add the left & right to the defUse set */
2227 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2229 OP_USES(IC_LEFT (ic))=
2230 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2231 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2234 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2236 OP_USES(IC_RIGHT (ic))=
2237 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2238 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2241 /* for the result it is special case, put the result */
2242 /* in the defuseSet if it a pointer or array access */
2243 if (POINTER_SET (defic) && IS_SYMOP (IC_RESULT (ic)))
2245 OP_USES(IC_RESULT (ic))=
2246 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2247 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2248 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2249 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2250 /* delete from inexpressions of all successors which
2251 have dfNum > than this block */
2252 for (i = 0; i < count; ebbs[i++]->visited = 0);
2253 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2255 /* delete from cseSet all other pointer sets
2257 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2258 /* add to the local pointerset set */
2259 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2263 /* add the result to definition set */
2264 if (IS_SYMOP (IC_RESULT (ic)))
2266 OP_DEFS(IC_RESULT (ic))=
2267 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2268 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2269 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2270 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2274 /* if this is an addressof instruction then */
2275 /* put the symbol in the address of list & */
2276 /* delete it from the cseSet */
2277 if (defic->op == ADDRESS_OF)
2279 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2280 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2284 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2285 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2286 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2287 addSetHead (&ebb->killedExprs, expr);
2289 setToNull ((void *) &ebb->outExprs);
2290 ebb->outExprs = cseSet;
2291 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2292 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2296 /*-----------------------------------------------------------------*/
2297 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2298 /*-----------------------------------------------------------------*/
2300 cseAllBlocks (ebbIndex * ebbi, int computeOnly)
2302 eBBlock ** ebbs = ebbi->dfOrder;
2303 int count = ebbi->count;
2307 /* if optimization turned off */
2309 for (i = 0; i < count; i++)
2310 change += cseBBlock (ebbs[i], computeOnly, ebbi);