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)
71 fprintf(stdout,"**null op**");
72 printOperand(cdp->sym,stdout);
73 icTab = getTableEntry(cdp->diCode->op) ;
74 icTab->iCodePrint(stdout,cdp->diCode,icTab->printName);
78 /*-----------------------------------------------------------------*/
79 /* replaceAllSymBySym - replaces all operands by operand in an */
80 /* instruction chain */
81 /*-----------------------------------------------------------------*/
82 void replaceAllSymBySym (iCode *ic, operand *from , operand *to)
86 for (lic = ic ; lic ; lic = lic->next ) {
89 if (IC_RESULT(lic) && IC_RESULT(lic)->key == from->key ) {
90 /* maintain du chains */
91 if (POINTER_SET(lic)) {
92 bitVectUnSetBit (OP_USES(from),lic->key);
93 OP_USES(to) = bitVectSetBit (OP_USES(to),lic->key);
96 bitVectUnSetBit (OP_DEFS(from),lic->key);
97 OP_DEFS(to) = bitVectSetBit (OP_DEFS(to),lic->key);
99 siaddr = IC_RESULT(lic)->isaddr ;
100 IC_RESULT(lic) = operandFromOperand(to);
101 IC_RESULT(lic)->isaddr = siaddr ;
104 if (IC_RIGHT(lic) && IC_RIGHT(lic)->key == from->key ) {
105 bitVectUnSetBit (OP_USES(from),lic->key);
106 OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
107 siaddr = IC_RIGHT(lic)->isaddr ;
108 IC_RIGHT(lic) = operandFromOperand(to);
109 IC_RIGHT(lic)->isaddr = siaddr ;
112 if (IC_LEFT(lic) && IC_LEFT(lic)->key == from->key ) {
113 bitVectUnSetBit (OP_USES(from),lic->key);
114 OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
115 siaddr = IC_LEFT(lic)->isaddr ;
116 IC_LEFT(lic) = operandFromOperand(to);
117 IC_LEFT(lic)->isaddr = siaddr ;
122 /*-----------------------------------------------------------------*/
123 /* iCodeKeyIs - if the icode keys match then return 1 */
124 /*-----------------------------------------------------------------*/
125 DEFSETFUNC(iCodeKeyIs)
130 if (cdp->diCode->key == key)
136 /*-----------------------------------------------------------------*/
137 /* removeFromInExprs - removes an icode from inexpressions */
138 /*-----------------------------------------------------------------*/
139 DEFSETFUNC(removeFromInExprs)
143 V_ARG(operand *,from);
145 V_ARG(eBBlock *,cbp);
151 deleteItemIf(&ebp->inExprs,iCodeKeyIs,ic->key);
152 if (ebp != cbp && !bitVectBitValue(cbp->domVect,ebp->bbnum))
153 replaceAllSymBySym(ebp->sch,from,to);
155 applyToSet(ebp->succList,removeFromInExprs,ic,from,to,cbp);
159 /*-----------------------------------------------------------------*/
160 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
161 /*-----------------------------------------------------------------*/
162 static bool isGlobalInNearSpace (operand *op)
164 link *type = getSpec(operandType(op));
165 /* this is 8051 specific: optimization
166 suggested by Jean-Louis VERN, with 8051s we have no
167 advantage of putting variables in near space into
169 if (isOperandGlobal(op) &&
170 IN_DIRSPACE(SPEC_OCLS(type)))
176 /*-----------------------------------------------------------------*/
177 /* findCheaperOp - cseBBlock support routine, will check to see if */
178 /* we have a operand previously defined */
179 /*-----------------------------------------------------------------*/
180 DEFSETFUNC(findCheaperOp)
183 V_ARG(operand *,cop);
184 V_ARG(operand **,opp);
186 /* if we have already found it */
190 /* not found it yet check if this is the one */
191 /* and this is not the defining one */
192 if (cop->key == cdp->key) {
194 /* do a special check this will help in */
195 /* constant propagation & dead code elim*/
196 /* for assignments only */
197 if (cdp->diCode->op == '=') {
198 /* if the result is volatile then return result */
199 if (IS_OP_VOLATILE (IC_RESULT(cdp->diCode)))
200 *opp = IC_RESULT(cdp->diCode);
202 /* if this is a straight assignment and
203 left is a temp then prefer the temporary to the
205 if (!POINTER_SET(cdp->diCode) &&
206 IS_ITEMP(IC_RESULT(cdp->diCode)) &&
207 IS_TRUE_SYMOP(IC_RIGHT(cdp->diCode)))
208 *opp = IC_RESULT(cdp->diCode);
210 /* if straight assignement && and both
211 are temps then prefer the one that
212 will not need extra space to spil, also
213 take into consideration if right side
214 an induction variable
216 if (!POINTER_SET(cdp->diCode) &&
217 IS_ITEMP(IC_RESULT(cdp->diCode)) &&
218 IS_ITEMP(IC_RIGHT(cdp->diCode)) &&
219 !OP_SYMBOL(IC_RIGHT(cdp->diCode))->isind &&
220 ( (!SPIL_LOC(IC_RIGHT(cdp->diCode)) &&
221 SPIL_LOC(IC_RESULT(cdp->diCode))) ||
222 ( SPIL_LOC(IC_RESULT(cdp->diCode)) &&
223 SPIL_LOC(IC_RESULT(cdp->diCode)) ==
224 SPIL_LOC(IC_RIGHT(cdp->diCode))) )
226 *opp = IC_RESULT(cdp->diCode);
228 *opp = IC_RIGHT(cdp->diCode);
231 *opp = IC_RESULT(cdp->diCode) ;
234 /* if this is an assign to a temp. then check
235 if the right side is this then return this */
236 if (IS_TRUE_SYMOP(cop) &&
237 cdp->diCode->op == '=' &&
238 !POINTER_SET(cdp->diCode) &&
239 cop->key == IC_RIGHT(cdp->diCode)->key &&
240 !isGlobalInNearSpace (IC_RIGHT(cdp->diCode)) &&
241 IS_ITEMP(IC_RESULT(cdp->diCode)))
242 *opp = IC_RESULT(cdp->diCode);
246 if ((isGlobalInNearSpace(cop) &&
247 !isOperandLiteral(*opp)) ||
248 isOperandVolatile(*opp,FALSE)
254 if (cop->key == (*opp)->key ) {
259 if ((*opp)->isaddr != cop->isaddr && IS_ITEMP(cop)) {
260 *opp = operandFromOperand(*opp);
261 (*opp)->isaddr = cop->isaddr;
271 /*-----------------------------------------------------------------*/
272 /* findPointerSet - finds the right side of a pointer set op */
273 /*-----------------------------------------------------------------*/
274 DEFSETFUNC(findPointerSet)
278 V_ARG(operand **,opp);
280 if (POINTER_SET(cdp->diCode) &&
281 IC_RESULT(cdp->diCode)->key == op->key &&
282 !isOperandVolatile(IC_RESULT(cdp->diCode),TRUE) &&
283 !isOperandVolatile(IC_RIGHT(cdp->diCode),TRUE)) {
284 *opp = IC_RIGHT(cdp->diCode);
291 /*-----------------------------------------------------------------*/
292 /* findPrevIc - cseBBlock support function will return the iCode */
293 /* which matches the current one */
294 /*-----------------------------------------------------------------*/
295 DEFSETFUNC(findPrevIc)
301 /* if already found */
305 /* if the iCodes are the same */
306 if (isiCodeEqual(ic,cdp->diCode) &&
307 isOperandEqual(cdp->sym,IC_RESULT(cdp->diCode))) {
312 /* if iCodes are not the same */
313 /* see the operands maybe interchanged */
314 if (ic->op == cdp->diCode->op &&
315 ( ic->op == '+' || ic->op == '*' ) &&
316 isOperandEqual(IC_LEFT(ic),IC_RIGHT(cdp->diCode)) &&
317 isOperandEqual(IC_RIGHT(ic),IC_LEFT(cdp->diCode))) {
325 /*-----------------------------------------------------------------*/
326 /* ifDefGlobal - if definition is global */
327 /*-----------------------------------------------------------------*/
328 DEFSETFUNC(ifDefGlobal)
332 return (isOperandGlobal(cdp->sym));
335 /*-----------------------------------------------------------------*/
336 /* ifOperandsHave - if any of the operand are the same as this */
337 /*-----------------------------------------------------------------*/
338 DEFSETFUNC(ifOperandsHave)
344 if (IC_LEFT(cdp->diCode) &&
345 IS_SYMOP(IC_LEFT(cdp->diCode)) &&
346 IC_LEFT(cdp->diCode)->key == op->key)
349 if (IC_RIGHT(cdp->diCode) &&
350 IS_SYMOP(IC_RIGHT(cdp->diCode)) &&
351 IC_RIGHT(cdp->diCode)->key == op->key)
354 /* or if any of the operands are volatile */
355 if (IC_LEFT(cdp->diCode) &&
356 IS_OP_VOLATILE(IC_LEFT(cdp->diCode)))
359 if (IC_RIGHT(cdp->diCode) &&
360 IS_OP_VOLATILE(IC_RIGHT(cdp->diCode)))
364 if (IC_RESULT(cdp->diCode) &&
365 IS_OP_VOLATILE(IC_RESULT(cdp->diCode)))
371 /*-----------------------------------------------------------------*/
372 /* ifDefSymIs - if a definition is found in the set */
373 /*-----------------------------------------------------------------*/
374 int ifDefSymIs (set *cseSet, operand *sym)
379 if (!sym || !IS_SYMOP(sym))
381 for (sl = cseSet ; sl ; sl = sl->next ) {
383 if (loop->sym->key == sym->key )
390 /*-----------------------------------------------------------------*/
391 /* ifDefSymIsX - will return 1 if the symbols match */
392 /*-----------------------------------------------------------------*/
393 DEFSETFUNC(ifDefSymIsX)
399 return cdp->sym->key == op->key ;
401 return ( isOperandEqual(cdp->sym,op) );
406 /*-----------------------------------------------------------------*/
407 /* ifDiCodeIs - returns truw if diCode is same */
408 /*-----------------------------------------------------------------*/
409 int ifDiCodeIs (set *cseSet, iCode *ic)
417 for (sl = cseSet ; sl ; sl = sl->next ) {
419 if (loop->diCode == ic)
426 /*-----------------------------------------------------------------*/
427 /* ifPointerGet - returns true if the icode is pointer get sym */
428 /*-----------------------------------------------------------------*/
429 DEFSETFUNC(ifPointerGet)
434 if (POINTER_GET(cdp->diCode) &&
435 IC_LEFT(cdp->diCode)->key == op->key)
441 /*-----------------------------------------------------------------*/
442 /* ifPointerSet - returns true if the icode is pointer set sym */
443 /*-----------------------------------------------------------------*/
444 DEFSETFUNC(ifPointerSet)
449 if (POINTER_SET(cdp->diCode) &&
450 IC_RESULT(cdp->diCode)->key == op->key)
456 /*-----------------------------------------------------------------*/
457 /* ifDiCodeIsX - will return 1 if the symbols match */
458 /*-----------------------------------------------------------------*/
459 DEFSETFUNC(ifDiCodeIsX)
464 return cdp->diCode == ic;
468 /*-----------------------------------------------------------------*/
469 /* algebraicOpts - does some algebraic optimizations */
470 /*-----------------------------------------------------------------*/
471 void algebraicOpts (iCode *ic)
473 /* we don't deal with the following iCodes
484 /* if both operands present & ! IFX */
485 /* then if they are both literal we */
486 /* perform the operation right now */
490 IS_OP_LITERAL(IC_LEFT(ic)) &&
491 IS_OP_LITERAL(IC_RIGHT(ic))) {
493 IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
496 operandType(IC_RESULT(ic)));
499 SET_RESULT_RIGHT(ic);
503 /* if not ifx & only one operand present */
506 IS_OP_LITERAL(IC_LEFT(ic)) &&
509 IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
512 operandType(IC_RESULT(ic)));
515 SET_RESULT_RIGHT(ic);
520 /* a special case : or in short a kludgy solution will think
521 about a better solution over a glass of wine someday */
522 if ( ic->op == GET_VALUE_AT_ADDRESS ) {
524 if (IS_ITEMP(IC_RESULT(ic)) &&
525 IS_TRUE_SYMOP(IC_LEFT(ic))) {
528 IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic));
529 IC_RIGHT(ic)->isaddr = 0;
531 IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
532 IC_RESULT(ic)->isaddr = 0;
533 setOperandType(IC_RESULT(ic),operandType(IC_RIGHT(ic)));
537 if (IS_ITEMP(IC_LEFT(ic)) &&
538 IS_ITEMP(IC_RESULT(ic)) &&
539 /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
540 /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
541 !IC_LEFT(ic)->isaddr ) {
543 IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic));
544 IC_RIGHT(ic)->isaddr = 0;
545 IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
546 IC_RESULT(ic)->isaddr = 0;
554 /* depending on the operation */
557 /* if adding the same thing change to left shift by 1*/
558 if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key &&
559 !IS_FLOAT(operandType(IC_RESULT(ic)))) {
561 IC_RIGHT(ic) = operandFromLit(1);
564 /* if addition then check if one of them is a zero */
565 /* if yes turn it into assignmnt*/
566 if (IS_OP_LITERAL(IC_LEFT(ic)) &&
567 operandLitValue(IC_LEFT(ic)) == 0.0 ) {
571 SET_ISADDR(IC_RESULT(ic),0);
572 SET_ISADDR(IC_RIGHT(ic),0);
575 if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
576 operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
579 IC_RIGHT(ic) = IC_LEFT(ic) ;
581 SET_ISADDR(IC_RIGHT(ic),0);
582 SET_ISADDR(IC_RESULT(ic),0);
587 /* if subtracting the the same thing then zero */
588 if ( IC_LEFT(ic)->key == IC_RIGHT(ic)->key ) {
590 IC_RIGHT(ic) = operandFromLit(0);
592 IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
593 IC_RESULT(ic)->isaddr = 0;
597 /* if subtraction then check if one of the operand */
598 /* is zero then depending on which operand change */
599 /* to assignment or unary minus */
600 if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
601 operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
602 /* right size zero change to assignment */
604 IC_RIGHT(ic) = IC_LEFT(ic);
606 SET_ISADDR(IC_RIGHT(ic),0);
607 SET_ISADDR(IC_RESULT(ic),0);
610 if (IS_OP_LITERAL(IC_LEFT(ic)) &&
611 operandLitValue (IC_LEFT(ic)) == 0.0) {
612 /* left zero turn into an unary minus */
613 ic->op = UNARYMINUS ;
614 IC_LEFT(ic) = IC_RIGHT(ic);
615 IC_RIGHT(ic) = NULL ;
619 /* if multiplication then check if either of */
620 /* them is zero then the result is zero */
621 /* if either of them is one then result is */
624 if (IS_OP_LITERAL(IC_LEFT(ic))) {
626 if (operandLitValue(IC_LEFT(ic)) == 0.0) {
628 IC_RIGHT(ic) = IC_LEFT(ic);
630 SET_RESULT_RIGHT(ic);
633 if ( operandLitValue(IC_LEFT(ic)) == 1.0) {
636 SET_RESULT_RIGHT(ic);
641 if (IS_OP_LITERAL(IC_RIGHT(ic))) {
643 if (operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
646 SET_RESULT_RIGHT(ic);
650 if (operandLitValue(IC_RIGHT(ic)) == 1.0) {
652 IC_RIGHT(ic) = IC_LEFT(ic);
654 SET_RESULT_RIGHT(ic);
660 /* if division by self then 1 */
661 if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key) {
663 IC_RIGHT(ic) = operandFromLit(1);
665 IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
666 IC_RESULT(ic)->isaddr = 0;
668 /* if this is a division then check if right */
669 /* is one then change it to an assignment */
670 if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
671 operandLitValue(IC_RIGHT(ic)) == 1.0 ) {
674 IC_RIGHT(ic) = IC_LEFT(ic);
676 SET_RESULT_RIGHT(ic);
680 /* if both are the same for an comparison operators */
684 if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) {
686 IC_RIGHT(ic) = operandFromLit(1);
688 SET_RESULT_RIGHT(ic);
694 if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) {
696 IC_RIGHT(ic) = operandFromLit(0);
698 SET_RESULT_RIGHT(ic);
702 /* if this is a cast of a literal value */
703 if ( IS_OP_LITERAL(IC_RIGHT(ic))) {
706 operandFromValue (valCastLiteral(operandType(IC_LEFT(ic)),
707 operandLitValue(IC_RIGHT(ic))));
709 SET_ISADDR(IC_RESULT(ic),0);
711 /* if casting to the same */
712 if ( checkType(operandType(IC_RESULT(ic)),
713 operandType(IC_RIGHT(ic))) == 1) {
716 SET_ISADDR(IC_RESULT(ic),0);
720 if (IS_OP_LITERAL(IC_LEFT(ic))) {
723 (operandLitValue(IC_LEFT(ic)) == 0 ?
724 operandFromLit(1) : operandFromLit(0));
726 SET_ISADDR(IC_RESULT(ic),0);
732 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
733 /*-----------------------------------------------------------------*/
734 /* updateSpillLocation - keeps track of register spill location */
735 /*-----------------------------------------------------------------*/
736 void updateSpillLocation ( iCode *ic)
747 /* for the form true_symbol := iTempNN */
748 if (ASSIGN_ITEMP_TO_SYM(ic)
749 && !SPIL_LOC(IC_RIGHT(ic))) {
751 setype = getSpec(operandType(IC_RESULT(ic)));
753 if (!IC_RIGHT(ic)->noSpilLoc &&
754 !IS_VOLATILE(setype) &&
755 !IN_FARSPACE(SPEC_OCLS(setype)) &&
756 !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )
758 SPIL_LOC(IC_RIGHT(ic)) =
759 IC_RESULT(ic)->operand.symOperand;
762 if (ASSIGN_ITEMP_TO_ITEMP(ic) &&
763 !SPIL_LOC(IC_RIGHT(ic)) &&
764 OP_SYMBOL(IC_RESULT(ic))->isreqv) {
766 setype = getSpec(operandType(IC_RESULT(ic)));
768 if (!IC_RIGHT(ic)->noSpilLoc &&
769 !IS_VOLATILE(setype) &&
770 !IN_FARSPACE(SPEC_OCLS(setype)) &&
771 !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )
773 SPIL_LOC(IC_RIGHT(ic)) =
774 SPIL_LOC(IC_RESULT(ic));
778 /*-----------------------------------------------------------------*/
779 /* setUsesDef - sets the uses def bitvector for a given operand */
780 /*-----------------------------------------------------------------*/
781 void setUsesDefs (operand *op, bitVect *bdefs,
782 bitVect *idefs, bitVect **oud)
784 /* compute the definitions alive at this point */
785 bitVect *adefs = bitVectUnion(bdefs,idefs);
787 /* of these definitions find the ones that are */
788 /* for this operand */
789 adefs = bitVectIntersect(adefs,OP_DEFS(op));
791 /* these are the definitions that this operand can use */
792 op->usesDefs = adefs;
794 /* the out defs is an union */
795 *oud = bitVectUnion(*oud,adefs);
798 /*-----------------------------------------------------------------*/
799 /* ifxOptimize - changes ifx conditions if it can */
800 /*-----------------------------------------------------------------*/
801 void ifxOptimize (iCode *ic, set *cseSet,
803 eBBlock *ebb, int *change,
804 eBBlock **ebbs, int count)
809 /* if the condition can be replaced */
812 applyToSetFTrue (cseSet,findCheaperOp,IC_COND(ic),&pdop);
819 /* if the conditional is a literal then */
820 if (IS_OP_LITERAL(IC_COND(ic))) {
822 if ( operandLitValue(IC_COND(ic)) && IC_TRUE(ic)) {
824 /* change to a goto */
826 IC_LABEL(ic) = IC_TRUE(ic);
831 if (!operandLitValue(IC_COND(ic)) && IC_FALSE(ic)) {
833 IC_LABEL(ic) = IC_FALSE(ic);
837 /* then kill this if condition */
838 remiCodeFromeBBlock (ebb,ic);
842 /* now we need to recompute the control flow */
843 /* since the control flow has changed */
844 /* this is very expensive but it does not happen */
845 /* too often, if it does happen then the user pays */
847 computeControlFlow (ebbs,count,1);
848 werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
852 /* if there is only one successor and that successor
853 is the same one we are conditionally going to then
854 we can remove this conditional statement */
855 label = (IC_TRUE(ic) ? IC_TRUE(ic) : IC_FALSE(ic));
856 if (elementsInSet(ebb->succList) == 1 &&
857 isinSet(ebb->succList,eBBWithEntryLabel(ebbs,label,count))) {
859 remiCodeFromeBBlock(ebb,ic);
860 computeControlFlow (ebbs,count,1);
861 werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
866 /* if it remains an IFX the update the use Set */
867 OP_USES(IC_COND(ic)) = bitVectSetBit(OP_USES(IC_COND(ic)),ic->key);
868 setUsesDefs(IC_COND(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
872 /*-----------------------------------------------------------------*/
873 /* unsetDefsAndUses - clear this operation for the operands */
874 /*-----------------------------------------------------------------*/
875 void unsetDefsAndUses ( iCode *ic )
877 if ( ic->op == JUMPTABLE)
880 /* take away this definition from the def chain of the */
881 /* result & take away from use set of the operands */
883 /* turn off def set */
884 if (IS_SYMOP(IC_RESULT(ic))) {
885 if ( !POINTER_SET(ic))
886 bitVectUnSetBit(OP_DEFS(IC_RESULT(ic)),ic->key);
888 bitVectUnSetBit(OP_USES(IC_RESULT(ic)),ic->key);
890 /* turn off the useSet for the operands */
891 if (IS_SYMOP(IC_LEFT(ic)))
892 bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key);
894 if (IS_SYMOP(IC_RIGHT(ic)))
895 bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
897 else /* must be ifx turn off the use */
898 if (IS_SYMOP(IC_COND(ic)))
899 bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key);
902 /*-----------------------------------------------------------------*/
903 /* diCodeForSym - finds the definiting instruction for a symbol */
904 /*-----------------------------------------------------------------*/
905 DEFSETFUNC(diCodeForSym)
908 V_ARG(operand *,sym);
911 /* if already found */
915 /* if not if this is the defining iCode */
916 if (sym->key == cdp->key) {
924 /*-----------------------------------------------------------------*/
925 /* constFold - does some constant folding */
926 /*-----------------------------------------------------------------*/
927 int constFold (iCode *ic, set *cseSet)
930 /* this routine will change
936 /* deal with only + & - */
941 /* this check is a hueristic to prevent live ranges
942 from becoming too long */
943 if (IS_PTR(operandType(IC_RESULT(ic))))
946 /* check if operation with a literal */
947 if (!IS_OP_LITERAL(IC_RIGHT(ic)))
950 /* check if we can find a definition for the
952 if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(ic),&dic)))
955 /* check that this is also a +/- */
956 if (dic->op != '+' && dic->op != '-')
960 if (!IS_OP_LITERAL(IC_RIGHT(dic)))
963 /* it is if the operations are the same*/
964 /* the literal parts need to be added */
965 IC_LEFT(ic) = operandFromOperand(IC_LEFT(dic));
966 if (ic->op == dic->op )
967 IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic))+
968 operandLitValue(IC_RIGHT(dic)));
970 IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) -
971 operandLitValue(IC_RIGHT(dic)));
973 if (IS_ITEMP(IC_RESULT(ic))) {
974 SPIL_LOC(IC_RESULT(ic)) = NULL;
975 IC_RESULT(ic)->noSpilLoc = 1;
982 /*-----------------------------------------------------------------*/
983 /* deleteGetPointers - called when a pointer is passed as parm */
984 /* will delete from cseSet all get pointers computed from this */
985 /* pointer. A simple ifOperandsHave is not good enough here */
986 /*-----------------------------------------------------------------*/
987 static void deleteGetPointers (set **cseSet,operand *op,eBBlock *ebb)
989 set *compItems = NULL;
997 /* first find all items computed from this operand .
998 This done fairly simply go thru the list and find
999 those that are computed by arthimetic with this
1001 for (cdp = setFirstItem(*cseSet); cdp ; cdp = setNextItem(*cseSet)) {
1002 if (IS_ARITHMETIC_OP(cdp->diCode)) {
1003 if (isOperandEqual(IC_LEFT(cdp->diCode),op) ||
1004 isOperandEqual(IC_RIGHT(cdp->diCode),op)) {
1005 /* save it in our list of items */
1006 addSet(&compItems,IC_RESULT(cdp->diCode));
1008 /* also check for those computed from our computed
1009 list . This will take care of situations like
1010 iTemp1 = iTemp0 + 8;
1011 iTemp2 = iTemp1 + 8; */
1012 if (isinSetWith(compItems,IC_LEFT(cdp->diCode),isOperandEqual) ||
1013 isinSetWith(compItems,IC_RIGHT(cdp->diCode),isOperandEqual)) {
1014 addSet(&compItems,IC_RESULT(cdp->diCode));
1019 /* now delete all pointer gets with this op */
1020 deleteItemIf(cseSet,ifPointerGet,op);
1021 /* set the bit vector used by dataFlow computation later */
1022 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,op->key);
1023 /* now for the computed items */
1024 for (cop = setFirstItem(compItems); cop ; cop = setNextItem(compItems)) {
1025 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,cop->key);
1026 deleteItemIf(cseSet,ifPointerGet,cop);
1030 /*-----------------------------------------------------------------*/
1031 /* delGetPointerSucc - delete get pointer from inExprs of succ with*/
1032 /* dfnum > supplied */
1033 /*-----------------------------------------------------------------*/
1034 DEFSETFUNC(delGetPointerSucc)
1036 eBBlock *ebp = item;
1037 V_ARG(operand *,op);
1044 if (ebp->dfnum > dfnum) {
1045 deleteItemIf(&ebp->inExprs,ifPointerGet,op);
1048 return applyToSet(ebp->succList,delGetPointerSucc,op,dfnum);
1051 /*-----------------------------------------------------------------*/
1052 /* cseBBlock - common subexpression elimination for basic blocks */
1053 /* this is the hackiest kludgiest routine in the whole */
1054 /* system. also the most important, since almost all */
1055 /* data flow related information is computed by it */
1056 /*-----------------------------------------------------------------*/
1057 int cseBBlock ( eBBlock *ebb, int computeOnly,
1058 eBBlock **ebbs, int count)
1064 set *ptrSetSet = NULL;
1066 /* if this block is not reachable */
1070 /* set of common subexpressions */
1071 cseSet = setFromSet (ebb->inExprs) ;
1073 /* these will be computed by this routine */
1074 setToNull ((void **)&ebb->outDefs);
1075 setToNull ((void **)&ebb->defSet);
1076 setToNull ((void **)&ebb->usesDefs);
1077 setToNull ((void **)&ebb->ptrsSet);
1078 setToNull ((void **)&ebb->addrOf);
1079 setToNull ((void **)&ebb->ldefs);
1081 ebb->outDefs = bitVectCopy (ebb->inDefs);
1082 bitVectDefault = iCodeKey;
1083 ebb->defSet = newBitVect(iCodeKey);
1084 ebb->usesDefs=newBitVect(iCodeKey);
1086 /* for all the instructions in this block do */
1087 for (ic = ebb->sch ; ic ; ic = ic->next ) {
1096 /* clear the def & use chains for the operands involved */
1097 /* in this operation . since it can change due to opts */
1098 unsetDefsAndUses (ic);
1100 if ( ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE) {
1101 /* add to defSet of the symbol */
1102 OP_DEFS(IC_RESULT(ic)) =
1103 bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
1104 /* add to the definition set of this block */
1105 ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);
1106 ebb->ldefs = bitVectSetBit (ebb->ldefs,ic->key);
1107 ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic)));
1108 setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1109 /* delete global variables from the cseSet
1110 since they can be modified by the function call */
1111 deleteItemIf(&cseSet,ifDefGlobal);
1114 /* for pcall & ipush we need to add to the useSet */
1115 if ((ic->op == PCALL ||
1119 IS_SYMOP(IC_LEFT(ic))) {
1121 /* check if they can be replaced */
1122 if ( !computeOnly ) {
1124 applyToSetFTrue(cseSet,findCheaperOp,IC_LEFT(ic),&pdop);
1126 IC_LEFT(ic) = pdop ;
1128 /* the lookup could have changed it*/
1129 if (IS_SYMOP(IC_LEFT(ic))) {
1130 OP_USES(IC_LEFT(ic)) =
1131 bitVectSetBit(OP_USES(IC_LEFT(ic)),ic->key);
1132 setUsesDefs(IC_LEFT(ic),ebb->defSet,
1133 ebb->outDefs,&ebb->usesDefs);
1135 /* if we a sending a pointer as a parameter
1136 then kill all cse since the pointed to item
1137 might be changed in the function being called */
1138 if (IS_PTR(operandType(IC_LEFT(ic)))) {
1139 deleteGetPointers(&cseSet,IC_LEFT(ic),ebb);
1144 /* if jumptable then mark the usage */
1145 if (ic->op == JUMPTABLE ) {
1146 OP_USES(IC_JTCOND(ic)) =
1147 bitVectSetBit(OP_USES(IC_JTCOND(ic)),ic->key);
1148 setUsesDefs(IC_JTCOND(ic),ebb->defSet,
1149 ebb->outDefs,&ebb->usesDefs);
1156 /* do some algebraic optimizations if possible */
1158 while (constFold(ic,cseSet));
1160 /* if this is a condition statment then */
1161 /* check if the condition can be replaced */
1162 if (ic->op == IFX ) {
1163 ifxOptimize (ic, cseSet, computeOnly,
1169 /* if the assignment & result is a temp */
1170 /* see if we can replace it */
1171 if (ic->op == '=') {
1173 /* update the spill location for this */
1174 updateSpillLocation (ic);
1176 if (POINTER_SET(ic)) {
1178 applyToSetFTrue (cseSet,findCheaperOp,IC_RESULT(ic),&pdop);
1179 if (pdop && IS_ITEMP(pdop) && !computeOnly)
1180 IC_RESULT(ic) = pdop;
1184 /* do the operand lookup i.e. for both the */
1185 /* right & left operand : check the cseSet */
1186 /* to see if they have been replaced if yes*/
1187 /* then replace them with those from cseSet*/
1189 /* and left is a symbol */
1190 if (IS_SYMOP(IC_LEFT(ic)) &&
1191 !computeOnly && ic->op != ADDRESS_OF ) {
1194 applyToSetFTrue (cseSet,findCheaperOp,IC_LEFT(ic),&pdop) ;
1196 if (POINTER_GET(ic)) {
1197 if (IS_ITEMP(pdop) || IS_OP_LITERAL(pdop)) {
1201 /* check if there is a pointer set
1202 for the same pointer visible if yes
1203 then change this into an assignment */
1205 if (applyToSetFTrue(cseSet,findPointerSet,IC_LEFT(ic),&pdop)){
1208 IC_RIGHT(ic) = pdop;
1209 SET_ISADDR(IC_RESULT(ic),0);
1214 IC_LEFT(ic) = pdop ;
1221 if (IS_SYMOP(IC_RIGHT(ic)) && !computeOnly) {
1224 applyToSetFTrue (cseSet,findCheaperOp,IC_RIGHT(ic),&pdop);
1227 IC_RIGHT(ic) = pdop;
1232 /* if left or right changed then do algebraic */
1235 while(constFold(ic,cseSet));
1238 /* if after all this it becomes a assignment to self
1239 then delete it and continue */
1240 if (ASSIGNMENT_TO_SELF(ic)) {
1241 remiCodeFromeBBlock(ebb,ic);
1245 /* now we will check to see if the entire */
1246 /* operation has been performed before */
1247 /* and is available */
1248 /* don't do assignments they will be killed */
1249 /* by dead code elimination if required do */
1250 /* it only if result is a temporary */
1252 if (!( POINTER_GET(ic) &&
1253 (IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
1254 isOperandVolatile(IC_LEFT(ic),TRUE))) &&
1256 IS_ITEMP(IC_RESULT(ic)) &&
1258 applyToSet (cseSet,findPrevIc,ic,&pdic);
1261 /* if found then eliminate this and add to*/
1262 /* to cseSet an element containing result */
1263 /* of this with previous opcode */
1266 if (IS_ITEMP(IC_RESULT(ic))) {
1268 /* replace in the remaining of this block */
1269 replaceAllSymBySym(ic->next,IC_RESULT(ic),IC_RESULT(pdic));
1270 /* remove this iCode from inexpressions of all
1271 its successors, it cannot be in the in expressions
1272 of any of the predecessors */
1273 for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1274 applyToSet(ebb->succList,removeFromInExprs,ic,IC_RESULT(ic),
1275 IC_RESULT(pdic),ebb);
1277 /* if this was moved from another block */
1278 /* then replace in those blocks too */
1279 if ( ic->movedFrom ) {
1281 for (owner = setFirstItem(ic->movedFrom); owner ;
1282 owner = setNextItem(ic->movedFrom))
1283 replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic));
1285 pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE);
1288 addSetHead (&cseSet,newCseDef(IC_RESULT(ic),pdic));
1291 /* eliminate this */
1292 remiCodeFromeBBlock (ebb,ic);
1297 if (IS_ITEMP(IC_RESULT(ic)))
1302 /* just add this as a previous expression except in */
1303 /* case of a pointer access in which case this is a */
1304 /* usage not a definition */
1305 if (! (POINTER_SET(ic)) && IC_RESULT(ic)){
1306 deleteItemIf (&cseSet, ifDefSymIsX,IC_RESULT(ic));
1307 addSetHead(&cseSet,newCseDef(IC_RESULT(ic),ic));
1313 /* if assignment to a parameter which is not
1314 mine and type is a pointer then delete
1315 pointerGets to take care of aliasing */
1316 if (ASSIGNMENT(ic) &&
1317 OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) &&
1318 IS_PTR(operandType(IC_RESULT(ic)))) {
1319 deleteGetPointers(&cseSet,IC_RIGHT(ic),ebb);
1322 /* if this is a pointerget then see if we can replace
1323 this with a previously assigned pointer value */
1324 if (POINTER_GET(ic) &&
1325 !(IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
1326 isOperandVolatile(IC_LEFT(ic),TRUE))) {
1328 applyToSet(ptrSetSet,findPointerSet,IC_LEFT(ic),&pdop);
1329 /* if we find it then locally replace all
1330 references to the result with what we assigned */
1332 replaceAllSymBySym(ic->next,IC_RESULT(ic),pdop);
1336 /* delete from the cseSet anything that has */
1337 /* operands matching the result of this */
1338 /* except in case of pointer access */
1339 if (!(POINTER_SET(ic)) && IC_RESULT(ic)) {
1340 deleteItemIf (&cseSet,ifOperandsHave,IC_RESULT(ic));
1341 /* delete any previous definitions */
1342 ebb->defSet = bitVectCplAnd (ebb->defSet,OP_DEFS(IC_RESULT(ic)));
1346 /* add the left & right to the defUse set */
1347 if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic))) {
1348 OP_USES(IC_LEFT(ic)) =
1349 bitVectSetBit (OP_USES(IC_LEFT(ic)),ic->key);
1350 setUsesDefs(IC_LEFT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1354 if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic))) {
1355 OP_USES(IC_RIGHT(ic)) =
1356 bitVectSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
1357 setUsesDefs(IC_RIGHT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1361 /* for the result it is special case, put the result */
1362 /* in the defuseSet if it a pointer or array access */
1363 if ( POINTER_SET(defic) ) {
1364 OP_USES(IC_RESULT(ic)) =
1365 bitVectSetBit (OP_USES(IC_RESULT(ic)),ic->key);
1366 setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
1367 deleteItemIf(&cseSet,ifPointerGet,IC_RESULT(ic));
1368 ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RESULT(ic)->key);
1369 /* delete from inexpressions of all successors which
1370 have dfNum > than this block */
1371 for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
1372 applyToSet(ebb->succList,delGetPointerSucc,IC_RESULT(ic),ebb->dfnum);
1374 /* delete from cseSet all other pointer sets
1376 deleteItemIf(&ptrSetSet,ifPointerSet,IC_RESULT(ic));
1377 /* add to the local pointerset set */
1378 addSetHead(&ptrSetSet,newCseDef(IC_RESULT(ic),ic));
1380 else /* add the result to defintion set */
1381 if (IC_RESULT(ic)) {
1382 OP_DEFS(IC_RESULT(ic)) =
1383 bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
1384 ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);
1385 ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic)));
1386 ebb->ldefs = bitVectSetBit (ebb->ldefs,ic->key);
1390 /* if this is an addressof instruction then */
1391 /* put the symbol in the address of list & */
1392 /* delete it from the cseSet */
1393 if (defic->op == ADDRESS_OF) {
1394 addSetHead (&ebb->addrOf, IC_LEFT(ic));
1395 deleteItemIf(&cseSet,ifDefSymIsX,IC_LEFT(ic));
1399 setToNull ((void **)&ebb->outExprs);
1400 ebb->outExprs = cseSet;
1401 ebb->outDefs = bitVectUnion (ebb->outDefs,ebb->defSet);
1402 ebb->ptrsSet = bitVectUnion (ebb->ptrsSet,ebb->inPtrsSet);
1406 /*-----------------------------------------------------------------*/
1407 /* cseAllBlocks - will sequentially go thru & do cse for all blocks*/
1408 /*-----------------------------------------------------------------*/
1409 int cseAllBlocks (eBBlock **ebbs,int count)
1414 /* if optimization turned off */
1416 for (i = 0 ; i < count ;i++ )
1417 change += cseBBlock (ebbs[i],FALSE,ebbs,count);