1 /*-------------------------------------------------------------------------
3 pcoderegs.c - post code generation register optimizations
5 Written By - Scott Dattalo scott@dattalo.com
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 -------------------------------------------------------------------------*/
26 The purpose of the code in this file is to optimize the register usage.
31 #include "common.h" // Include everything in the SDCC src directory
36 #include "pcoderegs.h"
37 #include "pcodeflow.h"
39 extern void dbg_dumpregusage(void);
40 void unlinkpCode(pCode *pc);
42 /*-----------------------------------------------------------------*
43 * void AddRegToFlow(regs *reg, pCodeFlow *pcfl)
44 *-----------------------------------------------------------------*/
46 void AddRegToFlow(regs *reg, pCodeFlow *pcfl)
49 if(!reg || ! pcfl || !isPCFL(pcflow))
53 pcfl->registers = newSet();
59 /*-----------------------------------------------------------------*
61 *-----------------------------------------------------------------*/
62 void dbg_regusage(set *fregs)
69 for (reg = setFirstItem(fregs) ; reg ;
70 reg = setNextItem(fregs)) {
72 fprintf (stderr, "%s addr=0x%03x rIdx=0x%03x",
77 pcfl = setFirstItem(reg->reglives.usedpFlows);
79 fprintf(stderr, "\n used in seq");
82 fprintf(stderr," 0x%03x",pcfl->seq);
83 pcfl = setNextItem(reg->reglives.usedpFlows);
86 pcfl = setFirstItem(reg->reglives.assignedpFlows);
88 fprintf(stderr, "\n assigned in seq");
91 fprintf(stderr," 0x%03x",pcfl->seq);
92 pcfl = setNextItem(reg->reglives.assignedpFlows);
95 pc = setFirstItem(reg->reglives.usedpCodes);
97 fprintf(stderr, "\n used in instructions ");
100 pcfl = PCODE(PCI(pc)->pcflow);
102 fprintf(stderr," 0x%03x:",pcfl->seq);
103 fprintf(stderr,"0x%03x",pc->seq);
105 pc = setNextItem(reg->reglives.usedpCodes);
108 fprintf(stderr, "\n");
113 /*-----------------------------------------------------------------*
115 *-----------------------------------------------------------------*/
116 void dbg_dumpregusage(void)
119 fprintf(stderr,"*** Register Usage ***\n");
120 fprintf(stderr,"InternalRegs:\n");
121 dbg_regusage(dynInternalRegs);
122 fprintf(stderr,"AllocRegs:\n");
123 dbg_regusage(dynAllocRegs);
124 fprintf(stderr,"StackRegs:\n");
125 dbg_regusage(dynStackRegs);
126 fprintf(stderr,"DirectRegs:\n");
127 dbg_regusage(dynDirectRegs);
128 fprintf(stderr,"DirectBitRegs:\n");
129 dbg_regusage(dynDirectBitRegs);
130 fprintf(stderr,"ProcessorRegs:\n");
131 dbg_regusage(dynProcessorRegs);
136 /*-----------------------------------------------------------------*
137 * void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
138 *-----------------------------------------------------------------*/
139 void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
151 pc = findNextInstruction(pcfl->pc.next);
153 while(isPCinFlow(pc,PCODE(pcfl))) {
156 reg = getRegFromInstruction(pc);
160 fprintf(stderr, "flow seq %d, inst seq %d %s ",PCODE(pcfl)->seq,pc->seq,reg->name);
161 fprintf(stderr, "addr = 0x%03x, type = %d rIdx=0x%03x\n",
162 reg->address,reg->type,reg->rIdx);
165 addSetIfnotP(& (PCFL(pcfl)->registers), reg);
167 if(PCC_REGISTER & PCI(pc)->inCond)
168 addSetIfnotP(& (reg->reglives.usedpFlows), pcfl);
170 if(PCC_REGISTER & PCI(pc)->outCond)
171 addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl);
173 addSetIfnotP(& (reg->reglives.usedpCodes), pc);
178 pc = findNextInstruction(pc->next);
183 /*-----------------------------------------------------------------*
184 * void pCodeRegMapLiveRanges(pBlock *pb)
185 *-----------------------------------------------------------------*/
186 void pCodeRegMapLiveRanges(pBlock *pb)
190 for( pcflow = findNextpCode(pb->pcHead, PC_FLOW);
192 pcflow = findNextpCode(pcflow->next, PC_FLOW) ) {
194 if(!isPCFL(pcflow)) {
195 fprintf(stderr, "pCodeRegMapLiveRanges - pcflow is not a flow object ");
198 pCodeRegMapLiveRangesInFlow(PCFL(pcflow));
202 for( pcflow = findNextpCode(pb->pcHead, PC_FLOW);
204 pcflow = findNextpCode(pcflow->next, PC_FLOW) ) {
206 regs *r = setFirstItem(PCFL(pcflow)->registers);
207 //fprintf(stderr,"flow seq %d\n", pcflow->seq);
209 //fprintf(stderr, " %s\n",r->name);
210 r = setNextItem(PCFL(pcflow)->registers);
216 // dbg_dumpregusage();
221 /*-----------------------------------------------------------------*
222 * void RemoveRegsFromSet(set *regset)
224 *-----------------------------------------------------------------*/
225 void RemoveRegsFromSet(set *regset)
229 for (reg = setFirstItem(regset) ; reg ;
230 reg = setNextItem(regset)) {
233 used = elementsInSet(reg->reglives.usedpCodes);
237 //fprintf(stderr," reg %s isfree=%d, wasused=%d\n",reg->name,reg->isFree,reg->wasUsed);
240 //fprintf(stderr," getting rid of reg %s\n",reg->name);
246 //fprintf(stderr," reg %s used only once\n",reg->name);
248 pc = setFirstItem(reg->reglives.usedpCodes);
251 pCode *pcn = findNextInstruction(pc->next);
253 if(pcn && PCI(pcn)->label) {
254 fprintf(stderr,"can't delete instruction with label...\n");
255 pc->print(stderr,pc);
258 /* Move the label to the next instruction */
260 PCI(pcn)->label = PCI(pc)->label;
265 fprintf(stderr, "WARNING, a skip instruction is being optimized out\n");
268 deleteSetItem (&(reg->reglives.usedpCodes),pc);
277 /*-----------------------------------------------------------------*
278 * void RemoveUnusedRegisters(void)
280 *-----------------------------------------------------------------*/
281 void RemoveUnusedRegisters(void)
285 //fprintf(stderr,"InternalRegs:\n");
286 RemoveRegsFromSet(dynInternalRegs);
287 //fprintf(stderr,"AllocRegs:\n");
288 RemoveRegsFromSet(dynAllocRegs);
289 //fprintf(stderr,"StackRegs:\n");
290 RemoveRegsFromSet(dynStackRegs);
293 don't do DirectRegs yet - there's a problem with arrays
294 //fprintf(stderr,"DirectRegs:\n");
295 RemoveRegsFromSet(dynDirectRegs);
297 //fprintf(stderr,"DirectBitRegs:\n");
298 RemoveRegsFromSet(dynDirectBitRegs);