1 /*-------------------------------------------------------------------------
3 SDCCptropt.c - source file for pointer arithmetic Optimizations
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
28 /*-----------------------------------------------------------------*/
29 /* pointerArithOpts - does some pointer arithmetic operations */
30 /*-----------------------------------------------------------------*/
31 int pointerArithOpts (iCode *ic, hTab *ptrs)
39 /* the aim here is to reduce the arithmetics performed */
40 /* during repeated pointer access . for eg. there are */
41 /* lot of places the code generated looks like this */
42 /* iTempNN = &[somevar] */
43 /* iTempNX = iTempNN + constant-1 */
44 /* *(iTempNX) := somevalue */
45 /* iTempNY = iTempNN + constant-2 */
46 /* *(iTempNY) := somevalue */
47 /* we want to change this sequence to */
48 /* iTempNN = &[somevar] */
49 /* iTempNN = iTempNN + constant-1 */
50 /* (*iTempNN) := someValue */
51 /* WHY ? this will reduce the number of definitions */
52 /* as well as help us in register allocation */
54 /* first check if +/- */
55 if (ic->op != '+' && ic->op != '-' )
58 /* if the result is not an iTemp */
59 if (!IS_ITEMP(IC_RESULT(ic)))
62 /* if +/- then check if one of them is literal */
63 if (! IS_OP_LITERAL(IC_LEFT(ic)) &&
64 ! IS_OP_LITERAL(IC_RIGHT(ic)) )
67 /* get the operand & literal value */
68 if (IS_OP_LITERAL(IC_LEFT(ic))) {
69 cval = operandLitValue(IC_LEFT(ic));
72 cval = operandLitValue(IC_RIGHT(ic)) ;
77 /* if this symbol does not exist the address of */
78 /* or if the symbol is the same as the result */
79 if (asym->key == IC_RESULT(ic)->key ||
80 (htip = hTabSearch(ptrs,asym->key)) == NULL )
86 /* if the constant value in induction is zero */
87 /* then we just change the operand */
89 ip->asym = IC_RESULT(ic) ;
90 ip->cval = cval ; /* update the offset info */
93 /* we can do the substitution */
94 replaceAllSymBySym (ic->next, IC_RESULT(ic),ip->asym);
95 IC_RESULT(ic) = operandFromOperand(ip->asym);
97 /* now we know that the constant value is greater than zero */
98 /* we have to do some arithmetic here : if the offset is greater */
99 /* than what we want then rechange it to subtraction */
100 if ( ip->cval > cval) {
103 IC_LEFT(ic) = operandFromOperand(ip->asym);
104 IC_RIGHT(ic) = operandFromLit(ip->cval - cval);
107 IC_RIGHT(ic) = operandFromOperand(ip->asym);
108 IC_LEFT(ic) = operandFromLit(ip->cval - cval);
112 IC_LEFT(ic) = operandFromOperand(ip->asym);
113 IC_RIGHT(ic) = operandFromLit(cval - ip->cval);
116 IC_RIGHT(ic) = operandFromOperand (ip->asym);
117 IC_LEFT(ic) = operandFromLit(cval - ip->cval);
125 /*-----------------------------------------------------------------*/
126 /* ptrAopts - pointer arithmetic optimizations for a basic block */
127 /*-----------------------------------------------------------------*/
128 void ptrAopts (eBBlock **ebbs, int count)
134 /* for each basic block do */
135 for (i = 0 ; i < count ; i++ ) {
138 setToNull((void **) &pointers);
139 /* iterate thru intructions in the basic block */
140 for (ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
142 if (SKIP_IC(ic) ||ic->op == IFX)
146 pointerArithOpts(ic,pointers);
148 if (!POINTER_SET(ic) && IC_RESULT(ic))
149 /* delete from pointer access */
150 hTabDeleteItem (&pointers, IC_RESULT(ic)->key,NULL,DELETE_CHAIN,NULL);
152 /* set up for pointers */
153 if ((ic->op == ADDRESS_OF || ADD_SUBTRACT_ITEMP(ic)) &&
154 IS_ITEMP(IC_RESULT(ic)) ) {
159 if ( ic->op == ADDRESS_OF){
165 asym = IC_RESULT(ic);
166 cval = operandLitValue(IC_RIGHT(ic));
169 /* put it in the pointer set */