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 /* findPointerGetSet - find the pointer get or set for a operand */
30 /*-----------------------------------------------------------------------*/
32 findPointerGetSet (iCode * sic, operand * op)
36 for (; ic; ic = ic->next)
38 if ((POINTER_SET (ic) && isOperandEqual (op, IC_RESULT (ic))) ||
39 (POINTER_GET (ic) && isOperandEqual (op, IC_LEFT (ic))))
42 /* if we find any other usage or definition of op null */
43 if (IC_RESULT (ic) && isOperandEqual (IC_RESULT (ic), op))
46 if (IC_RIGHT (ic) && isOperandEqual (IC_RIGHT (ic), op))
49 if (IC_LEFT (ic) && isOperandEqual (IC_LEFT (ic), op))
57 static int pattern1 (iCode *sic)
59 /* this is what we do. look for sequences like
61 iTempX := _SOME_POINTER_;
62 iTempY := _SOME_POINTER_ + nn ; nn = sizeof (pointed to object) sic->next
63 _SOME_POINTER_ := iTempY; sic->next->next
65 iTempZ := @[iTempX]; sic->next->next->next
67 *(iTempX) := ..something.. sic->next->next->next
68 if we find this then transform this to
69 iTempX := _SOME_POINTER_;
73 *(iTempX) := ..something..
74 iTempY := _SOME_POINTER_ + nn ; nn = sizeof (pointed to object)
75 _SOME_POINTER_ := iTempY; */
77 /* sounds simple enough so lets start , here I use -ve
78 tests all the way to return if any test fails */
81 if (!(sic->next && sic->next->next && sic->next->next->next))
83 if (sic->next->op != '+' && sic->next->op != '-')
85 if (!(sic->next->next->op == '=' &&
86 !POINTER_SET (sic->next->next)))
88 if (!isOperandEqual (IC_LEFT (sic->next), IC_RIGHT (sic)) ||
89 !IS_OP_LITERAL (IC_RIGHT (sic->next)))
91 if (operandLitValue (IC_RIGHT (sic->next)) !=
92 getSize (operandType (IC_RIGHT (sic))->next))
94 if (!isOperandEqual (IC_RESULT (sic->next->next),
97 if (!isOperandEqual (IC_RESULT (sic->next), IC_RIGHT (sic->next->next)))
99 if (!(pgs = findPointerGetSet (sic->next->next, IC_RESULT (sic))))
102 /* found the patter .. now do the transformation */
104 st = sic->next->next;
106 /* take the two out of the chain */
107 sic->next = st->next;
108 st->next->prev = sic;
110 /* and put them after the pointer get/set icode */
111 if ((st->next = pgs->next))
118 static int pattern2 (iCode *sic)
120 /* this is what we do. look for sequences like
122 iTempX := _SOME_POINTER_;
123 iTempY := _SOME_POINTER_ + nn ; nn = sizeof (pointed to object) sic->next
124 iTempK := iTempY; sic->next->next
125 _SOME_POINTER_ := iTempK; sic->next->next->next
127 iTempZ := @[iTempX]; sic->next->next->next->next
129 *(iTempX) := ..something.. sic->next->next->next->next
130 if we find this then transform this to
131 iTempX := _SOME_POINTER_;
135 *(iTempX) := ..something..
136 iTempY := _SOME_POINTER_ + nn ; nn = sizeof (pointed to object)
138 _SOME_POINTER_ := iTempK; */
140 /* sounds simple enough so lets start , here I use -ve
141 tests all the way to return if any test fails */
142 iCode *pgs, *sh, *st;
144 if (!(sic->next && sic->next->next && sic->next->next->next &&
145 sic->next->next->next->next))
148 /* yes I can OR them together and make one large if... but I have
149 simple mind and like to keep things simple & readable */
150 if (!(sic->next->op == '+' || sic->next->op == '-')) return 0;
151 if (!isOperandEqual(IC_RIGHT(sic),IC_LEFT(sic->next))) return 0;
152 if (!IS_OP_LITERAL (IC_RIGHT (sic->next))) return 0;
153 if (operandLitValue (IC_RIGHT (sic->next)) !=
154 getSize (operandType (IC_RIGHT (sic))->next)) return 0;
155 if (!IS_ASSIGN_ICODE(sic->next->next)) return 0;
156 if (!isOperandEqual(IC_RIGHT(sic->next->next),IC_RESULT(sic->next))) return 0;
157 if (!IS_ASSIGN_ICODE(sic->next->next->next)) return 0;
158 if (!isOperandEqual(IC_RIGHT(sic->next->next->next),IC_RESULT(sic->next->next))) return 0;
159 if (!isOperandEqual(IC_RESULT(sic->next->next->next),IC_LEFT(sic->next))) return 0;
160 if (!(pgs = findPointerGetSet (sic->next->next->next, IC_RESULT (sic)))) return 0;
162 /* found the patter .. now do the transformation */
164 st = sic->next->next->next;
166 /* take the three out of the chain */
167 sic->next = st->next;
168 st->next->prev = sic;
170 /* and put them after the pointer get/set icode */
171 if ((st->next = pgs->next))
179 /*-----------------------------------------------------------------------*/
180 /* ptrPostIncDecOpts - will do some pointer post increment optimizations */
181 /* this will help register allocation amongst others */
182 /*-----------------------------------------------------------------------*/
184 ptrPostIncDecOpt (iCode * sic)
186 if (pattern1(sic)) return ;