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 /*-----------------------------------------------------------------*/
28 /* newCseDef - new cseDef */
29 /*-----------------------------------------------------------------*/
30 cseDef *newCseDef (operand *sym, iCode *ic)
35 ALLOC(cdp,sizeof(cseDef));
46 /*-----------------------------------------------------------------*/
47 /* int isCseDefEqual - two definitions are equal */
48 /*-----------------------------------------------------------------*/
49 int isCseDefEqual ( void *vsrc, void *vdest)
57 return (src->key == dest->key &&
58 src->diCode == dest->diCode ) ;
62 /*-----------------------------------------------------------------*/
63 /* pcseDef - in the cseDef */
64 /*-----------------------------------------------------------------*/
65 int pcseDef (void *item, va_list ap)
73 fprintf(stdout,"**null op**");
74 printOperand(cdp->sym,stdout);
75 icTab = getTableEntry(cdp->diCode->op) ;
76 icTab->iCodePrint(stdout,cdp->diCode,icTab->printName);
80 /*-----------------------------------------------------------------*/
81 /* replaceAllSymBySym - replaces all operands by operand in an */
82 /* instruction chain */
83 /*-----------------------------------------------------------------*/
84 void replaceAllSymBySym (iCode *ic, operand *from , operand *to)
88 for (lic = ic ; lic ; lic = lic->next ) {
91 if (IC_RESULT(lic) && IC_RESULT(lic)->key == from->key ) {
92 /* maintain du chains */
93 if (POINTER_SET(lic)) {
94 bitVectUnSetBit (OP_USES(from),lic->key);
95 OP_USES(to) = bitVectSetBit (OP_USES(to),lic->key);
98 bitVectUnSetBit (OP_DEFS(from),lic->key);
99 OP_DEFS(to) = bitVectSetBit (OP_DEFS(to),lic->key);
101 siaddr = IC_RESULT(lic)->isaddr ;
102 IC_RESULT(lic) = operandFromOperand(to);
103 IC_RESULT(lic)->isaddr = siaddr ;
106 if (IC_RIGHT(lic) && IC_RIGHT(lic)->key == from->key ) {
107 bitVectUnSetBit (OP_USES(from),lic->key);
108 OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
109 siaddr = IC_RIGHT(lic)->isaddr ;
110 IC_RIGHT(lic) = operandFromOperand(to);
111 IC_RIGHT(lic)->isaddr = siaddr ;
114 if (IC_LEFT(lic) && IC_LEFT(lic)->key == from->key ) {
115 bitVectUnSetBit (OP_USES(from),lic->key);
116 OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
117 siaddr = IC_LEFT(lic)->isaddr ;
118 IC_LEFT(lic) = operandFromOperand(to);
119 IC_LEFT(lic)->isaddr = siaddr ;
124 /*-----------------------------------------------------------------*/
125 /* iCodeKeyIs - if the icode keys match then return 1 */
126 /*-----------------------------------------------------------------*/
127 DEFSETFUNC(iCodeKeyIs)
132 if (cdp->diCode->key == key)
138 /*-----------------------------------------------------------------*/
139 /* removeFromInExprs - removes an icode from inexpressions */
140 /*-----------------------------------------------------------------*/
141 DEFSETFUNC(removeFromInExprs)
145 V_ARG(operand *,from);
147 V_ARG(eBBlock *,cbp);
153 deleteItemIf(&ebp->inExprs,iCodeKeyIs,ic->key);
154 if (ebp != cbp && !bitVectBitValue(cbp->domVect,ebp->bbnum))
155 replaceAllSymBySym(ebp->sch,from,to);
157 applyToSet(ebp->succList,removeFromInExprs,ic,from,to,cbp);
161 /*-----------------------------------------------------------------*/
162 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
163 /*-----------------------------------------------------------------*/
164 static bool isGlobalInNearSpace (operand *op)
166 link *type = getSpec(operandType(op));
167 /* this is 8051 specific: optimization
168 suggested by Jean-Louis VERN, with 8051s we have no
169 advantage of putting variables in near space into
171 if (isOperandGlobal(op) &&
172 IN_DIRSPACE(SPEC_OCLS(type)))
178 /*-----------------------------------------------------------------*/
179 /* findCheaperOp - cseBBlock support routine, will check to see if */
180 /* we have a operand previously defined */
181 /*-----------------------------------------------------------------*/
182 DEFSETFUNC(findCheaperOp)
185 V_ARG(operand *,cop);
186 V_ARG(operand **,opp);
188 /* if we have already found it */
192 /* not found it yet check if this is the one */
193 /* and this is not the defining one */
194 if (cop->key == cdp->key) {
196 /* do a special check this will help in */
197 /* constant propagation & dead code elim*/
198 /* for assignments only */
199 if (cdp->diCode->op == '=') {
200 /* if the result is volatile then return result */
201 if (IS_OP_VOLATILE (IC_RESULT(cdp->diCode)))
202 *opp = IC_RESULT(cdp->diCode);
204 /* if this is a straight assignment and
205 left is a temp then prefer the temporary to the
207 if (!POINTER_SET(cdp->diCode) &&
208 IS_ITEMP(IC_RESULT(cdp->diCode)) &&
209 IS_TRUE_SYMOP(IC_RIGHT(cdp->diCode)))
210 *opp = IC_RESULT(cdp->diCode);
212 /* if straight assignement && and both
213 are temps then prefer the one that
214 will not need extra space to spil, also
215 take into consideration if right side
216 an induction variable
218 if (!POINTER_SET(cdp->diCode) &&
219 IS_ITEMP(IC_RESULT(cdp->diCode)) &&
220 IS_ITEMP(IC_RIGHT(cdp->diCode)) &&
221 !OP_SYMBOL(IC_RIGHT(cdp->diCode))->isind &&
222 ( (!SPIL_LOC(IC_RIGHT(cdp->diCode)) &&
223 SPIL_LOC(IC_RESULT(cdp->diCode))) ||
224 ( SPIL_LOC(IC_RESULT(cdp->diCode)) &&
225 SPIL_LOC(IC_RESULT(cdp->diCode)) ==
226 SPIL_LOC(IC_RIGHT(cdp->diCode))) )
228 *opp = IC_RESULT(cdp->diCode);
230 *opp = IC_RIGHT(cdp->diCode);
233 *opp = IC_RESULT(cdp->diCode) ;
236 /* if this is an assign to a temp. then check
237 if the right side is this then return this */
238 if (IS_TRUE_SYMOP(cop) &&
239 cdp->diCode->op == '=' &&
240 !POINTER_SET(cdp->diCode) &&
241 cop->key == IC_RIGHT(cdp->diCode)->key &&
242 !isGlobalInNearSpace (IC_RIGHT(cdp->diCode)) &&
243 IS_ITEMP(IC_RESULT(cdp->diCode)))
244 *opp = IC_RESULT(cdp->diCode);
248 if ((isGlobalInNearSpace(cop) &&
249 !isOperandLiteral(*opp)) ||
250 isOperandVolatile(*opp,FALSE)
256 if (cop->key == (*opp)->key ) {
261 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP(cop)) {
262 *opp = operandFromOperand(*opp);
263 (*opp)->isaddr = cop->isaddr;
273 /*-----------------------------------------------------------------*/
274 /* findPointerSet - finds the right side of a pointer set op */
275 /*-----------------------------------------------------------------*/
276 DEFSETFUNC(findPointerSet)
280 V_ARG(operand **,opp);
281 V_ARG(operand *,rop);
283 if (POINTER_SET(cdp->diCode) &&
284 IC_RESULT(cdp->diCode)->key == op->key &&
285 !isOperandVolatile(IC_RESULT(cdp->diCode),TRUE) &&
286 !isOperandVolatile(IC_RIGHT(cdp->diCode),TRUE) &&
287 getSize(operandType(IC_RIGHT(cdp->diCode))) ==
288 getSize(operandType(rop))) {
289 *opp = IC_RIGHT(cdp->diCode);
296 /*-----------------------------------------------------------------*/
297 /* findPrevIc - cseBBlock support function will return the iCode */
298 /* which matches the current one */
299 /*-----------------------------------------------------------------*/
300 DEFSETFUNC(findPrevIc)
306 /* if already found */
310 /* if the iCodes are the same */
311 if (isiCodeEqual(ic,cdp->diCode) &&
312 isOperandEqual(cdp->sym,IC_RESULT(cdp->diCode))) {
317 /* if iCodes are not the same */
318 /* see the operands maybe interchanged */
319 if (ic->op == cdp->diCode->op &&
320 ( ic->op == '+' || ic->op == '*' ) &&
321 isOperandEqual(IC_LEFT(ic),IC_RIGHT(cdp->diCode)) &&
322 isOperandEqual(IC_RIGHT(ic),IC_LEFT(cdp->diCode))) {
330 /*-----------------------------------------------------------------*/
331 /* ifDefGlobal - if definition is global */
332 /*-----------------------------------------------------------------*/
333 DEFSETFUNC(ifDefGlobal)
337 return (isOperandGlobal(cdp->sym));
340 /*-----------------------------------------------------------------*/
341 /* ifOperandsHave - if any of the operand are the same as this */
342 /*-----------------------------------------------------------------*/
343 DEFSETFUNC(ifOperandsHave)
349 if (IC_LEFT(cdp->diCode) &&
350 IS_SYMOP(IC_LEFT(cdp->diCode)) &&
351 IC_LEFT(cdp->diCode)->key == op->key)
354 if (IC_RIGHT(cdp->diCode) &&
355 IS_SYMOP(IC_RIGHT(cdp->diCode)) &&
356 IC_RIGHT(cdp->diCode)->key == op->key)
359 /* or if any of the operands are volatile */
360 if (IC_LEFT(cdp->diCode) &&
361 IS_OP_VOLATILE(IC_LEFT(cdp->diCode)))
364 if (IC_RIGHT(cdp->diCode) &&
365 IS_OP_VOLATILE(IC_RIGHT(cdp->diCode)))
369 if (IC_RESULT(cdp->diCode) &&
370 IS_OP_VOLATILE(IC_RESULT(cdp->diCode)))
376 /*-----------------------------------------------------------------*/
377 /* ifDefSymIs - if a definition is found in the set */
378 /*-----------------------------------------------------------------*/
379 int ifDefSymIs (set *cseSet, operand *sym)
384 if (!sym || !IS_SYMOP(sym))
386 for (sl = cseSet ; sl ; sl = sl->next ) {
388 if (loop->sym->key == sym->key )
395 /*-----------------------------------------------------------------*/
396 /* ifDefSymIsX - will return 1 if the symbols match */
397 /*-----------------------------------------------------------------*/
398 DEFSETFUNC(ifDefSymIsX)
404 return cdp->sym->key == op->key ;
406 return ( isOperandEqual(cdp->sym,op) );
411 /*-----------------------------------------------------------------*/
412 /* ifDiCodeIs - returns truw if diCode is same */
413 /*-----------------------------------------------------------------*/
414 int ifDiCodeIs (set *cseSet, iCode *ic)
422 for (sl = cseSet ; sl ; sl = sl->next ) {
424 if (loop->diCode == ic)
431 /*-----------------------------------------------------------------*/
432 /* ifPointerGet - returns true if the icode is pointer get sym */
433 /*-----------------------------------------------------------------*/
434 DEFSETFUNC(ifPointerGet)
438 iCode *dic = cdp->diCode;
439 operand *left = IC_LEFT(cdp->diCode);
441 if (POINTER_GET(dic) && left->key == op->key)
447 /*-----------------------------------------------------------------*/
448 /* ifPointerSet - returns true if the icode is pointer set sym */
449 /*-----------------------------------------------------------------*/
450 DEFSETFUNC(ifPointerSet)
455 if (POINTER_SET(cdp->diCode) &&
456 IC_RESULT(cdp->diCode)->key == op->key)
462 /*-----------------------------------------------------------------*/
463 /* ifDiCodeIsX - will return 1 if the symbols match */
464 /*-----------------------------------------------------------------*/
465 DEFSETFUNC(ifDiCodeIsX)
470 return cdp->diCode == ic;
474 /*-----------------------------------------------------------------*/
475 /* algebraicOpts - does some algebraic optimizations */
476 /*-----------------------------------------------------------------*/
477 void algebraicOpts (iCode *ic)
479 /* we don't deal with the following iCodes
490 /* if both operands present & ! IFX */
491 /* then if they are both literal we */
492 /* perform the operation right now */
496 IS_OP_LITERAL(IC_LEFT(ic)) &&
497 IS_OP_LITERAL(IC_RIGHT(ic))) {
499 IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
502 operandType(IC_RESULT(ic)));
505 SET_RESULT_RIGHT(ic);
509 /* if not ifx & only one operand present */
512 IS_OP_LITERAL(IC_LEFT(ic)) &&
515 IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
518 operandType(IC_RESULT(ic)));
521 SET_RESULT_RIGHT(ic);
526 /* a special case : or in short a kludgy solution will think
527 about a better solution over a glass of wine someday */
528 if ( ic->op == GET_VALUE_AT_ADDRESS ) {
530 if (IS_ITEMP(IC_RESULT(ic)) &&
531 IS_TRUE_SYMOP(IC_LEFT(ic))) {
534 IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic));
535 IC_RIGHT(ic)->isaddr = 0;
537 IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
538 IC_RESULT(ic)->isaddr = 0;
539 setOperandType(IC_RESULT(ic),operandType(IC_RIGHT(ic)));
543 if (IS_ITEMP(IC_LEFT(ic)) &&
544 IS_ITEMP(IC_RESULT(ic)) &&
545 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
546 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
547 !IC_LEFT(ic)->isaddr ) {
549 IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic));
550 IC_RIGHT(ic)->isaddr = 0;
551 IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
552 IC_RESULT(ic)->isaddr = 0;
560 /* depending on the operation */
563 /* if adding the same thing change to left shift by 1*/
564 if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key &&
565 !IS_FLOAT(operandType(IC_RESULT(ic)))) {
567 IC_RIGHT(ic) = operandFromLit(1);
570 /* if addition then check if one of them is a zero */
571 /* if yes turn it into assignmnt*/
572 if (IS_OP_LITERAL(IC_LEFT(ic)) &&
573 operandLitValue(IC_LEFT(ic)) == 0.0 ) {
577 SET_ISADDR(IC_RESULT(ic),0);
578 SET_ISADDR(IC_RIGHT(ic),0);
581 if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
582 operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
585 IC_RIGHT(ic) = IC_LEFT(ic) ;
587 SET_ISADDR(IC_RIGHT(ic),0);
588 SET_ISADDR(IC_RESULT(ic),0);
593 /* if subtracting the the same thing then zero */
594 if ( IC_LEFT(ic)->key == IC_RIGHT(ic)->key ) {
596 IC_RIGHT(ic) = operandFromLit(0);
598 IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
599 IC_RESULT(ic)->isaddr = 0;
603 /* if subtraction then check if one of the operand */
604 /* is zero then depending on which operand change */
605 /* to assignment or unary minus */
606 if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
607 operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
608 /* right size zero change to assignment */
610 IC_RIGHT(ic) = IC_LEFT(ic);
612 SET_ISADDR(IC_RIGHT(ic),0);
613 SET_ISADDR(IC_RESULT(ic),0);
616 if (IS_OP_LITERAL(IC_LEFT(ic)) &&
617 operandLitValue (IC_LEFT(ic)) == 0.0) {
618 /* left zero turn into an unary minus */
619 ic->op = UNARYMINUS ;
620 IC_LEFT(ic) = IC_RIGHT(ic);
621 IC_RIGHT(ic) = NULL ;
625 /* if multiplication then check if either of */
626 /* them is zero then the result is zero */
627 /* if either of them is one then result is */
630 if (IS_OP_LITERAL(IC_LEFT(ic))) {
632 if (operandLitValue(IC_LEFT(ic)) == 0.0) {
634 IC_RIGHT(ic) = IC_LEFT(ic);
636 SET_RESULT_RIGHT(ic);
639 if ( operandLitValue(IC_LEFT(ic)) == 1.0) {
642 SET_RESULT_RIGHT(ic);
647 if (IS_OP_LITERAL(IC_RIGHT(ic))) {
649 if (operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
652 SET_RESULT_RIGHT(ic);
656 if (operandLitValue(IC_RIGHT(ic)) == 1.0) {
658 IC_RIGHT(ic) = IC_LEFT(ic);
660 SET_RESULT_RIGHT(ic);
666 /* if division by self then 1 */
667 if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key) {
669 IC_RIGHT(ic) = operandFromLit(1);
671 IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
672 IC_RESULT(ic)->isaddr = 0;
674 /* if this is a division then check if right */
675 /* is one then change it to an assignment */
676 if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
677 operandLitValue(IC_RIGHT(ic)) == 1.0 ) {
680 IC_RIGHT(ic) = IC_LEFT(ic);
682 SET_RESULT_RIGHT(ic);
686 /* if both are the same for an comparison operators */
690 if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) {
692 IC_RIGHT(ic) = operandFromLit(1);
694 SET_RESULT_RIGHT(ic);
700 if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) {
702 IC_RIGHT(ic) = operandFromLit(0);
704 SET_RESULT_RIGHT(ic);
708 /* if this is a cast of a literal value */
709 if ( IS_OP_LITERAL(IC_RIGHT(ic))) {
712 operandFromValue (valCastLiteral(operandType(IC_LEFT(ic)),
713 operandLitValue(IC_RIGHT(ic))));
715 SET_ISADDR(IC_RESULT(ic),0);
717 /* if casting to the same */
718 if ( checkType(operandType(IC_RESULT(ic)),
719 operandType(IC_RIGHT(ic))) == 1) {
722 SET_ISADDR(IC_RESULT(ic),0);
726 if (IS_OP_LITERAL(IC_LEFT(ic))) {
729 (operandLitValue(IC_LEFT(ic)) == 0 ?
730 operandFromLit(1) : operandFromLit(0));
732 SET_ISADDR(IC_RESULT(ic),0);
738 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
739 /*-----------------------------------------------------------------*/
740 /* updateSpillLocation - keeps track of register spill location */
741 /*-----------------------------------------------------------------*/
742 void updateSpillLocation ( iCode *ic)
753 /* for the form true_symbol := iTempNN */
754 if (ASSIGN_ITEMP_TO_SYM(ic)
755 && !SPIL_LOC(IC_RIGHT(ic))) {
757 setype = getSpec(operandType(IC_RESULT(ic)));
759 if (!IC_RIGHT(ic)->noSpilLoc &&
760 !IS_VOLATILE(setype) &&
761 !IN_FARSPACE(SPEC_OCLS(setype)) &&
762 !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )
764 SPIL_LOC(IC_RIGHT(ic)) =
765 IC_RESULT(ic)->operand.symOperand;
768 if (ASSIGN_ITEMP_TO_ITEMP(ic) &&
769 !SPIL_LOC(IC_RIGHT(ic)) &&
770 !bitVectBitsInCommon(OP_DEFS(IC_RIGHT(ic)),OP_USES(IC_RESULT(ic))) &&
771 OP_SYMBOL(IC_RESULT(ic))->isreqv) {
773 setype = getSpec(operandType(IC_RESULT(ic)));
775 if (!IC_RIGHT(ic)->noSpilLoc &&
776 !IS_VOLATILE(setype) &&
777 !IN_FARSPACE(SPEC_OCLS(setype)) &&
778 !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )
780 SPIL_LOC(IC_RIGHT(ic)) =
781 SPIL_LOC(IC_RESULT(ic));
785 /*-----------------------------------------------------------------*/
786 /* setUsesDef - sets the uses def bitvector for a given operand */
787 /*-----------------------------------------------------------------*/
788 void setUsesDefs (operand *op, bitVect *bdefs,
789 bitVect *idefs, bitVect **oud)
791 /* compute the definitions alive at this point */
792 bitVect *adefs = bitVectUnion(bdefs,idefs);
794 /* of these definitions find the ones that are */
795 /* for this operand */
796 adefs = bitVectIntersect(adefs,OP_DEFS(op));
798 /* these are the definitions that this operand can use */
799 op->usesDefs = adefs;
801 /* the out defs is an union */
802 *oud = bitVectUnion(*oud,adefs);
805 /*-----------------------------------------------------------------*/
806 /* unsetDefsAndUses - clear this operation for the operands */
807 /*-----------------------------------------------------------------*/
808 void unsetDefsAndUses ( iCode *ic )
810 if ( ic->op == JUMPTABLE)
813 /* take away this definition from the def chain of the */
814 /* result & take away from use set of the operands */
816 /* turn off def set */
817 if (IS_SYMOP(IC_RESULT(ic))) {
818 if ( !POINTER_SET(ic))
819 bitVectUnSetBit(OP_DEFS(IC_RESULT(ic)),ic->key);
821 bitVectUnSetBit(OP_USES(IC_RESULT(ic)),ic->key);
823 /* turn off the useSet for the operands */
824 if (IS_SYMOP(IC_LEFT(ic)))
825 bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key);
827 if (IS_SYMOP(IC_RIGHT(ic)))
828 bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
830 else /* must be ifx turn off the use */
831 if (IS_SYMOP(IC_COND(ic)))
832 bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key);
835 /*-----------------------------------------------------------------*/
836 /* ifxOptimize - changes ifx conditions if it can */
837 /*-----------------------------------------------------------------*/
838 void ifxOptimize (iCode *ic, set *cseSet,
840 eBBlock *ebb, int *change,
841 eBBlock **ebbs, int count)
846 /* if the condition can be replaced */
849 applyToSetFTrue (cseSet,findCheaperOp,IC_COND(ic),&pdop);
856 /* if the conditional is a literal then */
857 if (IS_OP_LITERAL(IC_COND(ic))) {
859 if ( (operandLitValue(IC_COND(ic)) != 0.0) && IC_TRUE(ic)) {
861 /* change to a goto */
863 IC_LABEL(ic) = IC_TRUE(ic);
868 if (!operandLitValue(IC_COND(ic)) && IC_FALSE(ic)) {
870 IC_LABEL(ic) = IC_FALSE(ic);
874 /* then kill this if condition */
875 remiCodeFromeBBlock (ebb,ic);
879 /* now we need to recompute the control flow */
880 /* since the control flow has changed */
881 /* this is very expensive but it does not happen */
882 /* too often, if it does happen then the user pays */
884 computeControlFlow (ebbs,count,1);
885 werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
889 /* if there is only one successor and that successor
890 is the same one we are conditionally going to then
891 we can remove this conditional statement */
892 label = (IC_TRUE(ic) ? IC_TRUE(ic) : IC_FALSE(ic));
893 if (elementsInSet(ebb->succList) == 1 &&
894 isinSet(ebb->succList,eBBWithEntryLabel(ebbs,label,count))) {
896 remiCodeFromeBBlock(ebb,ic);
897 computeControlFlow (ebbs,count,1);
898 werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
903 /* if it remains an IFX the update the use Set */
904 OP_USES(IC_COND(ic)) = bitVectSetBit(OP_USES(IC_COND(ic)),ic->key);
905 setUsesDefs(IC_COND(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
909 /*-----------------------------------------------------------------*/
910 /* diCodeForSym - finds the definiting instruction for a symbol */
911 /*-----------------------------------------------------------------*/
912 DEFSETFUNC(diCodeForSym)
915 V_ARG(operand *,sym);
918 /* if already found */
922 /* if not if this is the defining iCode */
923 if (sym->key == cdp->key) {
931 /*-----------------------------------------------------------------*/
932 /* constFold - does some constant folding */
933 /*-----------------------------------------------------------------*/
934 int constFold (iCode *ic, set *cseSet)
937 /* this routine will change
943 /* deal with only + & - */
948 /* this check is a hueristic to prevent live ranges
949 from becoming too long */
950 if (IS_PTR(operandType(IC_RESULT(ic))))
953 /* check if operation with a literal */
954 if (!IS_OP_LITERAL(IC_RIGHT(ic)))
957 /* check if we can find a definition for the
959 if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(ic),&dic)))
962 /* check that this is also a +/- */
963 if (dic->op != '+' && dic->op != '-')
967 if (!IS_OP_LITERAL(IC_RIGHT(dic)))
970 /* it is if the operations are the same*/
971 /* the literal parts need to be added */
972 IC_LEFT(ic) = operandFromOperand(IC_LEFT(dic));
973 if (ic->op == dic->op )
974 IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic))+
975 operandLitValue(IC_RIGHT(dic)));
977 IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) -
978 operandLitValue(IC_RIGHT(dic)));
980 if (IS_ITEMP(IC_RESULT(ic))) {
981 SPIL_LOC(IC_RESULT(ic)) = NULL;
982 IC_RESULT(ic)->noSpilLoc = 1;
989 /*-----------------------------------------------------------------*/
990 /* deleteGetPointers - called when a pointer is passed as parm */
991 /* will delete from cseSet all get pointers computed from this */
992 /* pointer. A simple ifOperandsHave is not good enough here */
993 /*-----------------------------------------------------------------*/
994 static void deleteGetPointers (set **cseSet, set **pss, operand *op,eBBlock *ebb)
996 set *compItems = NULL;
1001 if (!*cseSet && !*pss)
1004 /* first find all items computed from this operand .
1005 This done fairly simply go thru the list and find
1006 those that are computed by arthimetic with this
1008 for (cdp = setFirstItem(*cseSet); cdp ; cdp = setNextItem(*cseSet)) {
1009 if (IS_ARITHMETIC_OP(cdp->diCode)) {
1010 if (isOperandEqual(IC_LEFT(cdp->diCode),op) ||
1011 isOperandEqual(IC_RIGHT(cdp->diCode),op)) {
1012 /* save it in our list of items */
1013 addSet(&compItems,IC_RESULT(cdp->diCode));
1015 /* also check for those computed from our computed
1016 list . This will take care of situations like
1017 iTemp1 = iTemp0 + 8;
1018 iTemp2 = iTemp1 + 8; */
1019 if (isinSetWith(compItems,IC_LEFT(cdp->diCode),isOperandEqual) ||
1020 isinSetWith(compItems,IC_RIGHT(cdp->diCode),isOperandEqual)) {
1021 addSet(&compItems,IC_RESULT(cdp->diCode));
1026 /* now delete all pointer gets with this op */
1027 deleteItemIf(cseSet,ifPointerGet,op);
1028 deleteItemIf(pss,ifPointerSet,op);
1030 /* set the bit vector used by dataFlow computation later */
1031 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,op->key);
1032 /* now for the computed items */
1033 for (cop = setFirstItem(compItems); cop ; cop = setNextItem(compItems)) {
1034 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,cop->key);
1035 deleteItemIf(cseSet,ifPointerGet,cop);
1036 deleteItemIf(pss,ifPointerSet,cop);
1040 /*-----------------------------------------------------------------*/
1041 /* delGetPointerSucc - delete get pointer from inExprs of succ with*/
1042 /* dfnum > supplied */
1043 /*-----------------------------------------------------------------*/
1044 DEFSETFUNC(delGetPointerSucc)
1046 eBBlock *ebp = item;
1047 V_ARG(operand *,op);
1054 if (ebp->dfnum > dfnum) {
1055 deleteItemIf(&ebp->inExprs,ifPointerGet,op);
1058 return applyToSet(ebp->succList,delGetPointerSucc,op,dfnum);
1061 /*-----------------------------------------------------------------*/
1062 /* cseBBlock - common subexpression elimination for basic blocks */
1063 /* this is the hackiest kludgiest routine in the whole */
1064 /* system. also the most important, since almost all */
1065 /* data flow related information is computed by it */
1066 /*-----------------------------------------------------------------*/
1067 int cseBBlock ( eBBlock *ebb, int computeOnly,
1068 eBBlock **ebbs, int count)
1074 set *ptrSetSet = NULL;
1076 /* if this block is not reachable */
1080 /* set of common subexpressions */
1081 cseSet = setFromSet (ebb->inExprs) ;
1083 /* these will be computed by this routine */
1084 setToNull ((void **)&ebb->outDefs);
1085 setToNull ((void **)&ebb->defSet);
1086 setToNull ((void **)&ebb->usesDefs);
1087 setToNull ((void **)&ebb->ptrsSet);
1088 setToNull ((void **)&ebb->addrOf);
1089 setToNull ((void **)&ebb->ldefs);
1091 ebb->outDefs = bitVectCopy (ebb->inDefs);
1092 bitVectDefault = iCodeKey;
1093 ebb->defSet = newBitVect(iCodeKey);
1094 ebb->usesDefs=newBitVect(iCodeKey);
1096 /* for all the instructions in this block do */
1097 for (ic = ebb->sch ; ic ; ic = ic->next ) {
1106 /* clear the def & use chains for the operands involved */
1107 /* in this operation . since it can change due to opts */
1108 unsetDefsAndUses (ic);
1110 if ( ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE) {
1111 /* add to defSet of the symbol */
1112 OP_DEFS(IC_RESULT(ic)) =
1113 bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
1114 /* add to the definition set of this block */
1115 ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);
1116 ebb->ldefs = bitVectSetBit (ebb->ldefs,ic->key);
1117 ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic)));
1118 setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1119 /* delete global variables from the cseSet
1120 since they can be modified by the function call */
1121 deleteItemIf(&cseSet,ifDefGlobal);
1124 /* for pcall & ipush we need to add to the useSet */
1125 if ((ic->op == PCALL ||
1129 IS_SYMOP(IC_LEFT(ic))) {
1131 /* check if they can be replaced */
1132 if ( !computeOnly ) {
1134 applyToSetFTrue(cseSet,findCheaperOp,IC_LEFT(ic),&pdop);
1136 IC_LEFT(ic) = pdop ;
1138 /* the lookup could have changed it*/
1139 if (IS_SYMOP(IC_LEFT(ic))) {
1140 OP_USES(IC_LEFT(ic)) =
1141 bitVectSetBit(OP_USES(IC_LEFT(ic)),ic->key);
1142 setUsesDefs(IC_LEFT(ic),ebb->defSet,
1143 ebb->outDefs,&ebb->usesDefs);
1147 /* if we a sending a pointer as a parameter
1148 then kill all cse since the pointed to item
1149 might be changed in the function being called */
1150 if ((ic->op == IPUSH || ic->op == SEND) &&
1151 IS_PTR(operandType(IC_LEFT(ic)))) {
1152 deleteGetPointers(&cseSet,&ptrSetSet,IC_LEFT(ic),ebb);
1153 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_LEFT(ic)->key);
1154 for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1155 applyToSet(ebb->succList,delGetPointerSucc,
1156 IC_LEFT(ic),ebb->dfnum);
1161 /* if jumptable then mark the usage */
1162 if (ic->op == JUMPTABLE ) {
1163 OP_USES(IC_JTCOND(ic)) =
1164 bitVectSetBit(OP_USES(IC_JTCOND(ic)),ic->key);
1165 setUsesDefs(IC_JTCOND(ic),ebb->defSet,
1166 ebb->outDefs,&ebb->usesDefs);
1173 /* do some algebraic optimizations if possible */
1175 while (constFold(ic,cseSet));
1178 if (POINTER_GET(ic) && !IS_PTR(operandType(IC_LEFT(ic)))) {
1179 setOperandType(IC_LEFT(ic),
1180 aggrToPtr(operandType(IC_LEFT(ic)),FALSE));
1182 if (POINTER_SET(ic) && !IS_PTR(operandType(IC_RESULT(ic)))) {
1183 setOperandType(IC_RESULT(ic),
1184 aggrToPtr(operandType(IC_RESULT(ic)),FALSE));
1187 /* if this is a condition statment then */
1188 /* check if the condition can be replaced */
1189 if (ic->op == IFX ) {
1190 ifxOptimize (ic, cseSet, computeOnly,
1196 /* if the assignment & result is a temp */
1197 /* see if we can replace it */
1198 if (ic->op == '=') {
1200 /* update the spill location for this */
1201 updateSpillLocation (ic);
1203 if (POINTER_SET(ic)) {
1205 applyToSetFTrue (cseSet,findCheaperOp,IC_RESULT(ic),&pdop);
1206 if (pdop && IS_ITEMP(pdop) && !computeOnly)
1207 IC_RESULT(ic) = pdop;
1211 /* do the operand lookup i.e. for both the */
1212 /* right & left operand : check the cseSet */
1213 /* to see if they have been replaced if yes*/
1214 /* then replace them with those from cseSet*/
1216 /* and left is a symbol */
1217 if (IS_SYMOP(IC_LEFT(ic)) &&
1218 !computeOnly && ic->op != ADDRESS_OF ) {
1221 applyToSetFTrue (cseSet,findCheaperOp,IC_LEFT(ic),&pdop) ;
1223 if (POINTER_GET(ic)) {
1224 if (IS_ITEMP(pdop) || IS_OP_LITERAL(pdop)) {
1228 /* check if there is a pointer set
1229 for the same pointer visible if yes
1230 then change this into an assignment */
1232 if (applyToSetFTrue(cseSet,findPointerSet,IC_LEFT(ic),&pdop,IC_RESULT(ic)) &&
1233 !bitVectBitValue(ebb->ptrsSet,pdop->key)){
1236 IC_RIGHT(ic) = pdop;
1237 SET_ISADDR(IC_RESULT(ic),0);
1242 IC_LEFT(ic) = pdop ;
1249 if (IS_SYMOP(IC_RIGHT(ic)) && !computeOnly) {
1252 applyToSetFTrue (cseSet,findCheaperOp,IC_RIGHT(ic),&pdop);
1255 IC_RIGHT(ic) = pdop;
1260 /* if left or right changed then do algebraic */
1263 while(constFold(ic,cseSet));
1266 /* if after all this it becomes a assignment to self
1267 then delete it and continue */
1268 if (ASSIGNMENT_TO_SELF(ic)) {
1269 remiCodeFromeBBlock(ebb,ic);
1273 /* now we will check to see if the entire */
1274 /* operation has been performed before */
1275 /* and is available */
1276 /* don't do assignments they will be killed */
1277 /* by dead code elimination if required do */
1278 /* it only if result is a temporary */
1280 if (!( POINTER_GET(ic) &&
1281 (IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
1282 isOperandVolatile(IC_LEFT(ic),TRUE))) &&
1284 IS_ITEMP(IC_RESULT(ic)) &&
1286 applyToSet (cseSet,findPrevIc,ic,&pdic);
1289 /* if found then eliminate this and add to*/
1290 /* to cseSet an element containing result */
1291 /* of this with previous opcode */
1294 if (IS_ITEMP(IC_RESULT(ic))) {
1296 /* replace in the remaining of this block */
1297 replaceAllSymBySym(ic->next,IC_RESULT(ic),IC_RESULT(pdic));
1298 /* remove this iCode from inexpressions of all
1299 its successors, it cannot be in the in expressions
1300 of any of the predecessors */
1301 for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1302 applyToSet(ebb->succList,removeFromInExprs,ic,IC_RESULT(ic),
1303 IC_RESULT(pdic),ebb);
1305 /* if this was moved from another block */
1306 /* then replace in those blocks too */
1307 if ( ic->movedFrom ) {
1309 for (owner = setFirstItem(ic->movedFrom); owner ;
1310 owner = setNextItem(ic->movedFrom))
1311 replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic));
1313 pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE);
1316 addSetHead (&cseSet,newCseDef(IC_RESULT(ic),pdic));
1319 /* eliminate this */
1320 remiCodeFromeBBlock (ebb,ic);
1325 if (IS_ITEMP(IC_RESULT(ic)))
1330 /* just add this as a previous expression except in */
1331 /* case of a pointer access in which case this is a */
1332 /* usage not a definition */
1333 if (! (POINTER_SET(ic)) && IC_RESULT(ic)){
1334 deleteItemIf (&cseSet, ifDefSymIsX,IC_RESULT(ic));
1335 addSetHead(&cseSet,newCseDef(IC_RESULT(ic),ic));
1341 /* if assignment to a parameter which is not
1342 mine and type is a pointer then delete
1343 pointerGets to take care of aliasing */
1344 if (ASSIGNMENT(ic) &&
1345 OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) &&
1346 IS_PTR(operandType(IC_RESULT(ic)))) {
1347 deleteGetPointers(&cseSet,&ptrSetSet,IC_RIGHT(ic),ebb);
1348 for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1349 applyToSet(ebb->succList,delGetPointerSucc,IC_RIGHT(ic),ebb->dfnum);
1350 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RIGHT(ic)->key);
1353 /* if this is a pointerget then see if we can replace
1354 this with a previously assigned pointer value */
1355 if (POINTER_GET(ic) &&
1356 !(IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
1357 isOperandVolatile(IC_LEFT(ic),TRUE))) {
1359 applyToSet(ptrSetSet,findPointerSet,IC_LEFT(ic),&pdop,IC_RESULT(ic));
1360 /* if we find it then locally replace all
1361 references to the result with what we assigned */
1363 replaceAllSymBySym(ic->next,IC_RESULT(ic),pdop);
1367 /* delete from the cseSet anything that has */
1368 /* operands matching the result of this */
1369 /* except in case of pointer access */
1370 if (!(POINTER_SET(ic)) && IC_RESULT(ic)) {
1371 deleteItemIf (&cseSet,ifOperandsHave,IC_RESULT(ic));
1372 /* delete any previous definitions */
1373 ebb->defSet = bitVectCplAnd (ebb->defSet,OP_DEFS(IC_RESULT(ic)));
1377 /* add the left & right to the defUse set */
1378 if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic))) {
1379 OP_USES(IC_LEFT(ic)) =
1380 bitVectSetBit (OP_USES(IC_LEFT(ic)),ic->key);
1381 setUsesDefs(IC_LEFT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1385 if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic))) {
1386 OP_USES(IC_RIGHT(ic)) =
1387 bitVectSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
1388 setUsesDefs(IC_RIGHT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1392 /* for the result it is special case, put the result */
1393 /* in the defuseSet if it a pointer or array access */
1394 if ( POINTER_SET(defic) ) {
1395 OP_USES(IC_RESULT(ic)) =
1396 bitVectSetBit (OP_USES(IC_RESULT(ic)),ic->key);
1397 setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1398 deleteItemIf(&cseSet,ifPointerGet,IC_RESULT(ic));
1399 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RESULT(ic)->key);
1400 /* delete from inexpressions of all successors which
1401 have dfNum > than this block */
1402 for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1403 applyToSet(ebb->succList,delGetPointerSucc,IC_RESULT(ic),ebb->dfnum);
1405 /* delete from cseSet all other pointer sets
1407 deleteItemIf(&ptrSetSet,ifPointerSet,IC_RESULT(ic));
1408 /* add to the local pointerset set */
1409 addSetHead(&ptrSetSet,newCseDef(IC_RESULT(ic),ic));
1411 else /* add the result to defintion set */
1412 if (IC_RESULT(ic)) {
1413 OP_DEFS(IC_RESULT(ic)) =
1414 bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
1415 ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);
1416 ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic)));
1417 ebb->ldefs = bitVectSetBit (ebb->ldefs,ic->key);
1421 /* if this is an addressof instruction then */
1422 /* put the symbol in the address of list & */
1423 /* delete it from the cseSet */
1424 if (defic->op == ADDRESS_OF) {
1425 addSetHead (&ebb->addrOf, IC_LEFT(ic));
1426 deleteItemIf(&cseSet,ifDefSymIsX,IC_LEFT(ic));
1430 setToNull ((void **)&ebb->outExprs);
1431 ebb->outExprs = cseSet;
1432 ebb->outDefs = bitVectUnion (ebb->outDefs,ebb->defSet);
1433 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet,ebb->inPtrsSet);
1437 /*-----------------------------------------------------------------*/
1438 /* cseAllBlocks - will sequentially go thru & do cse for all blocks*/
1439 /*-----------------------------------------------------------------*/
1440 int cseAllBlocks (eBBlock **ebbs,int count)
1445 /* if optimization turned off */
1447 for (i = 0 ; i < count ;i++ )
1448 change += cseBBlock (ebbs[i],FALSE,ebbs,count);