1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (ATMEL AVR) specific
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 -------------------------------------------------------------------------*/
30 /*-----------------------------------------------------------------*/
31 /* At this point we start getting processor specific although */
32 /* some routines are non-processor specific & can be reused when */
33 /* targetting other processors. The decision for this will have */
34 /* to be made on a routine by routine basis */
35 /* routines used to pack registers are most definitely not reusable*/
36 /* since the pack the registers depending strictly on the MCU */
37 /*-----------------------------------------------------------------*/
39 extern void genAVRCode(iCode *);
48 bitVect *funcrUsed; /* registers used in a function */
53 /* Shared with gen.c */
54 int avr_ptrRegReq; /* pointer register required */
59 { REG_GPR ,R0_IDX , REG_GPR , "r0", "r0" , "" , 0, 0, 0 }, /* used as scratch */
60 { REG_GPR ,R1_IDX , REG_GPR , "r1", "r1" , "" , 0, 0, 0 }, /* used as scratch */
61 { REG_GPR ,R2_IDX , REG_GPR , "r2", "r2" , "" , 0, 1, 1 }, /* gpr */
62 { REG_GPR ,R3_IDX , REG_GPR , "r3", "r3" , "" , 0, 1, 1 }, /* gpr */
63 { REG_GPR ,R4_IDX , REG_GPR , "r4", "r4" , "" , 0, 1, 1 }, /* gpr */
64 { REG_GPR ,R5_IDX , REG_GPR , "r5", "r5" , "" , 0, 1, 1 }, /* gpr */
65 { REG_GPR ,R6_IDX , REG_GPR , "r6", "r6" , "" , 0, 1, 1 }, /* gpr */
66 { REG_GPR ,R7_IDX , REG_GPR , "r7", "r7" , "" , 0, 1, 1 }, /* gpr */
67 { REG_GPR ,R8_IDX , REG_GPR , "r8", "r8" , "" , 0, 1, 1 }, /* gpr */
68 { REG_GPR ,R9_IDX , REG_GPR , "r9", "r9" , "" , 0, 1, 1 }, /* gpr */
69 { REG_GPR ,R10_IDX, REG_GPR , "r10", "r10", "" , 0, 1, 1 }, /* gpr */
70 { REG_GPR ,R11_IDX, REG_GPR , "r11", "r11", "" , 0, 1, 1 }, /* gpr */
71 { REG_GPR ,R12_IDX, REG_GPR , "r12", "r12", "" , 0, 1, 1 }, /* gpr */
72 { REG_GPR ,R13_IDX, REG_GPR , "r13", "r13", "" , 0, 1, 1 }, /* gpr */
73 { REG_GPR ,R14_IDX, REG_GPR , "r14", "r14", "" , 0, 1, 1 }, /* gpr */
74 { REG_GPR ,R15_IDX, REG_GPR , "r15", "r15", "" , 0, 1, 1 }, /* gpr */
75 { REG_GPR ,R16_IDX, REG_GPR , "r16", "r16", "" , 0, 1, 0 }, /* parm/gpr */
76 { REG_GPR ,R17_IDX, REG_GPR , "r17", "r17", "" , 0, 1, 0 }, /* parm/gpr */
77 { REG_GPR ,R18_IDX, REG_GPR , "r18", "r18", "" , 0, 1, 0 }, /* parm/gpr */
78 { REG_GPR ,R19_IDX, REG_GPR , "r19", "r19", "" , 0, 1, 0 }, /* parm/gpr */
79 { REG_GPR ,R20_IDX, REG_GPR , "r20", "r20", "" , 0, 1, 0 }, /* parm/gpr */
80 { REG_GPR ,R21_IDX, REG_GPR , "r21", "r21", "" , 0, 1, 0 }, /* parm/gpr */
81 { REG_GPR ,R22_IDX, REG_GPR , "r22", "r22", "" , 0, 1, 0 }, /* parm/gpr */
82 { REG_GPR ,R23_IDX, REG_GPR , "r23", "r23", "" , 0, 1, 0 }, /* parm/gpr */
83 { REG_GPR ,R24_IDX, REG_GPR , "r24", "r24", "" , 0, 0, 0 }, /* scratch */
84 { REG_GPR ,R25_IDX, REG_GPR , "r25", "r25", "" , 0, 0, 0 }, /* scratch */
85 { REG_GPR ,R26_IDX, REG_GPR , "r26", "r26", "" , 0, 1, 1 }, /* used as pointer reg X */
86 { REG_GPR ,R27_IDX, REG_GPR , "r27", "r27", "" , 0, 1, 1 }, /* used as pointer reg X */
87 { REG_GPR ,R28_IDX, REG_GPR , "r28", "r28", "" , 0, 1, 0 }, /* stack frame Y */
88 { REG_GPR ,R29_IDX, REG_GPR , "r29", "r29", "" , 0, 1, 0 }, /* stack frame Y */
89 { REG_GPR ,R30_IDX, REG_GPR , "r30", "r30", "" , 0, 1, 1 }, /* used as pointer reg Z */
90 { REG_GPR ,R31_IDX, REG_GPR , "r31", "r31", "" , 0, 1, 1 }, /* used as pointer reg Z */
91 { REG_PTR ,X_IDX , REG_PTR , "X" , "X" , "" , 0, 1, 0 },
92 { REG_PTR ,Z_IDX , REG_PTR , "Z" , "Z" , "" , 0, 1, 0 },
95 int avr_fReg = 0; /* first allocatable register */
97 static void spillThis (symbol *);
99 /*-----------------------------------------------------------------*/
100 /* allocReg - allocates register of given type */
101 /*-----------------------------------------------------------------*/
102 static regs *allocReg (short type)
106 for ( i = avr_fReg ; i < avr_nRegs ; i++ ) {
108 /* if type is given as 0 then any
109 free register will do */
111 regsAVR[i].isFree ) {
112 regsAVR[i].isFree = 0;
115 bitVectSetBit(currFunc->regsUsed,i);
118 /* other wise look for specific type
120 if (regsAVR[i].isFree &&
121 regsAVR[i].type == type) {
122 regsAVR[i].isFree = 0;
125 bitVectSetBit(currFunc->regsUsed,i);
132 /*-----------------------------------------------------------------*/
133 /* avr_regWithIdx - returns pointer to register wit index number */
134 /*-----------------------------------------------------------------*/
135 regs *avr_regWithIdx (int idx)
139 for (i=0 ; i < avr_nRegs;i++)
140 if (regsAVR[i].rIdx == idx)
143 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
144 "regWithIdx not found");
148 /*-----------------------------------------------------------------*/
149 /* freeReg - frees a register */
150 /*-----------------------------------------------------------------*/
151 static void freeReg (regs *reg)
157 /*-----------------------------------------------------------------*/
158 /* nFreeRegs - returns number of free registers */
159 /*-----------------------------------------------------------------*/
160 static int nFreeRegs (int type)
165 for (i = avr_fReg ; i < avr_nRegs; i++ )
166 if (regsAVR[i].isFree && regsAVR[i].type == type)
171 /*-----------------------------------------------------------------*/
172 /* nfreeRegsType - free registers with type */
173 /*-----------------------------------------------------------------*/
174 static int nfreeRegsType (int type)
177 if (type == REG_PTR) {
178 if ((nfr = nFreeRegs(type)) == 0)
179 return nFreeRegs(REG_GPR);
182 return nFreeRegs(type);
186 /*-----------------------------------------------------------------*/
187 /* allDefsOutOfRange - all definitions are out of a range */
188 /*-----------------------------------------------------------------*/
189 static bool allDefsOutOfRange (bitVect *defs,int fseq, int toseq)
196 for ( i = 0 ;i < defs->size ; i++ ) {
199 if (bitVectBitValue(defs,i) &&
200 (ic = hTabItemWithKey(iCodehTab,i)) &&
201 ( ic->seq >= fseq && ic->seq <= toseq))
210 /*-----------------------------------------------------------------*/
211 /* computeSpillable - given a point find the spillable live ranges */
212 /*-----------------------------------------------------------------*/
213 static bitVect *computeSpillable (iCode *ic)
217 /* spillable live ranges are those that are live at this
218 point . the following categories need to be subtracted
220 a) - those that are already spilt
221 b) - if being used by this one
222 c) - defined by this one */
224 spillable = bitVectCopy(ic->rlive);
226 bitVectCplAnd(spillable,_G.spiltSet); /* those already spilt */
228 bitVectCplAnd(spillable,ic->uses); /* used in this one */
229 bitVectUnSetBit(spillable,ic->defKey);
230 spillable = bitVectIntersect(spillable,_G.regAssigned);
235 /*-----------------------------------------------------------------*/
236 /* noSpilLoc - return true if a variable has no spil location */
237 /*-----------------------------------------------------------------*/
238 static int noSpilLoc (symbol *sym, eBBlock *ebp,iCode *ic)
240 return (sym->usl.spillLoc ? 0 : 1);
243 /*-----------------------------------------------------------------*/
244 /* hasSpilLoc - will return 1 if the symbol has spil location */
245 /*-----------------------------------------------------------------*/
246 static int hasSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
248 return (sym->usl.spillLoc ? 1 : 0);
251 /*-----------------------------------------------------------------*/
252 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location*/
253 /* but is not used as a pointer */
254 /*-----------------------------------------------------------------*/
255 static int hasSpilLocnoUptr (symbol *sym, eBBlock *ebp, iCode *ic)
257 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
260 /*-----------------------------------------------------------------*/
261 /* rematable - will return 1 if the remat flag is set */
262 /*-----------------------------------------------------------------*/
263 static int rematable (symbol *sym, eBBlock *ebp, iCode *ic)
268 /*-----------------------------------------------------------------*/
269 /* notUsedInBlock - not used in this block */
270 /*-----------------------------------------------------------------*/
271 static int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic)
273 return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs) &&
274 allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
277 /*-----------------------------------------------------------------*/
278 /* notUsedInRemaining - not used or defined in remain of the block */
279 /*-----------------------------------------------------------------*/
280 static int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
282 return ((usedInRemaining (operandFromSymbol(sym),ic) ? 0 : 1) &&
283 allDefsOutOfRange (sym->defs,ic->seq,ebp->lSeq));
286 /*-----------------------------------------------------------------*/
287 /* allLRs - return true for all */
288 /*-----------------------------------------------------------------*/
289 static int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
294 /*-----------------------------------------------------------------*/
295 /* liveRangesWith - applies function to a given set of live range */
296 /*-----------------------------------------------------------------*/
297 static set *liveRangesWith (bitVect *lrs,
298 int (func)(symbol *,eBBlock *, iCode *),
299 eBBlock *ebp, iCode *ic)
304 if (!lrs || !lrs->size)
307 for ( i = 1 ; i < lrs->size ; i++ ) {
309 if (!bitVectBitValue(lrs,i))
312 /* if we don't find it in the live range
313 hash table we are in serious trouble */
314 if (!(sym = hTabItemWithKey(liveRanges,i))) {
315 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
316 "liveRangesWith could not find liveRange");
320 if (func(sym,ebp,ic) && bitVectBitValue(_G.regAssigned,sym->key))
321 addSetHead(&rset,sym);
328 /*-----------------------------------------------------------------*/
329 /* leastUsedLR - given a set determines which is the least used */
330 /*-----------------------------------------------------------------*/
331 static symbol *leastUsedLR (set *sset)
333 symbol *sym = NULL, *lsym = NULL ;
335 sym = lsym = setFirstItem(sset);
340 for (; lsym; lsym = setNextItem(sset)) {
342 /* if usage is the same then prefer
343 the spill the smaller of the two */
344 if ( lsym->used == sym->used )
345 if (getSize(lsym->type) < getSize(sym->type))
349 if (lsym->used < sym->used )
354 setToNull((void **)&sset);
359 /*-----------------------------------------------------------------*/
360 /* noOverLap - will iterate through the list looking for over lap */
361 /*-----------------------------------------------------------------*/
362 static int noOverLap (set *itmpStack, symbol *fsym)
367 for (sym = setFirstItem(itmpStack); sym;
368 sym = setNextItem(itmpStack)) {
369 if (sym->liveTo > fsym->liveFrom )
377 /*-----------------------------------------------------------------*/
378 /* isFree - will return 1 if the a free spil location is found */
379 /*-----------------------------------------------------------------*/
380 static DEFSETFUNC(isFree)
383 V_ARG(symbol **,sloc);
384 V_ARG(symbol *,fsym);
386 /* if already found */
390 /* if it is free && and the itmp assigned to
391 this does not have any overlapping live ranges
392 with the one currently being assigned and
393 the size can be accomodated */
395 noOverLap(sym->usl.itmpStack,fsym) &&
396 getSize(sym->type) >= getSize(fsym->type)) {
404 /*-----------------------------------------------------------------*/
405 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
406 /*-----------------------------------------------------------------*/
407 static void spillLRWithPtrReg (symbol *forSym)
413 if (!_G.regAssigned ||
414 bitVectIsZero(_G.regAssigned))
417 X = avr_regWithIdx(X_IDX);
418 Z = avr_regWithIdx(Z_IDX);
420 /* for all live ranges */
421 for (lrsym = hTabFirstItem(liveRanges,&k) ; lrsym ;
422 lrsym = hTabNextItem(liveRanges,&k) ) {
425 /* if no registers assigned to it or
427 /* if it does not overlap with this then
428 not need to spill it */
430 if (lrsym->isspilt || !lrsym->nRegs ||
431 (lrsym->liveTo < forSym->liveFrom))
434 /* go thru the registers : if it is either
435 r0 or r1 then spil it */
436 for (j = 0 ; j < lrsym->nRegs ; j++ )
437 if (lrsym->regs[j] == X || lrsym->regs[j] == Z ) {
445 /*-----------------------------------------------------------------*/
446 /* createStackSpil - create a location on the stack to spil */
447 /*-----------------------------------------------------------------*/
448 static symbol *createStackSpil (symbol *sym)
451 int useXstack, model, noOverlay;
456 /* first go try and find a free one that is already
457 existing on the stack */
458 if (applyToSet(_G.stackSpil,isFree,&sloc, sym)) {
459 /* found a free one : just update & return */
460 sym->usl.spillLoc = sloc;
463 addSetHead(&sloc->usl.itmpStack,sym);
467 /* could not then have to create one , this is the hard part
468 we need to allocate this on the stack : this is really a
469 hack!! but cannot think of anything better at this time */
471 if (sprintf(slocBuffer,"sloc%d",_G.slocNum++) >= sizeof(slocBuffer))
473 fprintf(stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
478 sloc = newiTemp(slocBuffer);
480 /* set the type to the spilling symbol */
481 sloc->type = copyLinkChain(sym->type);
482 sloc->etype = getSpec(sloc->type);
483 SPEC_SCLS(sloc->etype) = S_AUTO ;
484 SPEC_EXTR(sloc->etype) = 0;
486 /* we don't allow it to be allocated`
487 onto the external stack since : so we
488 temporarily turn it off ; we also
489 turn off memory model to prevent
490 the spil from going to the external storage
491 and turn off overlaying
494 useXstack = options.useXstack;
495 model = options.model;
496 noOverlay = options.noOverlay;
497 stackAuto = options.stackAuto;
498 options.noOverlay = 1;
499 options.model = options.useXstack = 0;
503 options.useXstack = useXstack;
504 options.model = model;
505 options.noOverlay = noOverlay;
506 options.stackAuto = stackAuto;
507 sloc->isref = 1; /* to prevent compiler warning */
509 /* if it is on the stack then update the stack */
510 if (IN_STACK(sloc->etype)) {
511 currFunc->stack += getSize(sloc->type);
512 _G.stackExtend += getSize(sloc->type);
514 _G.dataExtend += getSize(sloc->type);
516 /* add it to the _G.stackSpil set */
517 addSetHead(&_G.stackSpil,sloc);
518 sym->usl.spillLoc = sloc;
521 /* add it to the set of itempStack set
522 of the spill location */
523 addSetHead(&sloc->usl.itmpStack,sym);
527 /*-----------------------------------------------------------------*/
528 /* isSpiltOnStack - returns true if the spil location is on stack */
529 /*-----------------------------------------------------------------*/
530 static bool isSpiltOnStack (symbol *sym)
541 if (!sym->usl.spillLoc)
544 etype = getSpec(sym->usl.spillLoc->type);
551 /*-----------------------------------------------------------------*/
552 /* spillThis - spils a specific operand */
553 /*-----------------------------------------------------------------*/
554 static void spillThis (symbol *sym)
557 /* if this is rematerializable or has a spillLocation
558 we are okay, else we need to create a spillLocation
560 if (!(sym->remat || sym->usl.spillLoc))
561 createStackSpil (sym);
564 /* mark it has spilt & put it in the spilt set */
566 _G.spiltSet = bitVectSetBit(_G.spiltSet,sym->key);
568 bitVectUnSetBit(_G.regAssigned,sym->key);
570 for (i = 0 ; i < sym->nRegs ; i++)
573 freeReg(sym->regs[i]);
577 if (sym->usl.spillLoc && !sym->remat)
578 sym->usl.spillLoc->allocreq = 1;
582 /*-----------------------------------------------------------------*/
583 /* selectSpil - select a iTemp to spil : rather a simple procedure */
584 /*-----------------------------------------------------------------*/
585 static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
587 bitVect *lrcs= NULL ;
591 /* get the spillable live ranges */
592 lrcs = computeSpillable (ic);
594 /* get all live ranges that are rematerizable */
595 if ((selectS = liveRangesWith(lrcs,rematable,ebp,ic))) {
597 /* return the least used of these */
598 return leastUsedLR(selectS);
601 /* if the symbol is local to the block then */
602 if (forSym->liveTo < ebp->lSeq ) {
604 /* check if there are any live ranges allocated
605 to registers that are not used in this block */
607 (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) {
608 sym = leastUsedLR(selectS);
609 /* if this is not rematerializable */
617 /* check if there are any live ranges that not
618 used in the remainder of the block */
620 (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
621 sym = leastUsedLR (selectS);
632 /* find live ranges with spillocation && not used as pointers */
633 if ((selectS = liveRangesWith(lrcs,hasSpilLocnoUptr,ebp,ic))) {
635 sym = leastUsedLR(selectS);
636 /* mark this as allocation required */
637 sym->usl.spillLoc->allocreq = 1;
641 /* find live ranges with spillocation */
642 if ((selectS = liveRangesWith(lrcs,hasSpilLoc,ebp,ic))) {
644 sym = leastUsedLR(selectS);
645 sym->usl.spillLoc->allocreq = 1;
649 /* couldn't find then we need to create a spil
650 location on the stack , for which one? the least
652 if ((selectS = liveRangesWith(lrcs,noSpilLoc,ebp,ic))) {
654 /* return a created spil location */
655 sym = createStackSpil(leastUsedLR(selectS));
656 sym->usl.spillLoc->allocreq = 1;
660 /* this is an extreme situation we will spill
661 this one : happens very rarely but it does happen */
662 spillThis ( forSym );
667 /*-----------------------------------------------------------------*/
668 /* spilSomething - spil some variable & mark registers as free */
669 /*-----------------------------------------------------------------*/
670 static bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
675 /* get something we can spil */
676 ssym = selectSpil(ic,ebp,forSym);
678 /* mark it as spilt */
680 _G.spiltSet = bitVectSetBit(_G.spiltSet,ssym->key);
682 /* mark it as not register assigned &
683 take it away from the set */
684 bitVectUnSetBit(_G.regAssigned,ssym->key);
686 /* mark the registers as free */
687 for (i = 0 ; i < ssym->nRegs ;i++ )
689 freeReg(ssym->regs[i]);
691 /* if this was a block level spil then insert push & pop
692 at the start & end of block respectively */
693 if (ssym->blockSpil) {
694 iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
695 /* add push to the start of the block */
696 addiCodeToeBBlock(ebp,nic,( ebp->sch->op == LABEL ?
697 ebp->sch->next : ebp->sch));
698 nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
699 /* add pop to the end of the block */
700 addiCodeToeBBlock(ebp,nic,NULL);
703 /* if spilt because not used in the remainder of the
704 block then add a push before this instruction and
705 a pop at the end of the block */
706 if (ssym->remainSpil) {
708 iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
709 /* add push just before this instruction */
710 addiCodeToeBBlock(ebp,nic,ic);
712 nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
713 /* add pop to the end of the block */
714 addiCodeToeBBlock(ebp,nic,NULL);
723 /*-----------------------------------------------------------------*/
724 /* getRegPtr - will try for PTR if not a GPR type if not spil */
725 /*-----------------------------------------------------------------*/
726 static regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
731 /* try for a ptr type */
732 if ((reg = allocReg(REG_PTR)))
735 /* try for gpr type */
736 if ((reg = allocReg(REG_GPR)))
739 /* we have to spil */
740 if (!spilSomething (ic,ebp,sym))
743 /* this looks like an infinite loop but
744 in really selectSpil will abort */
748 /*-----------------------------------------------------------------*/
749 /* getRegGpr - will try for GPR if not spil */
750 /*-----------------------------------------------------------------*/
751 static regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
756 /* try for gpr type */
757 if ((reg = allocReg(REG_GPR)))
761 if ((reg = allocReg(REG_PTR)))
764 /* we have to spil */
765 if (!spilSomething (ic,ebp,sym))
768 /* this looks like an infinite loop but
769 in reality selectSpil will abort */
773 /*-----------------------------------------------------------------*/
774 /* symHasReg - symbol has a given register */
775 /*-----------------------------------------------------------------*/
776 static bool symHasReg(symbol *sym,regs *reg)
780 for ( i = 0 ; i < sym->nRegs ; i++)
781 if (sym->regs[i] == reg)
787 /*-----------------------------------------------------------------*/
788 /* deassignLRs - check the live to and if they have registers & are*/
789 /* not spilt then free up the registers */
790 /*-----------------------------------------------------------------*/
791 static void deassignLRs (iCode *ic, eBBlock *ebp)
797 for (sym = hTabFirstItem(liveRanges,&k); sym;
798 sym = hTabNextItem(liveRanges,&k)) {
801 /* if it does not end here */
802 if (sym->liveTo > ic->seq )
805 /* if it was spilt on stack then we can
806 mark the stack spil location as free */
808 if (sym->stackSpil) {
809 sym->usl.spillLoc->isFree = 1;
815 if (!bitVectBitValue(_G.regAssigned,sym->key))
818 /* special case check if this is an IFX &
819 the privious one was a pop and the
820 previous one was not spilt then keep track
822 if (ic->op == IFX && ic->prev &&
823 ic->prev->op == IPOP &&
824 !ic->prev->parmPush &&
825 !OP_SYMBOL(IC_LEFT(ic->prev))->isspilt)
826 psym = OP_SYMBOL(IC_LEFT(ic->prev));
831 bitVectUnSetBit(_G.regAssigned,sym->key);
833 /* if the result of this one needs registers
834 and does not have it then assign it right
837 ! (SKIP_IC2(ic) || /* not a special icode */
838 ic->op == JUMPTABLE ||
844 (result = OP_SYMBOL(IC_RESULT(ic))) && /* has a result */
845 result->liveTo > ic->seq && /* and will live beyond this */
846 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
847 result->regType == sym->regType && /* same register types */
848 result->nRegs && /* which needs registers */
849 ! result->isspilt && /* and does not already have them */
851 ! bitVectBitValue(_G.regAssigned,result->key) &&
852 /* the number of free regs + number of regs in this LR
853 can accomodate the what result Needs */
854 ((nfreeRegsType(result->regType) +
855 sym->nRegs) >= result->nRegs)
858 for (i = 0 ; i < result->nRegs ; i++)
860 result->regs[i] = sym->regs[i] ;
862 result->regs[i] = getRegGpr (ic,ebp,result);
864 _G.regAssigned = bitVectSetBit(_G.regAssigned,result->key);
868 /* free the remaining */
869 for (; i < sym->nRegs ; i++) {
871 if (!symHasReg(psym,sym->regs[i]))
872 freeReg(sym->regs[i]);
874 freeReg(sym->regs[i]);
881 /*-----------------------------------------------------------------*/
882 /* reassignLR - reassign this to registers */
883 /*-----------------------------------------------------------------*/
884 static void reassignLR (operand *op)
886 symbol *sym = OP_SYMBOL(op);
889 /* not spilt any more */
890 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
891 bitVectUnSetBit(_G.spiltSet,sym->key);
893 _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
897 for (i=0;i<sym->nRegs;i++)
898 sym->regs[i]->isFree = 0;
901 /*-----------------------------------------------------------------*/
902 /* willCauseSpill - determines if allocating will cause a spill */
903 /*-----------------------------------------------------------------*/
904 static int willCauseSpill ( int nr, int rt)
906 /* first check if there are any avlb registers
907 of te type required */
909 /* special case for pointer type
910 if pointer type not avlb then
911 check for type gpr */
912 if (nFreeRegs(rt) >= nr)
914 if (nFreeRegs(REG_GPR) >= nr)
918 if (nFreeRegs(rt) >= nr)
921 if (nFreeRegs(REG_PTR) +
922 nFreeRegs(REG_GPR) >= nr)
927 /* it will cause a spil */
931 /*-----------------------------------------------------------------*/
932 /* positionRegs - the allocator can allocate same registers to res-*/
933 /* ult and operand, if this happens make sure they are in the same */
934 /* position as the operand otherwise chaos results */
935 /*-----------------------------------------------------------------*/
936 static void positionRegs (symbol *result, symbol *opsym, int lineno)
938 int count = min(result->nRegs,opsym->nRegs);
939 int i , j = 0, shared = 0;
941 /* if the result has been spilt then cannot share */
946 /* first make sure that they actually share */
947 for ( i = 0 ; i < count; i++ ) {
948 for (j = 0 ; j < count ; j++ ) {
949 if (result->regs[i] == opsym->regs[j] && i !=j) {
957 regs *tmp = result->regs[i];
958 result->regs[i] = result->regs[j];
959 result->regs[j] = tmp;
964 /*-----------------------------------------------------------------*/
965 /* serialRegAssign - serially allocate registers to the variables */
966 /*-----------------------------------------------------------------*/
967 static void serialRegAssign (eBBlock **ebbs, int count)
972 for (i = 0; i < count ; i++ ) {
976 if (ebbs[i]->noPath &&
977 (ebbs[i]->entryLabel != entryLabel &&
978 ebbs[i]->entryLabel != returnLabel ))
981 /* of all instructions do */
982 for (ic = ebbs[i]->sch ; ic ; ic = ic->next) {
984 /* if this is an ipop that means some live
985 range will have to be assigned again */
987 reassignLR (IC_LEFT(ic));
989 /* if result is present && is a true symbol */
990 if (IC_RESULT(ic) && ic->op != IFX &&
991 IS_TRUE_SYMOP(IC_RESULT(ic)))
992 OP_SYMBOL(IC_RESULT(ic))->allocreq = 1;
994 /* take away registers from live
995 ranges that end at this instruction */
996 deassignLRs (ic, ebbs[i]) ;
998 /* some don't need registers */
1000 ic->op == JUMPTABLE ||
1004 (IC_RESULT(ic) &&POINTER_SET(ic)) )
1007 /* now we need to allocate registers
1008 only for the result */
1009 if (IC_RESULT(ic)) {
1010 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
1015 /* if it does not need or is spilt
1016 or is already assigned to registers
1017 or will not live beyond this instructions */
1020 bitVectBitValue(_G.regAssigned,sym->key) ||
1021 sym->liveTo <= ic->seq)
1024 /* if some liverange has been spilt at the block level
1025 and this one live beyond this block then spil this
1027 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1031 /* if trying to allocate this will cause
1032 a spill and there is nothing to spill
1033 or this one is rematerializable then
1035 willCS = willCauseSpill(sym->nRegs,sym->regType);
1036 spillable = computeSpillable(ic);
1038 (willCS && bitVectIsZero(spillable) ) ) {
1045 /* if it has a spillocation & is used less than
1046 all other live ranges then spill this */
1047 if ( willCS && sym->usl.spillLoc ) {
1050 leastUsedLR(liveRangesWith (spillable ,
1055 leastUsed->used > sym->used) {
1061 /* we assign registers to it */
1062 _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
1064 for (j = 0 ; j < sym->nRegs ;j++ ) {
1065 if (sym->regType == REG_PTR)
1066 sym->regs[j] = getRegPtr(ic,ebbs[i],sym);
1068 sym->regs[j] = getRegGpr(ic,ebbs[i],sym);
1070 /* if the allocation falied which means
1071 this was spilt then break */
1075 /* if it shares registers with operands make sure
1076 that they are in the same position */
1077 if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
1078 OP_SYMBOL(IC_LEFT(ic))->nRegs && ic->op != '=')
1079 positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1080 OP_SYMBOL(IC_LEFT(ic)),ic->lineno);
1081 /* do the same for the right operand */
1082 if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
1083 OP_SYMBOL(IC_RIGHT(ic))->nRegs )
1084 positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1085 OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
1092 /*-----------------------------------------------------------------*/
1093 /* rUmaskForOp :- returns register mask for an operand */
1094 /*-----------------------------------------------------------------*/
1095 static bitVect *rUmaskForOp (operand *op)
1101 /* only temporaries are assigned registers */
1105 sym = OP_SYMBOL(op);
1107 /* if spilt or no registers assigned to it
1109 if (sym->isspilt || !sym->nRegs)
1112 rumask = newBitVect(avr_nRegs);
1114 for (j = 0; j < sym->nRegs; j++) {
1115 rumask = bitVectSetBit(rumask,
1116 sym->regs[j]->rIdx);
1122 /*-----------------------------------------------------------------*/
1123 /* regsUsedIniCode :- returns bit vector of registers used in iCode*/
1124 /*-----------------------------------------------------------------*/
1125 static bitVect *regsUsedIniCode (iCode *ic)
1127 bitVect *rmask = newBitVect(avr_nRegs);
1129 /* do the special cases first */
1130 if (ic->op == IFX ) {
1131 rmask = bitVectUnion(rmask,
1132 rUmaskForOp(IC_COND(ic)));
1136 /* for the jumptable */
1137 if (ic->op == JUMPTABLE) {
1138 rmask = bitVectUnion(rmask,
1139 rUmaskForOp(IC_JTCOND(ic)));
1144 /* of all other cases */
1146 rmask = bitVectUnion(rmask,
1147 rUmaskForOp(IC_LEFT(ic)));
1151 rmask = bitVectUnion(rmask,
1152 rUmaskForOp(IC_RIGHT(ic)));
1155 rmask = bitVectUnion(rmask,
1156 rUmaskForOp(IC_RESULT(ic)));
1162 /*-----------------------------------------------------------------*/
1163 /* createRegMask - for each instruction will determine the regsUsed*/
1164 /*-----------------------------------------------------------------*/
1165 static void createRegMask (eBBlock **ebbs, int count)
1169 /* for all blocks */
1170 for (i = 0; i < count ; i++ ) {
1173 if ( ebbs[i]->noPath &&
1174 ( ebbs[i]->entryLabel != entryLabel &&
1175 ebbs[i]->entryLabel != returnLabel ))
1178 /* for all instructions */
1179 for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
1183 if (SKIP_IC2(ic) || !ic->rlive)
1186 /* first mark the registers used in this
1188 ic->rUsed = regsUsedIniCode(ic);
1189 _G.funcrUsed = bitVectUnion(_G.funcrUsed,ic->rUsed);
1191 /* now create the register mask for those
1192 registers that are in use : this is a
1193 super set of ic->rUsed */
1194 ic->rMask = newBitVect(avr_nRegs+1);
1196 /* for all live Ranges alive at this point */
1197 for (j = 1; j < ic->rlive->size; j++ ) {
1201 /* if not alive then continue */
1202 if (!bitVectBitValue(ic->rlive,j))
1205 /* find the live range we are interested in */
1206 if (!(sym = hTabItemWithKey(liveRanges,j))) {
1207 werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
1208 "createRegMask cannot find live range");
1212 /* if no register assigned to it */
1213 if (!sym->nRegs || sym->isspilt)
1216 /* for all the registers allocated to it */
1217 for (k = 0 ; k < sym->nRegs ;k++)
1220 bitVectSetBit(ic->rMask,sym->regs[k]->rIdx);
1226 /*-----------------------------------------------------------------*/
1227 /* rematStr - returns the rematerialized string for a remat var */
1228 /*-----------------------------------------------------------------*/
1229 static char *rematStr (symbol *sym)
1232 iCode *ic = sym->rematiCode;
1236 /* if plus or minus print the right hand side */
1237 if (ic->op == '+' || ic->op == '-') {
1238 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1241 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1245 /* we reached the end */
1246 sprintf(s,"%s",OP_SYMBOL(IC_LEFT(ic))->rname);
1253 /*-----------------------------------------------------------------*/
1254 /* regTypeNum - computes the type & number of registers required */
1255 /*-----------------------------------------------------------------*/
1256 static void regTypeNum ()
1262 /* for each live range do */
1263 for ( sym = hTabFirstItem(liveRanges,&k); sym ;
1264 sym = hTabNextItem(liveRanges,&k)) {
1266 /* if used zero times then no registers needed */
1267 if ((sym->liveTo - sym->liveFrom) == 0)
1271 /* if the live range is a temporary */
1274 /* if the type is marked as a conditional */
1275 if (sym->regType == REG_CND)
1278 /* if used in return only then we don't
1280 if (sym->ruonly || sym->accuse) {
1281 if (IS_AGGREGATE(sym->type) || sym->isptr)
1282 sym->type = aggrToPtr(sym->type,FALSE);
1286 /* if the symbol has only one definition &
1287 that definition is a get_pointer and the
1288 pointer we are getting is rematerializable and
1291 if (bitVectnBitsOn(sym->defs) == 1 &&
1292 (ic = hTabItemWithKey(iCodehTab,
1293 bitVectFirstBit(sym->defs))) &&
1295 !IS_BITVAR(sym->etype)) {
1297 /* if in data space or idata space then try to
1298 allocate pointer register */
1302 /* if not then we require registers */
1303 sym->nRegs = ((IS_AGGREGATE(sym->type) || sym->isptr ) ?
1304 getSize(sym->type = aggrToPtr(sym->type,FALSE)) :
1305 getSize(sym->type));
1307 if (sym->nRegs > 4) {
1308 fprintf(stderr,"allocated more than 4 or 0 registers for type ");
1309 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1312 /* determine the type of register required */
1313 if (sym->nRegs == 2 && /* size is two */
1314 IS_PTR(sym->type) && /* is a pointer */
1315 sym->uptr) { /* has pointer usage i.e. get/set pointer */
1316 sym->regType = REG_PTR ;
1320 /* live accross a function call then gpr else scratch */
1321 if (sym->isLiveFcall)
1322 sym->regType = REG_GPR ;
1324 sym->regType = REG_SCR ;
1327 /* for the first run we don't provide */
1328 /* registers for true symbols we will */
1329 /* see how things go */
1335 /*-----------------------------------------------------------------*/
1336 /* deallocStackSpil - this will set the stack pointer back */
1337 /*-----------------------------------------------------------------*/
1338 static DEFSETFUNC(deallocStackSpil)
1346 /*-----------------------------------------------------------------*/
1347 /* farSpacePackable - returns the packable icode for far variables */
1348 /*-----------------------------------------------------------------*/
1349 static iCode *farSpacePackable (iCode *ic)
1353 /* go thru till we find a definition for the
1354 symbol on the right */
1355 for ( dic = ic->prev ; dic ; dic = dic->prev) {
1357 /* if the definition is a call then no */
1358 if ((dic->op == CALL || dic->op == PCALL) &&
1359 IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1363 /* if shift by unknown amount then not */
1364 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1365 IC_RESULT(dic)->key == IC_RIGHT(ic)->key)
1368 /* if pointer get and size > 1 */
1369 if (POINTER_GET(dic) &&
1370 getSize(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)) > 1)
1373 if (POINTER_SET(dic) &&
1374 getSize(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)) > 1)
1377 /* if any three is a true symbol in far space */
1378 if (IC_RESULT(dic) &&
1379 IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1380 isOperandInFarSpace(IC_RESULT(dic)))
1383 if (IC_RIGHT(dic) &&
1384 IS_TRUE_SYMOP(IC_RIGHT(dic)) &&
1385 isOperandInFarSpace(IC_RIGHT(dic)) &&
1386 !isOperandEqual(IC_RIGHT(dic),IC_RESULT(ic)))
1390 IS_TRUE_SYMOP(IC_LEFT(dic)) &&
1391 isOperandInFarSpace(IC_LEFT(dic)) &&
1392 !isOperandEqual(IC_LEFT(dic),IC_RESULT(ic)))
1395 if (isOperandEqual(IC_RIGHT(ic),IC_RESULT(dic))) {
1396 if ( (dic->op == LEFT_OP ||
1397 dic->op == RIGHT_OP ||
1399 IS_OP_LITERAL(IC_RIGHT(dic)))
1409 /*-----------------------------------------------------------------*/
1410 /* packRegsForAssign - register reduction for assignment */
1411 /*-----------------------------------------------------------------*/
1412 static int packRegsForAssign (iCode *ic,eBBlock *ebp)
1416 if (!IS_ITEMP(IC_RIGHT(ic)) ||
1417 OP_SYMBOL(IC_RIGHT(ic))->isind ||
1418 OP_LIVETO(IC_RIGHT(ic)) > ic->seq) {
1422 /* find the definition of iTempNN scanning backwards if we find a
1423 a use of the true symbol in before we find the definition then
1425 for ( dic = ic->prev ; dic ; dic = dic->prev) {
1427 /* if there is a function call and this is
1428 a parameter & not my parameter then don't pack it */
1429 if ( (dic->op == CALL || dic->op == PCALL) &&
1430 (OP_SYMBOL(IC_RESULT(ic))->_isparm &&
1431 !OP_SYMBOL(IC_RESULT(ic))->ismyparm)) {
1439 if (IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1440 IS_OP_VOLATILE(IC_RESULT(dic))) {
1445 if (IS_SYMOP(IC_RESULT(dic)) &&
1446 IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1447 if (POINTER_SET(dic))
1453 if (IS_SYMOP(IC_RIGHT(dic)) &&
1454 (IC_RIGHT(dic)->key == IC_RESULT(ic)->key ||
1455 IC_RIGHT(dic)->key == IC_RIGHT(ic)->key)) {
1460 if (IS_SYMOP(IC_LEFT(dic)) &&
1461 (IC_LEFT(dic)->key == IC_RESULT(ic)->key ||
1462 IC_LEFT(dic)->key == IC_RIGHT(ic)->key)) {
1467 if (POINTER_SET(dic) &&
1468 IC_RESULT(dic)->key == IC_RESULT(ic)->key ) {
1475 return 0 ; /* did not find */
1477 /* if the result is on stack or iaccess then it must be
1478 the same atleast one of the operands */
1479 if (OP_SYMBOL(IC_RESULT(ic))->onStack ||
1480 OP_SYMBOL(IC_RESULT(ic))->iaccess ) {
1482 /* the operation has only one symbol
1483 operator then we can pack */
1484 if ((IC_LEFT(dic) && !IS_SYMOP(IC_LEFT(dic))) ||
1485 (IC_RIGHT(dic) && !IS_SYMOP(IC_RIGHT(dic))))
1488 if (!((IC_LEFT(dic) &&
1489 IC_RESULT(ic)->key == IC_LEFT(dic)->key) ||
1491 IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
1495 /* if in far space & tru symbol then don't */
1496 if ((IS_TRUE_SYMOP(IC_RESULT(ic))) && isOperandInFarSpace(IC_RESULT(ic)))
1498 /* found the definition */
1499 /* replace the result with the result of */
1500 /* this assignment and remove this assignment */
1501 IC_RESULT(dic) = IC_RESULT(ic) ;
1503 if (IS_ITEMP(IC_RESULT(dic)) && OP_SYMBOL(IC_RESULT(dic))->liveFrom > dic->seq) {
1504 OP_SYMBOL(IC_RESULT(dic))->liveFrom = dic->seq;
1506 /* delete from liverange table also
1507 delete from all the points inbetween and the new
1509 for ( sic = dic; sic != ic ; sic = sic->next ) {
1510 bitVectUnSetBit(sic->rlive,IC_RESULT(ic)->key);
1511 if (IS_ITEMP(IC_RESULT(dic)))
1512 bitVectSetBit(sic->rlive,IC_RESULT(dic)->key);
1515 remiCodeFromeBBlock(ebp,ic);
1516 hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
1521 /*-----------------------------------------------------------------*/
1522 /* findAssignToSym : scanning backwards looks for first assig found*/
1523 /*-----------------------------------------------------------------*/
1524 static iCode *findAssignToSym (operand *op,iCode *ic)
1528 for (dic = ic->prev ; dic ; dic = dic->prev) {
1530 /* if definition by assignment */
1531 if (dic->op == '=' &&
1532 !POINTER_SET(dic) &&
1533 IC_RESULT(dic)->key == op->key
1534 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1537 /* we are interested only if defined in far space */
1538 /* or in stack space in case of + & - */
1540 /* if assigned to a non-symbol then return
1542 if (!IS_SYMOP(IC_RIGHT(dic)))
1545 /* if the symbol is in far space then
1547 if (isOperandInFarSpace(IC_RIGHT(dic)))
1550 /* for + & - operations make sure that
1551 if it is on the stack it is the same
1552 as one of the three operands */
1553 if ((ic->op == '+' || ic->op == '-') &&
1554 OP_SYMBOL(IC_RIGHT(dic))->onStack) {
1556 if ( IC_RESULT(ic)->key != IC_RIGHT(dic)->key &&
1557 IC_LEFT(ic)->key != IC_RIGHT(dic)->key &&
1558 IC_RIGHT(ic)->key != IC_RIGHT(dic)->key)
1566 /* if we find an usage then we cannot delete it */
1567 if (IC_LEFT(dic) && IC_LEFT(dic)->key == op->key)
1570 if (IC_RIGHT(dic) && IC_RIGHT(dic)->key == op->key)
1573 if (POINTER_SET(dic) && IC_RESULT(dic)->key == op->key)
1577 /* now make sure that the right side of dic
1578 is not defined between ic & dic */
1580 iCode *sic = dic->next ;
1582 for (; sic != ic ; sic = sic->next)
1583 if (IC_RESULT(sic) &&
1584 IC_RESULT(sic)->key == IC_RIGHT(dic)->key)
1593 /*-----------------------------------------------------------------*/
1594 /* packRegsForSupport :- reduce some registers for support calls */
1595 /*-----------------------------------------------------------------*/
1596 static int packRegsForSupport (iCode *ic, eBBlock *ebp)
1599 /* for the left & right operand :- look to see if the
1600 left was assigned a true symbol in far space in that
1601 case replace them */
1602 if (IS_ITEMP(IC_LEFT(ic)) &&
1603 OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) {
1604 iCode *dic = findAssignToSym(IC_LEFT(ic),ic);
1610 /* found it we need to remove it from the
1612 for ( sic = dic; sic != ic ; sic = sic->next )
1613 bitVectUnSetBit(sic->rlive,IC_LEFT(ic)->key);
1615 IC_LEFT(ic)->operand.symOperand =
1616 IC_RIGHT(dic)->operand.symOperand;
1617 IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
1618 remiCodeFromeBBlock(ebp,dic);
1619 hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1623 /* do the same for the right operand */
1626 IS_ITEMP(IC_RIGHT(ic)) &&
1627 OP_SYMBOL(IC_RIGHT(ic))->liveTo <= ic->seq) {
1628 iCode *dic = findAssignToSym(IC_RIGHT(ic),ic);
1634 /* if this is a subtraction & the result
1635 is a true symbol in far space then don't pack */
1636 if (ic->op == '-' && IS_TRUE_SYMOP(IC_RESULT(dic))) {
1637 link *etype =getSpec(operandType(IC_RESULT(dic)));
1638 if (IN_FARSPACE(SPEC_OCLS(etype)))
1641 /* found it we need to remove it from the
1643 for ( sic = dic; sic != ic ; sic = sic->next )
1644 bitVectUnSetBit(sic->rlive,IC_RIGHT(ic)->key);
1646 IC_RIGHT(ic)->operand.symOperand =
1647 IC_RIGHT(dic)->operand.symOperand;
1648 IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
1650 remiCodeFromeBBlock(ebp,dic);
1651 hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1658 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1661 /*-----------------------------------------------------------------*/
1662 /* packRegsForOneuse : - will reduce some registers for single Use */
1663 /*-----------------------------------------------------------------*/
1664 static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
1669 /* if returning a literal then do nothing */
1673 /* only upto 2 bytes since we cannot predict
1674 the usage of b, & acc */
1675 if (getSize(operandType(op)) > (fReturnSize - 2) &&
1680 /* this routine will mark the a symbol as used in one
1681 instruction use only && if the defintion is local
1682 (ie. within the basic block) && has only one definition &&
1683 that definiion is either a return value from a
1684 function or does not contain any variables in
1686 uses = bitVectCopy(OP_USES(op));
1687 bitVectUnSetBit(uses,ic->key); /* take away this iCode */
1688 if (!bitVectIsZero(uses)) /* has other uses */
1691 /* if it has only one defintion */
1692 if (bitVectnBitsOn(OP_DEFS(op)) > 1)
1693 return NULL ; /* has more than one definition */
1695 /* get the that definition */
1697 hTabItemWithKey(iCodehTab,
1698 bitVectFirstBit(OP_DEFS(op)))))
1701 /* found the definition now check if it is local */
1702 if (dic->seq < ebp->fSeq ||
1703 dic->seq > ebp->lSeq)
1704 return NULL ; /* non-local */
1706 /* now check if it is the return from
1708 if (dic->op == CALL || dic->op == PCALL ) {
1709 if (ic->op != SEND && ic->op != RETURN) {
1710 /* OP_SYMBOL(op)->ruonly = 1; */
1717 /* otherwise check that the definition does
1718 not contain any symbols in far space */
1719 if (isOperandInFarSpace(IC_LEFT(dic)) ||
1720 isOperandInFarSpace(IC_RIGHT(dic)) ||
1721 IS_OP_RUONLY(IC_LEFT(ic)) ||
1722 IS_OP_RUONLY(IC_RIGHT(ic)) ) {
1726 /* if pointer set then make sure the pointer
1728 if (POINTER_SET(dic) &&
1729 !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
1732 if (POINTER_GET(dic) &&
1733 !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
1738 /* also make sure the intervenening instructions
1739 don't have any thing in far space */
1740 for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
1742 /* if there is an intervening function call then no */
1743 if (dic->op == CALL || dic->op == PCALL)
1745 /* if pointer set then make sure the pointer
1747 if (POINTER_SET(dic) &&
1748 !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
1751 if (POINTER_GET(dic) &&
1752 !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
1755 /* if address of & the result is remat the okay */
1756 if (dic->op == ADDRESS_OF &&
1757 OP_SYMBOL(IC_RESULT(dic))->remat)
1760 /* if operand has size of three or more & this
1761 operation is a '*','/' or '%' then 'b' may
1763 if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1764 getSize(operandType(op)) >= 3)
1767 /* if left or right or result is in far space */
1768 if (isOperandInFarSpace(IC_LEFT(dic)) ||
1769 isOperandInFarSpace(IC_RIGHT(dic)) ||
1770 isOperandInFarSpace(IC_RESULT(dic)) ||
1771 IS_OP_RUONLY(IC_LEFT(dic)) ||
1772 IS_OP_RUONLY(IC_RIGHT(dic)) ||
1773 IS_OP_RUONLY(IC_RESULT(dic)) ) {
1778 /* OP_SYMBOL(op)->ruonly = 1; */
1783 /*-----------------------------------------------------------------*/
1784 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1785 /*-----------------------------------------------------------------*/
1786 static bool isBitwiseOptimizable (iCode *ic)
1788 link *ltype = getSpec(operandType(IC_LEFT(ic)));
1789 link *rtype = getSpec(operandType(IC_RIGHT(ic)));
1791 /* bitwise operations are considered optimizable
1792 under the following conditions (Jean-Louis VERN)
1804 if ( IS_LITERAL(rtype) ||
1805 (IS_BITVAR(ltype) && IN_BITSPACE(SPEC_OCLS(ltype))))
1811 /*-----------------------------------------------------------------*/
1812 /* packRegsForAccUse - pack registers for acc use */
1813 /*-----------------------------------------------------------------*/
1814 static void packRegsForAccUse (iCode *ic)
1818 /* if + or - then it has to be one byte result */
1819 if ((ic->op == '+' || ic->op == '-')
1820 && getSize(operandType(IC_RESULT(ic))) > 1)
1823 /* if shift operation make sure right side is not a literal */
1824 if (ic->op == RIGHT_OP &&
1825 ( isOperandLiteral(IC_RIGHT(ic)) ||
1826 getSize(operandType(IC_RESULT(ic))) > 1))
1829 if (ic->op == LEFT_OP &&
1830 ( isOperandLiteral(IC_RIGHT(ic)) ||
1831 getSize(operandType(IC_RESULT(ic))) > 1))
1834 if (IS_BITWISE_OP(ic) &&
1835 getSize(operandType(IC_RESULT(ic))) > 1)
1839 /* has only one definition */
1840 if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
1843 /* has only one use */
1844 if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
1847 /* and the usage immediately follows this iCode */
1848 if (!(uic = hTabItemWithKey(iCodehTab,
1849 bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
1852 if (ic->next != uic)
1855 /* if it is a conditional branch then we definitely can */
1856 if (uic->op == IFX )
1859 if ( uic->op == JUMPTABLE )
1862 /* if the usage is not is an assignment
1863 or an arithmetic / bitwise / shift operation then not */
1864 if (POINTER_SET(uic) &&
1865 getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1)
1868 if (uic->op != '=' &&
1869 !IS_ARITHMETIC_OP(uic) &&
1870 !IS_BITWISE_OP(uic) &&
1871 uic->op != LEFT_OP &&
1872 uic->op != RIGHT_OP )
1875 /* if used in ^ operation then make sure right is not a
1877 if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic)))
1880 /* if shift operation make sure right side is not a literal */
1881 if (uic->op == RIGHT_OP &&
1882 ( isOperandLiteral(IC_RIGHT(uic)) ||
1883 getSize(operandType(IC_RESULT(uic))) > 1))
1886 if (uic->op == LEFT_OP &&
1887 ( isOperandLiteral(IC_RIGHT(uic)) ||
1888 getSize(operandType(IC_RESULT(uic))) > 1))
1891 /* make sure that the result of this icode is not on the
1892 stack, since acc is used to compute stack offset */
1893 if (IS_TRUE_SYMOP(IC_RESULT(uic)) &&
1894 OP_SYMBOL(IC_RESULT(uic))->onStack)
1897 /* if either one of them in far space then we cannot */
1898 if ((IS_TRUE_SYMOP(IC_LEFT(uic)) &&
1899 isOperandInFarSpace(IC_LEFT(uic))) ||
1900 (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
1901 isOperandInFarSpace(IC_RIGHT(uic))))
1904 /* if the usage has only one operand then we can */
1905 if (IC_LEFT(uic) == NULL ||
1906 IC_RIGHT(uic) == NULL)
1909 /* make sure this is on the left side if not
1910 a '+' since '+' is commutative */
1911 if (ic->op != '+' &&
1912 IC_LEFT(uic)->key != IC_RESULT(ic)->key)
1915 /* if one of them is a literal then we can */
1916 if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) ||
1917 (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) {
1918 OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
1922 /* if the other one is not on stack then we can */
1923 if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
1924 (IS_ITEMP(IC_RIGHT(uic)) ||
1925 (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
1926 !OP_SYMBOL(IC_RIGHT(uic))->onStack)))
1929 if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
1930 (IS_ITEMP(IC_LEFT(uic)) ||
1931 (IS_TRUE_SYMOP(IC_LEFT(uic)) &&
1932 !OP_SYMBOL(IC_LEFT(uic))->onStack)))
1938 OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
1943 /*-----------------------------------------------------------------*/
1944 /* packForPush - hueristics to reduce iCode for pushing */
1945 /*-----------------------------------------------------------------*/
1946 static void packForPush(iCode *ic, eBBlock *ebp)
1950 if (ic->op != IPUSH || !IS_ITEMP(IC_LEFT(ic)))
1953 /* must have only definition & one usage */
1954 if (bitVectnBitsOn(OP_DEFS(IC_LEFT(ic))) != 1 ||
1955 bitVectnBitsOn(OP_USES(IC_LEFT(ic))) != 1 )
1958 /* find the definition */
1959 if (!(dic = hTabItemWithKey(iCodehTab,
1960 bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
1963 if (dic->op != '=' || POINTER_SET(dic))
1966 /* we now we know that it has one & only one def & use
1967 and the that the definition is an assignment */
1968 IC_LEFT(ic) = IC_RIGHT(dic);
1970 remiCodeFromeBBlock(ebp,dic);
1971 hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1974 /*-----------------------------------------------------------------*/
1975 /* packRegisters - does some transformations to reduce register */
1977 /*-----------------------------------------------------------------*/
1978 static void packRegisters (eBBlock *ebp)
1987 /* look for assignments of the form */
1988 /* iTempNN = TRueSym (someoperation) SomeOperand */
1990 /* TrueSym := iTempNN:1 */
1991 for ( ic = ebp->sch ; ic ; ic = ic->next ) {
1994 /* find assignment of the form TrueSym := iTempNN:1 */
1995 if (ic->op == '=' && !POINTER_SET(ic))
1996 change += packRegsForAssign(ic,ebp);
2003 for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2005 /* if this is an itemp & result of a address of a true sym
2006 then mark this as rematerialisable */
2007 if (ic->op == ADDRESS_OF &&
2008 IS_ITEMP(IC_RESULT(ic)) &&
2009 IS_TRUE_SYMOP(IC_LEFT(ic)) &&
2010 bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2011 !OP_SYMBOL(IC_LEFT(ic))->onStack ) {
2013 OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2014 OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2015 OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2019 /* if straight assignment then carry remat flag if
2020 this is the only definition */
2021 if (ic->op == '=' &&
2023 IS_SYMOP(IC_RIGHT(ic)) &&
2024 OP_SYMBOL(IC_RIGHT(ic))->remat &&
2025 bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->defs) <= 1) {
2027 OP_SYMBOL(IC_RESULT(ic))->remat =
2028 OP_SYMBOL(IC_RIGHT(ic))->remat;
2029 OP_SYMBOL(IC_RESULT(ic))->rematiCode =
2030 OP_SYMBOL(IC_RIGHT(ic))->rematiCode ;
2033 /* if this is a +/- operation with a rematerizable
2034 then mark this as rematerializable as well only
2035 if the literal value is within the range -255 and + 255
2036 the assembler cannot handle it other wise */
2037 if ((ic->op == '+' || ic->op == '-') &&
2039 (IS_SYMOP(IC_LEFT(ic)) &&
2040 IS_ITEMP(IC_RESULT(ic)) &&
2041 OP_SYMBOL(IC_LEFT(ic))->remat &&
2042 bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2043 IS_OP_LITERAL(IC_RIGHT(ic))) ) {
2045 int i = operandLitValue(IC_RIGHT(ic));
2046 if ( i < 255 && i > -255) {
2047 OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2048 OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2049 OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2053 /* mark the pointer usages */
2054 if (POINTER_SET(ic))
2055 OP_SYMBOL(IC_RESULT(ic))->uptr = 1;
2057 if (POINTER_GET(ic))
2058 OP_SYMBOL(IC_LEFT(ic))->uptr = 1;
2060 /* if the condition of an if instruction
2061 is defined in the previous instruction then
2062 mark the itemp as a conditional */
2063 if ((IS_CONDITIONAL(ic) ||
2064 ( ( ic->op == BITWISEAND ||
2067 isBitwiseOptimizable(ic))) &&
2068 ic->next && ic->next->op == IFX &&
2069 isOperandEqual(IC_RESULT(ic),IC_COND(ic->next)) &&
2070 OP_SYMBOL(IC_RESULT(ic))->liveTo <= ic->next->seq) {
2072 OP_SYMBOL(IC_RESULT(ic))->regType = REG_CND;
2076 /* reduce for support function calls */
2077 /* if (ic->supportRtn || ic->op == '+' || ic->op == '-' ) */
2078 /* packRegsForSupport (ic,ebp); */
2080 /* some cases the redundant moves can
2081 can be eliminated for return statements */
2082 /* if ((ic->op == RETURN || ic->op == SEND) && */
2083 /* !isOperandInFarSpace(IC_LEFT(ic)) && */
2084 /* !options.model) */
2085 /* packRegsForOneuse (ic,IC_LEFT(ic),ebp); */
2087 /* if pointer set & left has a size more than
2088 one and right is not in far space */
2089 /* if (POINTER_SET(ic) && */
2090 /* !isOperandInFarSpace(IC_RIGHT(ic)) && */
2091 /* !OP_SYMBOL(IC_RESULT(ic))->remat && */
2092 /* !IS_OP_RUONLY(IC_RIGHT(ic)) && */
2093 /* getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 ) */
2095 /* packRegsForOneuse (ic,IC_RESULT(ic),ebp); */
2097 /* if pointer get */
2098 /* if (POINTER_GET(ic) && */
2099 /* !isOperandInFarSpace(IC_RESULT(ic))&& */
2100 /* !OP_SYMBOL(IC_LEFT(ic))->remat && */
2101 /* !IS_OP_RUONLY(IC_RESULT(ic)) && */
2102 /* getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 ) */
2104 /* packRegsForOneuse (ic,IC_LEFT(ic),ebp); */
2107 /* if this is cast for intergral promotion then
2108 check if only use of the definition of the
2109 operand being casted/ if yes then replace
2110 the result of that arithmetic operation with
2111 this result and get rid of the cast */
2112 if (ic->op == CAST) {
2113 link *fromType = operandType(IC_RIGHT(ic));
2114 link *toType = operandType(IC_LEFT(ic));
2116 if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
2117 getSize(fromType) != getSize(toType) ) {
2119 iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
2121 if (IS_ARITHMETIC_OP(dic)) {
2122 IC_RESULT(dic) = IC_RESULT(ic);
2123 remiCodeFromeBBlock(ebp,ic);
2124 hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2127 OP_SYMBOL(IC_RIGHT(ic))->ruonly = 0;
2131 /* if the type from and type to are the same
2132 then if this is the only use then packit */
2133 if (checkType(operandType(IC_RIGHT(ic)),
2134 operandType(IC_LEFT(ic))) == 1) {
2135 iCode *dic = packRegsForOneuse (ic,IC_RIGHT(ic),ebp);
2137 IC_RESULT(dic) = IC_RESULT(ic);
2138 remiCodeFromeBBlock(ebp,ic);
2139 hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2147 iTempNN := (some variable in farspace) V1
2152 /* if (ic->op == IPUSH ) { */
2153 /* packForPush(ic,ebp); */
2157 /* pack registers for accumulator use, when the
2158 result of an arithmetic or bit wise operation
2159 has only one use, that use is immediately following
2160 the defintion and the using iCode has only one
2161 operand or has two operands but one is literal &
2162 the result of that operation is not on stack then
2163 we can leave the result of this operation in acc:b
2165 /* if ((IS_ARITHMETIC_OP(ic) */
2167 /* || IS_BITWISE_OP(ic) */
2169 /* || ic->op == LEFT_OP || ic->op == RIGHT_OP */
2172 /* IS_ITEMP(IC_RESULT(ic)) && */
2173 /* getSize(operandType(IC_RESULT(ic))) <= 2) */
2175 /* packRegsForAccUse (ic); */
2180 /*-----------------------------------------------------------------*/
2181 /* preAssignParms - we have a leaf function preassign registers */
2182 /*-----------------------------------------------------------------*/
2183 static void preAssignParms (iCode *ic)
2186 /* look for receives and assign registers
2187 to the result of the receives */
2189 /* if it is a receive */
2190 if (ic->op == RECEIVE) {
2191 symbol *r = OP_SYMBOL(IC_RESULT(ic));
2192 int size = getSize(r->type);
2193 if (r->regType == REG_GPR) {
2196 r->regs[j++] = ®sAVR[i++];
2197 regsAVR[i-1].isFree = 0;
2199 /* put in the regassigned vector */
2200 _G.regAssigned = bitVectSetBit(_G.regAssigned,r->key);
2202 /* not a GPR then we should mark as free */
2204 regsAVR[i++].isFree =1;
2210 /* mark anything remaining as free */
2211 while (i <= R23_IDX)
2212 regsAVR[i++].isFree =1;
2215 /*-----------------------------------------------------------------*/
2216 /* setdefaultRegs - do setup stuff for register allocation */
2217 /*-----------------------------------------------------------------*/
2218 static void setDefaultRegs(eBBlock **ebbs,int count)
2222 /* if no pointer registers required in this function
2223 then mark r26-27 & r30-r31 as GPR & free */
2224 if (!avr_ptrRegReq) {
2225 regsAVR[R26_IDX].isFree =
2226 regsAVR[R27_IDX].isFree =
2227 regsAVR[R30_IDX].isFree =
2228 regsAVR[R31_IDX].isFree = 1;
2229 regsAVR[R26_IDX].type =
2230 regsAVR[R27_IDX].type =
2231 regsAVR[R30_IDX].type =
2232 regsAVR[R31_IDX].type = REG_GPR ;
2234 regsAVR[R26_IDX].isFree =
2235 regsAVR[R27_IDX].isFree =
2236 regsAVR[R30_IDX].isFree =
2237 regsAVR[R31_IDX].isFree = 1;
2238 regsAVR[R26_IDX].type =
2239 regsAVR[R27_IDX].type =
2240 regsAVR[R30_IDX].type =
2241 regsAVR[R31_IDX].type = REG_PTR ;
2244 /* registers 0-1 / 24-25 used as scratch */
2245 regsAVR[R0_IDX].isFree =
2246 regsAVR[R1_IDX].isFree =
2247 regsAVR[R24_IDX].isFree =
2248 regsAVR[R25_IDX].isFree = 0;
2250 /* if this has no function calls then we need
2251 to do something special
2252 a) pre-assign registers to parameters RECEIVE
2253 b) mark the remaining parameter regs as free */
2254 if (!currFunc->hasFcall) {
2255 /* mark the parameter regs as GPR */
2256 for (i= R16_IDX ; i <= R23_IDX ;i++) {
2257 regsAVR[i].type = REG_GPR;
2258 regsAVR[i].isFree = 1;
2260 preAssignParms(ebbs[0]->sch);
2263 /* otherwise mark them as free scratch */
2264 for (i= R16_IDX ; i <= R23_IDX ;i++) {
2265 regsAVR[i].type = REG_SCR;
2266 regsAVR[i].isFree = 1;
2270 /* Y - is not allocated (it is the stack frame) */
2271 regsAVR[R28_IDX].isFree =
2272 regsAVR[R28_IDX].isFree =0;
2275 /*-----------------------------------------------------------------*/
2276 /* assignRegisters - assigns registers to each live range as need */
2277 /*-----------------------------------------------------------------*/
2278 void avr_assignRegisters (eBBlock **ebbs, int count)
2283 setToNull((void *)&_G.funcrUsed);
2284 avr_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2286 /* change assignments this will remove some
2287 live ranges reducing some register pressure */
2288 for (i = 0 ; i < count ;i++ )
2289 packRegisters (ebbs[i]);
2291 if (options.dump_pack)
2292 dumpEbbsToFileExt(".dumppack",ebbs,count);
2294 /* first determine for each live range the number of
2295 registers & the type of registers required for each */
2298 /* setup the default registers */
2299 setDefaultRegs(ebbs,count);
2301 /* and serially allocate registers */
2302 serialRegAssign(ebbs,count);
2304 /* if stack was extended then tell the user */
2305 if (_G.stackExtend) {
2306 /* werror(W_TOOMANY_SPILS,"stack", */
2307 /* _G.stackExtend,currFunc->name,""); */
2308 _G.stackExtend = 0 ;
2311 if (_G.dataExtend) {
2312 /* werror(W_TOOMANY_SPILS,"data space", */
2313 /* _G.dataExtend,currFunc->name,""); */
2317 /* after that create the register mask
2318 for each of the instruction */
2319 createRegMask (ebbs,count);
2321 /* redo that offsets for stacked automatic variables */
2322 redoStackOffsets ();
2324 if (options.dump_rassgn)
2325 dumpEbbsToFileExt(".dumprassgn",ebbs,count);
2327 /* now get back the chain */
2328 ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));
2333 /* free up any _G.stackSpil locations allocated */
2334 applyToSet(_G.stackSpil,deallocStackSpil);
2336 setToNull((void **)&_G.stackSpil);
2337 setToNull((void **)&_G.spiltSet);
2338 /* mark all registers as free */