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 /* '*' can have two unsigned chars as operands */
1042 /* and an unsigned int as result. */
1043 if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
1045 if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
1046 (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
1051 op = operandFromOperand (IC_RESULT (ic));
1053 setOperandType (op, INTTYPE);
1054 newic = newiCode (CAST, op, IC_LEFT (ic));
1055 IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
1056 addiCodeToeBBlock (ebp, newic, ic);
1057 IC_LEFT (ic) = IC_RESULT (newic);
1060 /* convert x * -1 to -x */
1061 ic->op = UNARYMINUS;
1062 IC_RIGHT (ic) = NULL;
1068 /* if division by self then 1 */
1069 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
1072 IC_RIGHT (ic) = operandFromLit (1);
1073 IC_LEFT (ic) = NULL;
1074 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
1075 IC_RESULT (ic)->isaddr = 0;
1078 /* if this is a division then check if left is zero */
1079 /* and right is not then change it to an assignment */
1080 if (IS_OP_LITERAL (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic)) &&
1081 (operandLitValue (IC_LEFT (ic)) == 0.0) && (operandLitValue (IC_RIGHT (ic)) != 0.0))
1084 IC_RIGHT (ic) = IC_LEFT (ic);
1085 IC_LEFT (ic) = NULL;
1086 SET_RESULT_RIGHT (ic);
1089 /* if this is a division then check if right */
1090 /* is one then change it to an assignment */
1091 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1093 double rightValue = operandLitValue (IC_RIGHT (ic));
1094 if (rightValue == 1.0)
1097 IC_RIGHT (ic) = IC_LEFT (ic);
1098 IC_LEFT (ic) = NULL;
1099 SET_RESULT_RIGHT (ic);
1102 if (rightValue == -1.0)
1104 /* '/' can have two unsigned chars as operands */
1105 /* and an unsigned int as result. */
1106 if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
1108 if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
1109 (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
1114 op = operandFromOperand (IC_RESULT (ic));
1116 setOperandType (op, INTTYPE);
1117 newic = newiCode (CAST, op, IC_LEFT (ic));
1118 IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
1119 addiCodeToeBBlock (ebp, newic, ic);
1120 IC_LEFT (ic) = IC_RESULT (newic);
1123 /* convert x / -1 to -x */
1124 ic->op = UNARYMINUS;
1125 IC_RIGHT (ic) = NULL;
1130 /* if both are the same for an comparison operators */
1134 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1137 IC_RIGHT (ic) = operandFromLit (1);
1138 IC_LEFT (ic) = NULL;
1139 SET_RESULT_RIGHT (ic);
1145 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1148 IC_RIGHT (ic) = operandFromLit (0);
1149 IC_LEFT (ic) = NULL;
1150 SET_RESULT_RIGHT (ic);
1155 sym_link *otype = operandType(IC_RIGHT(ic));
1156 sym_link *ctype = operandType(IC_LEFT(ic));
1157 /* if this is a cast of a literal value */
1158 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1159 !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype))))
1162 IC_RIGHT (ic) = operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
1163 operandLitValue (IC_RIGHT (ic))));
1164 IC_LEFT (ic) = NULL;
1165 SET_ISADDR (IC_RESULT (ic), 0);
1167 /* if casting to the same */
1168 if (compareType (operandType (IC_RESULT (ic)), operandType (IC_RIGHT (ic))) == 1)
1171 IC_LEFT (ic) = NULL;
1172 SET_ISADDR (IC_RESULT (ic), 0);
1177 if (IS_OP_LITERAL (IC_LEFT (ic)))
1181 (operandLitValue (IC_LEFT (ic)) == 0 ?
1182 operandFromLit (1) : operandFromLit (0));
1183 IC_LEFT (ic) = NULL;
1184 SET_ISADDR (IC_RESULT (ic), 0);
1188 /* if both operands are equal */
1189 /* if yes turn it into assignment */
1190 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1192 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1194 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1195 IC_RESULT (newic) = IC_LEFT (ic);
1196 newic->filename = ic->filename;
1197 newic->lineno = ic->lineno;
1198 addiCodeToeBBlock (ebp, newic, ic->next);
1201 IC_LEFT (ic) = NULL;
1202 SET_RESULT_RIGHT (ic);
1205 /* swap literal to right ic */
1206 if (IS_OP_LITERAL (IC_LEFT (ic)))
1211 IC_LEFT (ic) = IC_RIGHT (ic);
1214 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1216 /* if BITWISEAND then check if one of them is a zero */
1217 /* if yes turn it into 0 assignment */
1218 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1220 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1222 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1223 IC_RESULT (newic) = IC_LEFT (ic);
1224 newic->filename = ic->filename;
1225 newic->lineno = ic->lineno;
1226 addiCodeToeBBlock (ebp, newic, ic->next);
1229 IC_LEFT (ic) = NULL;
1230 SET_RESULT_RIGHT (ic);
1233 /* if BITWISEAND then check if one of them is 0xff... */
1234 /* if yes turn it into assignment */
1238 switch (getSize (operandType (IC_RIGHT (ic))))
1252 if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
1255 IC_RIGHT (ic) = IC_LEFT (ic);
1256 IC_LEFT (ic) = NULL;
1257 SET_RESULT_RIGHT (ic);
1264 /* if both operands are equal */
1265 /* if yes turn it into assignment */
1266 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1268 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1270 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1271 IC_RESULT (newic) = IC_LEFT (ic);
1272 newic->filename = ic->filename;
1273 newic->lineno = ic->lineno;
1274 addiCodeToeBBlock (ebp, newic, ic->next);
1277 IC_LEFT (ic) = NULL;
1278 SET_RESULT_RIGHT (ic);
1281 /* swap literal to right ic */
1282 if (IS_OP_LITERAL (IC_LEFT (ic)))
1287 IC_LEFT (ic) = IC_RIGHT (ic);
1290 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1292 /* if BITWISEOR then check if one of them is a zero */
1293 /* if yes turn it into assignment */
1294 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1297 IC_RIGHT (ic) = IC_LEFT (ic);
1298 IC_LEFT (ic) = NULL;
1299 SET_RESULT_RIGHT (ic);
1302 /* if BITWISEOR then check if one of them is 0xff... */
1303 /* if yes turn it into 0xff... assignment */
1307 switch (getSize (operandType (IC_RIGHT (ic))))
1321 if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
1323 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1325 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1326 IC_RESULT (newic) = IC_LEFT (ic);
1327 newic->filename = ic->filename;
1328 newic->lineno = ic->lineno;
1329 addiCodeToeBBlock (ebp, newic, ic->next);
1332 IC_LEFT (ic) = NULL;
1333 SET_RESULT_RIGHT (ic);
1340 /* if both operands are equal */
1341 /* if yes turn it into 0 assignment */
1342 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1344 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1346 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1347 IC_RESULT (newic) = IC_LEFT (ic);
1348 newic->filename = ic->filename;
1349 newic->lineno = ic->lineno;
1350 addiCodeToeBBlock (ebp, newic, ic->next);
1352 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1353 IC_RESULT (newic) = IC_LEFT (ic);
1354 newic->filename = ic->filename;
1355 newic->lineno = ic->lineno;
1356 addiCodeToeBBlock (ebp, newic, ic->next);
1359 IC_RIGHT (ic) = operandFromLit (0);
1360 IC_LEFT (ic) = NULL;
1361 SET_RESULT_RIGHT (ic);
1364 /* swap literal to right ic */
1365 if (IS_OP_LITERAL (IC_LEFT (ic)))
1370 IC_LEFT (ic) = IC_RIGHT (ic);
1373 /* if XOR then check if one of them is a zero */
1374 /* if yes turn it into assignment */
1375 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1377 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1380 IC_RIGHT (ic) = IC_LEFT (ic);
1381 IC_LEFT (ic) = NULL;
1382 SET_RESULT_RIGHT (ic);
1391 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1392 /*-----------------------------------------------------------------*/
1393 /* updateSpillLocation - keeps track of register spill location */
1394 /*-----------------------------------------------------------------*/
1396 updateSpillLocation (iCode * ic, int induction)
1400 if (POINTER_SET (ic))
1407 /* for the form true_symbol := iTempNN */
1408 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1409 !SPIL_LOC (IC_RIGHT (ic))) {
1411 setype = getSpec (operandType (IC_RESULT (ic)));
1413 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1414 !IS_VOLATILE (setype) &&
1415 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1416 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1418 wassert(IS_SYMOP(IC_RESULT (ic)));
1419 wassert(IS_SYMOP(IC_RIGHT (ic)));
1420 SPIL_LOC (IC_RIGHT (ic)) =
1421 IC_RESULT (ic)->operand.symOperand;
1427 #if 0 /* this needs furthur investigation can save a lot of code */
1428 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1429 !SPIL_LOC(IC_RESULT(ic))) {
1430 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1431 SPIL_LOC (IC_RESULT (ic)) =
1432 IC_RIGHT (ic)->operand.symOperand;
1435 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1437 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1438 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1439 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1441 setype = getSpec (operandType (IC_RESULT (ic)));
1443 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1444 !IS_VOLATILE (setype) &&
1445 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1446 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) {
1448 SPIL_LOC (IC_RIGHT (ic)) =
1449 SPIL_LOC (IC_RESULT (ic));
1450 OP_SYMBOL (IC_RIGHT (ic))->prereqv =
1451 OP_SYMBOL (IC_RESULT (ic))->prereqv;
1454 /* special case for inductions */
1456 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1457 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1458 !SPIL_LOC(IC_RESULT(ic))) {
1459 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1460 OP_SYMBOL (IC_RESULT (ic))->prereqv =
1461 OP_SYMBOL (IC_RIGHT (ic))->prereqv;
1465 /*-----------------------------------------------------------------*/
1466 /* setUsesDef - sets the uses def bitvector for a given operand */
1467 /*-----------------------------------------------------------------*/
1469 setUsesDefs (operand * op, bitVect * bdefs,
1470 bitVect * idefs, bitVect ** oud)
1472 /* compute the definitions alive at this point */
1473 bitVect *adefs = bitVectUnion (bdefs, idefs);
1475 /* of these definitions find the ones that are */
1476 /* for this operand */
1477 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1479 /* these are the definitions that this operand can use */
1480 op->usesDefs = adefs;
1482 /* the out defs is an union */
1483 *oud = bitVectUnion (*oud, adefs);
1486 /*-----------------------------------------------------------------*/
1487 /* unsetDefsAndUses - clear this operation for the operands */
1488 /*-----------------------------------------------------------------*/
1490 unsetDefsAndUses (iCode * ic)
1492 if (ic->op == JUMPTABLE)
1495 /* take away this definition from the def chain of the */
1496 /* result & take away from use set of the operands */
1499 /* turn off def set */
1500 if (IS_SYMOP (IC_RESULT (ic)))
1502 if (!POINTER_SET (ic))
1503 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1505 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1507 /* turn off the useSet for the operands */
1508 if (IS_SYMOP (IC_LEFT (ic)))
1509 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1511 if (IS_SYMOP (IC_RIGHT (ic)))
1512 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1515 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1516 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1519 /*-----------------------------------------------------------------*/
1520 /* ifxOptimize - changes ifx conditions if it can */
1521 /*-----------------------------------------------------------------*/
1523 ifxOptimize (iCode * ic, set * cseSet,
1525 eBBlock * ebb, int *change,
1531 /* if the condition can be replaced */
1535 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1538 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1543 /* if the conditional is a literal then */
1544 if (IS_OP_LITERAL (IC_COND (ic)))
1546 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1548 /* change to a goto */
1550 IC_LABEL (ic) = IC_TRUE (ic);
1555 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1558 IC_LABEL (ic) = IC_FALSE (ic);
1563 /* then kill this if condition */
1564 remiCodeFromeBBlock (ebb, ic);
1568 /* now we need to recompute the control flow */
1569 /* since the control flow has changed */
1570 /* this is very expensive but it does not happen */
1571 /* too often, if it does happen then the user pays */
1573 computeControlFlow (ebbi);
1574 if (!options.lessPedantic)
1576 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1581 /* if there is only one successor and that successor
1582 is the same one we are conditionally going to then
1583 we can remove this conditional statement */
1584 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1585 if (elementsInSet (ebb->succList) == 1 &&
1586 isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
1588 if (!options.lessPedantic)
1590 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1592 if (IS_OP_VOLATILE (IC_COND (ic)))
1594 IC_RIGHT (ic) = IC_COND (ic);
1595 IC_LEFT (ic) = NULL;
1596 IC_RESULT (ic) = NULL;
1597 ic->op = DUMMY_READ_VOLATILE;
1601 remiCodeFromeBBlock (ebb, ic);
1602 computeControlFlow (ebbi);
1607 /* if it remains an IFX then update the use Set */
1610 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1611 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1613 else if (ic->op == DUMMY_READ_VOLATILE)
1615 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1616 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1621 /*-----------------------------------------------------------------*/
1622 /* diCodeForSym - finds the definiting instruction for a symbol */
1623 /*-----------------------------------------------------------------*/
1624 DEFSETFUNC (diCodeForSym)
1627 V_ARG (operand *, sym);
1628 V_ARG (iCode **, dic);
1630 /* if already found */
1634 /* if not if this is the defining iCode */
1635 if (sym->key == cdp->key)
1644 /*-----------------------------------------------------------------*/
1645 /* constFold - does some constant folding */
1646 /*-----------------------------------------------------------------*/
1648 constFold (iCode * ic, set * cseSet)
1652 /* this routine will change
1658 /* deal with only + & - */
1659 if (ic->op != '+' &&
1663 /* this check is a heuristic to prevent live ranges
1664 from becoming too long */
1665 if (IS_PTR (operandType (IC_RESULT (ic))))
1668 /* check if operation with a literal */
1669 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1672 /* check if we can find a definition for the
1674 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1677 /* check that this is also a +/- */
1678 if (dic->op != '+' && dic->op != '-')
1681 /* with a literal */
1682 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1685 /* find the definition of the left operand
1686 of dic.then check if this defined with a
1687 get_pointer return 0 if the pointer size is
1688 less than 2 (MCS51 specific) */
1689 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1692 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1695 /* it is if the operations are the same */
1696 /* the literal parts need to be added */
1697 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1698 if (ic->op == dic->op)
1699 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1700 operandLitValue (IC_RIGHT (dic)));
1702 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1703 operandLitValue (IC_RIGHT (dic)));
1705 if (IS_ITEMP (IC_RESULT (ic)))
1707 SPIL_LOC (IC_RESULT (ic)) = NULL;
1708 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1715 /*-----------------------------------------------------------------*/
1716 /* deleteGetPointers - called when a pointer is passed as parm */
1717 /* will delete from cseSet all get pointers computed from this */
1718 /* pointer. A simple ifOperandsHave is not good enough here */
1719 /*-----------------------------------------------------------------*/
1721 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1723 set *compItems = NULL;
1729 if (!*cseSet && !*pss)
1732 addSet (&compItems, op);
1734 /* Recursively find all items computed from this operand .
1735 This done fairly simply go thru the list and find
1736 those that are computed by arthimetic with these
1738 /* Also check for those computed from our computed
1739 list . This will take care of situations like
1740 iTemp1 = iTemp0 + 8;
1741 iTemp2 = iTemp1 + 8; */
1745 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1747 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1749 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1750 (insetwithFunc)isOperandEqual) ||
1751 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1752 (insetwithFunc)isOperandEqual))
1754 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1755 (insetwithFunc)isOperandEqual))
1757 addSet (&compItems, IC_RESULT (cdp->diCode));
1766 /* now for the computed items */
1767 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1769 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1770 deleteItemIf (cseSet, ifPointerGet, cop);
1771 deleteItemIf (cseSet, ifDefSymIsX, cop);
1772 deleteItemIf (pss, ifPointerSet, cop);
1776 /*-----------------------------------------------------------------*/
1777 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1778 /* dfnum > supplied */
1779 /*-----------------------------------------------------------------*/
1780 DEFSETFUNC (delGetPointerSucc)
1782 eBBlock *ebp = item;
1783 V_ARG (operand *, op);
1790 if (ebp->dfnum > dfnum)
1792 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1795 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1798 /*-----------------------------------------------------------------*/
1799 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1800 /*-----------------------------------------------------------------*/
1802 fixUpTypes (iCode * ic)
1804 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1806 /* if (TARGET_IS_DS390) */
1807 if (options.model == MODEL_FLAT24)
1813 /* for pointer_gets if the types of result & left r the
1814 same then change it type of result to next */
1816 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1818 setOperandType (IC_RESULT (ic), t2->next);
1822 /*-----------------------------------------------------------------*/
1823 /* isSignedOp - will return 1 if sign is important to operation */
1824 /*-----------------------------------------------------------------*/
1825 static int isSignedOp (iCode *ic)
1846 case GET_VALUE_AT_ADDRESS:
1877 dumpCseSet(set *cseSet)
1881 cseDef *item=cseSet->item;
1883 printOperand (item->sym, NULL);
1885 piCode (item->diCode, NULL);
1886 cseSet = cseSet->next;
1891 /*-----------------------------------------------------------------*/
1892 /* cseBBlock - common subexpression elimination for basic blocks */
1893 /* this is the hackiest kludgiest routine in the whole */
1894 /* system. also the most important, since almost all */
1895 /* data flow related information is computed by it */
1896 /*-----------------------------------------------------------------*/
1898 cseBBlock (eBBlock * ebb, int computeOnly,
1901 eBBlock ** ebbs = ebbi->bbOrder;
1902 int count = ebbi->count;
1907 set *ptrSetSet = NULL;
1910 /* if this block is not reachable */
1914 /* set of common subexpressions */
1915 cseSet = setFromSet (ebb->inExprs);
1917 /* these will be computed by this routine */
1918 setToNull ((void *) &ebb->outDefs);
1919 setToNull ((void *) &ebb->defSet);
1920 setToNull ((void *) &ebb->usesDefs);
1921 setToNull ((void *) &ebb->ptrsSet);
1922 setToNull ((void *) &ebb->addrOf);
1923 setToNull ((void *) &ebb->ldefs);
1925 ebb->outDefs = bitVectCopy (ebb->inDefs);
1926 bitVectDefault = iCodeKey;
1927 ebb->defSet = newBitVect (iCodeKey);
1928 ebb->usesDefs = newBitVect (iCodeKey);
1930 /* for all the instructions in this block do */
1931 for (ic = ebb->sch; ic; ic = ic->next)
1938 ic->eBBlockNum = ebb->bbnum;
1943 /* if this is an assignment from true symbol
1944 to a temp then do pointer post inc/dec optimization */
1945 if (ic->op == '=' && !POINTER_SET (ic) &&
1946 IS_PTR (operandType (IC_RESULT (ic))))
1948 ptrPostIncDecOpt (ic);
1951 /* clear the def & use chains for the operands involved */
1952 /* in this operation . since it can change due to opts */
1953 unsetDefsAndUses (ic);
1955 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1957 /* add to defSet of the symbol */
1958 OP_DEFS(IC_RESULT (ic))=
1959 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1960 /* add to the definition set of this block */
1961 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1962 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1963 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1964 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1965 /* delete global variables from the cseSet
1966 since they can be modified by the function call */
1967 deleteItemIf (&cseSet, ifDefGlobal);
1969 /* and also iTemps derived from globals */
1970 deleteItemIf (&cseSet, ifFromGlobal);
1972 /* Delete iTemps derived from symbols whose address */
1973 /* has been taken */
1974 deleteItemIf (&cseSet, ifFromAddrTaken);
1976 /* delete all getpointer iCodes from cseSet, this should
1977 be done only for global arrays & pointers but at this
1978 point we don't know if globals, so to be safe do all */
1979 deleteItemIf (&cseSet, ifAnyGetPointer);
1981 /* can't cache pointer set/get operations across a call */
1982 deleteSet (&ptrSetSet);
1985 /* for pcall & ipush we need to add to the useSet */
1986 if ((ic->op == PCALL ||
1990 IS_SYMOP (IC_LEFT (ic)))
1993 /* check if they can be replaced */
1997 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1999 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2001 /* the lookup could have changed it */
2002 if (IS_SYMOP (IC_LEFT (ic)))
2004 OP_USES(IC_LEFT (ic))=
2005 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2006 setUsesDefs (IC_LEFT (ic), ebb->defSet,
2007 ebb->outDefs, &ebb->usesDefs);
2011 /* if we a sending a pointer as a parameter
2012 then kill all cse since the pointed to item
2013 might be changed in the function being called */
2014 if ((ic->op == IPUSH || ic->op == SEND) &&
2015 IS_PTR (operandType (IC_LEFT (ic))))
2017 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
2018 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
2019 for (i = 0; i < count; ebbs[i++]->visited = 0);
2020 applyToSet (ebb->succList, delGetPointerSucc,
2021 IC_LEFT (ic), ebb->dfnum);
2026 /* if jumptable then mark the usage */
2027 if (ic->op == JUMPTABLE)
2029 if (IS_SYMOP (IC_JTCOND (ic)))
2031 OP_USES(IC_JTCOND (ic)) =
2032 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
2033 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
2034 ebb->outDefs, &ebb->usesDefs);
2044 /* do some algebraic optimizations if possible */
2045 algebraicOpts (ic, ebb);
2046 while (constFold (ic, cseSet));
2050 if (POINTER_GET (ic))
2052 if (!IS_PTR (operandType (IC_LEFT (ic))))
2054 setOperandType (IC_LEFT (ic),
2055 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
2056 IC_LEFT (ic)->aggr2ptr = 0;
2059 else if (IC_LEFT (ic)->aggr2ptr == 1)
2060 {/* band aid for kludge */
2061 setOperandType (IC_LEFT (ic),
2062 aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
2063 IC_LEFT (ic)->aggr2ptr++;
2068 if (POINTER_SET (ic))
2070 if (!IS_PTR (operandType (IC_RESULT (ic))))
2072 setOperandType (IC_RESULT (ic),
2073 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2074 IC_RESULT (ic)->aggr2ptr = 0;
2076 else if (IC_RESULT (ic)->aggr2ptr == 1)
2077 {/* band aid for kludge */
2078 setOperandType (IC_RESULT (ic),
2079 aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2080 IC_RESULT (ic)->aggr2ptr++;
2084 /* if this is a condition statement then */
2085 /* check if the condition can be replaced */
2088 ifxOptimize (ic, cseSet, computeOnly,
2094 /* if the assignment & result is a temp */
2095 /* see if we can replace it */
2096 if (!computeOnly && ic->op == '=')
2099 /* update the spill location for this */
2100 updateSpillLocation (ic,0);
2102 if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)) &&
2103 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
2106 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
2107 if (pdop && !computeOnly && IS_ITEMP (pdop))
2109 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
2110 if (!IS_PTR (operandType (IC_RESULT (ic))))
2112 setOperandType (IC_RESULT (ic),
2113 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2119 checkSign = isSignedOp(ic);
2121 /* do the operand lookup i.e. for both the */
2122 /* right & left operand : check the cseSet */
2123 /* to see if they have been replaced if yes */
2124 /* then replace them with those from cseSet */
2126 /* and left is a symbol */
2127 if (IS_SYMOP (IC_LEFT (ic)) &&
2128 !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
2129 !computeOnly && ic->op != ADDRESS_OF)
2133 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2136 if (POINTER_GET (ic))
2138 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2140 /* some non dominating block does POINTER_SET with
2141 this variable .. unsafe to remove any POINTER_GETs */
2142 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
2143 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
2144 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2147 /* check if there is a pointer set
2148 for the same pointer visible if yes
2149 then change this into an assignment */
2151 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2152 !bitVectBitValue (ebb->ptrsSet, pdop->key))
2155 IC_LEFT (ic) = NULL;
2156 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2157 SET_ISADDR (IC_RESULT (ic), 0);
2163 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2170 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2174 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2176 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2181 /* if left or right changed then do algebraic */
2182 if (!computeOnly && change)
2184 algebraicOpts (ic, ebb);
2185 while (constFold (ic, cseSet));
2188 /* if after all this it becomes an assignment to self
2189 then delete it and continue */
2190 if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
2192 remiCodeFromeBBlock (ebb, ic);
2196 /* now we will check to see if the entire */
2197 /* operation has been performed before */
2198 /* and is available */
2199 /* don't do assignments they will be killed */
2200 /* by dead code elimination if required do */
2201 /* it only if result is a temporary */
2203 if (!(POINTER_GET (ic) &&
2204 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2205 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2206 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2208 IS_ITEMP (IC_RESULT (ic)) &&
2211 applyToSet (cseSet, findPrevIc, ic, &pdic);
2212 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2213 operandType (IC_RESULT (ic))) != 1)
2215 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2219 /* Alternate code */
2220 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2221 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2222 /* Mmm, found an equivalent pointer get at a lower level.
2223 This could be a loop however with the same pointer set
2226 /* if previous definition found change this to an assignment */
2229 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2230 SET_ISADDR(IC_RESULT(ic),0);
2231 SET_ISADDR(IC_RIGHT (ic),0);
2235 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2237 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2238 csed = newCseDef (IC_RESULT (ic), ic);
2239 updateCseDefAncestors (csed, cseSet);
2240 addSetHead (&cseSet, csed);
2244 /* if assignment to a parameter which is not
2245 mine and type is a pointer then delete
2246 pointerGets to take care of aliasing */
2247 if (ASSIGNMENT (ic) &&
2248 IS_SYMOP (IC_RESULT (ic)) &&
2249 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2250 IS_PTR (operandType (IC_RESULT (ic))))
2252 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2253 for (i = 0; i < count; ebbs[i++]->visited = 0);
2254 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2255 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2258 /* if this is a pointerget then see if we can replace
2259 this with a previously assigned pointer value */
2260 if (POINTER_GET (ic) &&
2261 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2262 isOperandVolatile (IC_LEFT (ic), TRUE)))
2265 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2266 /* if we find it then locally replace all
2267 references to the result with what we assigned */
2270 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2274 /* delete from the cseSet anything that has */
2275 /* operands matching the result of this */
2276 /* except in case of pointer access */
2277 if (!(POINTER_SET (ic)) && IS_SYMOP (IC_RESULT (ic)))
2279 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2280 /* delete any previous definitions */
2281 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2284 /* add the left & right to the defUse set */
2285 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2287 OP_USES(IC_LEFT (ic))=
2288 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2289 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2292 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2294 OP_USES(IC_RIGHT (ic))=
2295 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2296 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2299 /* for the result it is special case, put the result */
2300 /* in the defuseSet if it a pointer or array access */
2301 if (POINTER_SET (defic) && IS_SYMOP (IC_RESULT (ic)))
2303 OP_USES(IC_RESULT (ic))=
2304 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2305 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2306 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2307 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2308 /* delete from inexpressions of all successors which
2309 have dfNum > than this block */
2310 for (i = 0; i < count; ebbs[i++]->visited = 0);
2311 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2313 /* delete from cseSet all other pointer sets
2315 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2316 /* add to the local pointerset set */
2317 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2321 /* add the result to definition set */
2322 if (IS_SYMOP (IC_RESULT (ic)))
2324 OP_DEFS(IC_RESULT (ic))=
2325 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2326 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2327 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2328 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2332 /* if this is an addressof instruction then */
2333 /* put the symbol in the address of list & */
2334 /* delete it from the cseSet */
2335 if (defic->op == ADDRESS_OF)
2337 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2338 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2342 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2343 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2344 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2345 addSetHead (&ebb->killedExprs, expr);
2347 setToNull ((void *) &ebb->outExprs);
2348 ebb->outExprs = cseSet;
2349 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2350 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2354 /*-----------------------------------------------------------------*/
2355 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2356 /*-----------------------------------------------------------------*/
2358 cseAllBlocks (ebbIndex * ebbi, int computeOnly)
2360 eBBlock ** ebbs = ebbi->dfOrder;
2361 int count = ebbi->count;
2365 /* if optimization turned off */
2367 for (i = 0; i < count; i++)
2368 change += cseBBlock (ebbs[i], computeOnly, ebbi);