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->lineno = ic->lineno;
1139 addiCodeToeBBlock (ebp, newic, ic->next);
1142 IC_LEFT (ic) = NULL;
1143 SET_RESULT_RIGHT (ic);
1146 /* swap literal to right ic */
1147 if (IS_OP_LITERAL (IC_LEFT (ic)))
1152 IC_LEFT (ic) = IC_RIGHT (ic);
1155 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1157 /* if BITWISEAND then check if one of them is a zero */
1158 /* if yes turn it into 0 assignment */
1159 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1161 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1163 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1164 IC_RESULT (newic) = IC_LEFT (ic);
1165 newic->lineno = ic->lineno;
1166 addiCodeToeBBlock (ebp, newic, ic->next);
1169 IC_LEFT (ic) = NULL;
1170 SET_RESULT_RIGHT (ic);
1173 /* if BITWISEAND then check if one of them is 0xff... */
1174 /* if yes turn it into assignment */
1178 switch (getSize (operandType (IC_RIGHT (ic))))
1192 if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
1195 IC_RIGHT (ic) = IC_LEFT (ic);
1196 IC_LEFT (ic) = NULL;
1197 SET_RESULT_RIGHT (ic);
1204 /* if both operands are equal */
1205 /* if yes turn it into assignment */
1206 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1208 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1210 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1211 IC_RESULT (newic) = IC_LEFT (ic);
1212 newic->lineno = ic->lineno;
1213 addiCodeToeBBlock (ebp, newic, ic->next);
1216 IC_LEFT (ic) = NULL;
1217 SET_RESULT_RIGHT (ic);
1220 /* swap literal to right ic */
1221 if (IS_OP_LITERAL (IC_LEFT (ic)))
1226 IC_LEFT (ic) = IC_RIGHT (ic);
1229 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1231 /* if BITWISEOR then check if one of them is a zero */
1232 /* if yes turn it into assignment */
1233 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1236 IC_RIGHT (ic) = IC_LEFT (ic);
1237 IC_LEFT (ic) = NULL;
1238 SET_RESULT_RIGHT (ic);
1241 /* if BITWISEOR then check if one of them is 0xff... */
1242 /* if yes turn it into 0xff... assignment */
1246 switch (getSize (operandType (IC_RIGHT (ic))))
1260 if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
1262 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1264 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1265 IC_RESULT (newic) = IC_LEFT (ic);
1266 newic->lineno = ic->lineno;
1267 addiCodeToeBBlock (ebp, newic, ic->next);
1270 IC_LEFT (ic) = NULL;
1271 SET_RESULT_RIGHT (ic);
1278 /* if both operands are equal */
1279 /* if yes turn it into 0 assignment */
1280 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1282 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1284 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1285 IC_RESULT (newic) = IC_LEFT (ic);
1286 newic->lineno = ic->lineno;
1287 addiCodeToeBBlock (ebp, newic, ic->next);
1289 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1290 IC_RESULT (newic) = IC_LEFT (ic);
1291 newic->lineno = ic->lineno;
1292 addiCodeToeBBlock (ebp, newic, ic->next);
1295 IC_RIGHT (ic) = operandFromLit (0);
1296 IC_LEFT (ic) = NULL;
1297 SET_RESULT_RIGHT (ic);
1300 /* swap literal to right ic */
1301 if (IS_OP_LITERAL (IC_LEFT (ic)))
1306 IC_LEFT (ic) = IC_RIGHT (ic);
1309 /* if XOR then check if one of them is a zero */
1310 /* if yes turn it into assignment */
1311 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1313 if (operandLitValue (IC_RIGHT (ic)) == 0.0)
1316 IC_RIGHT (ic) = IC_LEFT (ic);
1317 IC_LEFT (ic) = NULL;
1318 SET_RESULT_RIGHT (ic);
1327 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1328 /*-----------------------------------------------------------------*/
1329 /* updateSpillLocation - keeps track of register spill location */
1330 /*-----------------------------------------------------------------*/
1332 updateSpillLocation (iCode * ic, int induction)
1336 if (POINTER_SET (ic))
1343 /* for the form true_symbol := iTempNN */
1344 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1345 !SPIL_LOC (IC_RIGHT (ic))) {
1347 setype = getSpec (operandType (IC_RESULT (ic)));
1349 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1350 !IS_VOLATILE (setype) &&
1351 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1352 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1354 wassert(IS_SYMOP(IC_RESULT (ic)));
1355 wassert(IS_SYMOP(IC_RIGHT (ic)));
1356 SPIL_LOC (IC_RIGHT (ic)) =
1357 IC_RESULT (ic)->operand.symOperand;
1363 #if 0 /* this needs furthur investigation can save a lot of code */
1364 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1365 !SPIL_LOC(IC_RESULT(ic))) {
1366 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1367 SPIL_LOC (IC_RESULT (ic)) =
1368 IC_RIGHT (ic)->operand.symOperand;
1371 if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
1373 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1374 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1375 OP_SYMBOL (IC_RESULT (ic))->isreqv) {
1377 setype = getSpec (operandType (IC_RESULT (ic)));
1379 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1380 !IS_VOLATILE (setype) &&
1381 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1382 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) {
1384 SPIL_LOC (IC_RIGHT (ic)) =
1385 SPIL_LOC (IC_RESULT (ic));
1386 OP_SYMBOL (IC_RIGHT (ic))->prereqv =
1387 OP_SYMBOL (IC_RESULT (ic))->prereqv;
1390 /* special case for inductions */
1392 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1393 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1394 !SPIL_LOC(IC_RESULT(ic))) {
1395 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1396 OP_SYMBOL (IC_RESULT (ic))->prereqv =
1397 OP_SYMBOL (IC_RIGHT (ic))->prereqv;
1401 /*-----------------------------------------------------------------*/
1402 /* setUsesDef - sets the uses def bitvector for a given operand */
1403 /*-----------------------------------------------------------------*/
1405 setUsesDefs (operand * op, bitVect * bdefs,
1406 bitVect * idefs, bitVect ** oud)
1408 /* compute the definitions alive at this point */
1409 bitVect *adefs = bitVectUnion (bdefs, idefs);
1411 /* of these definitions find the ones that are */
1412 /* for this operand */
1413 adefs = bitVectIntersect (adefs, OP_DEFS (op));
1415 /* these are the definitions that this operand can use */
1416 op->usesDefs = adefs;
1418 /* the out defs is an union */
1419 *oud = bitVectUnion (*oud, adefs);
1422 /*-----------------------------------------------------------------*/
1423 /* unsetDefsAndUses - clear this operation for the operands */
1424 /*-----------------------------------------------------------------*/
1426 unsetDefsAndUses (iCode * ic)
1428 if (ic->op == JUMPTABLE)
1431 /* take away this definition from the def chain of the */
1432 /* result & take away from use set of the operands */
1435 /* turn off def set */
1436 if (IS_SYMOP (IC_RESULT (ic)))
1438 if (!POINTER_SET (ic))
1439 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1441 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1443 /* turn off the useSet for the operands */
1444 if (IS_SYMOP (IC_LEFT (ic)))
1445 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1447 if (IS_SYMOP (IC_RIGHT (ic)))
1448 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1451 /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
1452 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1455 /*-----------------------------------------------------------------*/
1456 /* ifxOptimize - changes ifx conditions if it can */
1457 /*-----------------------------------------------------------------*/
1459 ifxOptimize (iCode * ic, set * cseSet,
1461 eBBlock * ebb, int *change,
1467 /* if the condition can be replaced */
1471 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1474 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1479 /* if the conditional is a literal then */
1480 if (IS_OP_LITERAL (IC_COND (ic)))
1483 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1486 /* change to a goto */
1488 IC_LABEL (ic) = IC_TRUE (ic);
1495 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1498 IC_LABEL (ic) = IC_FALSE (ic);
1504 /* then kill this if condition */
1505 remiCodeFromeBBlock (ebb, ic);
1509 /* now we need to recompute the control flow */
1510 /* since the control flow has changed */
1511 /* this is very expensive but it does not happen */
1512 /* too often, if it does happen then the user pays */
1514 computeControlFlow (ebbi);
1515 if (!options.lessPedantic) {
1516 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1521 /* if there is only one successor and that successor
1522 is the same one we are conditionally going to then
1523 we can remove this conditional statement */
1524 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1525 if (elementsInSet (ebb->succList) == 1 &&
1526 isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
1529 if (!options.lessPedantic) {
1530 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1532 if (IS_OP_VOLATILE (IC_COND (ic)))
1534 IC_RIGHT (ic) = IC_COND (ic);
1535 IC_LEFT (ic) = NULL;
1536 IC_RESULT (ic) = NULL;
1537 ic->op = DUMMY_READ_VOLATILE;
1541 remiCodeFromeBBlock (ebb, ic);
1542 computeControlFlow (ebbi);
1548 /* if it remains an IFX the update the use Set */
1551 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1552 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1554 else if (ic->op == DUMMY_READ_VOLATILE)
1556 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1557 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1562 /*-----------------------------------------------------------------*/
1563 /* diCodeForSym - finds the definiting instruction for a symbol */
1564 /*-----------------------------------------------------------------*/
1565 DEFSETFUNC (diCodeForSym)
1568 V_ARG (operand *, sym);
1569 V_ARG (iCode **, dic);
1571 /* if already found */
1575 /* if not if this is the defining iCode */
1576 if (sym->key == cdp->key)
1585 /*-----------------------------------------------------------------*/
1586 /* constFold - does some constant folding */
1587 /*-----------------------------------------------------------------*/
1589 constFold (iCode * ic, set * cseSet)
1593 /* this routine will change
1599 /* deal with only + & - */
1600 if (ic->op != '+' &&
1604 /* this check is a heuristic to prevent live ranges
1605 from becoming too long */
1606 if (IS_PTR (operandType (IC_RESULT (ic))))
1609 /* check if operation with a literal */
1610 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1613 /* check if we can find a definition for the
1615 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1618 /* check that this is also a +/- */
1619 if (dic->op != '+' && dic->op != '-')
1622 /* with a literal */
1623 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1626 /* find the definition of the left operand
1627 of dic.then check if this defined with a
1628 get_pointer return 0 if the pointer size is
1629 less than 2 (MCS51 specific) */
1630 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1633 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1636 /* it is if the operations are the same */
1637 /* the literal parts need to be added */
1638 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1639 if (ic->op == dic->op)
1640 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1641 operandLitValue (IC_RIGHT (dic)));
1643 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1644 operandLitValue (IC_RIGHT (dic)));
1646 if (IS_ITEMP (IC_RESULT (ic)))
1648 SPIL_LOC (IC_RESULT (ic)) = NULL;
1649 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1656 /*-----------------------------------------------------------------*/
1657 /* deleteGetPointers - called when a pointer is passed as parm */
1658 /* will delete from cseSet all get pointers computed from this */
1659 /* pointer. A simple ifOperandsHave is not good enough here */
1660 /*-----------------------------------------------------------------*/
1662 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
1664 set *compItems = NULL;
1670 if (!*cseSet && !*pss)
1673 addSet (&compItems, op);
1675 /* Recursively find all items computed from this operand .
1676 This done fairly simply go thru the list and find
1677 those that are computed by arthimetic with these
1679 /* Also check for those computed from our computed
1680 list . This will take care of situations like
1681 iTemp1 = iTemp0 + 8;
1682 iTemp2 = iTemp1 + 8; */
1686 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
1688 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
1690 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
1691 (insetwithFunc)isOperandEqual) ||
1692 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
1693 (insetwithFunc)isOperandEqual))
1695 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
1696 (insetwithFunc)isOperandEqual))
1698 addSet (&compItems, IC_RESULT (cdp->diCode));
1707 /* now for the computed items */
1708 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
1710 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
1711 deleteItemIf (cseSet, ifPointerGet, cop);
1712 deleteItemIf (cseSet, ifDefSymIsX, cop);
1713 deleteItemIf (pss, ifPointerSet, cop);
1717 /*-----------------------------------------------------------------*/
1718 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
1719 /* dfnum > supplied */
1720 /*-----------------------------------------------------------------*/
1721 DEFSETFUNC (delGetPointerSucc)
1723 eBBlock *ebp = item;
1724 V_ARG (operand *, op);
1731 if (ebp->dfnum > dfnum)
1733 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
1736 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
1739 /*-----------------------------------------------------------------*/
1740 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
1741 /*-----------------------------------------------------------------*/
1743 fixUpTypes (iCode * ic)
1745 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
1747 /* if (TARGET_IS_DS390) */
1748 if (options.model == MODEL_FLAT24)
1754 /* for pointer_gets if the types of result & left r the
1755 same then change it type of result to next */
1757 compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
1759 setOperandType (IC_RESULT (ic), t2->next);
1763 /*-----------------------------------------------------------------*/
1764 /* isSignedOp - will return 1 if sign is important to operation */
1765 /*-----------------------------------------------------------------*/
1766 static int isSignedOp (iCode *ic)
1787 case GET_VALUE_AT_ADDRESS:
1818 dumpCseSet(set *cseSet)
1822 cseDef *item=cseSet->item;
1824 printOperand (item->sym, NULL);
1826 piCode (item->diCode, NULL);
1827 cseSet = cseSet->next;
1832 /*-----------------------------------------------------------------*/
1833 /* cseBBlock - common subexpression elimination for basic blocks */
1834 /* this is the hackiest kludgiest routine in the whole */
1835 /* system. also the most important, since almost all */
1836 /* data flow related information is computed by it */
1837 /*-----------------------------------------------------------------*/
1839 cseBBlock (eBBlock * ebb, int computeOnly,
1842 eBBlock ** ebbs = ebbi->bbOrder;
1843 int count = ebbi->count;
1848 set *ptrSetSet = NULL;
1851 /* if this block is not reachable */
1855 /* set of common subexpressions */
1856 cseSet = setFromSet (ebb->inExprs);
1858 /* these will be computed by this routine */
1859 setToNull ((void *) &ebb->outDefs);
1860 setToNull ((void *) &ebb->defSet);
1861 setToNull ((void *) &ebb->usesDefs);
1862 setToNull ((void *) &ebb->ptrsSet);
1863 setToNull ((void *) &ebb->addrOf);
1864 setToNull ((void *) &ebb->ldefs);
1866 ebb->outDefs = bitVectCopy (ebb->inDefs);
1867 bitVectDefault = iCodeKey;
1868 ebb->defSet = newBitVect (iCodeKey);
1869 ebb->usesDefs = newBitVect (iCodeKey);
1871 /* for all the instructions in this block do */
1872 for (ic = ebb->sch; ic; ic = ic->next)
1879 ic->eBBlockNum = ebb->bbnum;
1884 /* if this is an assignment from true symbol
1885 to a temp then do pointer post inc/dec optimzation */
1886 if (ic->op == '=' && !POINTER_SET (ic) &&
1887 IS_PTR (operandType (IC_RESULT (ic))))
1889 ptrPostIncDecOpt (ic);
1892 /* clear the def & use chains for the operands involved */
1893 /* in this operation . since it can change due to opts */
1894 unsetDefsAndUses (ic);
1896 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
1898 /* add to defSet of the symbol */
1899 OP_DEFS(IC_RESULT (ic))=
1900 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1901 /* add to the definition set of this block */
1902 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
1903 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
1904 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
1905 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1906 /* delete global variables from the cseSet
1907 since they can be modified by the function call */
1908 deleteItemIf (&cseSet, ifDefGlobal);
1910 /* and also iTemps derived from globals */
1911 deleteItemIf (&cseSet, ifFromGlobal);
1913 /* Delete iTemps derived from symbols whose address */
1914 /* has been taken */
1915 deleteItemIf (&cseSet, ifFromAddrTaken);
1917 /* delete all getpointer iCodes from cseSet, this should
1918 be done only for global arrays & pointers but at this
1919 point we don't know if globals, so to be safe do all */
1920 deleteItemIf (&cseSet, ifAnyGetPointer);
1922 /* can't cache pointer set/get operations across a call */
1923 deleteSet (&ptrSetSet);
1926 /* for pcall & ipush we need to add to the useSet */
1927 if ((ic->op == PCALL ||
1931 IS_SYMOP (IC_LEFT (ic)))
1934 /* check if they can be replaced */
1938 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
1940 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
1942 /* the lookup could have changed it */
1943 if (IS_SYMOP (IC_LEFT (ic)))
1945 OP_USES(IC_LEFT (ic))=
1946 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1947 setUsesDefs (IC_LEFT (ic), ebb->defSet,
1948 ebb->outDefs, &ebb->usesDefs);
1952 /* if we a sending a pointer as a parameter
1953 then kill all cse since the pointed to item
1954 might be changed in the function being called */
1955 if ((ic->op == IPUSH || ic->op == SEND) &&
1956 IS_PTR (operandType (IC_LEFT (ic))))
1958 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
1959 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
1960 for (i = 0; i < count; ebbs[i++]->visited = 0);
1961 applyToSet (ebb->succList, delGetPointerSucc,
1962 IC_LEFT (ic), ebb->dfnum);
1967 /* if jumptable then mark the usage */
1968 if (ic->op == JUMPTABLE)
1970 if (IS_SYMOP (IC_JTCOND (ic)))
1972 OP_USES(IC_JTCOND (ic)) =
1973 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
1974 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
1975 ebb->outDefs, &ebb->usesDefs);
1985 /* do some algebraic optimizations if possible */
1986 algebraicOpts (ic, ebb);
1987 while (constFold (ic, cseSet));
1991 if (POINTER_GET (ic))
1993 if (!IS_PTR (operandType (IC_LEFT (ic))))
1995 setOperandType (IC_LEFT (ic),
1996 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
1997 IC_LEFT (ic)->aggr2ptr = 0;
2000 else if (IC_LEFT (ic)->aggr2ptr == 1)
2001 {/* band aid for kludge */
2002 setOperandType (IC_LEFT (ic),
2003 aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
2004 IC_LEFT (ic)->aggr2ptr++;
2009 if (POINTER_SET (ic))
2011 if (!IS_PTR (operandType (IC_RESULT (ic))))
2013 setOperandType (IC_RESULT (ic),
2014 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2015 IC_RESULT (ic)->aggr2ptr = 0;
2017 else if (IC_RESULT (ic)->aggr2ptr == 1)
2018 {/* band aid for kludge */
2019 setOperandType (IC_RESULT (ic),
2020 aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2021 IC_RESULT (ic)->aggr2ptr++;
2025 /* if this is a condition statement then */
2026 /* check if the condition can be replaced */
2029 ifxOptimize (ic, cseSet, computeOnly,
2035 /* if the assignment & result is a temp */
2036 /* see if we can replace it */
2037 if (!computeOnly && ic->op == '=')
2040 /* update the spill location for this */
2041 updateSpillLocation (ic,0);
2043 if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)) &&
2044 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
2047 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
2048 if (pdop && !computeOnly && IS_ITEMP (pdop))
2050 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
2051 if (!IS_PTR (operandType (IC_RESULT (ic))))
2053 setOperandType (IC_RESULT (ic),
2054 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2060 checkSign = isSignedOp(ic);
2062 /* do the operand lookup i.e. for both the */
2063 /* right & left operand : check the cseSet */
2064 /* to see if they have been replaced if yes */
2065 /* then replace them with those from cseSet */
2067 /* and left is a symbol */
2068 if (IS_SYMOP (IC_LEFT (ic)) &&
2069 !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
2070 !computeOnly && ic->op != ADDRESS_OF)
2074 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2077 if (POINTER_GET (ic))
2079 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2081 /* some non dominating block does POINTER_SET with
2082 this variable .. unsafe to remove any POINTER_GETs */
2083 if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
2084 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
2085 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2088 /* check if there is a pointer set
2089 for the same pointer visible if yes
2090 then change this into an assignment */
2092 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2093 !bitVectBitValue (ebb->ptrsSet, pdop->key))
2096 IC_LEFT (ic) = NULL;
2097 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2098 SET_ISADDR (IC_RESULT (ic), 0);
2104 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2111 if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
2115 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2117 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
2122 /* if left or right changed then do algebraic */
2123 if (!computeOnly && change)
2125 algebraicOpts (ic, ebb);
2126 while (constFold (ic, cseSet));
2129 /* if after all this it becomes an assignment to self
2130 then delete it and continue */
2131 if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
2133 remiCodeFromeBBlock (ebb, ic);
2137 /* now we will check to see if the entire */
2138 /* operation has been performed before */
2139 /* and is available */
2140 /* don't do assignments they will be killed */
2141 /* by dead code elimination if required do */
2142 /* it only if result is a temporary */
2144 if (!(POINTER_GET (ic) &&
2145 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2146 isOperandVolatile (IC_LEFT (ic), TRUE) ||
2147 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2149 IS_ITEMP (IC_RESULT (ic)) &&
2152 applyToSet (cseSet, findPrevIc, ic, &pdic);
2153 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2154 operandType (IC_RESULT (ic))) != 1)
2156 if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
2160 /* Alternate code */
2161 if (pdic && IS_ITEMP(IC_RESULT(ic))) {
2162 if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
2163 /* Mmm, found an equivalent pointer get at a lower level.
2164 This could be a loop however with the same pointer set
2167 /* if previous definition found change this to an assignment */
2170 IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
2171 SET_ISADDR(IC_RESULT(ic),0);
2172 SET_ISADDR(IC_RIGHT (ic),0);
2176 if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
2178 deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
2179 csed = newCseDef (IC_RESULT (ic), ic);
2180 updateCseDefAncestors (csed, cseSet);
2181 addSetHead (&cseSet, csed);
2185 /* if assignment to a parameter which is not
2186 mine and type is a pointer then delete
2187 pointerGets to take care of aliasing */
2188 if (ASSIGNMENT (ic) &&
2189 IS_SYMOP (IC_RESULT (ic)) &&
2190 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2191 IS_PTR (operandType (IC_RESULT (ic))))
2193 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2194 for (i = 0; i < count; ebbs[i++]->visited = 0);
2195 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2196 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2199 /* if this is a pointerget then see if we can replace
2200 this with a previously assigned pointer value */
2201 if (POINTER_GET (ic) &&
2202 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2203 isOperandVolatile (IC_LEFT (ic), TRUE)))
2206 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2207 /* if we find it then locally replace all
2208 references to the result with what we assigned */
2211 replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
2215 /* delete from the cseSet anything that has */
2216 /* operands matching the result of this */
2217 /* except in case of pointer access */
2218 if (!(POINTER_SET (ic)) && IS_SYMOP (IC_RESULT (ic)))
2220 deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
2221 /* delete any previous definitions */
2222 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2225 /* add the left & right to the defUse set */
2226 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2228 OP_USES(IC_LEFT (ic))=
2229 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2230 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2233 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2235 OP_USES(IC_RIGHT (ic))=
2236 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2237 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2240 /* for the result it is special case, put the result */
2241 /* in the defuseSet if it a pointer or array access */
2242 if (POINTER_SET (defic) && IS_SYMOP (IC_RESULT (ic)))
2244 OP_USES(IC_RESULT (ic))=
2245 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2246 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2247 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2248 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2249 /* delete from inexpressions of all successors which
2250 have dfNum > than this block */
2251 for (i = 0; i < count; ebbs[i++]->visited = 0);
2252 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2254 /* delete from cseSet all other pointer sets
2256 deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
2257 /* add to the local pointerset set */
2258 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2262 /* add the result to definition set */
2263 if (IS_SYMOP (IC_RESULT (ic)))
2265 OP_DEFS(IC_RESULT (ic))=
2266 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2267 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2268 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2269 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2273 /* if this is an addressof instruction then */
2274 /* put the symbol in the address of list & */
2275 /* delete it from the cseSet */
2276 if (defic->op == ADDRESS_OF)
2278 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2279 deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
2283 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2284 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2285 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
2286 addSetHead (&ebb->killedExprs, expr);
2288 setToNull ((void *) &ebb->outExprs);
2289 ebb->outExprs = cseSet;
2290 ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
2291 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
2295 /*-----------------------------------------------------------------*/
2296 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2297 /*-----------------------------------------------------------------*/
2299 cseAllBlocks (ebbIndex * ebbi, int computeOnly)
2301 eBBlock ** ebbs = ebbi->dfOrder;
2302 int count = ebbi->count;
2306 /* if optimization turned off */
2308 for (i = 0; i < count; i++)
2309 change += cseBBlock (ebbs[i], computeOnly, ebbi);