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 #include "SDCCglobl.h"
32 #include "SDCChasht.h"
35 #include "SDCCicode.h"
36 #include "SDCClabel.h"
37 #include "SDCCBBlock.h"
38 #include "SDCCcflow.h"
43 /*-----------------------------------------------------------------*/
44 /* pointerArithOpts - does some pointer arithmetic operations */
45 /*-----------------------------------------------------------------*/
46 int pointerArithOpts (iCode *ic, hTab *ptrs)
54 /* the aim here is to reduce the arithmetics performed */
55 /* during repeated pointer access . for eg. there are */
56 /* lot of places the code generated looks like this */
57 /* iTempNN = &[somevar] */
58 /* iTempNX = iTempNN + constant-1 */
59 /* *(iTempNX) := somevalue */
60 /* iTempNY = iTempNN + constant-2 */
61 /* *(iTempNY) := somevalue */
62 /* we want to change this sequence to */
63 /* iTempNN = &[somevar] */
64 /* iTempNN = iTempNN + constant-1 */
65 /* (*iTempNN) := someValue */
66 /* WHY ? this will reduce the number of definitions */
67 /* as well as help us in register allocation */
69 /* first check if +/- */
70 if (ic->op != '+' && ic->op != '-' )
73 /* if the result is not an iTemp */
74 if (!IS_ITEMP(IC_RESULT(ic)))
77 /* if +/- then check if one of them is literal */
78 if (! IS_OP_LITERAL(IC_LEFT(ic)) &&
79 ! IS_OP_LITERAL(IC_RIGHT(ic)) )
82 /* get the operand & literal value */
83 if (IS_OP_LITERAL(IC_LEFT(ic))) {
84 cval = operandLitValue(IC_LEFT(ic));
87 cval = operandLitValue(IC_RIGHT(ic)) ;
92 /* if this symbol does not exist the address of */
93 /* or if the symbol is the same as the result */
94 if (asym->key == IC_RESULT(ic)->key ||
95 (htip = hTabSearch(ptrs,asym->key)) == NULL )
101 /* if the constant value in induction is zero */
102 /* then we just change the operand */
104 ip->asym = IC_RESULT(ic) ;
105 ip->cval = cval ; /* update the offset info */
108 /* we can do the substitution */
109 replaceAllSymBySym (ic->next, IC_RESULT(ic),ip->asym);
110 IC_RESULT(ic) = operandFromOperand(ip->asym);
112 /* now we know that the constant value is greater than zero */
113 /* we have to do some arithmetic here : if the offset is greater */
114 /* than what we want then rechange it to subtraction */
115 if ( ip->cval > cval) {
118 IC_LEFT(ic) = operandFromOperand(ip->asym);
119 IC_RIGHT(ic) = operandFromLit(ip->cval - cval);
122 IC_RIGHT(ic) = operandFromOperand(ip->asym);
123 IC_LEFT(ic) = operandFromLit(ip->cval - cval);
127 IC_LEFT(ic) = operandFromOperand(ip->asym);
128 IC_RIGHT(ic) = operandFromLit(cval - ip->cval);
131 IC_RIGHT(ic) = operandFromOperand (ip->asym);
132 IC_LEFT(ic) = operandFromLit(cval - ip->cval);
140 /*-----------------------------------------------------------------*/
141 /* ptrAopts - pointer arithmetic optimizations for a basic block */
142 /*-----------------------------------------------------------------*/
143 void ptrAopts (eBBlock **ebbs, int count)
149 /* for each basic block do */
150 for (i = 0 ; i < count ; i++ ) {
153 setToNull((void **) &pointers);
154 /* iterate thru intructions in the basic block */
155 for (ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
157 if (SKIP_IC(ic) ||ic->op == IFX)
161 pointerArithOpts(ic,pointers);
163 if (!POINTER_SET(ic) && IC_RESULT(ic))
164 /* delete from pointer access */
165 hTabDeleteItem (&pointers, IC_RESULT(ic)->key,NULL,DELETE_CHAIN,NULL);
167 /* set up for pointers */
168 if ((ic->op == ADDRESS_OF || ADD_SUBTRACT_ITEMP(ic)) &&
169 IS_ITEMP(IC_RESULT(ic)) ) {
174 if ( ic->op == ADDRESS_OF){
180 asym = IC_RESULT(ic);
181 cval = operandLitValue(IC_RIGHT(ic));
184 /* put it in the pointer set */