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"
29 /*-----------------------------------------------------------------*/
30 /* newCseDef - new cseDef */
31 /*-----------------------------------------------------------------*/
33 newCseDef (operand
* sym
, iCode
* ic
)
39 cdp
= Safe_alloc (sizeof (cseDef
));
44 cdp
->ancestors
= newBitVect(operandKey
);
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
))));
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
))));
68 cdp
->fromGlobal
|= (1 << map
->ptrType
);
70 cdp
->fromAddrTaken
|= OP_SYMBOL (IC_RIGHT (ic
))->addrtaken
;
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
);
93 updateCseDefAncestors(cseDef
*cdp
, set
* cseSet
)
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
)
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
;
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
)
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
;
135 /*-----------------------------------------------------------------*/
136 /* int isCseDefEqual - two definitions are equal */
137 /*-----------------------------------------------------------------*/
139 isCseDefEqual (void *vsrc
, void *vdest
)
142 cseDef
*dest
= vdest
;
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
)
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
);
173 void ReplaceOpWithCheaperOp(operand
**op
, operand
*cop
) {
175 printf ("ReplaceOpWithCheaperOp\n\t");
176 printOperand (*op
, stdout
);
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
)) {
186 OP_SYMBOL((*op
))->isreqv
=0;
187 OP_SYMBOL(cop
)->isreqv
=1;
197 /*-----------------------------------------------------------------*/
198 /* replaceAllSymBySym - replaces all operands by operand in an */
199 /* instruction chain */
200 /*-----------------------------------------------------------------*/
202 replaceAllSymBySym (iCode
* ic
, operand
* from
, operand
* to
, bitVect
** ndpset
)
207 printf ("replaceAllSymBySym\n\t");
208 printOperand (from
, stdout
);
210 printOperand (to
, stdout
);
213 for (lic
= ic
; lic
; lic
= lic
->next
)
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
);
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
;
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
;
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
)
275 if (cdp
->diCode
->key
== key
)
281 /*-----------------------------------------------------------------*/
282 /* removeFromInExprs - removes an icode from inexpressions */
283 /*-----------------------------------------------------------------*/
284 DEFSETFUNC (removeFromInExprs
)
288 V_ARG (operand
*, from
);
289 V_ARG (operand
*, to
);
290 V_ARG (eBBlock
*, cbp
);
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
);
304 /*-----------------------------------------------------------------*/
305 /* isGlobalInNearSpace - return TRUE if variable is a globalin data */
306 /*-----------------------------------------------------------------*/
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
315 if (isOperandGlobal (op
) && !IN_FARSPACE (SPEC_OCLS (type
)) &&
316 IN_DIRSPACE (SPEC_OCLS (type
)))
322 /*-----------------------------------------------------------------*/
323 /* findCheaperOp - cseBBlock support routine, will check to see if */
324 /* we have a operand previously defined */
325 /*-----------------------------------------------------------------*/
326 DEFSETFUNC (findCheaperOp
)
329 V_ARG (operand
*, cop
);
330 V_ARG (operand
**, opp
);
331 V_ARG (int, checkSign
);
333 /* if we have already found it */
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
);
353 /* if this is a straight assignment and
354 left is a temp then prefer the temporary to the
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
);
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
);
382 *opp
= IC_RIGHT (cdp
->diCode
);
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
);
406 (isOperandLiteral(*opp
) || !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
))
419 if (cop
->key
== (*opp
)->key
)
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
;
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
) &&
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
)))
491 Reminder for Bernhard: check of signedness
492 could be unnecessary together with 'checkSign', if
493 signedness of operation is stored in ic */
496 *opp
= IC_RIGHT (cdp
->diCode
);
503 /*-----------------------------------------------------------------*/
504 /* findPrevIc - cseBBlock support function will return the iCode */
505 /* which matches the current one */
506 /*-----------------------------------------------------------------*/
507 DEFSETFUNC (findPrevIc
)
511 V_ARG (iCode
**, icp
);
513 /* if already found */
517 /* if the iCodes are the same */
518 if (isiCodeEqual (ic
, cdp
->diCode
) &&
519 isOperandEqual (cdp
->sym
, IC_RESULT (cdp
->diCode
)))
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
)))
539 /*-------------------------------------------------------------------*/
540 /* ifAssignedFromGlobal - if definition is an assignment from global */
541 /*-------------------------------------------------------------------*/
542 DEFSETFUNC (ifAssignedFromGlobal
)
545 iCode
*dic
=cdp
->diCode
;
547 if (dic
->op
=='=' && isOperandGlobal(IC_RIGHT(dic
))) {
553 /*-------------------------------------------------------------------*/
554 /* ifFromGlobal - if definition is derived from global */
555 /*-------------------------------------------------------------------*/
556 DEFSETFUNC (ifFromGlobal
)
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
)
570 V_ARG (DECLARATOR_TYPE
, decl
);
572 if (decl
== GPOINTER
&& cdp
->fromGlobal
)
574 else if (cdp
->fromGlobal
& (1 << decl
))
580 /*-----------------------------------------------------------------*/
581 /* ifDefGlobal - if definition is global */
582 /*-----------------------------------------------------------------*/
583 DEFSETFUNC (ifDefGlobal
)
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
)
597 V_ARG (DECLARATOR_TYPE
, decl
);
600 if (!isOperandGlobal (cdp
->sym
))
602 if (decl
== GPOINTER
)
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
)
616 if (OP_SYMBOL(cdp
->sym
)->addrtaken
)
618 return cdp
->fromAddrTaken
;
622 /*-----------------------------------------------------------------*/
623 /* ifAnyGetPointer - if get pointer icode */
624 /*-----------------------------------------------------------------*/
625 DEFSETFUNC (ifAnyGetPointer
)
629 if (cdp
->diCode
&& POINTER_GET (cdp
->diCode
))
634 /*-----------------------------------------------------------------*/
635 /* ifAnyUnrestrictedGetPointer - if get pointer icode */
636 /*-----------------------------------------------------------------*/
637 DEFSETFUNC (ifAnyUnrestrictedGetPointer
)
640 V_ARG (DECLARATOR_TYPE
, decl
);
642 if (cdp
->diCode
&& POINTER_GET (cdp
->diCode
))
645 ptype
= operandType (IC_LEFT (cdp
->diCode
));
646 if (!IS_PTR_RESTRICT (ptype
))
648 if (DCL_TYPE (ptype
) == decl
|| IS_GENPTR (ptype
))
655 /*-----------------------------------------------------------------*/
656 /* ifAnyUnrestrictedSetPointer - if set pointer icode */
657 /*-----------------------------------------------------------------*/
658 DEFSETFUNC (ifAnyUnrestrictedSetPointer
)
661 V_ARG (DECLARATOR_TYPE
, decl
);
663 if (cdp
->diCode
&& POINTER_SET (cdp
->diCode
))
666 ptype
= operandType (IC_RESULT (cdp
->diCode
));
667 if (!IS_PTR_RESTRICT (ptype
))
669 if (DCL_TYPE (ptype
) == decl
|| IS_GENPTR (ptype
))
676 /*-----------------------------------------------------------------*/
677 /* ifOperandsHave - if any of the operand are the same as this */
678 /*-----------------------------------------------------------------*/
679 DEFSETFUNC (ifOperandsHave
)
682 V_ARG (operand
*, op
);
684 if (bitVectBitValue(cdp
->ancestors
, op
->key
))
687 if (IC_LEFT (cdp
->diCode
) &&
688 IS_SYMOP (IC_LEFT (cdp
->diCode
)) &&
689 IC_LEFT (cdp
->diCode
)->key
== op
->key
)
692 if (IC_RIGHT (cdp
->diCode
) &&
693 IS_SYMOP (IC_RIGHT (cdp
->diCode
)) &&
694 IC_RIGHT (cdp
->diCode
)->key
== op
->key
)
697 if (POINTER_SET (cdp
->diCode
) &&
698 IS_SYMOP (IC_RESULT (cdp
->diCode
)) &&
699 IC_RESULT (cdp
->diCode
)->key
== op
->key
)
702 /* or if any of the operands are volatile */
703 if (IC_LEFT (cdp
->diCode
) &&
704 IS_OP_VOLATILE (IC_LEFT (cdp
->diCode
)))
707 if (IC_RIGHT (cdp
->diCode
) &&
708 IS_OP_VOLATILE (IC_RIGHT (cdp
->diCode
)))
712 if (IC_RESULT (cdp
->diCode
) &&
713 IS_OP_VOLATILE (IC_RESULT (cdp
->diCode
)))
719 /*-----------------------------------------------------------------*/
720 /* ifDefSymIs - if a definition is found in the set */
721 /*-----------------------------------------------------------------*/
723 ifDefSymIs (set
* cseSet
, operand
* sym
)
728 if (!sym
|| !IS_SYMOP (sym
))
730 for (sl
= cseSet
; sl
; sl
= sl
->next
)
733 if (loop
->sym
->key
== sym
->key
)
740 /*-----------------------------------------------------------------*/
741 /* ifDefSymIsX - will return 1 if the symbols match */
742 /*-----------------------------------------------------------------*/
743 DEFSETFUNC (ifDefSymIsX
)
746 V_ARG (operand
*, op
);
749 if (op
&& cdp
->sym
&& op
->key
)
750 match
= cdp
->sym
->key
== op
->key
;
752 match
= (isOperandEqual (cdp
->sym
, op
));
755 printf("%s ",OP_SYMBOL(cdp
->sym
)->name
);
761 /*-----------------------------------------------------------------*/
762 /* ifDiCodeIs - returns true if diCode is same */
763 /*-----------------------------------------------------------------*/
765 ifDiCodeIs (set
* cseSet
, iCode
* ic
)
773 for (sl
= cseSet
; sl
; sl
= sl
->next
)
776 if (loop
->diCode
== ic
)
783 /*-----------------------------------------------------------------*/
784 /* ifPointerGet - returns true if the icode is pointer get sym */
785 /*-----------------------------------------------------------------*/
786 DEFSETFUNC (ifPointerGet
)
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
)
799 /*-----------------------------------------------------------------*/
800 /* ifPointerSet - returns true if the icode is pointer set sym */
801 /*-----------------------------------------------------------------*/
802 DEFSETFUNC (ifPointerSet
)
805 V_ARG (operand
*, op
);
807 if (POINTER_SET (cdp
->diCode
) && op
->key
&&
808 IC_RESULT (cdp
->diCode
)->key
== op
->key
)
815 /*-----------------------------------------------------------------*/
816 /* promoteptrdcl - promote specialized pointer DCL value to more */
817 /* generalized pointer DCL value */
818 /*-----------------------------------------------------------------*/
820 promoteptrdcl (const int dcl
)
825 if (TARGET_HC08_LIKE
)
826 return FPOINTER
; /* zero page part of full address space */
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 */
833 if (TARGET_MCS51_LIKE
)
834 return FPOINTER
; /* paged memory part of external memory */
841 /*-----------------------------------------------------------------*/
842 /* ifPointersAlias - returns true if this is a pointer operation */
843 /* that may alias a pointer at an iCode */
844 /*-----------------------------------------------------------------*/
845 DEFSETFUNC (ifPointersAlias
)
848 int ptrop1dcl
, ptrop2dcl
;
850 V_ARG (operand
*, ptrop1
);
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
);
858 return 0; /* only consider pointer operations */
860 /* A pointer always aliases itself */
861 if (ptrop1
->key
&& ptrop1
->key
== ptrop2
->type
)
864 /* We'll need this eventually but suppress the unused variable */
865 /* warning for now. */
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
)
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
)
891 /*-----------------------------------------------------------------*/
892 /* ifDiCodeIsX - will return 1 if the symbols match */
893 /*-----------------------------------------------------------------*/
894 DEFSETFUNC (ifDiCodeIsX
)
899 return cdp
->diCode
== ic
;
903 /*-----------------------------------------------------------------*/
904 /* findBackwardDef - scan backwards to find definition of operand */
905 /*-----------------------------------------------------------------*/
906 iCode
*findBackwardDef(operand
*op
,iCode
*ic
)
910 for (lic
= ic
; lic
; lic
= lic
->prev
) {
911 if (IC_RESULT(lic
) && isOperandEqual(op
,IC_RESULT(lic
)))
917 /*-----------------------------------------------------------------*/
918 /* algebraicOpts - does some algebraic optimizations */
919 /*-----------------------------------------------------------------*/
921 algebraicOpts (iCode
* ic
, eBBlock
* ebp
)
923 lineno
= ic
->lineno
; // For error messages
925 /* we don't deal with the following iCodes
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
) &&
942 IS_OP_LITERAL (IC_LEFT (ic
)) &&
943 IS_OP_LITERAL (IC_RIGHT (ic
)))
945 IC_RIGHT (ic
) = operandOperation (IC_LEFT (ic
),
948 operandType (IC_RESULT (ic
)));
951 SET_RESULT_RIGHT (ic
);
954 /* if not ifx & only one operand present */
955 if (IC_RESULT (ic
) &&
957 IS_OP_LITERAL (IC_LEFT (ic
)) &&
961 IC_RIGHT (ic
) = operandOperation (IC_LEFT (ic
),
964 operandType (IC_RESULT (ic
)));
967 SET_RESULT_RIGHT (ic
);
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
)))
979 IC_RIGHT (ic
) = operandFromOperand (IC_LEFT (ic
));
980 IC_RIGHT (ic
)->isaddr
= 0;
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;
993 if (IS_ITEMP (IC_LEFT (ic
)) &&
994 IS_ITEMP (IC_RESULT (ic
)) &&
995 !IC_LEFT (ic
)->isaddr
)
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
;
1007 /* depending on the operation */
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
)))))
1018 IC_RIGHT (ic
) = operandFromLit (1);
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))
1027 typematch
= compareType (operandType (IC_RESULT (ic
)),
1028 operandType (IC_RIGHT (ic
)), false);
1029 if ((typematch
<0) || (IS_TRUE_SYMOP (IC_RIGHT (ic
))))
1032 IC_LEFT (ic
) = operandFromLink (operandType (IC_RESULT (ic
)));
1037 IC_LEFT (ic
) = NULL
;
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);
1049 if (IS_OP_LITERAL (IC_RIGHT (ic
)) &&
1050 isEqualVal (OP_VALUE (IC_RIGHT (ic
)), 0))
1053 typematch
= compareType (operandType (IC_RESULT (ic
)),
1054 operandType (IC_LEFT (ic
)), false);
1055 if ((typematch
<0) || (IS_TRUE_SYMOP (IC_LEFT (ic
))))
1058 IC_RIGHT (ic
) = IC_LEFT (ic
);
1059 IC_LEFT (ic
) = operandFromLink (operandType (IC_RESULT (ic
)));
1064 IC_RIGHT (ic
) = IC_LEFT (ic
);
1065 IC_LEFT (ic
) = NULL
;
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);
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
)))
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;
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 */
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);
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
;
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 */
1120 if (IS_OP_LITERAL (IC_LEFT (ic
)))
1122 if (isEqualVal (OP_VALUE (IC_LEFT (ic
)), 0))
1125 IC_RIGHT (ic
) = IC_LEFT (ic
);
1126 IC_LEFT (ic
) = NULL
;
1127 SET_RESULT_RIGHT (ic
);
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)
1138 IC_LEFT (ic
) = NULL
;
1139 SET_RESULT_RIGHT (ic
);
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
)));
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
;
1161 if (IS_OP_LITERAL (IC_RIGHT (ic
)))
1163 if (isEqualVal (OP_VALUE (IC_RIGHT (ic
)), 0))
1166 IC_LEFT (ic
) = NULL
;
1167 SET_RESULT_RIGHT (ic
);
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)
1179 IC_RIGHT (ic
) = IC_LEFT (ic
);
1180 IC_LEFT (ic
) = NULL
;
1181 SET_RESULT_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
)));
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
)))))
1209 op
= operandFromOperand (IC_RESULT (ic
));
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
;
1226 /* if division by self then 1 */
1227 if (IC_LEFT (ic
)->key
== IC_RIGHT (ic
)->key
)
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;
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))
1241 IC_RIGHT (ic
) = IC_LEFT (ic
);
1242 IC_LEFT (ic
) = NULL
;
1243 SET_RESULT_RIGHT (ic
);
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))
1253 IC_RIGHT (ic
) = IC_LEFT (ic
);
1254 IC_LEFT (ic
) = NULL
;
1255 SET_RESULT_RIGHT (ic
);
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
)))))
1270 op
= operandFromOperand (IC_RESULT (ic
));
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
;
1286 /* if both are the same for an comparison operators */
1290 if (isOperandEqual (IC_LEFT (ic
), IC_RIGHT (ic
)) &&
1291 !IS_OP_VOLATILE (IC_LEFT (ic
)))
1294 IC_RIGHT (ic
) = operandFromLit (1);
1295 IC_LEFT (ic
) = NULL
;
1296 SET_RESULT_RIGHT (ic
);
1302 if (isOperandEqual (IC_LEFT (ic
), IC_RIGHT (ic
)) &&
1303 !IS_OP_VOLATILE (IC_LEFT (ic
)))
1306 IC_RIGHT (ic
) = operandFromLit (0);
1307 IC_LEFT (ic
) = NULL
;
1308 SET_RESULT_RIGHT (ic
);
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);
1330 litval
= llitval
= gpVal
;
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)
1341 IC_LEFT (ic
) = NULL
;
1342 SET_ISADDR (IC_RESULT (ic
), 0);
1347 if (IS_OP_LITERAL (IC_LEFT (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);
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
);
1371 IC_LEFT (ic
) = NULL
;
1372 SET_RESULT_RIGHT (ic
);
1375 /* swap literal to right ic */
1376 if (IS_OP_LITERAL (IC_LEFT (ic
)))
1381 IC_LEFT (ic
) = IC_RIGHT (ic
);
1384 if (IS_OP_LITERAL (IC_RIGHT (ic
)))
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
);
1401 IC_LEFT (ic
) = NULL
;
1402 SET_RESULT_RIGHT (ic
);
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 */
1409 switch (bitsForType (operandType (IC_RIGHT (ic
))))
1427 if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic
))) & val
) == val
)
1430 IC_RIGHT (ic
) = IC_LEFT (ic
);
1431 IC_LEFT (ic
) = NULL
;
1432 SET_RESULT_RIGHT (ic
);
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
);
1451 IC_LEFT (ic
) = NULL
;
1452 SET_RESULT_RIGHT (ic
);
1455 /* swap literal to right ic */
1456 if (IS_OP_LITERAL (IC_LEFT (ic
)))
1461 IC_LEFT (ic
) = IC_RIGHT (ic
);
1464 if (IS_OP_LITERAL (IC_RIGHT (ic
)))
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))
1473 IC_RIGHT (ic
) = IC_LEFT (ic
);
1474 IC_LEFT (ic
) = NULL
;
1475 SET_RESULT_RIGHT (ic
);
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
))))
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
);
1508 IC_LEFT (ic
) = NULL
;
1509 SET_RESULT_RIGHT (ic
);
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
);
1534 IC_RIGHT (ic
) = operandFromLit (0);
1535 IC_LEFT (ic
) = NULL
;
1536 SET_RESULT_RIGHT (ic
);
1539 /* swap literal to right ic */
1540 if (IS_OP_LITERAL (IC_LEFT (ic
)))
1545 IC_LEFT (ic
) = IC_RIGHT (ic
);
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))
1555 IC_RIGHT (ic
) = IC_LEFT (ic
);
1556 IC_LEFT (ic
) = NULL
;
1557 SET_RESULT_RIGHT (ic
);
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))
1571 IC_RIGHT (ic
) = NULL
;
1577 IC_RIGHT (ic
) = operandFromLit (1);
1578 IC_LEFT (ic
) = NULL
;
1579 SET_RESULT_RIGHT (ic
);
1589 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
1590 /*-----------------------------------------------------------------*/
1591 /* updateSpillLocation - keeps track of register spill location */
1592 /*-----------------------------------------------------------------*/
1594 updateSpillLocation (iCode
* ic
, int induction
)
1598 if (POINTER_SET (ic
))
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
;
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
;
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 */
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 /*-----------------------------------------------------------------*/
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 */
1685 /*-----------------------------------------------------------------*/
1686 /* unsetDefsAndUses - clear this operation for the operands */
1687 /*-----------------------------------------------------------------*/
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
);
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 /*-----------------------------------------------------------------*/
1714 ifxOptimize (iCode
* ic
, set
* cseSet
,
1716 eBBlock
* ebb
, int *change
,
1722 /* if the condition can be replaced */
1726 applyToSetFTrue (cseSet
, findCheaperOp
, IC_COND (ic
), &pdop
, 0);
1729 ReplaceOpWithCheaperOp(&IC_COND (ic
), pdop
);
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
));
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 */
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 */
1764 bitVectUnSetBit (OP_USES (IC_COND (ic
)), ic
->key
);
1765 ReplaceOpWithCheaperOp(&IC_COND (ic
), IC_RIGHT (ic
->prev
));
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
;
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 */
1786 IC_LABEL (ic
) = IC_TRUE (ic
);
1791 if (!operandLitValue (IC_COND (ic
)) && IC_FALSE (ic
))
1794 IC_LABEL (ic
) = IC_FALSE (ic
);
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 */
1809 computeControlFlow (ebbi
);
1811 werrorfl (ic
->filename
, ic
->lineno
, W_CONTROL_FLOW
);
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
)))
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
;
1833 remiCodeFromeBBlock (ebb
, ic
);
1834 computeControlFlow (ebbi
);
1839 /* if it remains an IFX then update the use Set */
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
);
1853 /*-----------------------------------------------------------------*/
1854 /* diCodeForSym - finds the definiting instruction for a symbol */
1855 /*-----------------------------------------------------------------*/
1856 DEFSETFUNC (diCodeForSym
)
1859 V_ARG (operand
*, sym
);
1860 V_ARG (iCode
**, dic
);
1862 /* if already found */
1866 /* if not if this is the defining iCode */
1867 if (sym
->key
== cdp
->key
)
1876 /*-----------------------------------------------------------------*/
1877 /* constFold - does some constant folding */
1878 /*-----------------------------------------------------------------*/
1880 constFold (iCode
* ic
, set
* cseSet
)
1884 /* this routine will change
1890 /* deal with only + & - */
1891 if (ic
->op
!= '+' &&
1893 ic
->op
!= BITWISEAND
)
1896 /* check if operation with a literal */
1897 if (!IS_OP_LITERAL (IC_RIGHT (ic
)))
1900 /* check if we can find a definition for the
1902 if (!(applyToSet (cseSet
, diCodeForSym
, IC_LEFT (ic
), &dic
)))
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
!= '!')
1911 IC_RIGHT (ic
) = (operandLitValueUll (IC_RIGHT (ic
)) & 1) ? IC_LEFT (ic
) : operandFromLit (0);
1919 /* check that this is also a +/- */
1920 if (dic
->op
!= '+' && dic
->op
!= '-')
1923 /* with a literal */
1924 if (!IS_OP_LITERAL (IC_RIGHT (dic
)))
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
)))
1934 if (POINTER_GET (ldic
) && getSize (operandType (IC_LEFT (ldic
))) <= 1)
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
)));
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;
1956 /* Remove casts to bool from results of logical operations. */
1958 boolCast (iCode
* ic
, set
* cseSet
)
1962 /* Only casts to booleans are optimized away. */
1963 if (ic
->op
!= CAST
|| !IS_BOOL ( operandType (IC_RESULT (ic
))))
1966 /* Find the definition for the right hand side. */
1967 if (!(applyToSet (cseSet
, diCodeForSym
, IC_RIGHT (ic
), &dic
)))
1970 /* Check that this is a logic op. */
1985 if (IS_BOOL (operandType (IC_LEFT (dic
))) || IS_BOOL (operandType (IC_RIGHT (dic
))))
1987 if (IS_OP_LITERAL (IC_RIGHT (dic
)) && operandLitValue (IC_RIGHT (dic
)) == 1)
1993 /* Replace cast by assignment. */
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 /*-----------------------------------------------------------------*/
2005 deleteGetPointers (set
** cseSet
, set
** pss
, operand
* op
, eBBlock
* ebb
)
2007 set
*compItems
= NULL
;
2013 if (!*cseSet
&& !*pss
)
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
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; */
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
));
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
);
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 /*-----------------------------------------------------------------*/
2087 fixUpTypes (iCode
* ic
)
2089 sym_link
*t1
= operandType (IC_LEFT (ic
)), *t2
;
2091 /* if (TARGET_IS_DS390) */
2092 if (options
.model
== MODEL_FLAT24
)
2098 /* for pointer_gets if the types of result & left r the
2099 same then change it type of result to next */
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
)
2117 case IPUSH_VALUE_AT_ADDRESS
:
2133 case GET_VALUE_AT_ADDRESS
:
2161 dumpCseSet(set
*cseSet
)
2165 cseDef
*item
=cseSet
->item
;
2167 printOperand (item
->sym
, NULL
);
2169 piCode (item
->diCode
, NULL
);
2170 cseSet
= cseSet
->next
;
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
;
2191 set
*ptrSetSet
= NULL
;
2194 int recomputeDataFlow
= 0;
2196 /* if this block is not reachable */
2199 for (ic
= ebb
->sch
; ic
; ic
= ic
->next
)
2201 unsetDefsAndUses (ic
);
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
)
2235 ic
->eBBlockNum
= ebb
->bbnum
;
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
||
2286 IS_SYMOP (IC_LEFT (ic
)))
2288 /* check if they can be replaced */
2292 applyToSetFTrue (cseSet
, findCheaperOp
, IC_LEFT (ic
), &pdop
, 0);
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
);
2320 /* if jumptable then mark the usage */
2321 if (ic
->op
== JUMPTABLE
)
2323 if (IS_SYMOP (IC_JTCOND (ic
)))
2326 applyToSetFTrue (cseSet
, findCheaperOp
, IC_JTCOND (ic
), &pdop
, true);
2327 if (pdop
&& !computeOnly
)
2329 ReplaceOpWithCheaperOp (&IC_JTCOND (ic
), pdop
);
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
);
2349 /* do some algebraic optimizations if possible */
2350 algebraicOpts (ic
, ebb
);
2351 while (constFold (ic
, cseSet
));
2352 while (boolCast (ic
, cseSet
));
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;
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
++;
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 */
2394 ifxOptimize (ic
, cseSet
, computeOnly
, ebb
, &change
, ebbi
);
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
)))
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
);
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 */
2430 /* and left is a symbol */
2432 ic
->op
!= ADDRESS_OF
&&
2433 IS_SYMOP (IC_LEFT (ic
)) &&
2434 !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic
))))
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 */
2456 if (applyToSetFTrue (cseSet
, findPointerSet
, IC_LEFT (ic
), &pdop
, IC_RESULT (ic
)) &&
2457 !bitVectBitValue (ebb
->ptrsSet
, pdop
->key
))
2460 IC_LEFT (ic
) = NULL
;
2461 ReplaceOpWithCheaperOp (&IC_RIGHT (ic
), pdop
);
2462 SET_ISADDR (IC_RESULT (ic
), 0);
2468 ReplaceOpWithCheaperOp (&IC_LEFT (ic
), pdop
);
2469 change
= replaced
= 1;
2475 if (!computeOnly
&& IS_SYMOP (IC_RIGHT (ic
)))
2478 applyToSetFTrue (cseSet
, findCheaperOp
, IC_RIGHT (ic
), &pdop
, checkSign
);
2481 ReplaceOpWithCheaperOp (&IC_RIGHT (ic
), pdop
);
2482 change
= replaced
= 1;
2488 IS_SYMOP (IC_RESULT (ic
)) &&
2489 !IS_BITFIELD (OP_SYM_ETYPE (IC_RESULT (ic
))))
2492 applyToSetFTrue (cseSet
, findCheaperOp
, IC_RESULT (ic
), &pdop
, checkSign
);
2495 ReplaceOpWithCheaperOp (&IC_RESULT (ic
), pdop
);
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
);
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 */
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
))) &&
2529 IS_ITEMP (IC_RESULT (ic
)) &&
2532 applyToSet (cseSet
, findPrevIc
, ic
, &pdic
);
2533 if (pdic
&& compareType (operandType (IC_RESULT (pdic
)),
2534 operandType (IC_RESULT (ic
)), false) != 1)
2538 if (pdic
&& port
->cseOk
&& (*port
->cseOk
)(ic
, pdic
) == 0)
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
2555 /* if previous definition found change this to an assignment */
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
)))
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 */
2578 IC_LEFT (ic
) = NULL
;
2579 ReplaceOpWithCheaperOp (&IC_RIGHT (ic
), pdop
);
2580 SET_ISADDR (IC_RESULT (ic
), 0);
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
))
2590 destructItemIf (&cseSet
, freeLocalCseDef
, ifDefSymIsX
, IC_RESULT (ic
));
2591 csed
= newCseDef (IC_RESULT (ic
), ic
);
2592 updateCseDefAncestors (csed
, cseSet
);
2593 addSetHead (&cseSet
, csed
);
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
);
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
);
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
;
2753 /* if optimization turned off */
2755 for (i
= 0; i
< count
; i
++)
2756 change
+= cseBBlock (ebbs
[i
], computeOnly
, ebbi
);
2762 /*------------------------------------------------------------------*/
2763 /* freeCSEdata - free data created by cseBBlock */
2764 /*------------------------------------------------------------------*/
2766 freeCSEdata (eBBlock
* ebb
)
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
;
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
);