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 assignement && 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 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 assignmnt 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)));
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)));
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 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 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)),
1111 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)))
1489 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1492 /* change to a goto */
1494 IC_LABEL (ic) = IC_TRUE (ic);
1501 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1504 IC_LABEL (ic) = IC_FALSE (ic);
1510 /* then kill this if condition */
1511 remiCodeFromeBBlock (ebb, ic);
1515 /* now we need to recompute the control flow */
1516 /* since the control flow has changed */
1517 /* this is very expensive but it does not happen */
1518 /* too often, if it does happen then the user pays */
1520 computeControlFlow (ebbi);
1521 if (!options.lessPedantic) {
1522 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1527 /* if there is only one successor and that successor
1528 is the same one we are conditionally going to then
1529 we can remove this conditional statement */
1530 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1531 if (elementsInSet (ebb->succList) == 1 &&
1532 isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
1535 if (!options.lessPedantic) {
1536 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1538 if (IS_OP_VOLATILE (IC_COND (ic)))
1540 IC_RIGHT (ic) = IC_COND (ic);
1541 IC_LEFT (ic) = NULL;
1542 IC_RESULT (ic) = NULL;
1543 ic->op = DUMMY_READ_VOLATILE;
1547 remiCodeFromeBBlock (ebb, ic);
1548 computeControlFlow (ebbi);
1554 /* if it remains an IFX the update the use Set */
1557 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1558 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1560 else if (ic->op == DUMMY_READ_VOLATILE)
1562 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1563 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1568 /*-----------------------------------------------------------------*/
1569 /* diCodeForSym - finds the definiting instruction for a symbol */
1570 /*-----------------------------------------------------------------*/
1571 DEFSETFUNC (diCodeForSym)
1574 V_ARG (operand *, sym);
1575 V_ARG (iCode **, dic);
1577 /* if already found */
1581 /* if not if this is the defining iCode */
1582 if (sym->key == cdp->key)
1591 /*-----------------------------------------------------------------*/
1592 /* constFold - does some constant folding */
1593 /*-----------------------------------------------------------------*/
1595 constFold (iCode * ic, set * cseSet)
1599 /* this routine will change
1605 /* deal with only + & - */
1606 if (ic->op != '+' &&
1610 /* this check is a heuristic to prevent live ranges
1611 from becoming too long */
1612 if (IS_PTR (operandType (IC_RESULT (ic))))
1615 /* check if operation with a literal */
1616 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1619 /* check if we can find a definition for the
1621 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1624 /* check that this is also a +/- */
1625 if (dic->op != '+' && dic->op != '-')
1628 /* with a literal */
1629 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1632 /* find the definition of the left operand
1633 of dic.then check if this defined with a
1634 get_pointer return 0 if the pointer size is
1635 less than 2 (MCS51 specific) */
1636 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1639 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1642 /* it is if the operations are the same */
1643 /* the literal parts need to be added */
1644 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1645 if (ic->op == dic->op)
1646 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1647 operandLitValue (IC_RIGHT (dic)));
1649 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1650 operandLitValue (IC_RIGHT (dic)));
1652 if (IS_ITEMP (IC_RESULT (ic)))
1654 SPIL_LOC (IC_RESULT (ic)) = NULL;
1655 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1662 /*-----------------------------------------------------------------*/
1663 /* deleteGetPointers - called when a pointer is passed as parm */
1664 /* will delete from cseSet all get pointers computed from this */
1665 /* pointer. A simple ifOperandsHave is not good enough here */
1666 /*-----------------------------------------------------------------*/
1668 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1670 set *compItems = NULL;
1676 if (!*cseSet && !*pss)
1679 addSet (&compItems, op);
1681 /* Recursively find all items computed from this operand .
1682 This done fairly simply go thru the list and find
1683 those that are computed by arthimetic with these
1685 /* Also check for those computed from our computed
1686 list . This will take care of situations like
1687 iTemp1 = iTemp0 + 8;
1688 iTemp2 = iTemp1 + 8; */
1692 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1694 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1696 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1697 (insetwithFunc)isOperandEqual) ||
1698 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1699 (insetwithFunc)isOperandEqual))
1701 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1702 (insetwithFunc)isOperandEqual))
1704 addSet (&compItems, IC_RESULT (cdp->diCode));
1713 /* now for the computed items */
1714 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1716 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1717 deleteItemIf (cseSet, ifPointerGet, cop);
1718 deleteItemIf (cseSet, ifDefSymIsX, cop);
1719 deleteItemIf (pss, ifPointerSet, cop);
1723 /*-----------------------------------------------------------------*/
1724 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1725 /* dfnum > supplied */
1726 /*-----------------------------------------------------------------*/
1727 DEFSETFUNC (delGetPointerSucc)
1729 eBBlock *ebp = item;
1730 V_ARG (operand *, op);
1737 if (ebp->dfnum > dfnum)
1739 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1742 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1745 /*-----------------------------------------------------------------*/
1746 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1747 /*-----------------------------------------------------------------*/
1749 fixUpTypes (iCode * ic)
1751 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1753 /* if (TARGET_IS_DS390) */
1754 if (options.model == MODEL_FLAT24)
1760 /* for pointer_gets if the types of result & left r the
1761 same then change it type of result to next */
1763 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1765 setOperandType (IC_RESULT (ic), t2->next);
1769 /*-----------------------------------------------------------------*/
1770 /* isSignedOp - will return 1 if sign is important to operation */
1771 /*-----------------------------------------------------------------*/
1772 static int isSignedOp (iCode *ic)
1793 case GET_VALUE_AT_ADDRESS:
1824 dumpCseSet(set *cseSet)
1828 cseDef *item=cseSet->item;
1830 printOperand (item->sym, NULL);
1832 piCode (item->diCode, NULL);
1833 cseSet = cseSet->next;
1838 /*-----------------------------------------------------------------*/
1839 /* cseBBlock - common subexpression elimination for basic blocks */
1840 /* this is the hackiest kludgiest routine in the whole */
1841 /* system. also the most important, since almost all */
1842 /* data flow related information is computed by it */
1843 /*-----------------------------------------------------------------*/
1845 cseBBlock (eBBlock * ebb, int computeOnly,
1848 eBBlock ** ebbs = ebbi->bbOrder;
1849 int count = ebbi->count;
1854 set *ptrSetSet = NULL;
1857 /* if this block is not reachable */
1861 /* set of common subexpressions */
1862 cseSet = setFromSet (ebb->inExprs);
1864 /* these will be computed by this routine */
1865 setToNull ((void *) &ebb->outDefs);
1866 setToNull ((void *) &ebb->defSet);
1867 setToNull ((void *) &ebb->usesDefs);
1868 setToNull ((void *) &ebb->ptrsSet);
1869 setToNull ((void *) &ebb->addrOf);
1870 setToNull ((void *) &ebb->ldefs);
1872 ebb->outDefs = bitVectCopy (ebb->inDefs);
1873 bitVectDefault = iCodeKey;
1874 ebb->defSet = newBitVect (iCodeKey);
1875 ebb->usesDefs = newBitVect (iCodeKey);
1877 /* for all the instructions in this block do */
1878 for (ic = ebb->sch; ic; ic = ic->next)
1885 ic->eBBlockNum = ebb->bbnum;
1890 /* if this is an assignment from true symbol
1891 to a temp then do pointer post inc/dec optimzation */
1892 if (ic->op == '=' && !POINTER_SET (ic) &&
1893 IS_PTR (operandType (IC_RESULT (ic))))
1895 ptrPostIncDecOpt (ic);
1898 /* clear the def & use chains for the operands involved */
1899 /* in this operation . since it can change due to opts */
1900 unsetDefsAndUses (ic);
1902 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1904 /* add to defSet of the symbol */
1905 OP_DEFS(IC_RESULT (ic))=
1906 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1907 /* add to the definition set of this block */
1908 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1909 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1910 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1911 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1912 /* delete global variables from the cseSet
1913 since they can be modified by the function call */
1914 deleteItemIf (&cseSet, ifDefGlobal);
1916 /* and also iTemps derived from globals */
1917 deleteItemIf (&cseSet, ifFromGlobal);
1919 /* Delete iTemps derived from symbols whose address */
1920 /* has been taken */
1921 deleteItemIf (&cseSet, ifFromAddrTaken);
1923 /* delete all getpointer iCodes from cseSet, this should
1924 be done only for global arrays & pointers but at this
1925 point we don't know if globals, so to be safe do all */
1926 deleteItemIf (&cseSet, ifAnyGetPointer);
1928 /* can't cache pointer set/get operations across a call */
1929 deleteSet (&ptrSetSet);
1932 /* for pcall & ipush we need to add to the useSet */
1933 if ((ic->op == PCALL ||
1937 IS_SYMOP (IC_LEFT (ic)))
1940 /* check if they can be replaced */
1944 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1946 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1948 /* the lookup could have changed it */
1949 if (IS_SYMOP (IC_LEFT (ic)))
1951 OP_USES(IC_LEFT (ic))=
1952 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1953 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1954 ebb->outDefs, &ebb->usesDefs);
1958 /* if we a sending a pointer as a parameter
1959 then kill all cse since the pointed to item
1960 might be changed in the function being called */
1961 if ((ic->op == IPUSH || ic->op == SEND) &&
1962 IS_PTR (operandType (IC_LEFT (ic))))
1964 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1965 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1966 for (i = 0; i < count; ebbs[i++]->visited = 0);
1967 applyToSet (ebb->succList, delGetPointerSucc,
1968 IC_LEFT (ic), ebb->dfnum);
1973 /* if jumptable then mark the usage */
1974 if (ic->op == JUMPTABLE)
1976 if (IS_SYMOP (IC_JTCOND (ic)))
1978 OP_USES(IC_JTCOND (ic)) =
1979 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1980 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1981 ebb->outDefs, &ebb->usesDefs);
1991 /* do some algebraic optimizations if possible */
1992 algebraicOpts (ic, ebb);
1993 while (constFold (ic, cseSet));
1997 if (POINTER_GET (ic))
1999 if (!IS_PTR (operandType (IC_LEFT (ic))))
2001 setOperandType (IC_LEFT (ic),
2002 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
2003 IC_LEFT (ic)->aggr2ptr = 0;
2006 else if (IC_LEFT (ic)->aggr2ptr == 1)
2007 {/* band aid for kludge */
2008 setOperandType (IC_LEFT (ic),
2009 aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
2010 IC_LEFT (ic)->aggr2ptr++;
2015 if (POINTER_SET (ic))
2017 if (!IS_PTR (operandType (IC_RESULT (ic))))
2019 setOperandType (IC_RESULT (ic),
2020 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2021 IC_RESULT (ic)->aggr2ptr = 0;
2023 else if (IC_RESULT (ic)->aggr2ptr == 1)
2024 {/* band aid for kludge */
2025 setOperandType (IC_RESULT (ic),
2026 aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2027 IC_RESULT (ic)->aggr2ptr++;
2031 /* if this is a condition statement then */
2032 /* check if the condition can be replaced */
2035 ifxOptimize (ic, cseSet, computeOnly,
2041 /* if the assignment & result is a temp */
2042 /* see if we can replace it */
2043 if (!computeOnly && ic->op == '=')
2046 /* update the spill location for this */
2047 updateSpillLocation (ic,0);
2049 if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)) &&
2050 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
2053 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
2054 if (pdop && !computeOnly && IS_ITEMP (pdop))
2056 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
2057 if (!IS_PTR (operandType (IC_RESULT (ic))))
2059 setOperandType (IC_RESULT (ic),
2060 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2066 checkSign = isSignedOp(ic);
2068 /* do the operand lookup i.e. for both the */
2069 /* right & left operand : check the cseSet */
2070 /* to see if they have been replaced if yes */
2071 /* then replace them with those from cseSet */
2073 /* and left is a symbol */
2074 if (IS_SYMOP (IC_LEFT (ic)) &&
2075 !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
2076 !computeOnly && ic->op != ADDRESS_OF)
2080 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2083 if (POINTER_GET (ic))
2085 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2087 /* some non dominating block does POINTER_SET with
2088 this variable .. unsafe to remove any POINTER_GETs */
2089 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
2090 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
2091 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2094 /* check if there is a pointer set
2095 for the same pointer visible if yes
2096 then change this into an assignment */
2098 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2099 !bitVectBitValue (ebb->ptrsSet, pdop->key))
2102 IC_LEFT (ic) = NULL;
2103 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2104 SET_ISADDR (IC_RESULT (ic), 0);
2110 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2117 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2121 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2123 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2128 /* if left or right changed then do algebraic */
2129 if (!computeOnly && change)
2131 algebraicOpts (ic, ebb);
2132 while (constFold (ic, cseSet));
2135 /* if after all this it becomes an assignment to self
2136 then delete it and continue */
2137 if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
2139 remiCodeFromeBBlock (ebb, ic);
2143 /* now we will check to see if the entire */
2144 /* operation has been performed before */
2145 /* and is available */
2146 /* don't do assignments they will be killed */
2147 /* by dead code elimination if required do */
2148 /* it only if result is a temporary */
2150 if (!(POINTER_GET (ic) &&
2151 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2152 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2153 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2155 IS_ITEMP (IC_RESULT (ic)) &&
2158 applyToSet (cseSet, findPrevIc, ic, &pdic);
2159 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2160 operandType (IC_RESULT (ic))) != 1)
2162 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2166 /* Alternate code */
2167 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2168 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2169 /* Mmm, found an equivalent pointer get at a lower level.
2170 This could be a loop however with the same pointer set
2173 /* if previous definition found change this to an assignment */
2176 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2177 SET_ISADDR(IC_RESULT(ic),0);
2178 SET_ISADDR(IC_RIGHT (ic),0);
2182 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2184 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2185 csed = newCseDef (IC_RESULT (ic), ic);
2186 updateCseDefAncestors (csed, cseSet);
2187 addSetHead (&cseSet, csed);
2191 /* if assignment to a parameter which is not
2192 mine and type is a pointer then delete
2193 pointerGets to take care of aliasing */
2194 if (ASSIGNMENT (ic) &&
2195 IS_SYMOP (IC_RESULT (ic)) &&
2196 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2197 IS_PTR (operandType (IC_RESULT (ic))))
2199 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2200 for (i = 0; i < count; ebbs[i++]->visited = 0);
2201 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2202 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2205 /* if this is a pointerget then see if we can replace
2206 this with a previously assigned pointer value */
2207 if (POINTER_GET (ic) &&
2208 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2209 isOperandVolatile (IC_LEFT (ic), TRUE)))
2212 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2213 /* if we find it then locally replace all
2214 references to the result with what we assigned */
2217 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2221 /* delete from the cseSet anything that has */
2222 /* operands matching the result of this */
2223 /* except in case of pointer access */
2224 if (!(POINTER_SET (ic)) && IS_SYMOP (IC_RESULT (ic)))
2226 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2227 /* delete any previous definitions */
2228 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2231 /* add the left & right to the defUse set */
2232 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2234 OP_USES(IC_LEFT (ic))=
2235 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2236 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2239 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2241 OP_USES(IC_RIGHT (ic))=
2242 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2243 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2246 /* for the result it is special case, put the result */
2247 /* in the defuseSet if it a pointer or array access */
2248 if (POINTER_SET (defic) && IS_SYMOP (IC_RESULT (ic)))
2250 OP_USES(IC_RESULT (ic))=
2251 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2252 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2253 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2254 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2255 /* delete from inexpressions of all successors which
2256 have dfNum > than this block */
2257 for (i = 0; i < count; ebbs[i++]->visited = 0);
2258 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2260 /* delete from cseSet all other pointer sets
2262 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2263 /* add to the local pointerset set */
2264 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2268 /* add the result to definition set */
2269 if (IS_SYMOP (IC_RESULT (ic)))
2271 OP_DEFS(IC_RESULT (ic))=
2272 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2273 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2274 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2275 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2279 /* if this is an addressof instruction then */
2280 /* put the symbol in the address of list & */
2281 /* delete it from the cseSet */
2282 if (defic->op == ADDRESS_OF)
2284 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2285 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2289 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2290 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2291 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2292 addSetHead (&ebb->killedExprs, expr);
2294 setToNull ((void *) &ebb->outExprs);
2295 ebb->outExprs = cseSet;
2296 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2297 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2301 /*-----------------------------------------------------------------*/
2302 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2303 /*-----------------------------------------------------------------*/
2305 cseAllBlocks (ebbIndex * ebbi, int computeOnly)
2307 eBBlock ** ebbs = ebbi->dfOrder;
2308 int count = ebbi->count;
2312 /* if optimization turned off */
2314 for (i = 0; i < count; i++)
2315 change += cseBBlock (ebbs[i], computeOnly, ebbi);