Update svn merge history.
[sdcc.git] / sdcc / src / SDCCcse.c
blobeda5c6eaba17fb0b560d5d8fe8b409f935656be7
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
9 later version.
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 -------------------------------------------------------------------------*/
25 #include "common.h"
26 #include "newalloc.h"
27 #include "dbuf_string.h"
29 /*-----------------------------------------------------------------*/
30 /* newCseDef - new cseDef */
31 /*-----------------------------------------------------------------*/
32 cseDef *
33 newCseDef (operand * sym, iCode * ic)
35 cseDef *cdp;
36 memmap *map;
38 assert (sym);
39 cdp = Safe_alloc (sizeof (cseDef));
41 cdp->sym = sym;
42 cdp->diCode = ic;
43 cdp->key = sym->key;
44 cdp->ancestors = newBitVect(operandKey);
45 cdp->fromGlobal = 0;
46 cdp->fromAddrTaken = 0;
48 if (ic->op != IF && ic->op != JUMPTABLE)
50 if (ic->op != ADDRESS_OF && IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
52 bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
53 if (isOperandGlobal (IC_LEFT (ic)))
55 map = SPEC_OCLS (getSpec (operandType (IC_LEFT (ic))));
56 if (map)
57 cdp->fromGlobal |= (1 << map->ptrType);
59 cdp->fromAddrTaken |= OP_SYMBOL (IC_LEFT (ic))->addrtaken;
61 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
63 bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
64 if (isOperandGlobal (IC_RIGHT (ic)))
66 map = SPEC_OCLS (getSpec (operandType (IC_RIGHT (ic))));
67 if (map)
68 cdp->fromGlobal |= (1 << map->ptrType);
70 cdp->fromAddrTaken |= OP_SYMBOL (IC_RIGHT (ic))->addrtaken;
74 return cdp;
77 void
78 freeLocalCseDef (void *item)
80 cseDef * cse = (cseDef *)item;
82 /* If this CSE definition being deleted is not visible outside */
83 /* its defining eBBlock, we can safely deallocate it completely */
84 if (!cse->nonLocalCSE)
86 freeBitVect(cse->ancestors);
87 Safe_free(cse);
92 void
93 updateCseDefAncestors(cseDef *cdp, set * cseSet)
95 cseDef *loop;
96 set *sl;
97 iCode *ic = cdp->diCode;
99 if (ic->op!=IF && ic->op!=JUMPTABLE)
101 if (ic->op != ADDRESS_OF && IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
103 bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
104 for (sl = cseSet; sl; sl = sl->next)
106 loop = sl->item;
107 if (loop->sym->key == IC_LEFT (ic)->key)
109 cdp->ancestors = bitVectInplaceUnion (cdp->ancestors, loop->ancestors);
110 cdp->fromGlobal |= loop->fromGlobal;
111 cdp->fromAddrTaken |= loop->fromAddrTaken;
112 break;
116 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
118 bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
119 for (sl = cseSet; sl; sl = sl->next)
121 loop = sl->item;
122 if (loop->sym->key == IC_RIGHT (ic)->key)
124 cdp->ancestors = bitVectInplaceUnion (cdp->ancestors, loop->ancestors);
125 cdp->fromGlobal |= loop->fromGlobal;
126 cdp->fromAddrTaken |= loop->fromAddrTaken;
127 break;
135 /*-----------------------------------------------------------------*/
136 /* int isCseDefEqual - two definitions are equal */
137 /*-----------------------------------------------------------------*/
139 isCseDefEqual (void *vsrc, void *vdest)
141 cseDef *src = vsrc;
142 cseDef *dest = vdest;
144 if (src == dest)
145 return 1;
147 return (src->key == dest->key &&
148 src->diCode == dest->diCode);
151 /*-----------------------------------------------------------------*/
152 /* pcseDef - in the cseDef */
153 /*-----------------------------------------------------------------*/
155 pcseDef (void *item, va_list ap)
157 cseDef *cdp = item;
158 iCodeTable *icTab;
159 struct dbuf_s dbuf;
161 (void) ap;
163 if (!cdp->sym)
164 fprintf (stdout, "**null op**");
165 printOperand (cdp->sym, stdout);
166 icTab = getTableEntry (cdp->diCode->op);
167 dbuf_init (&dbuf, 1024);
168 icTab->iCodePrint (&dbuf, cdp->diCode, icTab->printName);
169 dbuf_write_and_destroy (&dbuf, stdout);
170 return 1;
173 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
174 #ifdef RANGEHUNT
175 printf ("ReplaceOpWithCheaperOp\n\t");
176 printOperand (*op, stdout);
177 printf ("\nwith\t");
178 printOperand (cop, stdout);
180 // if op is a register equivalent
181 if (IS_ITEMP(cop) && IS_SYMOP((*op)) && OP_SYMBOL((*op))->isreqv) {
182 operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
183 if (isOperandEqual(*rop, *op)) {
184 printf ("true");
185 *rop=cop;
186 OP_SYMBOL((*op))->isreqv=0;
187 OP_SYMBOL(cop)->isreqv=1;
188 } else {
189 printf ("false");
192 printf ("\n");
193 #endif
194 *op=cop;
197 /*-----------------------------------------------------------------*/
198 /* replaceAllSymBySym - replaces all operands by operand in an */
199 /* instruction chain */
200 /*-----------------------------------------------------------------*/
201 void
202 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
204 iCode *lic;
206 #ifdef RANGEHUNT
207 printf ("replaceAllSymBySym\n\t");
208 printOperand (from, stdout);
209 printf ("\nwith\t");
210 printOperand (to, stdout);
211 printf ("\n");
212 #endif
213 for (lic = ic; lic; lic = lic->next)
215 int isaddr;
217 if (IS_SYMOP(to) &&
218 IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
220 /* maintain du chains */
221 if (POINTER_SET (lic))
223 bitVectUnSetBit (OP_USES (from), lic->key);
224 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
226 /* also check if the "from" was in the non-dominating
227 pointer sets and replace it with "to" in the bitVector */
228 if (bitVectBitValue (*ndpset, from->key))
230 bitVectUnSetBit (*ndpset, from->key);
231 bitVectSetBit (*ndpset, to->key);
235 else
237 bitVectUnSetBit (OP_DEFS (from), lic->key);
238 OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
240 isaddr = IC_RESULT (lic)->isaddr;
241 IC_RESULT (lic) = operandFromOperand (to);
242 IC_RESULT (lic)->isaddr = isaddr;
245 if (IS_SYMOP (to) &&
246 IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
248 bitVectUnSetBit (OP_USES (from), lic->key);
249 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
250 isaddr = IC_RIGHT (lic)->isaddr;
251 IC_RIGHT (lic) = operandFromOperand (to);
252 IC_RIGHT (lic)->isaddr = isaddr;
255 if (IS_SYMOP (to) &&
256 IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
258 bitVectUnSetBit (OP_USES (from), lic->key);
259 OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
260 isaddr = IC_LEFT (lic)->isaddr;
261 IC_LEFT (lic) = operandFromOperand (to);
262 IC_LEFT (lic)->isaddr = isaddr;
267 /*-----------------------------------------------------------------*/
268 /* iCodeKeyIs - if the icode keys match then return 1 */
269 /*-----------------------------------------------------------------*/
270 DEFSETFUNC (iCodeKeyIs)
272 cseDef *cdp = item;
273 V_ARG (int, key);
275 if (cdp->diCode->key == key)
276 return 1;
277 else
278 return 0;
281 /*-----------------------------------------------------------------*/
282 /* removeFromInExprs - removes an icode from inexpressions */
283 /*-----------------------------------------------------------------*/
284 DEFSETFUNC (removeFromInExprs)
286 eBBlock *ebp = item;
287 V_ARG (iCode *, ic);
288 V_ARG (operand *, from);
289 V_ARG (operand *, to);
290 V_ARG (eBBlock *, cbp);
292 if (ebp->visited)
293 return 0;
295 ebp->visited = 1;
296 deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
297 if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
298 replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
300 applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
301 return 0;
304 /*-----------------------------------------------------------------*/
305 /* isGlobalInNearSpace - return TRUE if variable is a globalin data */
306 /*-----------------------------------------------------------------*/
307 static bool
308 isGlobalInNearSpace (operand * op)
310 sym_link *type = getSpec (operandType (op));
311 /* this is 8051 specific: optimization
312 suggested by Jean-Louis VERN, with 8051s we have no
313 advantage of putting variables in near space into
314 registers */
315 if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
316 IN_DIRSPACE (SPEC_OCLS (type)))
317 return TRUE;
318 else
319 return FALSE;
322 /*-----------------------------------------------------------------*/
323 /* findCheaperOp - cseBBlock support routine, will check to see if */
324 /* we have a operand previously defined */
325 /*-----------------------------------------------------------------*/
326 DEFSETFUNC (findCheaperOp)
328 cseDef *cdp = item;
329 V_ARG (operand *, cop);
330 V_ARG (operand **, opp);
331 V_ARG (int, checkSign);
333 /* if we have already found it */
334 if (*opp)
335 return 1;
337 /* not found it yet check if this is the one */
338 /* and this is not the defining one */
339 if (cop->key && cop->key == cdp->key)
341 /* do a special check this will help in */
342 /* constant propagation & dead code elim */
343 /* for assignments only */
344 if (cdp->diCode->op == '=')
346 /* if the result is volatile then return result */
347 if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
349 *opp = IC_RESULT (cdp->diCode);
351 else
353 /* if this is a straight assignment and
354 left is a temp then prefer the temporary to the
355 true symbol */
356 if (!POINTER_SET (cdp->diCode) &&
357 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
358 IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
360 *opp = IC_RESULT (cdp->diCode);
362 else
364 /* if straight assignment and both
365 are temps then prefer the one that
366 will not need extra space to spil, also
367 take into consideration if right side
368 is an induction variable
370 if (!POINTER_SET (cdp->diCode) &&
371 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
372 IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
373 !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
374 !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
375 ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) && SPIL_LOC (IC_RESULT (cdp->diCode))) ||
376 (SPIL_LOC (IC_RESULT (cdp->diCode)) && SPIL_LOC (IC_RESULT (cdp->diCode)) == SPIL_LOC (IC_RIGHT (cdp->diCode)))))
378 *opp = IC_RESULT (cdp->diCode);
380 else
382 *opp = IC_RIGHT (cdp->diCode);
387 else
389 *opp = IC_RESULT (cdp->diCode);
393 /* if this is an assign to a temp. then check
394 if the right side is this then return this */
395 if (IS_TRUE_SYMOP (cop) &&
396 cdp->diCode->op == '=' &&
397 !POINTER_SET (cdp->diCode) &&
398 cop->key == IC_RIGHT (cdp->diCode)->key &&
399 !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
400 IS_ITEMP (IC_RESULT (cdp->diCode)))
402 *opp = IC_RESULT (cdp->diCode);
405 if ((*opp) &&
406 (isOperandLiteral(*opp) || !checkSign ||
407 (checkSign &&
408 IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
409 (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
410 (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
412 if ((isGlobalInNearSpace (cop) && !isOperandLiteral (*opp)) ||
413 isOperandVolatile (*opp, FALSE))
415 *opp = NULL;
416 return 0;
419 if (cop->key == (*opp)->key)
421 *opp = NULL;
422 return 0;
425 *opp = operandFromOperand (*opp);
427 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
428 (*opp)->isaddr = cop->isaddr;
430 /* copy signedness to literal operands */
431 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp))
432 && isOperandLiteral(*opp)
433 && SPEC_NOUN(operandType(*opp)) == SPEC_NOUN(operandType(cop))
434 && SPEC_USIGN(operandType(*opp)) != SPEC_USIGN(operandType(cop)))
436 SPEC_USIGN(operandType(*opp)) = SPEC_USIGN(operandType(cop));
439 if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
440 SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
442 // special case: we can make an unsigned char literal
443 // into an int literal with no cost.
444 if (isOperandLiteral(*opp) &&
445 SPEC_NOUN(operandType(*opp)) == V_CHAR &&
446 SPEC_NOUN(operandType(cop)) == V_INT)
448 SPEC_NOUN(operandType(*opp)) = V_INT;
450 // more special cases: we need this one to avoid regressions from _BOOL -> __bit optimization.
451 else if (IS_BOOL (operandType(cop)) && SPEC_NOUN(operandType(*opp)) == V_BIT)
453 SPEC_NOUN(operandType(*opp)) = V_BOOL;
455 else
457 // No clue...
458 *opp = NULL;
459 return 0;
462 return 1;
464 *opp=NULL;
465 return 0;
468 /*-----------------------------------------------------------------*/
469 /* findPointerSet - finds the right side of a pointer set op */
470 /*-----------------------------------------------------------------*/
471 DEFSETFUNC (findPointerSet)
473 cseDef *cdp = item;
474 V_ARG (operand *, op);
475 V_ARG (operand **, opp);
476 V_ARG (operand *, rop);
478 if (POINTER_SET (cdp->diCode) &&
479 op->key &&
480 IC_RESULT (cdp->diCode)->key == op->key &&
481 !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
482 !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
483 getSize (operandType (IC_RIGHT (cdp->diCode))) ==
484 getSize (operandType (rop)))
486 if (IS_SPEC (operandType (IC_RIGHT (cdp->diCode))) &&
487 SPEC_USIGN (operandType (IC_RIGHT (cdp->diCode))) !=
488 SPEC_USIGN (operandType (rop)))
490 /* bug #1493710
491 Reminder for Bernhard: check of signedness
492 could be unnecessary together with 'checkSign', if
493 signedness of operation is stored in ic */
494 return 0;
496 *opp = IC_RIGHT (cdp->diCode);
497 return 1;
500 return 0;
503 /*-----------------------------------------------------------------*/
504 /* findPrevIc - cseBBlock support function will return the iCode */
505 /* which matches the current one */
506 /*-----------------------------------------------------------------*/
507 DEFSETFUNC (findPrevIc)
509 cseDef *cdp = item;
510 V_ARG (iCode *, ic);
511 V_ARG (iCode **, icp);
513 /* if already found */
514 if (*icp)
515 return 1;
517 /* if the iCodes are the same */
518 if (isiCodeEqual (ic, cdp->diCode) &&
519 isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
521 *icp = cdp->diCode;
522 return 1;
525 /* if iCodes are not the same */
526 /* see the operands maybe interchanged */
527 if (ic->op == cdp->diCode->op &&
528 IS_COMMUTATIVE (ic) &&
529 isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
530 isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
532 *icp = cdp->diCode;
533 return 1;
536 return 0;
539 /*-------------------------------------------------------------------*/
540 /* ifAssignedFromGlobal - if definition is an assignment from global */
541 /*-------------------------------------------------------------------*/
542 DEFSETFUNC (ifAssignedFromGlobal)
544 cseDef *cdp = item;
545 iCode *dic=cdp->diCode;
547 if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
548 return 1;
550 return 0;
553 /*-------------------------------------------------------------------*/
554 /* ifFromGlobal - if definition is derived from global */
555 /*-------------------------------------------------------------------*/
556 DEFSETFUNC (ifFromGlobal)
558 cseDef *cdp = item;
560 return cdp->fromGlobal;
563 /*-------------------------------------------------------------------*/
564 /* ifFromGlobalAliasableByPtr - if definition is derived from global */
565 /* that may be aliasble by a particular pointer type */
566 /*-------------------------------------------------------------------*/
567 DEFSETFUNC (ifFromGlobalAliasableByPtr)
569 cseDef *cdp = item;
570 V_ARG (DECLARATOR_TYPE, decl);
572 if (decl == GPOINTER && cdp->fromGlobal)
573 return 1;
574 else if (cdp->fromGlobal & (1 << decl))
575 return 1;
576 else
577 return 0;
580 /*-----------------------------------------------------------------*/
581 /* ifDefGlobal - if definition is global */
582 /*-----------------------------------------------------------------*/
583 DEFSETFUNC (ifDefGlobal)
585 cseDef *cdp = item;
587 return (isOperandGlobal (cdp->sym));
590 /*-----------------------------------------------------------------*/
591 /* ifDefGlobalAliasableByPtr - if definition is global */
592 /* and may be aliasble by a particular pointer type */
593 /*-----------------------------------------------------------------*/
594 DEFSETFUNC (ifDefGlobalAliasableByPtr)
596 cseDef *cdp = item;
597 V_ARG (DECLARATOR_TYPE, decl);
598 memmap *map;
600 if (!isOperandGlobal (cdp->sym))
601 return 0;
602 if (decl == GPOINTER)
603 return 1;
604 map = SPEC_OCLS (getSpec (operandType (cdp->sym)));
605 return (map->ptrType == decl);
608 /*-------------------------------------------------------------------*/
609 /* ifFromAddrTaken - if definition is derived from a symbol whose */
610 /* address was taken */
611 /*-------------------------------------------------------------------*/
612 DEFSETFUNC (ifFromAddrTaken)
614 cseDef *cdp = item;
616 if (OP_SYMBOL(cdp->sym)->addrtaken)
617 return 1;
618 return cdp->fromAddrTaken;
622 /*-----------------------------------------------------------------*/
623 /* ifAnyGetPointer - if get pointer icode */
624 /*-----------------------------------------------------------------*/
625 DEFSETFUNC (ifAnyGetPointer)
627 cseDef *cdp = item;
629 if (cdp->diCode && POINTER_GET (cdp->diCode))
630 return 1;
631 return 0;
634 /*-----------------------------------------------------------------*/
635 /* ifAnyUnrestrictedGetPointer - if get pointer icode */
636 /*-----------------------------------------------------------------*/
637 DEFSETFUNC (ifAnyUnrestrictedGetPointer)
639 cseDef *cdp = item;
640 V_ARG (DECLARATOR_TYPE, decl);
642 if (cdp->diCode && POINTER_GET (cdp->diCode))
644 sym_link *ptype;
645 ptype = operandType (IC_LEFT (cdp->diCode));
646 if (!IS_PTR_RESTRICT (ptype))
648 if (DCL_TYPE (ptype) == decl || IS_GENPTR (ptype))
649 return 1;
652 return 0;
655 /*-----------------------------------------------------------------*/
656 /* ifAnyUnrestrictedSetPointer - if set pointer icode */
657 /*-----------------------------------------------------------------*/
658 DEFSETFUNC (ifAnyUnrestrictedSetPointer)
660 cseDef *cdp = item;
661 V_ARG (DECLARATOR_TYPE, decl);
663 if (cdp->diCode && POINTER_SET (cdp->diCode))
665 sym_link *ptype;
666 ptype = operandType (IC_RESULT (cdp->diCode));
667 if (!IS_PTR_RESTRICT (ptype))
669 if (DCL_TYPE (ptype) == decl || IS_GENPTR (ptype))
670 return 1;
673 return 0;
676 /*-----------------------------------------------------------------*/
677 /* ifOperandsHave - if any of the operand are the same as this */
678 /*-----------------------------------------------------------------*/
679 DEFSETFUNC (ifOperandsHave)
681 cseDef *cdp = item;
682 V_ARG (operand *, op);
684 if (bitVectBitValue(cdp->ancestors, op->key))
685 return 1;
687 if (IC_LEFT (cdp->diCode) &&
688 IS_SYMOP (IC_LEFT (cdp->diCode)) &&
689 IC_LEFT (cdp->diCode)->key == op->key)
690 return 1;
692 if (IC_RIGHT (cdp->diCode) &&
693 IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
694 IC_RIGHT (cdp->diCode)->key == op->key)
695 return 1;
697 if (POINTER_SET (cdp->diCode) &&
698 IS_SYMOP (IC_RESULT (cdp->diCode)) &&
699 IC_RESULT (cdp->diCode)->key == op->key)
700 return 1;
702 /* or if any of the operands are volatile */
703 if (IC_LEFT (cdp->diCode) &&
704 IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
705 return 1;
707 if (IC_RIGHT (cdp->diCode) &&
708 IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
709 return 1;
712 if (IC_RESULT (cdp->diCode) &&
713 IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
714 return 1;
716 return 0;
719 /*-----------------------------------------------------------------*/
720 /* ifDefSymIs - if a definition is found in the set */
721 /*-----------------------------------------------------------------*/
723 ifDefSymIs (set * cseSet, operand * sym)
725 cseDef *loop;
726 set *sl;
728 if (!sym || !IS_SYMOP (sym))
729 return 0;
730 for (sl = cseSet; sl; sl = sl->next)
732 loop = sl->item;
733 if (loop->sym->key == sym->key)
734 return 1;
736 return 0;
740 /*-----------------------------------------------------------------*/
741 /* ifDefSymIsX - will return 1 if the symbols match */
742 /*-----------------------------------------------------------------*/
743 DEFSETFUNC (ifDefSymIsX)
745 cseDef *cdp = item;
746 V_ARG (operand *, op);
747 int match;
749 if (op && cdp->sym && op->key)
750 match = cdp->sym->key == op->key;
751 else
752 match = (isOperandEqual (cdp->sym, op));
753 #if 0
754 if (match)
755 printf("%s ",OP_SYMBOL(cdp->sym)->name);
756 #endif
757 return match;
761 /*-----------------------------------------------------------------*/
762 /* ifDiCodeIs - returns true if diCode is same */
763 /*-----------------------------------------------------------------*/
765 ifDiCodeIs (set * cseSet, iCode * ic)
767 cseDef *loop;
768 set *sl;
770 if (!ic)
771 return 0;
773 for (sl = cseSet; sl; sl = sl->next)
775 loop = sl->item;
776 if (loop->diCode == ic)
777 return 1;
779 return 0;
783 /*-----------------------------------------------------------------*/
784 /* ifPointerGet - returns true if the icode is pointer get sym */
785 /*-----------------------------------------------------------------*/
786 DEFSETFUNC (ifPointerGet)
788 cseDef *cdp = item;
789 V_ARG (operand *, op);
790 iCode *dic = cdp->diCode;
791 operand *left = IC_LEFT (cdp->diCode);
793 if (POINTER_GET (dic) && op->key && left->key == op->key)
794 return 1;
796 return 0;
799 /*-----------------------------------------------------------------*/
800 /* ifPointerSet - returns true if the icode is pointer set sym */
801 /*-----------------------------------------------------------------*/
802 DEFSETFUNC (ifPointerSet)
804 cseDef *cdp = item;
805 V_ARG (operand *, op);
807 if (POINTER_SET (cdp->diCode) && op->key &&
808 IC_RESULT (cdp->diCode)->key == op->key)
809 return 1;
811 return 0;
815 /*-----------------------------------------------------------------*/
816 /* promoteptrdcl - promote specialized pointer DCL value to more */
817 /* generalized pointer DCL value */
818 /*-----------------------------------------------------------------*/
819 static int
820 promoteptrdcl (const int dcl)
822 switch (dcl)
824 case POINTER:
825 if (TARGET_HC08_LIKE)
826 return FPOINTER; /* zero page part of full address space */
827 break;
828 case IPOINTER:
829 /* Hypothetically qualified with TARGET_MCS51_LIKE, but */
830 /* IPOINTER isn't used anywhere else so just assume it */
831 return POINTER; /* same pointer type for the CPU */
832 case PPOINTER:
833 if (TARGET_MCS51_LIKE)
834 return FPOINTER; /* paged memory part of external memory */
835 break;
837 return dcl;
841 /*-----------------------------------------------------------------*/
842 /* ifPointersAlias - returns true if this is a pointer operation */
843 /* that may alias a pointer at an iCode */
844 /*-----------------------------------------------------------------*/
845 DEFSETFUNC (ifPointersAlias)
847 operand *ptrop2;
848 int ptrop1dcl, ptrop2dcl;
849 cseDef *cdp = item;
850 V_ARG (operand *, ptrop1);
851 V_ARG (iCode *, ic);
853 if (POINTER_SET (cdp->diCode))
854 ptrop2 = IC_RESULT (cdp->diCode);
855 else if (POINTER_GET (cdp->diCode))
856 ptrop2 = IC_LEFT (cdp->diCode);
857 else
858 return 0; /* only consider pointer operations */
860 /* A pointer always aliases itself */
861 if (ptrop1->key && ptrop1->key == ptrop2->type)
862 return 1;
864 /* We'll need this eventually but suppress the unused variable */
865 /* warning for now. */
866 (void)ic;
868 /* We could be more precise about the aliasing situation if there */
869 /* was information about how the pointer value was derived. In the */
870 /* meantime, do what we can with the pointer type. */
872 ptrop1dcl = DCL_TYPE (operandType (ptrop1));
873 ptrop2dcl = DCL_TYPE (operandType (ptrop2));
875 /* A generic pointer can point to anything, so assume worst case */
876 if (ptrop1dcl == GPOINTER || ptrop2dcl == GPOINTER)
877 return 1;
879 ptrop1dcl = promoteptrdcl (ptrop1dcl);
880 ptrop2dcl = promoteptrdcl (ptrop2dcl);
882 /* If these are unrelated pointer types, we can safely claim */
883 /* that they can not alias each other. */
884 if (ptrop1dcl != ptrop2dcl)
885 return 0;
887 return 1;
891 /*-----------------------------------------------------------------*/
892 /* ifDiCodeIsX - will return 1 if the symbols match */
893 /*-----------------------------------------------------------------*/
894 DEFSETFUNC (ifDiCodeIsX)
896 cseDef *cdp = item;
897 V_ARG (iCode *, ic);
899 return cdp->diCode == ic;
903 /*-----------------------------------------------------------------*/
904 /* findBackwardDef - scan backwards to find definition of operand */
905 /*-----------------------------------------------------------------*/
906 iCode *findBackwardDef(operand *op,iCode *ic)
908 iCode *lic;
910 for (lic = ic; lic ; lic = lic->prev) {
911 if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
912 return lic;
914 return NULL;
917 /*-----------------------------------------------------------------*/
918 /* algebraicOpts - does some algebraic optimizations */
919 /*-----------------------------------------------------------------*/
920 static void
921 algebraicOpts (iCode * ic, eBBlock * ebp)
923 lineno = ic->lineno; // For error messages
925 /* we don't deal with the following iCodes
926 here */
927 if (ic->op == IFX ||
928 ic->op == IPUSH ||
929 ic->op == IPOP ||
930 ic->op == CALL ||
931 ic->op == PCALL ||
932 ic->op == RETURN ||
933 POINTER_GET (ic))
934 return;
936 /* if both operands present & ! IFX */
937 /* then if they are both literal we */
938 /* perform the operation right now */
939 if (IC_RESULT (ic) &&
940 IC_RIGHT (ic) &&
941 IC_LEFT (ic) &&
942 IS_OP_LITERAL (IC_LEFT (ic)) &&
943 IS_OP_LITERAL (IC_RIGHT (ic)))
945 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
946 IC_RIGHT (ic),
947 ic->op,
948 operandType (IC_RESULT (ic)));
949 ic->op = '=';
950 IC_LEFT (ic) = NULL;
951 SET_RESULT_RIGHT (ic);
952 return;
954 /* if not ifx & only one operand present */
955 if (IC_RESULT (ic) &&
956 IC_LEFT (ic) &&
957 IS_OP_LITERAL (IC_LEFT (ic)) &&
958 !IC_RIGHT (ic))
960 lineno = ic->lineno;
961 IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
962 IC_RIGHT (ic),
963 ic->op,
964 operandType (IC_RESULT (ic)));
965 ic->op = '=';
966 IC_LEFT (ic) = NULL;
967 SET_RESULT_RIGHT (ic);
968 return;
971 /* a special case : or in short a kludgy solution will think
972 about a better solution over a glass of wine someday */
973 if (ic->op == GET_VALUE_AT_ADDRESS)
975 if (IS_ITEMP (IC_RESULT (ic)) &&
976 IS_TRUE_SYMOP (IC_LEFT (ic)))
978 ic->op = '=';
979 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
980 IC_RIGHT (ic)->isaddr = 0;
981 IC_LEFT (ic) = NULL;
982 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
983 IC_RESULT (ic)->isaddr = 0;
984 setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
985 if (IS_DECL (operandType (IC_RESULT (ic))))
987 DCL_PTR_VOLATILE (operandType (IC_RESULT (ic))) = 0;
988 DCL_PTR_ADDRSPACE (operandType (IC_RESULT (ic))) = 0;
990 return;
993 if (IS_ITEMP (IC_LEFT (ic)) &&
994 IS_ITEMP (IC_RESULT (ic)) &&
995 !IC_LEFT (ic)->isaddr)
997 ic->op = '=';
998 IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
999 IC_RIGHT (ic)->isaddr = 0;
1000 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
1001 IC_RESULT (ic)->isaddr = 0;
1002 IC_LEFT (ic) = NULL;
1003 return;
1007 /* depending on the operation */
1008 switch (ic->op)
1010 case '+':
1011 /* if adding the same thing change to left shift by 1 */
1012 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
1013 !IS_OP_VOLATILE (IC_LEFT (ic)) &&
1014 !(IS_FLOAT (operandType (IC_RESULT (ic)))
1015 || IS_FIXED(operandType (IC_RESULT (ic)))))
1017 ic->op = LEFT_OP;
1018 IC_RIGHT (ic) = operandFromLit (1);
1019 return;
1021 /* if addition then check if one of them is a zero */
1022 /* if yes turn it into assignment or cast */
1023 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
1024 isEqualVal (OP_VALUE (IC_LEFT (ic)), 0))
1026 int typematch;
1027 typematch = compareType (operandType (IC_RESULT (ic)),
1028 operandType (IC_RIGHT (ic)), false);
1029 if ((typematch<0) || (IS_TRUE_SYMOP (IC_RIGHT (ic))))
1031 ic->op = CAST;
1032 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
1034 else
1036 ic->op = '=';
1037 IC_LEFT (ic) = NULL;
1038 if (typematch==0)
1040 /* for completely different types, preserve the source type */
1041 IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
1042 setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
1045 SET_ISADDR (IC_RESULT (ic), 0);
1046 SET_ISADDR (IC_RIGHT (ic), 0);
1047 return;
1049 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1050 isEqualVal (OP_VALUE (IC_RIGHT (ic)), 0))
1052 int typematch;
1053 typematch = compareType (operandType (IC_RESULT (ic)),
1054 operandType (IC_LEFT (ic)), false);
1055 if ((typematch<0) || (IS_TRUE_SYMOP (IC_LEFT (ic))))
1057 ic->op = CAST;
1058 IC_RIGHT (ic) = IC_LEFT (ic);
1059 IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
1061 else
1063 ic->op = '=';
1064 IC_RIGHT (ic) = IC_LEFT (ic);
1065 IC_LEFT (ic) = NULL;
1066 if (typematch==0)
1068 /* for completely different types, preserve the source type */
1069 IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
1070 setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
1073 SET_ISADDR (IC_RIGHT (ic), 0);
1074 SET_ISADDR (IC_RESULT (ic), 0);
1075 return;
1077 break;
1078 case '-':
1079 /* if subtracting the same thing then zero */
1080 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
1081 !IS_OP_VOLATILE (IC_LEFT (ic)))
1083 ic->op = '=';
1084 IC_RIGHT (ic) = operandFromLit (0);
1085 IC_LEFT (ic) = NULL;
1086 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
1087 IC_RESULT (ic)->isaddr = 0;
1088 return;
1091 /* if subtraction then check if one of the operand */
1092 /* is zero then depending on which operand change */
1093 /* to assignment or unary minus */
1094 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1095 isEqualVal (OP_VALUE (IC_RIGHT (ic)), 0))
1097 /* right size zero change to assignment */
1098 ic->op = '=';
1099 IC_RIGHT (ic) = IC_LEFT (ic);
1100 IC_LEFT (ic) = NULL;
1101 SET_ISADDR (IC_RIGHT (ic), 0);
1102 SET_ISADDR (IC_RESULT (ic), 0);
1103 return;
1105 if (IS_OP_LITERAL (IC_LEFT (ic)) &&
1106 isEqualVal (OP_VALUE (IC_LEFT (ic)), 0))
1108 /* left zero turn into an unary minus */
1109 ic->op = UNARYMINUS;
1110 IC_LEFT (ic) = IC_RIGHT (ic);
1111 IC_RIGHT (ic) = NULL;
1112 return;
1114 break;
1115 /* if multiplication then check if either of */
1116 /* them is zero then the result is zero */
1117 /* if either of them is one then result is */
1118 /* the other one */
1119 case '*':
1120 if (IS_OP_LITERAL (IC_LEFT (ic)))
1122 if (isEqualVal (OP_VALUE (IC_LEFT (ic)), 0))
1124 ic->op = '=';
1125 IC_RIGHT (ic) = IC_LEFT (ic);
1126 IC_LEFT (ic) = NULL;
1127 SET_RESULT_RIGHT (ic);
1128 return;
1130 if (isEqualVal (OP_VALUE (IC_LEFT (ic)), 1))
1132 /* '*' can have two unsigned chars as operands */
1133 /* and an unsigned int as result. */
1134 if (compareType (operandType (IC_RESULT (ic)),
1135 operandType (IC_RIGHT (ic)), false) == 1)
1137 ic->op = '=';
1138 IC_LEFT (ic) = NULL;
1139 SET_RESULT_RIGHT (ic);
1141 else
1143 ic->op = CAST;
1144 IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
1145 IC_LEFT (ic)->type = TYPE;
1146 IC_LEFT (ic)->isLiteral = 0;
1147 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
1149 return;
1151 if (isEqualVal (OP_VALUE (IC_LEFT (ic)), -1))
1153 /* convert -1 * x to -x */
1154 ic->op = UNARYMINUS;
1155 IC_LEFT (ic) = IC_RIGHT (ic);
1156 IC_RIGHT (ic) = NULL;
1157 return;
1161 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1163 if (isEqualVal (OP_VALUE (IC_RIGHT (ic)), 0))
1165 ic->op = '=';
1166 IC_LEFT (ic) = NULL;
1167 SET_RESULT_RIGHT (ic);
1168 return;
1171 if (isEqualVal (OP_VALUE (IC_RIGHT (ic)), 1))
1173 /* '*' can have two unsigned chars as operands */
1174 /* and an unsigned int as result. */
1175 if (compareType (operandType (IC_RESULT (ic)),
1176 operandType (IC_LEFT (ic)), false) == 1)
1178 ic->op = '=';
1179 IC_RIGHT (ic) = IC_LEFT (ic);
1180 IC_LEFT (ic) = NULL;
1181 SET_RESULT_RIGHT (ic);
1183 else
1185 operand *op;
1187 ic->op = CAST;
1188 op = IC_RIGHT (ic);
1189 IC_RIGHT (ic) = IC_LEFT (ic);
1190 IC_LEFT (ic) = operandFromOperand (op);
1191 IC_LEFT (ic)->type = TYPE;
1192 IC_LEFT (ic)->isLiteral = 0;
1193 setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
1195 return;
1197 if (isEqualVal (OP_VALUE (IC_RIGHT (ic)), -1))
1199 /* '*' can have two unsigned chars as operands */
1200 /* and an unsigned int as result. */
1201 if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
1203 if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
1204 (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
1206 operand * op;
1207 iCode * newic;
1208 /* Widen to int. */
1209 op = operandFromOperand (IC_RESULT (ic));
1210 op->type = TYPE;
1211 setOperandType (op, INTTYPE);
1212 newic = newiCode (CAST, op, IC_LEFT (ic));
1213 IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
1214 addiCodeToeBBlock (ebp, newic, ic);
1215 IC_LEFT (ic) = IC_RESULT (newic);
1218 /* convert x * -1 to -x */
1219 ic->op = UNARYMINUS;
1220 IC_RIGHT (ic) = NULL;
1221 return;
1224 break;
1225 case '/':
1226 /* if division by self then 1 */
1227 if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
1229 ic->op = '=';
1230 IC_RIGHT (ic) = operandFromLit (1);
1231 IC_LEFT (ic) = NULL;
1232 IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
1233 IC_RESULT (ic)->isaddr = 0;
1234 return;
1236 /* if this is a division then check if left is zero */
1237 /* then change it to an assignment */
1238 if (IS_OP_LITERAL (IC_LEFT (ic)) && isEqualVal (OP_VALUE (IC_LEFT (ic)), 0))
1240 ic->op = '=';
1241 IC_RIGHT (ic) = IC_LEFT (ic);
1242 IC_LEFT (ic) = NULL;
1243 SET_RESULT_RIGHT (ic);
1244 return;
1246 /* if this is a division then check if right */
1247 /* is one then change it to an assignment */
1248 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1250 if (isEqualVal (OP_VALUE (IC_RIGHT (ic)), 1))
1252 ic->op = '=';
1253 IC_RIGHT (ic) = IC_LEFT (ic);
1254 IC_LEFT (ic) = NULL;
1255 SET_RESULT_RIGHT (ic);
1256 return;
1258 if (isEqualVal (OP_VALUE (IC_RIGHT (ic)), -1))
1260 /* '/' can have two unsigned chars as operands */
1261 /* and an unsigned int as result. */
1262 if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
1264 if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
1265 (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
1267 operand * op;
1268 iCode * newic;
1269 /* Widen to int. */
1270 op = operandFromOperand (IC_RESULT (ic));
1271 op->type = TYPE;
1272 setOperandType (op, INTTYPE);
1273 newic = newiCode (CAST, op, IC_LEFT (ic));
1274 IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
1275 addiCodeToeBBlock (ebp, newic, ic);
1276 IC_LEFT (ic) = IC_RESULT (newic);
1279 /* convert x / -1 to -x */
1280 ic->op = UNARYMINUS;
1281 IC_RIGHT (ic) = NULL;
1282 return;
1285 break;
1286 /* if both are the same for an comparison operators */
1287 case EQ_OP:
1288 case LE_OP:
1289 case GE_OP:
1290 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)) &&
1291 !IS_OP_VOLATILE (IC_LEFT (ic)))
1293 ic->op = '=';
1294 IC_RIGHT (ic) = operandFromLit (1);
1295 IC_LEFT (ic) = NULL;
1296 SET_RESULT_RIGHT (ic);
1298 break;
1299 case NE_OP:
1300 case '>':
1301 case '<':
1302 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)) &&
1303 !IS_OP_VOLATILE (IC_LEFT (ic)))
1305 ic->op = '=';
1306 IC_RIGHT (ic) = operandFromLit (0);
1307 IC_LEFT (ic) = NULL;
1308 SET_RESULT_RIGHT (ic);
1310 break;
1311 case CAST:
1313 sym_link *otype = operandType(IC_RIGHT(ic));
1314 sym_link *ctype = operandType(IC_LEFT(ic));
1315 /* if this is a cast of a literal value */
1316 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1318 double litval = operandLitValue (IC_RIGHT (ic));
1319 unsigned long long llitval = operandLitValueUll (IC_RIGHT (ic));
1320 if (IS_GENPTR(ctype) && IS_PTR(otype))
1322 unsigned long gpVal = 0;
1323 const char *name = IS_SYMOP (IC_RESULT (ic)) ? OP_SYMBOL (IC_RESULT (ic))->name : NULL;
1324 if (IS_FUNCPTR(otype))
1325 gpVal = pointerTypeToGPByte (DCL_TYPE (otype->next), NULL, name);
1326 if (!IS_GENPTR(otype))
1327 gpVal = pointerTypeToGPByte (DCL_TYPE (otype), NULL, name);
1328 gpVal <<= ((GPTRSIZE - 1) * 8);
1329 gpVal |= llitval;
1330 litval = llitval = gpVal;
1332 ic->op = '=';
1333 IC_RIGHT (ic) = operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)), litval, llitval), false);
1334 IC_LEFT (ic) = NULL;
1335 SET_ISADDR (IC_RESULT (ic), 0);
1337 /* if casting to the same */
1338 if (compareType (operandType (IC_RESULT (ic)), operandType (IC_RIGHT (ic)), false) == 1)
1340 ic->op = '=';
1341 IC_LEFT (ic) = NULL;
1342 SET_ISADDR (IC_RESULT (ic), 0);
1345 break;
1346 case '!':
1347 if (IS_OP_LITERAL (IC_LEFT (ic)))
1349 ic->op = '=';
1350 IC_RIGHT (ic) =
1351 (isEqualVal (OP_VALUE (IC_LEFT (ic)), 0) ?
1352 operandFromLit (1) : operandFromLit (0));
1353 IC_LEFT (ic) = NULL;
1354 SET_ISADDR (IC_RESULT (ic), 0);
1356 break;
1357 case BITWISEAND:
1358 /* if both operands are equal */
1359 /* if yes turn it into assignment */
1360 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1362 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1364 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1365 IC_RESULT (newic) = IC_LEFT (ic);
1366 newic->filename = ic->filename;
1367 newic->lineno = ic->lineno;
1368 addiCodeToeBBlock (ebp, newic, ic->next);
1370 ic->op = '=';
1371 IC_LEFT (ic) = NULL;
1372 SET_RESULT_RIGHT (ic);
1373 return;
1375 /* swap literal to right ic */
1376 if (IS_OP_LITERAL (IC_LEFT (ic)))
1378 operand *op;
1380 op = IC_LEFT (ic);
1381 IC_LEFT (ic) = IC_RIGHT (ic);
1382 IC_RIGHT (ic) = op;
1384 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1386 unsigned val;
1388 /* if BITWISEAND then check if one of them is a zero */
1389 /* if yes turn it into 0 assignment */
1390 if (isEqualVal (OP_VALUE (IC_RIGHT (ic)), 0))
1392 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1394 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1395 IC_RESULT (newic) = IC_LEFT (ic);
1396 newic->filename = ic->filename;
1397 newic->lineno = ic->lineno;
1398 addiCodeToeBBlock (ebp, newic, ic->next);
1400 ic->op = '=';
1401 IC_LEFT (ic) = NULL;
1402 SET_RESULT_RIGHT (ic);
1403 return;
1405 /* if BITWISEAND then check if one of them is 0xff... */
1406 /* if yes turn it into assignment */
1407 if (IS_BOOLEAN (operandType (IC_RIGHT (ic)))) /* Special handling since _Bool is stored in 8 bits */
1408 goto boolcase;
1409 switch (bitsForType (operandType (IC_RIGHT (ic))))
1411 case 1:
1412 boolcase:
1413 val = 0x01;
1414 break;
1415 case 8:
1416 val = 0xff;
1417 break;
1418 case 16:
1419 val = 0xffff;
1420 break;
1421 case 32:
1422 val = 0xffffffff;
1423 break;
1424 default:
1425 return;
1427 if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
1429 ic->op = '=';
1430 IC_RIGHT (ic) = IC_LEFT (ic);
1431 IC_LEFT (ic) = NULL;
1432 SET_RESULT_RIGHT (ic);
1433 return;
1436 break;
1437 case '|':
1438 /* if both operands are equal */
1439 /* if yes turn it into assignment */
1440 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1442 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1444 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1445 IC_RESULT (newic) = IC_LEFT (ic);
1446 newic->filename = ic->filename;
1447 newic->lineno = ic->lineno;
1448 addiCodeToeBBlock (ebp, newic, ic->next);
1450 ic->op = '=';
1451 IC_LEFT (ic) = NULL;
1452 SET_RESULT_RIGHT (ic);
1453 return;
1455 /* swap literal to right ic */
1456 if (IS_OP_LITERAL (IC_LEFT (ic)))
1458 operand *op;
1460 op = IC_LEFT (ic);
1461 IC_LEFT (ic) = IC_RIGHT (ic);
1462 IC_RIGHT (ic) = op;
1464 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1466 unsigned val;
1468 /* if BITWISEOR then check if one of them is a zero */
1469 /* if yes turn it into assignment */
1470 if (isEqualVal (OP_VALUE (IC_RIGHT (ic)), 0))
1472 ic->op = '=';
1473 IC_RIGHT (ic) = IC_LEFT (ic);
1474 IC_LEFT (ic) = NULL;
1475 SET_RESULT_RIGHT (ic);
1476 return;
1478 /* if BITWISEOR then check if one of them is 0xff... */
1479 /* if yes turn it into 0xff... assignment */
1480 switch (bitsForType (operandType (IC_RIGHT (ic))))
1482 case 1:
1483 val = 0x01;
1484 break;
1485 case 8:
1486 val = 0xff;
1487 break;
1488 case 16:
1489 val = 0xffff;
1490 break;
1491 case 32:
1492 val = 0xffffffff;
1493 break;
1494 default:
1495 return;
1497 if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
1499 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1501 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1502 IC_RESULT (newic) = IC_LEFT (ic);
1503 newic->filename = ic->filename;
1504 newic->lineno = ic->lineno;
1505 addiCodeToeBBlock (ebp, newic, ic->next);
1507 ic->op = '=';
1508 IC_LEFT (ic) = NULL;
1509 SET_RESULT_RIGHT (ic);
1510 return;
1513 break;
1514 case '^':
1515 /* if both operands are equal */
1516 /* if yes turn it into 0 assignment */
1517 if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
1519 if (IS_OP_VOLATILE (IC_LEFT (ic)))
1521 iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1522 IC_RESULT (newic) = IC_LEFT (ic);
1523 newic->filename = ic->filename;
1524 newic->lineno = ic->lineno;
1525 addiCodeToeBBlock (ebp, newic, ic->next);
1527 newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
1528 IC_RESULT (newic) = IC_LEFT (ic);
1529 newic->filename = ic->filename;
1530 newic->lineno = ic->lineno;
1531 addiCodeToeBBlock (ebp, newic, ic->next);
1533 ic->op = '=';
1534 IC_RIGHT (ic) = operandFromLit (0);
1535 IC_LEFT (ic) = NULL;
1536 SET_RESULT_RIGHT (ic);
1537 return;
1539 /* swap literal to right ic */
1540 if (IS_OP_LITERAL (IC_LEFT (ic)))
1542 operand *op;
1544 op = IC_LEFT (ic);
1545 IC_LEFT (ic) = IC_RIGHT (ic);
1546 IC_RIGHT (ic) = op;
1548 /* if XOR then check if one of them is a zero */
1549 /* if yes turn it into assignment */
1550 if (IS_OP_LITERAL (IC_RIGHT (ic)))
1552 if (isEqualVal (OP_VALUE (IC_RIGHT (ic)), 0))
1554 ic->op = '=';
1555 IC_RIGHT (ic) = IC_LEFT (ic);
1556 IC_LEFT (ic) = NULL;
1557 SET_RESULT_RIGHT (ic);
1558 return;
1561 /* if XOR then check if one of them is a zero or one */
1562 /* if yes turn it into assignment or invert */
1563 if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
1564 IS_BOOLEAN (operandType (IC_LEFT (ic))) &&
1565 IS_BOOLEAN (operandType (IC_RESULT (ic)))
1568 if (isEqualVal (OP_VALUE (IC_RIGHT (ic)), 1))
1570 ic->op = '!';
1571 IC_RIGHT (ic) = NULL;
1572 return;
1574 else
1576 ic->op = '=';
1577 IC_RIGHT (ic) = operandFromLit (1);
1578 IC_LEFT (ic) = NULL;
1579 SET_RESULT_RIGHT (ic);
1580 return;
1583 break;
1586 return;
1589 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1590 /*-----------------------------------------------------------------*/
1591 /* updateSpillLocation - keeps track of register spill location */
1592 /*-----------------------------------------------------------------*/
1593 void
1594 updateSpillLocation (iCode * ic, int induction)
1596 sym_link *setype;
1598 if (POINTER_SET (ic))
1599 return;
1601 if (ic->nosupdate)
1602 return;
1604 #if 0
1605 /* for the form true_symbol := iTempNN */
1606 if (ASSIGN_ITEMP_TO_SYM (ic) &&
1607 !SPIL_LOC (IC_RIGHT (ic)))
1609 setype = getSpec (operandType (IC_RESULT (ic)));
1611 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1612 !IS_VOLATILE (setype) &&
1613 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1614 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1616 wassert(IS_SYMOP(IC_RESULT (ic)));
1617 wassert(IS_SYMOP(IC_RIGHT (ic)));
1618 SPIL_LOC (IC_RIGHT (ic)) = IC_RESULT (ic)->operand.symOperand;
1621 #endif
1623 #if 0 /* this needs furthur investigation can save a lot of code */
1624 if (ASSIGN_SYM_TO_ITEMP(ic) &&
1625 !SPIL_LOC(IC_RESULT(ic)))
1627 if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
1628 SPIL_LOC (IC_RESULT (ic)) = IC_RIGHT (ic)->operand.symOperand;
1630 #endif
1631 if (ASSIGN_ITEMP_TO_ITEMP (ic))
1633 if (!SPIL_LOC (IC_RIGHT (ic)) &&
1634 !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
1635 OP_SYMBOL (IC_RESULT (ic))->isreqv)
1637 setype = getSpec (operandType (IC_RESULT (ic)));
1639 if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
1640 !IS_VOLATILE (setype) &&
1641 !IN_FARSPACE (SPEC_OCLS (setype)) &&
1642 !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
1644 SPIL_LOC (IC_RIGHT (ic)) = SPIL_LOC (IC_RESULT (ic));
1645 OP_SYMBOL (IC_RIGHT (ic))->prereqv = OP_SYMBOL (IC_RESULT (ic))->prereqv;
1648 /* special case for inductions */
1649 if (induction &&
1650 OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
1651 !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
1652 !SPIL_LOC(IC_RESULT(ic)))
1654 SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
1655 OP_SYMBOL (IC_RESULT (ic))->prereqv = OP_SYMBOL (IC_RIGHT (ic))->prereqv;
1660 /*-----------------------------------------------------------------*/
1661 /* setUsesDef - sets the uses def bitvector for a given operand */
1662 /*-----------------------------------------------------------------*/
1663 void
1664 setUsesDefs (operand * op, bitVect * bdefs,
1665 bitVect * idefs, bitVect ** oud)
1667 /* compute the definitions alive at this point */
1668 bitVect *adefs = bitVectUnion (bdefs, idefs);
1670 /* of these definitions find the ones that are */
1671 /* for this operand */
1672 adefs = bitVectInplaceIntersect (adefs, OP_DEFS (op));
1674 /* these are the definitions that this operand can use */
1675 /* Nothing uses op->usesDefs, so why? EEP - 2018-06-10 */
1676 //op->usesDefs = adefs;
1678 /* the out defs is an union */
1679 *oud = bitVectInplaceUnion (*oud, adefs);
1681 /* If not assigning op->usesDefs, we can safely free adefs */
1682 freeBitVect(adefs);
1685 /*-----------------------------------------------------------------*/
1686 /* unsetDefsAndUses - clear this operation for the operands */
1687 /*-----------------------------------------------------------------*/
1688 void
1689 unsetDefsAndUses (iCode *ic)
1691 /* take away this definition from the def chain of the */
1692 /* result & take away from use set of the operands */
1694 /* turn off def set */
1695 if (IS_SYMOP (IC_RESULT (ic)))
1697 if (!POINTER_SET (ic))
1698 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1699 else
1700 bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
1702 /* turn off the useSet for the operands */
1703 if (IS_SYMOP (IC_LEFT (ic)))
1704 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
1706 if (IS_SYMOP (IC_RIGHT (ic)))
1707 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1710 /*-----------------------------------------------------------------*/
1711 /* ifxOptimize - changes ifx conditions if it can */
1712 /*-----------------------------------------------------------------*/
1713 void
1714 ifxOptimize (iCode * ic, set * cseSet,
1715 int computeOnly,
1716 eBBlock * ebb, int *change,
1717 ebbIndex * ebbi)
1719 operand *pdop;
1720 symbol *label;
1722 /* if the condition can be replaced */
1723 if (!computeOnly)
1725 pdop = NULL;
1726 applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
1727 if (pdop)
1729 ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
1730 (*change)++;
1732 else if (ic->prev && /* Remove unnecessary casts */
1733 (ic->prev->op == '=' || ic->prev->op == CAST || ic->prev->op == '!') &&
1734 IS_ITEMP (IC_RESULT (ic->prev)) &&
1735 IC_RESULT (ic->prev)->key == IC_COND (ic)->key &&
1736 bitVectnBitsOn (OP_USES (IC_RESULT (ic->prev))) <= 1)
1738 /* Don't do this for "if (--c)", it inhibits DJNZ generation */
1739 if (!ic->prev->prev || ic->prev->prev->op != '-' || !IS_OP_LITERAL(IC_RIGHT(ic->prev->prev)))
1741 sym_link *type = operandType (IC_RESULT (ic->prev));
1742 if (ic->prev->op != CAST || IS_BOOL (type) || bitsForType (operandType (IC_RIGHT (ic->prev))) < bitsForType (type))
1744 if (!isOperandVolatile (ic->prev->op == '!' ? IC_LEFT (ic->prev) : IC_RIGHT (ic->prev), FALSE))
1746 if (ic->prev->op == '!') /* Invert jump logic */
1748 symbol *tmp = IC_TRUE (ic);
1749 IC_TRUE (ic) = IC_FALSE (ic);
1750 IC_FALSE (ic) = tmp;
1752 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1753 ReplaceOpWithCheaperOp(&IC_COND (ic), ic->prev->op == '!' ? IC_LEFT (ic->prev) : IC_RIGHT (ic->prev));
1754 (*change)++;
1756 /* There's an optimization opportunity here, but OP_USES doesn't seem to be */
1757 /* initialized properly at this point. - EEP 2016-08-04 */
1758 #if 0
1759 else if (bitVectnBitsOn (OP_USES(IC_COND (ic))) == 1)
1761 /* We can replace the iTemp with the original volatile symbol */
1762 /* but we must make sure the volatile symbol is still accessed */
1763 /* only once. */
1764 bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
1765 ReplaceOpWithCheaperOp(&IC_COND (ic), IC_RIGHT (ic->prev));
1766 (*change)++;
1767 /* Make previous assignment an assignment to self. */
1768 /* killDeadCode() will eliminiate it. */
1769 IC_RIGHT (ic->prev) = IC_RESULT (ic->prev);
1770 IC_LEFT (ic->prev) = NULL;
1771 ic->prev->op = '=';
1773 #endif
1779 /* if the conditional is a literal then */
1780 if (IS_OP_LITERAL (IC_COND (ic)))
1782 if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
1784 /* change to a goto */
1785 ic->op = GOTO;
1786 IC_LABEL (ic) = IC_TRUE (ic);
1787 (*change)++;
1789 else
1791 if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
1793 ic->op = GOTO;
1794 IC_LABEL (ic) = IC_FALSE (ic);
1795 (*change)++;
1797 else
1799 /* then kill this if condition */
1800 remiCodeFromeBBlock (ebb, ic);
1804 /* now we need to recompute the control flow */
1805 /* since the control flow has changed */
1806 /* this is very expensive but it does not happen */
1807 /* too often, if it does happen then the user pays */
1808 /* the price */
1809 computeControlFlow (ebbi);
1810 if (!ic->inlined)
1811 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1812 return;
1815 /* if there is only one successor and that successor
1816 is the same one we are conditionally going to then
1817 we can remove this conditional statement */
1818 label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
1819 if (elementsInSet (ebb->succList) == 1 &&
1820 isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
1822 if (!ic->inlined)
1823 werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
1824 if (IS_OP_VOLATILE (IC_COND (ic)))
1826 IC_RIGHT (ic) = IC_COND (ic);
1827 IC_LEFT (ic) = NULL;
1828 IC_RESULT (ic) = NULL;
1829 ic->op = DUMMY_READ_VOLATILE;
1831 else
1833 remiCodeFromeBBlock (ebb, ic);
1834 computeControlFlow (ebbi);
1835 return;
1839 /* if it remains an IFX then update the use Set */
1840 if (ic->op == IFX)
1842 OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
1843 setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1845 else if (ic->op == DUMMY_READ_VOLATILE)
1847 OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
1848 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
1850 return;
1853 /*-----------------------------------------------------------------*/
1854 /* diCodeForSym - finds the definiting instruction for a symbol */
1855 /*-----------------------------------------------------------------*/
1856 DEFSETFUNC (diCodeForSym)
1858 cseDef *cdp = item;
1859 V_ARG (operand *, sym);
1860 V_ARG (iCode **, dic);
1862 /* if already found */
1863 if (*dic)
1864 return 0;
1866 /* if not if this is the defining iCode */
1867 if (sym->key == cdp->key)
1869 *dic = cdp->diCode;
1870 return 1;
1873 return 0;
1876 /*-----------------------------------------------------------------*/
1877 /* constFold - does some constant folding */
1878 /*-----------------------------------------------------------------*/
1880 constFold (iCode * ic, set * cseSet)
1882 iCode *dic = NULL;
1883 iCode *ldic = NULL;
1884 /* this routine will change
1885 a = b + 10;
1886 c = a + 10;
1888 c = b + 20; */
1890 /* deal with only + & - */
1891 if (ic->op != '+' &&
1892 ic->op != '-' &&
1893 ic->op != BITWISEAND)
1894 return 0;
1896 /* check if operation with a literal */
1897 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
1898 return 0;
1900 /* check if we can find a definition for the
1901 left hand side */
1902 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
1903 return 0;
1905 if (ic->op == BITWISEAND) /* Optimize out bitwise and of comparison results */
1907 /* check that this results in 0 or 1 only */
1908 if(dic->op != EQ_OP && dic->op != NE_OP && dic->op != LE_OP && dic->op != GE_OP && dic->op != '<' && dic->op != '>' && dic->op != '!')
1909 return 0;
1911 IC_RIGHT (ic) = (operandLitValueUll (IC_RIGHT (ic)) & 1) ? IC_LEFT (ic) : operandFromLit (0);
1913 ic->op = '=';
1914 IC_LEFT (ic) = 0;
1916 return 1;
1919 /* check that this is also a +/- */
1920 if (dic->op != '+' && dic->op != '-')
1921 return 0;
1923 /* with a literal */
1924 if (!IS_OP_LITERAL (IC_RIGHT (dic)))
1925 return 0;
1927 /* find the definition of the left operand
1928 of dic.then check if this defined with a
1929 get_pointer return 0 if the pointer size is
1930 less than 2 (MCS51 specific) */
1931 if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
1932 return 0;
1934 if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
1935 return 0;
1937 /* it is if the operations are the same */
1938 /* the literal parts need to be added */
1939 IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
1940 if (ic->op == dic->op)
1941 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
1942 operandLitValue (IC_RIGHT (dic)));
1943 else
1944 IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
1945 operandLitValue (IC_RIGHT (dic)));
1947 if (IS_ITEMP (IC_RESULT (ic)))
1949 SPIL_LOC (IC_RESULT (ic)) = NULL;
1950 OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
1953 return 1;
1956 /* Remove casts to bool from results of logical operations. */
1957 static int
1958 boolCast (iCode * ic, set * cseSet)
1960 iCode *dic = NULL;
1962 /* Only casts to booleans are optimized away. */
1963 if (ic->op != CAST || !IS_BOOL ( operandType (IC_RESULT (ic))))
1964 return 0;
1966 /* Find the definition for the right hand side. */
1967 if (!(applyToSet (cseSet, diCodeForSym, IC_RIGHT (ic), &dic)))
1968 return 0;
1970 /* Check that this is a logic op. */
1971 switch (dic->op)
1973 case '!':
1974 case '<':
1975 case '>':
1976 case LE_OP:
1977 case GE_OP:
1978 case EQ_OP:
1979 case NE_OP:
1980 case AND_OP:
1981 case OR_OP:
1982 case GETABIT:
1983 break;
1984 case BITWISEAND:
1985 if (IS_BOOL (operandType (IC_LEFT (dic))) || IS_BOOL (operandType (IC_RIGHT (dic))))
1986 break;
1987 if (IS_OP_LITERAL (IC_RIGHT (dic)) && operandLitValue (IC_RIGHT (dic)) == 1)
1988 break;
1989 default:
1990 return 0;
1993 /* Replace cast by assignment. */
1994 ic->op = '=';
1996 return 0;
1999 /*-----------------------------------------------------------------*/
2000 /* deleteGetPointers - called when a pointer is passed as parm */
2001 /* will delete from cseSet all get pointers computed from this */
2002 /* pointer. A simple ifOperandsHave is not good enough here */
2003 /*-----------------------------------------------------------------*/
2004 static void
2005 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
2007 set *compItems = NULL;
2008 cseDef *cdp;
2009 operand *cop;
2010 int changes;
2012 /* easy return */
2013 if (!*cseSet && !*pss)
2014 return;
2016 addSet (&compItems, op);
2018 /* Recursively find all items computed from this operand .
2019 This done fairly simply go thru the list and find
2020 those that are computed by arthimetic with these
2021 ops */
2022 /* Also check for those computed from our computed
2023 list . This will take care of situations like
2024 iTemp1 = iTemp0 + 8;
2025 iTemp2 = iTemp1 + 8; */
2028 changes = 0;
2029 for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
2031 if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
2033 if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
2034 (insetwithFunc)isOperandEqual) ||
2035 isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
2036 (insetwithFunc)isOperandEqual))
2038 if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
2039 (insetwithFunc)isOperandEqual))
2041 addSet (&compItems, IC_RESULT (cdp->diCode));
2042 changes++;
2048 while (changes);
2050 /* now for the computed items */
2051 for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
2053 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
2054 deleteItemIf (cseSet, ifPointerGet, cop);
2055 deleteItemIf (cseSet, ifDefSymIsX, cop);
2056 deleteItemIf (pss, ifPointerSet, cop);
2058 deleteSet (&compItems);
2061 /*-----------------------------------------------------------------*/
2062 /* delGetPointerSucc - delete get pointer from inExprs of succ with */
2063 /* dfnum > supplied */
2064 /*-----------------------------------------------------------------*/
2065 DEFSETFUNC (delGetPointerSucc)
2067 eBBlock *ebp = item;
2068 V_ARG (operand *, op);
2069 V_ARG (int, dfnum);
2071 if (ebp->visited)
2072 return 0;
2074 ebp->visited = 1;
2075 if (ebp->dfnum > dfnum)
2077 deleteItemIf (&ebp->inExprs, ifPointerGet, op);
2080 return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
2083 /*-----------------------------------------------------------------*/
2084 /* fixUpTypes - KLUGE HACK fixup a lowering problem */
2085 /*-----------------------------------------------------------------*/
2086 static void
2087 fixUpTypes (iCode * ic)
2089 sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
2091 /* if (TARGET_IS_DS390) */
2092 if (options.model == MODEL_FLAT24)
2094 /* hack-o-matic! */
2095 return;
2098 /* for pointer_gets if the types of result & left r the
2099 same then change it type of result to next */
2100 if (IS_PTR (t1) &&
2101 compareType (t2 = operandType (IC_RESULT (ic)), t1, false) == 1)
2103 setOperandType (IC_RESULT (ic), t2->next);
2107 /*-----------------------------------------------------------------*/
2108 /* isSignedOp - will return 1 if sign is important to operation */
2109 /*-----------------------------------------------------------------*/
2110 static int isSignedOp (iCode *ic)
2112 switch (ic->op) {
2113 case '!':
2114 case '~':
2115 case UNARYMINUS:
2116 case IPUSH:
2117 case IPUSH_VALUE_AT_ADDRESS:
2118 case IPOP:
2119 case CALL:
2120 case PCALL:
2121 case RETURN:
2122 case '+':
2123 case '-':
2124 case EQ_OP:
2125 case AND_OP:
2126 case OR_OP:
2127 case '^':
2128 case '|':
2129 case BITWISEAND:
2130 case INLINEASM:
2131 case ROT:
2132 case LEFT_OP:
2133 case GET_VALUE_AT_ADDRESS:
2134 case '=':
2135 case IFX:
2136 case RECEIVE:
2137 case SEND:
2138 return 0;
2139 case '*':
2140 case '/':
2141 case '%':
2142 case '>':
2143 case '<':
2144 case LE_OP:
2145 case GE_OP:
2146 case NE_OP:
2147 case GETABIT:
2148 case GETBYTE:
2149 case GETWORD:
2150 case RIGHT_OP:
2151 case CAST:
2152 case ARRAYINIT:
2153 return 1;
2154 default:
2155 return 0;
2159 #if 0
2160 static void
2161 dumpCseSet(set *cseSet)
2163 while (cseSet)
2165 cseDef *item=cseSet->item;
2166 printf("->");
2167 printOperand (item->sym, NULL);
2168 printf(" ");
2169 piCode (item->diCode, NULL);
2170 cseSet = cseSet->next;
2173 #endif
2175 /*-----------------------------------------------------------------*/
2176 /* cseBBlock - common subexpression elimination for basic blocks */
2177 /* this is the hackiest kludgiest routine in the whole */
2178 /* system. also the most important, since almost all */
2179 /* data flow related information is computed by it */
2180 /*-----------------------------------------------------------------*/
2182 cseBBlock (eBBlock * ebb, int computeOnly, ebbIndex * ebbi)
2184 eBBlock ** ebbs = ebbi->bbOrder;
2185 int count = ebbi->count;
2186 set *cseSet;
2187 set *setnode;
2188 iCode *ic;
2189 int change = 0;
2190 int i;
2191 set *ptrSetSet = NULL;
2192 cseDef *expr;
2193 int replaced;
2194 int recomputeDataFlow = 0;
2196 /* if this block is not reachable */
2197 if (ebb->noPath)
2199 for (ic = ebb->sch; ic; ic = ic->next)
2200 if (!SKIP_IC2 (ic))
2201 unsetDefsAndUses (ic);
2202 return 0;
2205 /* Mark incoming subexpressions as non-local */
2206 for (setnode = ebb->inExprs; setnode; setnode = setnode->next)
2208 expr = (cseDef *)setnode->item;
2209 expr->nonLocalCSE = 1;
2211 /* set of common subexpressions */
2212 cseSet = setFromSet (ebb->inExprs);
2215 /* these will be computed by this routine */
2216 freeBitVect(ebb->outDefs); ebb->outDefs = NULL;
2217 freeBitVect(ebb->defSet); ebb->defSet = NULL;
2218 freeBitVect(ebb->usesDefs); ebb->usesDefs = NULL;
2219 freeBitVect(ebb->ptrsSet); ebb->ptrsSet = NULL;
2220 deleteSet(&ebb->addrOf);
2221 freeBitVect(ebb->ldefs); ebb->ldefs = NULL;
2222 ebb->outDefs = bitVectCopy (ebb->inDefs);
2223 bitVectDefault = iCodeKey;
2224 ebb->defSet = newBitVect (iCodeKey);
2225 ebb->usesDefs = newBitVect (iCodeKey);
2227 /* for all the instructions in this block do */
2228 for (ic = ebb->sch; ic; ic = ic->next)
2230 iCode *pdic;
2231 operand *pdop;
2232 iCode *defic;
2233 int checkSign ;
2235 ic->eBBlockNum = ebb->bbnum;
2237 if (SKIP_IC2 (ic))
2238 continue;
2240 /* if this is an assignment from true symbol
2241 to a temp then do pointer post inc/dec optimization */
2242 if (ic->op == '=' && !POINTER_SET (ic) &&
2243 IS_PTR (operandType (IC_RESULT (ic))))
2245 ptrPostIncDecOpt (ic, ebb);
2248 /* clear the def & use chains for the operands involved */
2249 /* in this operation since it can change due to opts */
2250 unsetDefsAndUses (ic);
2252 if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
2254 /* add to defSet of the symbol */
2255 OP_DEFS (IC_RESULT (ic)) = bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2256 /* add to the definition set of this block */
2257 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2258 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2259 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2260 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2261 /* delete global variables from the cseSet
2262 since they can be modified by the function call */
2263 destructItemIf (&cseSet, freeLocalCseDef, ifDefGlobal);
2265 /* and also iTemps derived from globals */
2266 destructItemIf (&cseSet, freeLocalCseDef, ifFromGlobal);
2268 /* Delete iTemps derived from symbols whose address */
2269 /* has been taken */
2270 destructItemIf (&cseSet, freeLocalCseDef, ifFromAddrTaken);
2272 /* delete all getpointer iCodes from cseSet, this should
2273 be done only for global arrays & pointers but at this
2274 point we don't know if globals, so to be safe do all */
2275 destructItemIf (&cseSet, freeLocalCseDef, ifAnyGetPointer);
2277 /* can't cache pointer set/get operations across a call */
2278 deleteSet (&ptrSetSet);
2281 /* for pcall & ipush we need to add to the useSet */
2282 if ((ic->op == PCALL ||
2283 ic->op == IPUSH || ic->op == IPUSH_VALUE_AT_ADDRESS ||
2284 ic->op == IPOP ||
2285 ic->op == SEND) &&
2286 IS_SYMOP (IC_LEFT (ic)))
2288 /* check if they can be replaced */
2289 if (!computeOnly)
2291 pdop = NULL;
2292 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
2293 if (pdop)
2294 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
2296 /* the lookup could have changed it */
2297 if (IS_SYMOP (IC_LEFT (ic)))
2299 OP_USES(IC_LEFT (ic))=
2300 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2301 setUsesDefs (IC_LEFT (ic), ebb->defSet,
2302 ebb->outDefs, &ebb->usesDefs);
2305 /* if we are sending a pointer as a parameter
2306 then kill all cse since the pointed to item
2307 might be changed in the function being called */
2308 if ((ic->op == IPUSH || ic->op == SEND) &&
2309 IS_PTR (operandType (IC_LEFT (ic))))
2311 deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
2312 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
2313 for (i = 0; i < count; ebbs[i++]->visited = 0);
2314 applyToSet (ebb->succList, delGetPointerSucc,
2315 IC_LEFT (ic), ebb->dfnum);
2317 continue;
2320 /* if jumptable then mark the usage */
2321 if (ic->op == JUMPTABLE)
2323 if (IS_SYMOP (IC_JTCOND (ic)))
2325 pdop = NULL;
2326 applyToSetFTrue (cseSet, findCheaperOp, IC_JTCOND (ic), &pdop, true);
2327 if (pdop && !computeOnly)
2329 ReplaceOpWithCheaperOp (&IC_JTCOND (ic), pdop);
2330 change = 1;
2332 /* recheck since this may no longer be a symbol */
2333 if (IS_SYMOP (IC_JTCOND (ic)))
2335 OP_USES(IC_JTCOND (ic)) =
2336 bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
2337 setUsesDefs (IC_JTCOND (ic), ebb->defSet,
2338 ebb->outDefs, &ebb->usesDefs);
2341 continue;
2344 if (SKIP_IC (ic))
2345 continue;
2347 if (!computeOnly)
2349 /* do some algebraic optimizations if possible */
2350 algebraicOpts (ic, ebb);
2351 while (constFold (ic, cseSet));
2352 while (boolCast (ic, cseSet));
2355 /* small kludge */
2356 if (POINTER_GET (ic))
2358 if (!IS_PTR (operandType (IC_LEFT (ic))))
2360 setOperandType (IC_LEFT (ic),
2361 aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
2362 IC_LEFT (ic)->aggr2ptr = 0;
2363 fixUpTypes (ic);
2365 else if (IC_LEFT (ic)->aggr2ptr == 1)
2366 {/* band aid for kludge */
2367 setOperandType (IC_LEFT (ic),
2368 aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
2369 IC_LEFT (ic)->aggr2ptr++;
2370 fixUpTypes (ic);
2374 if (POINTER_SET (ic))
2376 if (!IS_PTR (operandType (IC_RESULT (ic))))
2378 setOperandType (IC_RESULT (ic),
2379 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2380 IC_RESULT (ic)->aggr2ptr = 0;
2382 else if (IC_RESULT (ic)->aggr2ptr == 1)
2383 {/* band aid for kludge */
2384 setOperandType (IC_RESULT (ic),
2385 aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2386 IC_RESULT (ic)->aggr2ptr++;
2390 /* if this is a condition statement then */
2391 /* check if the condition can be replaced */
2392 if (ic->op == IFX)
2394 ifxOptimize (ic, cseSet, computeOnly, ebb, &change, ebbi);
2395 continue;
2398 /* if the assignment & result is a temp */
2399 /* see if we can replace it */
2400 if (!computeOnly && ic->op == '=')
2402 /* update the spill location for this */
2403 updateSpillLocation (ic, 0);
2405 if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)) &&
2406 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
2408 pdop = NULL;
2409 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
2410 if (pdop && !computeOnly && IS_ITEMP (pdop))
2412 ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
2413 if (!IS_PTR (operandType (IC_RESULT (ic))))
2415 setOperandType (IC_RESULT (ic),
2416 aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
2422 checkSign = isSignedOp(ic);
2423 replaced = 0;
2425 /* do the operand lookup i.e. for both the */
2426 /* right & left operand : check the cseSet */
2427 /* to see if they have been replaced if yes */
2428 /* then replace them with those from cseSet */
2429 /* left operand */
2430 /* and left is a symbol */
2431 if (!computeOnly &&
2432 ic->op != ADDRESS_OF &&
2433 IS_SYMOP (IC_LEFT (ic)) &&
2434 !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))))
2436 pdop = NULL;
2437 applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
2438 if (pdop && !(IS_SYMOP (pdop) && IS_BITFIELD (OP_SYM_ETYPE (pdop))))
2440 if (POINTER_GET (ic))
2442 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
2444 /* some non dominating block does POINTER_SET with
2445 this variable .. unsafe to remove any POINTER_GETs */
2446 if (bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))
2447 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, pdop->key);
2448 ReplaceOpWithCheaperOp (&IC_LEFT (ic), pdop);
2449 SET_ISADDR (IC_LEFT (ic), 1);
2450 change = replaced = 1;
2452 /* check if there is a pointer set
2453 for the same pointer visible if yes
2454 then change this into an assignment */
2455 pdop = NULL;
2456 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
2457 !bitVectBitValue (ebb->ptrsSet, pdop->key))
2459 ic->op = '=';
2460 IC_LEFT (ic) = NULL;
2461 ReplaceOpWithCheaperOp (&IC_RIGHT (ic), pdop);
2462 SET_ISADDR (IC_RESULT (ic), 0);
2463 replaced = 1;
2466 else
2468 ReplaceOpWithCheaperOp (&IC_LEFT (ic), pdop);
2469 change = replaced = 1;
2474 /* right operand */
2475 if (!computeOnly && IS_SYMOP (IC_RIGHT (ic)))
2477 pdop = NULL;
2478 applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
2479 if (pdop)
2481 ReplaceOpWithCheaperOp (&IC_RIGHT (ic), pdop);
2482 change = replaced = 1;
2486 if (!computeOnly &&
2487 POINTER_SET (ic) &&
2488 IS_SYMOP (IC_RESULT (ic)) &&
2489 !IS_BITFIELD (OP_SYM_ETYPE (IC_RESULT (ic))))
2491 pdop = NULL;
2492 applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, checkSign);
2493 if (pdop)
2495 ReplaceOpWithCheaperOp (&IC_RESULT (ic), pdop);
2496 change = 1;
2500 /* if left or right changed then do algebraic */
2501 if (!computeOnly && change)
2503 algebraicOpts (ic, ebb);
2504 while (constFold (ic, cseSet));
2505 while (boolCast (ic, cseSet));
2508 /* if after all this it becomes an assignment to self
2509 then delete it and continue */
2510 if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
2512 unsetDefsAndUses (ic);
2513 remiCodeFromeBBlock (ebb, ic);
2514 continue;
2517 /* now we will check to see if the entire */
2518 /* operation has been performed before */
2519 /* and is available */
2520 /* don't do assignments they will be killed */
2521 /* by dead code elimination if required do */
2522 /* it only if result is a temporary */
2523 pdic = NULL;
2524 if (!(POINTER_GET (ic) &&
2525 (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2526 isOperandVolatile (IC_LEFT (ic), TRUE) || IS_VOLATILE (operandType (IC_LEFT (ic))->next) ||
2527 bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
2528 !ASSIGNMENT (ic) &&
2529 IS_ITEMP (IC_RESULT (ic)) &&
2530 !computeOnly)
2532 applyToSet (cseSet, findPrevIc, ic, &pdic);
2533 if (pdic && compareType (operandType (IC_RESULT (pdic)),
2534 operandType (IC_RESULT (ic)), false) != 1)
2536 pdic = NULL;
2538 if (pdic && port->cseOk && (*port->cseOk)(ic, pdic) == 0)
2540 pdic = NULL;
2544 /* Alternate code */
2545 if (pdic && IS_ITEMP (IC_RESULT (ic)))
2547 if (POINTER_GET (ic) && bitVectBitValue (ebb->ptrsSet, IC_LEFT (ic)->key))
2549 /* Mmm, found an equivalent pointer get at a lower level.
2550 This could be a loop however with the same pointer set
2551 later on */
2553 else
2555 /* if previous definition found change this to an assignment */
2556 ic->op = '=';
2557 IC_LEFT (ic) = NULL;
2558 IC_RIGHT (ic) = operandFromOperand (IC_RESULT (pdic));
2559 SET_ISADDR (IC_RESULT (ic), 0);
2560 SET_ISADDR (IC_RIGHT (ic), 0);
2564 /* if this is a pointer get then see if we can replace
2565 this with a previously assigned pointer value */
2566 if (!computeOnly && POINTER_GET (ic) &&
2567 !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
2568 isOperandVolatile (IC_LEFT (ic), TRUE)))
2570 pdop = NULL;
2571 applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
2573 /* if pointer set found, replace the pointer get with
2574 an assignment of the value used in the pointer set */
2575 if (pdop)
2577 ic->op = '=';
2578 IC_LEFT (ic) = NULL;
2579 ReplaceOpWithCheaperOp (&IC_RIGHT (ic), pdop);
2580 SET_ISADDR (IC_RESULT (ic), 0);
2581 replaced = 1;
2585 /* Now maybe add this iCode to cseSet. Can't modify the iCode */
2586 /* after this point or the cse info will be wrong. */
2587 if (!(POINTER_SET (ic)) && IC_RESULT (ic))
2589 cseDef *csed;
2590 destructItemIf (&cseSet, freeLocalCseDef, ifDefSymIsX, IC_RESULT (ic));
2591 csed = newCseDef (IC_RESULT (ic), ic);
2592 updateCseDefAncestors (csed, cseSet);
2593 addSetHead (&cseSet, csed);
2595 defic = ic;
2597 /* if assignment to a parameter which is not
2598 mine and type is a pointer then delete
2599 pointerGets to take care of aliasing */
2600 if (ASSIGNMENT (ic) &&
2601 IS_SYMOP (IC_RESULT (ic)) &&
2602 OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
2603 IS_PTR (operandType (IC_RESULT (ic))))
2605 deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
2606 for (i = 0; i < count; ebbs[i++]->visited = 0);
2607 applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
2608 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
2611 /* delete from the cseSet anything that has */
2612 /* operands matching the result of this */
2613 /* except in case of pointer access */
2614 if (!(POINTER_SET (ic)) && IS_SYMOP (IC_RESULT (ic)))
2616 destructItemIf (&cseSet, freeLocalCseDef, ifOperandsHave, IC_RESULT (ic));
2617 destructItemIf (&ptrSetSet, freeLocalCseDef, ifOperandsHave, IC_RESULT (ic));
2618 /* delete any previous definitions */
2619 ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
2621 /* Until pointer tracking is complete, by conservative and delete all */
2622 /* pointer accesses that might alias this symbol. */
2623 if (isOperandGlobal (IC_RESULT (ic)) || OP_SYMBOL (IC_RESULT (ic))->addrtaken)
2625 memmap *map = SPEC_OCLS (getSpec (operandType (IC_RESULT (ic))));
2626 destructItemIf (&cseSet, freeLocalCseDef, ifAnyUnrestrictedGetPointer, map->ptrType);
2627 destructItemIf (&ptrSetSet, freeLocalCseDef, ifAnyUnrestrictedSetPointer, map->ptrType);
2631 /* add the left & right to the defUse set */
2632 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
2634 OP_USES (IC_LEFT (ic)) =
2635 bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2636 setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2639 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
2641 OP_USES (IC_RIGHT (ic)) =
2642 bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2643 setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2646 /* for the result it is special case, put the result */
2647 /* in the defuseSet if it is a pointer or array access */
2648 if (POINTER_SET (defic) &&
2649 (IS_SYMOP (IC_RESULT (ic)) || IS_OP_LITERAL (IC_RESULT (ic))))
2651 sym_link *ptype = operandType (IC_RESULT (ic));
2653 if (IS_SYMOP (IC_RESULT (ic)))
2655 OP_USES (IC_RESULT (ic)) =
2656 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
2657 setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
2659 deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
2660 ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
2661 /* delete from inexpressions of all successors which
2662 have dfNum > than this block */
2663 for (i = 0; i < count; ebbs[i++]->visited = 0);
2664 applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
2666 /* delete from ptrSetSet all other pointer sets for this operand */
2667 destructItemIf (&ptrSetSet, freeLocalCseDef, ifPointerSet, IC_RESULT (ic));
2668 /* delete from ptrSetSet all other pointer sets that may alias this */
2669 destructItemIf (&ptrSetSet, freeLocalCseDef, ifPointersAlias, IC_RESULT (ic), ic);
2670 /* add to the local pointerset set */
2671 addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
2673 /* A write via a non-restrict pointer may modify a global */
2674 /* variable used by this function, so delete them */
2675 /* and any derived symbols from cseSet. */
2676 if (!IS_PTR_RESTRICT (ptype))
2678 destructItemIf (&cseSet, freeLocalCseDef, ifDefGlobalAliasableByPtr, DCL_TYPE(ptype));
2679 destructItemIf (&cseSet, freeLocalCseDef, ifFromGlobalAliasableByPtr, DCL_TYPE(ptype));
2682 /* This could be made more specific for better optimization, but */
2683 /* for safety, delete anything this write may have modified. */
2684 destructItemIf (&cseSet, freeLocalCseDef, ifFromAddrTaken);
2685 destructItemIf (&cseSet, freeLocalCseDef, ifAnyGetPointer);
2687 else
2689 /* add the result to definition set */
2690 if (IS_SYMOP (IC_RESULT (ic)))
2692 OP_DEFS(IC_RESULT (ic))=
2693 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2694 ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
2695 ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
2696 ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
2700 /* if this is an addressof instruction then */
2701 /* put the symbol in the address of list & */
2702 /* delete it from the cseSet */
2703 if (defic->op == ADDRESS_OF)
2705 addSetHead (&ebb->addrOf, IC_LEFT (ic));
2706 destructItemIf (&cseSet, freeLocalCseDef, ifDefSymIsX, IC_LEFT (ic));
2709 /* If this was previously in the out expressions in the */
2710 /* original form, it might need to be killed by another block */
2711 /* in the new form if we have replaced operands, so recompute */
2712 /* the data flow after we finish this block */
2713 if (replaced && ifDiCodeIs (ebb->outExprs, ic))
2714 recomputeDataFlow = 1;
2717 for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
2718 if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
2719 !isinSetWith (ebb->killedExprs, expr, isCseDefEqual))
2721 addSetHead (&ebb->killedExprs, expr);
2724 deleteSet (&ptrSetSet);
2725 deleteSet (&ebb->outExprs);
2726 ebb->outExprs = cseSet;
2727 ebb->outDefs = bitVectInplaceUnion (ebb->outDefs, ebb->defSet);
2728 ebb->ptrsSet = bitVectInplaceUnion (ebb->ptrsSet, ebb->inPtrsSet);
2730 for (setnode = ebb->outExprs; setnode; setnode = setnode->next)
2732 expr = (cseDef *)setnode->item;
2733 expr->nonLocalCSE = 1;
2736 if (recomputeDataFlow)
2737 computeDataFlow (ebbi);
2739 return change;
2742 /*------------------------------------------------------------------*/
2743 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
2744 /*------------------------------------------------------------------*/
2746 cseAllBlocks (ebbIndex * ebbi, int computeOnly)
2748 eBBlock ** ebbs = ebbi->dfOrder;
2749 int count = ebbi->count;
2750 int i;
2751 int change = 0;
2753 /* if optimization turned off */
2755 for (i = 0; i < count; i++)
2756 change += cseBBlock (ebbs[i], computeOnly, ebbi);
2758 return change;
2762 /*------------------------------------------------------------------*/
2763 /* freeCSEdata - free data created by cseBBlock */
2764 /*------------------------------------------------------------------*/
2765 void
2766 freeCSEdata (eBBlock * ebb)
2768 set * s;
2770 /* We should really free the cseDefs too, but I haven't */
2771 /* found a good way to do this yet. For the moment, at */
2772 /* least free up the associated bitVects - EEP */
2773 for (s = ebb->outExprs; s; s = s->next)
2775 cseDef *cdp = s->item;
2776 if (!cdp) continue;
2777 if (cdp->ancestors)
2779 freeBitVect (cdp->ancestors);
2780 cdp->ancestors = NULL;
2784 deleteSet (&ebb->inExprs);
2785 deleteSet (&ebb->outExprs);
2786 deleteSet (&ebb->killedExprs);
2788 freeBitVect (ebb->inDefs);
2789 freeBitVect (ebb->outDefs);
2790 freeBitVect (ebb->defSet);
2791 freeBitVect (ebb->ldefs);
2792 freeBitVect (ebb->usesDefs);
2793 freeBitVect (ebb->ptrsSet);
2794 freeBitVect (ebb->inPtrsSet);
2795 freeBitVect (ebb->ndompset);
2796 deleteSet (&ebb->addrOf);
2797 freeBitVect (ebb->linds);