1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (xa51) 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 genXA51Code (iCode *);
49 bitVect *totRegAssigned; /* final set of LRs that got into registers */
52 bitVect *funcrUsed; /* registers used in a function */
60 // index size type name regMask offset isFree symbol
61 {0x20, 2, REG_SCR, "r0", 0x0003, 0, 1, NULL}, // r0 used for scratch
62 {0x21, 2, REG_SCR, "r1", 0x000c, 2, 1, NULL}, // r1 used for scratch
63 {0x22, 2, REG_PTR, "r2", 0x0030, 4, 1, NULL},
64 {0x23, 2, REG_PTR, "r3", 0x00c0, 6, 1, NULL},
65 {0x24, 2, REG_PTR, "r4", 0x0300, 8, 1, NULL},
66 {0x25, 2, REG_PTR, "r5", 0x0c00, 10, 1, NULL},
67 {0x26, 2, REG_PTR, "r6", 0x3000, 12, 1, NULL},
68 {0x27, 2, REG_STK, "r7", 0xc000, 14, 1, NULL}, // r7=SP
69 #if 0 // some derivates have even more! (only bit/word access no ptr use)
70 {0x28, 2, REG_GPR, "r8", 0x10000, 16, 1, NULL},
71 {0x29, 2, REG_GPR, "r9", 0x20000, 18, 1, NULL},
72 {0x2a, 2, REG_GPR, "r10", 0x40000, 20, 1, NULL},
73 {0x2b, 2, REG_GPR, "r11", 0x80000, 22, 1, NULL},
74 {0x2c, 2, REG_GPR, "r12", 0x100000, 24, 1, NULL},
75 {0x2d, 2, REG_GPR, "r13", 0x200000, 26, 1, NULL},
76 {0x2e, 2, REG_GPR, "r14", 0x400000, 28, 1, NULL},
77 {0x2f, 2, REG_GPR, "r15", 0x800000, 20, 1, NULL},
79 {0x10, 1, REG_SCR, "r0h", 0x0001, 1, 1, NULL}, // r0h used for scratch
80 {0x11, 1, REG_SCR, "r0l", 0x0002, 1, 1, NULL}, // r0l used for scratch
81 {0x12, 1, REG_SCR, "r1h", 0x0004, 2, 1, NULL}, // r1h used for scratch
82 {0x13, 1, REG_SCR, "r1l", 0x0008, 3, 1, NULL}, // r1l used for scratch
83 {0x14, 1, REG_PTR, "r2h", 0x0010, 4, 1, NULL},
84 {0x15, 1, REG_PTR, "r2l", 0x0020, 5, 1, NULL},
85 {0x16, 1, REG_PTR, "r3h", 0x0040, 6, 1, NULL},
86 {0x17, 1, REG_PTR, "r3l", 0x0080, 7, 1, NULL},
87 {0x18, 1, REG_PTR, "r4h", 0x0100, 8, 1, NULL},
88 {0x19, 1, REG_PTR, "r4l", 0x0200, 9, 1, NULL},
89 {0x1a, 1, REG_PTR, "r5h", 0x0400, 10, 1, NULL},
90 {0x1b, 1, REG_PTR, "r5l", 0x0800, 11, 1, NULL},
91 {0x1c, 1, REG_PTR, "r6h", 0x1000, 12, 1, NULL},
92 {0x1d, 1, REG_PTR, "r6l", 0x2000, 13, 1, NULL},
93 {0x1e, 1, REG_STK, "r7h", 0x4000, 14, 1, NULL}, // r7=SP
94 {0x1f, 1, REG_STK, "r7l", 0x8000, 15, 1, NULL}, // r7=SP
97 int xa51_nRegs=sizeof(regsXA51)/sizeof(regs);
99 udword xa51RegsInUse=0;
101 // this should be set with a command line switch
102 bool xa51HasGprRegs=0;
104 /*-----------------------------------------------------------------*/
105 /* xa51_regWithMask - returns pointer to register with mask */
106 /*-----------------------------------------------------------------*/
107 regs *xa51_regWithMask (udword mask) {
109 for (i=0; i<xa51_nRegs; i++) {
110 if (regsXA51[i].regMask==mask) {
117 /*-----------------------------------------------------------------*/
118 /* checkRegsMask - check the consistancy of the regMask redundancy */
119 /*-----------------------------------------------------------------*/
121 void checkRegMask(char *f) { // for debugging purposes only
125 for (i=0; i<xa51_nRegs; i++) {
126 if (!regsXA51[i].isFree) {
127 regMask |= regsXA51[i].regMask;
131 if (regMask != xa51RegsInUse) {
132 fprintf (stderr, "error(%s): regMask inconsistent 0x%08x != 0x%08x\n",
133 f, regMask, xa51RegsInUse);
134 regMask=regMask^xa51RegsInUse;
135 fprintf (stderr, "%s used by %s\n",
136 xa51_regWithMask(regMask)->name,
137 xa51_regWithMask(regMask)->sym->name);
144 char *regTypeToStr(short type) {
147 case REG_PTR: return "ptr"; break; // pointer
148 case REG_GPR: return "gpr"; break; // general purpose
149 case REG_CND: return "cnd"; break; // condition (bit)
150 case REG_STK: return "stk"; break; // stack
151 case REG_SCR: return "scr"; break; // scratch
152 default: return "???"; break;
156 /*-----------------------------------------------------------------*/
157 /* freeReg - frees a previous allocated register */
158 /*-----------------------------------------------------------------*/
159 static void freeReg (regs * reg, bool silent) {
161 checkRegMask(__FUNCTION__);
164 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
165 "freeReg - freeing NULL register");
170 D(fprintf (stderr, "freeReg: (%08x) %s (%s) ", xa51RegsInUse,
171 reg->name, reg->sym->name));
174 if (reg->isFree || ((xa51RegsInUse®->regMask)!=reg->regMask)) {
175 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
176 "freeReg - freeing unused register(s)");
179 xa51RegsInUse &= ~reg->regMask;
182 if (!silent) D(fprintf (stderr, "(%08x)\n", xa51RegsInUse));
184 checkRegMask(__FUNCTION__);
187 /*-----------------------------------------------------------------*/
188 /* allocReg - allocates register of given size (byte, word) */
189 /* and type (ptr, gpr, cnd) */
190 /*-----------------------------------------------------------------*/
191 static bool allocReg (short size, short type, symbol *sym,
192 short offset, bool silent) {
195 checkRegMask(__FUNCTION__);
198 D(fprintf (stderr, "allocReg (%08x) for %s size:%d, type:%s ",
201 size, regTypeToStr(type)));
206 // TODO: gaps could be filled for dwords too
208 // let's see if we can fill a gap
209 for (i=0; i<xa51_nRegs; i++) {
210 if (regsXA51[i].size==2 && regsXA51[i].type==type) {
211 udword mask=regsXA51[i].regMask & ~xa51RegsInUse;
212 if (mask && mask!=regsXA51[i].regMask) {
213 regs *reg=xa51_regWithMask(mask);
215 sym->regs[offset]=reg;
216 xa51RegsInUse |= mask;
217 reg->isFree=0; // redundant
220 D(fprintf (stderr, "(using gap) %s\n", reg->name));
222 checkRegMask(__FUNCTION__);
227 // no we can't, fall through
229 for (i=0; i<xa51_nRegs; i++) {
230 if (regsXA51[i].size==size &&
231 regsXA51[i].type==type &&
232 (regsXA51[i].regMask & xa51RegsInUse)==0) {
233 xa51RegsInUse |= regsXA51[i].regMask;
234 regsXA51[i].isFree = 0; // redundant
235 regsXA51[i].sym = sym;
237 D(fprintf (stderr, "%s\n", regsXA51[i].name));
239 sym->regs[offset]=®sXA51[i];
240 checkRegMask(__FUNCTION__);
245 D(fprintf (stderr, "failed (%08x)\n", xa51RegsInUse));
247 checkRegMask(__FUNCTION__);
251 // this must be a generic pointer
253 D(fprintf (stderr, "trying 1+2\n"));
255 // get the generic part
256 if ((xa51HasGprRegs && allocReg (1, REG_GPR, sym, offset+1, silent)) ||
257 allocReg (1, REG_PTR, sym, offset+1, silent)) {
258 // get the pointer part
259 if (allocReg (2, REG_PTR, sym, offset, silent)) {
260 checkRegMask(__FUNCTION__);
263 freeReg(sym->regs[offset+1], silent);
264 sym->regs[offset+1]=NULL;
266 checkRegMask(__FUNCTION__);
269 case 4: // this is a dword
271 D(fprintf (stderr, "trying 2+2\n"));
273 if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset, silent)) ||
274 allocReg (2, REG_PTR, sym, offset, silent)) {
275 if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset+1, silent)) ||
276 allocReg (2, REG_PTR, sym, offset+1, silent)) {
277 checkRegMask(__FUNCTION__);
281 if (sym->regs[offset]) {
282 freeReg(sym->regs[offset], FALSE);
283 sym->regs[offset]=NULL;
285 checkRegMask(__FUNCTION__);
289 fprintf (stderr, "\nallocReg: cannot allocate reg of size %d\n", size);
293 // we should never come here
297 /*-------------------------------------------------------------------*/
298 /* freeAllRegs - frees all registers */
299 /*-------------------------------------------------------------------*/
300 // just to be sure, this should not be needed
301 static void freeAllRegs (void) {
306 checkRegMask(__FUNCTION__);
309 for (i=0; i<xa51_nRegs; i++) {
310 if (!regsXA51[i].isFree) {
311 strcat (regsFreed, regsXA51[i].name);
312 strcat (regsFreed, " ");
313 regsXA51[i].isFree=1;
314 regsXA51[i].sym=NULL;
320 fprintf (stderr, "freeAllRegisters: %d regs freed (%s)\n", nfr, regsFreed);
325 /*-----------------------------------------------------------------*/
326 /* allDefsOutOfRange - all definitions are out of a range */
327 /*-----------------------------------------------------------------*/
328 static bool allDefsOutOfRange (bitVect * defs, int fseq, int toseq) {
334 for (i = 0; i < defs->size; i++)
338 if (bitVectBitValue (defs, i) &&
339 (ic = hTabItemWithKey (iCodehTab, i)) &&
340 (ic->seq >= fseq && ic->seq <= toseq))
346 /*-----------------------------------------------------------------*/
347 /* computeSpillable - given a point find the spillable live ranges */
348 /*-----------------------------------------------------------------*/
349 static bitVect *computeSpillable (iCode * ic) {
352 /* spillable live ranges are those that are live at this
353 point . the following categories need to be subtracted
355 a) - those that are already spilt
356 b) - if being used by this one
357 c) - defined by this one */
359 spillable = bitVectCopy (ic->rlive);
361 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
363 bitVectCplAnd (spillable, ic->uses); /* used in this one */
364 bitVectUnSetBit (spillable, ic->defKey); /* defined by this one */
365 spillable = bitVectIntersect (spillable, _G.regAssigned);
370 /*-----------------------------------------------------------------*/
371 /* noSpilLoc - return true if a variable has no spil location */
372 /*-----------------------------------------------------------------*/
374 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
376 return (sym->usl.spillLoc ? 0 : 1);
379 /*-----------------------------------------------------------------*/
380 /* hasSpilLoc - will return 1 if the symbol has spil location */
381 /*-----------------------------------------------------------------*/
383 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
385 return (sym->usl.spillLoc ? 1 : 0);
388 /*-----------------------------------------------------------------*/
389 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
390 /* but is not used as a pointer */
391 /*-----------------------------------------------------------------*/
393 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
395 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
398 /*-----------------------------------------------------------------*/
399 /* rematable - will return 1 if the remat flag is set */
400 /*-----------------------------------------------------------------*/
402 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
407 /*-----------------------------------------------------------------*/
408 /* notUsedInBlock - not used in this block */
409 /*-----------------------------------------------------------------*/
411 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
413 return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
414 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
415 /* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
418 /*-----------------------------------------------------------------*/
419 /* notUsedInRemaining - not used or defined in remain of the block */
420 /*-----------------------------------------------------------------*/
422 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
424 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
425 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
428 /*-----------------------------------------------------------------*/
429 /* allLRs - return true for all */
430 /*-----------------------------------------------------------------*/
432 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
437 /*-----------------------------------------------------------------*/
438 /* liveRangesWith - applies function to a given set of live range */
439 /*-----------------------------------------------------------------*/
441 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
442 eBBlock * ebp, iCode * ic)
447 if (!lrs || !lrs->size)
450 for (i = 1; i < lrs->size; i++)
453 if (!bitVectBitValue (lrs, i))
456 /* if we don't find it in the live range
457 hash table we are in serious trouble */
458 if (!(sym = hTabItemWithKey (liveRanges, i)))
460 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
461 "liveRangesWith could not find liveRange");
465 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
466 addSetHead (&rset, sym);
473 /*-----------------------------------------------------------------*/
474 /* leastUsedLR - given a set determines which is the least used */
475 /*-----------------------------------------------------------------*/
477 leastUsedLR (set * sset)
479 symbol *sym = NULL, *lsym = NULL;
481 sym = lsym = setFirstItem (sset);
486 for (; lsym; lsym = setNextItem (sset))
489 /* if usage is the same then prefer
490 the spill the smaller of the two */
491 if (lsym->used == sym->used)
492 if (getSize (lsym->type) < getSize (sym->type))
496 if (lsym->used < sym->used)
501 setToNull ((void **) &sset);
506 /*-----------------------------------------------------------------*/
507 /* noOverLap - will iterate through the list looking for over lap */
508 /*-----------------------------------------------------------------*/
510 noOverLap (set * itmpStack, symbol * fsym)
515 for (sym = setFirstItem (itmpStack); sym;
516 sym = setNextItem (itmpStack))
518 if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
524 /*-----------------------------------------------------------------*/
525 /* isFree - will return 1 if the a free spil location is found */
526 /*-----------------------------------------------------------------*/
527 static DEFSETFUNC (isFree) {
529 V_ARG (symbol **, sloc);
530 V_ARG (symbol *, fsym);
532 /* if already found */
536 /* if it is free && and the itmp assigned to
537 this does not have any overlapping live ranges
538 with the one currently being assigned and
539 the size can be accomodated */
541 noOverLap (sym->usl.itmpStack, fsym) &&
542 /* TODO: this is a waste but causes to many problems
543 getSize (sym->type) >= getSize (fsym->type)) {
545 getSize (sym->type) == getSize (fsym->type)) {
553 /*-----------------------------------------------------------------*/
554 /* createStackSpil - create a location on the stack to spil */
555 /*-----------------------------------------------------------------*/
557 createStackSpil (symbol * sym)
562 D(fprintf (stderr, " createStackSpil: %s\n", sym->name));
564 /* first go try and find a free one that is already
565 existing on the stack */
566 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
568 /* found a free one : just update & return */
569 sym->usl.spillLoc = sloc;
572 addSetHead (&sloc->usl.itmpStack, sym);
576 sprintf (slocBuffer, "sloc%d", _G.slocNum++);
577 sloc = newiTemp (slocBuffer);
579 /* set the type to the spilling symbol */
580 sloc->type = copyLinkChain (sym->type);
581 sloc->etype = getSpec (sloc->type);
582 SPEC_SCLS (sloc->etype) = S_STACK;
583 SPEC_EXTR (sloc->etype) = 0;
584 SPEC_STAT (sloc->etype) = 0;
585 SPEC_VOLATILE(sloc->etype) = 0;
586 SPEC_ABSA(sloc->etype) = 0;
590 sloc->isref = 1; /* to prevent compiler warning */
592 currFunc->stack += getSize (sloc->type);
593 _G.stackExtend += getSize (sloc->type);
595 /* add it to the _G.stackSpil set */
596 addSetHead (&_G.stackSpil, sloc);
597 sym->usl.spillLoc = sloc;
600 /* add it to the set of itempStack set
601 of the spill location */
602 addSetHead (&sloc->usl.itmpStack, sym);
606 /*-----------------------------------------------------------------*/
607 /* spillThis - spils a specific operand */
608 /*-----------------------------------------------------------------*/
610 spillThis (symbol * sym)
614 D(fprintf (stderr, " spillThis: %s\n", sym->name));
616 /* if this is rematerializable or has a spillLocation
617 we are okay, else we need to create a spillLocation
619 if (!(sym->remat || sym->usl.spillLoc))
620 createStackSpil (sym);
623 /* mark it has spilt & put it in the spilt set */
624 sym->isspilt = sym->spillA = 1;
625 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
627 bitVectUnSetBit (_G.regAssigned, sym->key);
628 bitVectUnSetBit (_G.totRegAssigned, sym->key);
630 for (i = 0; i < sym->nRegs; i++)
634 freeReg (sym->regs[i], FALSE);
637 if (sym->usl.spillLoc && !sym->remat)
638 sym->usl.spillLoc->allocreq++;
642 /*-----------------------------------------------------------------*/
643 /* selectSpil - select a iTemp to spil : rather a simple procedure */
644 /*-----------------------------------------------------------------*/
646 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
648 bitVect *lrcs = NULL;
652 /* get the spillable live ranges */
653 lrcs = computeSpillable (ic);
655 /* get all live ranges that are rematerizable */
656 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
658 /* return the least used of these */
659 return leastUsedLR (selectS);
662 /* if the symbol is local to the block then */
663 if (forSym->liveTo < ebp->lSeq)
666 /* check if there are any live ranges allocated
667 to registers that are not used in this block */
668 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
670 sym = leastUsedLR (selectS);
671 /* if this is not rematerializable */
680 /* check if there are any live ranges that not
681 used in the remainder of the block */
682 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
684 sym = leastUsedLR (selectS);
697 /* find live ranges with spillocation && not used as pointers */
698 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
701 sym = leastUsedLR (selectS);
702 /* mark this as allocation required */
703 sym->usl.spillLoc->allocreq++;
707 /* find live ranges with spillocation */
708 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
711 sym = leastUsedLR (selectS);
712 sym->usl.spillLoc->allocreq++;
716 /* couldn't find then we need to create a spil
717 location on the stack , for which one? the least
719 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
722 /* return a created spil location */
723 sym = createStackSpil (leastUsedLR (selectS));
724 sym->usl.spillLoc->allocreq++;
728 /* this is an extreme situation we will spill
729 this one : happens very rarely but it does happen */
734 /*-----------------------------------------------------------------*/
735 /* spillSomething - spil some variable & mark registers as free */
736 /*-----------------------------------------------------------------*/
738 spillSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
743 /* get something we can spil */
744 ssym = selectSpil (ic, ebp, forSym);
746 D(fprintf (stderr, " spillSomething: spilling %s\n", ssym->name));
748 /* mark it as spilt */
749 ssym->isspilt = ssym->spillA = 1;
750 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
752 /* mark it as not register assigned &
753 take it away from the set */
754 bitVectUnSetBit (_G.regAssigned, ssym->key);
755 bitVectUnSetBit (_G.totRegAssigned, ssym->key);
757 /* mark the registers as free */
758 for (i = 0; i < ssym->nRegs; i++) {
760 freeReg (ssym->regs[i], FALSE);
761 // dont NULL ssym->regs[i], it might be used later
765 /* if this was a block level spil then insert push & pop
766 at the start & end of block respectively */
769 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
770 /* add push to the start of the block */
771 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
772 ebp->sch->next : ebp->sch));
773 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
774 /* add pop to the end of the block */
775 addiCodeToeBBlock (ebp, nic, NULL);
778 /* if spilt because not used in the remainder of the
779 block then add a push before this instruction and
780 a pop at the end of the block */
781 if (ssym->remainSpil)
784 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
785 /* add push just before this instruction */
786 addiCodeToeBBlock (ebp, nic, ic);
788 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
789 /* add pop to the end of the block */
790 addiCodeToeBBlock (ebp, nic, NULL);
799 /*-----------------------------------------------------------------*/
800 /* getRegPtr - will try for PTR if not a GPR type if not spil */
801 /*-----------------------------------------------------------------*/
802 static bool getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
804 D(fprintf (stderr, "getRegPtr: %s ", sym->name));
805 D(printTypeChain(sym->type, stderr));
806 D(fprintf (stderr, "\n"));
809 /* try for a ptr type */
810 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
813 /* try for gpr type */
814 if (xa51HasGprRegs && allocReg (getSize(sym->type),
815 REG_GPR, sym, offset, FALSE))
818 /* we have to spil */
819 if (!spillSomething (ic, ebp, sym))
822 /* this looks like an infinite loop but
823 in really selectSpil will abort */
827 /*-----------------------------------------------------------------*/
828 /* getRegGpr - will try for GPR if not spil */
829 /*-----------------------------------------------------------------*/
830 static bool getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
832 D(fprintf (stderr, "getRegGpr: %s ", sym->name));
833 D(printTypeChain(sym->type, stderr));
834 D(fprintf (stderr, "\n"));
837 /* try for gpr type */
838 if (xa51HasGprRegs && allocReg (getSize(sym->type),
839 REG_GPR, sym, offset, FALSE))
842 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
845 /* we have to spil */
846 if (!spillSomething (ic, ebp, sym))
849 /* this looks like an infinite loop but
850 in really selectSpil will abort */
854 /*-----------------------------------------------------------------*/
855 /* deassignLRs - check the live to and if they have registers & are */
856 /* not spilt then free up the registers */
857 /*-----------------------------------------------------------------*/
859 deassignLRs (iCode * ic, eBBlock * ebp)
864 for (sym = hTabFirstItem (liveRanges, &k); sym;
865 sym = hTabNextItem (liveRanges, &k))
867 /* if it does not end here */
868 if (sym->liveTo > ic->seq)
871 /* if it was spilt on stack then we can
872 mark the stack spil location as free */
877 sym->usl.spillLoc->isFree = 1;
883 if (!bitVectBitValue (_G.regAssigned, sym->key))
889 bitVectUnSetBit (_G.regAssigned, sym->key);
892 for (i=0; i < sym->nRegs; i++) {
893 freeReg (sym->regs[i], FALSE);
899 /*-----------------------------------------------------------------*/
900 /* willCauseSpill - determines if allocating will cause a spill */
901 /*-----------------------------------------------------------------*/
902 static bool willCauseSpill (symbol *sym) {
904 // do it the rude way
905 if (allocReg (getSize(sym->type), sym->regType, sym, 0, TRUE) ||
906 allocReg (getSize(sym->type), sym->regType==REG_PTR?REG_GPR:REG_PTR,
908 // so we can, but we won't
909 for (i=0; i<sym->nRegs; i++) {
910 freeReg (sym->regs[i], TRUE);
915 D(fprintf (stderr, " %s will cause a spill\n", sym->name));
919 /*-----------------------------------------------------------------*/
920 /* positionRegs - the allocator can allocate same registers to res- */
921 /* ult and operand, if this happens make sure they are in the same */
922 /* position as the operand otherwise chaos results */
923 /*-----------------------------------------------------------------*/
925 positionRegs (symbol * result, symbol * opsym)
927 int count = min (result->nRegs, opsym->nRegs);
928 int i, j = 0, shared = 0;
931 /* if the result has been spilt then cannot share */
936 /* first make sure that they actually share */
937 for (i = 0; i < count; i++)
939 for (j = 0; j < count; j++)
941 if (result->regs[i] == opsym->regs[j] && i != j)
951 regs *tmp = result->regs[i];
952 result->regs[i] = result->regs[j];
953 result->regs[j] = tmp;
960 /*-----------------------------------------------------------------*/
961 /* serialRegAssign - serially allocate registers to the variables */
962 /*-----------------------------------------------------------------*/
964 serialRegAssign (eBBlock ** ebbs, int count)
969 for (i = 0; i < count; i++) {
973 if (ebbs[i]->noPath &&
974 (ebbs[i]->entryLabel != entryLabel &&
975 ebbs[i]->entryLabel != returnLabel))
978 /* of all instructions do */
979 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
981 /* if result is present && is a true symbol */
982 if (IC_RESULT (ic) && ic->op != IFX &&
983 IS_TRUE_SYMOP (IC_RESULT (ic))) {
984 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
987 /* take away registers from live
988 ranges that end at this instruction */
989 deassignLRs (ic, ebbs[i]);
991 /* some don't need registers */
993 ic->op == JUMPTABLE ||
997 (IC_RESULT (ic) && POINTER_SET (ic)))
1001 /* xa51 has advance compare instructions */
1002 if (ic->op == '<' || ic->op == '>' ||
1003 ic->op == LE_OP || ic->op == GE_OP ||
1004 ic->op == NE_OP || ic->op == EQ_OP) {
1005 /* if this result is only used for an ifx, we don't
1006 need registers nor the ifx */
1007 int used=bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->uses);
1010 fprintf (stderr, "unexpected \"used\" for cmp:%d\n", ic->op);
1014 for (nic=ic->next; nic; nic=nic->next) {
1015 if (nic->op == IFX) {
1020 // we are in big trouble
1021 fprintf (stderr, "No ifx found for %d\n",
1026 nic->prev->next=nic->next;
1028 nic->next->prev=nic->prev;
1033 /* now we need to allocate registers
1034 only for the result */
1035 if (IC_RESULT (ic)) {
1036 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1040 /* if it does not need or is spilt
1041 or is already assigned to registers
1042 or will not live beyond this instructions */
1045 bitVectBitValue (_G.regAssigned, sym->key) ||
1046 sym->liveTo <= ic->seq)
1049 /* if some liverange has been spilt at the block level
1050 and this one live beyond this block then spil this
1052 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1056 /* if trying to allocate this will cause
1057 a spill and there is nothing to spill
1058 or this one is rematerializable then
1060 willCS = willCauseSpill (sym);
1061 spillable = computeSpillable (ic);
1062 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1067 /* if it has a spillocation & is used less than
1068 all other live ranges then spill this */
1070 if (sym->usl.spillLoc) {
1071 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1072 allLRs, ebbs[i], ic));
1073 if (leastUsed && leastUsed->used > sym->used) {
1078 /* if none of the liveRanges have a spillLocation then better
1079 to spill this one than anything else already assigned to registers */
1080 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1081 /* if this is local to this block then we might find a block spil */
1082 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1090 /* else we assign registers to it */
1091 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1092 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1094 if (sym->regType == REG_PTR)
1095 getRegPtr (ic, ebbs[i], sym, 0);
1097 getRegGpr (ic, ebbs[i], sym, 0);
1099 /* if it shares registers with operands make sure
1100 that they are in the same position */
1101 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1102 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1103 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1104 OP_SYMBOL (IC_LEFT (ic)));
1106 /* do the same for the right operand */
1107 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1108 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1109 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1110 OP_SYMBOL (IC_RIGHT (ic)));
1117 /*-----------------------------------------------------------------*/
1118 /* rUmaskForOp :- returns register mask for an operand */
1119 /*-----------------------------------------------------------------*/
1120 bitVect *xa51_rUmaskForOp (operand * op) {
1125 /* only temporaries are assigned registers */
1129 sym = OP_SYMBOL (op);
1131 /* if spilt or no registers assigned to it
1133 if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1136 rumask = newBitVect (xa51_nRegs);
1138 for (j = 0; j < sym->nRegs; j++) {
1139 rumask = bitVectSetBit (rumask,
1140 sym->regs[j]->rIdx);
1145 /*-----------------------------------------------------------------*/
1146 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1147 /*-----------------------------------------------------------------*/
1149 regsUsedIniCode (iCode * ic)
1151 bitVect *rmask = newBitVect (xa51_nRegs);
1153 /* do the special cases first */
1156 rmask = bitVectUnion (rmask,
1157 xa51_rUmaskForOp (IC_COND (ic)));
1161 /* for the jumptable */
1162 if (ic->op == JUMPTABLE)
1164 rmask = bitVectUnion (rmask,
1165 xa51_rUmaskForOp (IC_JTCOND (ic)));
1170 /* of all other cases */
1172 rmask = bitVectUnion (rmask,
1173 xa51_rUmaskForOp (IC_LEFT (ic)));
1177 rmask = bitVectUnion (rmask,
1178 xa51_rUmaskForOp (IC_RIGHT (ic)));
1181 rmask = bitVectUnion (rmask,
1182 xa51_rUmaskForOp (IC_RESULT (ic)));
1188 /*-----------------------------------------------------------------*/
1189 /* createRegMask - for each instruction will determine the regsUsed */
1190 /*-----------------------------------------------------------------*/
1192 createRegMask (eBBlock ** ebbs, int count)
1196 /* for all blocks */
1197 for (i = 0; i < count; i++)
1201 if (ebbs[i]->noPath &&
1202 (ebbs[i]->entryLabel != entryLabel &&
1203 ebbs[i]->entryLabel != returnLabel))
1206 /* for all instructions */
1207 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1212 if (SKIP_IC2 (ic) || !ic->rlive)
1215 /* first mark the registers used in this
1217 ic->rUsed = regsUsedIniCode (ic);
1218 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1220 /* now create the register mask for those
1221 registers that are in use : this is a
1222 super set of ic->rUsed */
1223 ic->rMask = newBitVect (xa51_nRegs + 1);
1225 /* for all live Ranges alive at this point */
1226 for (j = 1; j < ic->rlive->size; j++)
1231 /* if not alive then continue */
1232 if (!bitVectBitValue (ic->rlive, j))
1235 /* find the live range we are interested in */
1236 if (!(sym = hTabItemWithKey (liveRanges, j)))
1238 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1239 "createRegMask cannot find live range");
1243 /* if no register assigned to it */
1244 if (!sym->nRegs || sym->isspilt)
1247 /* for all the registers allocated to it */
1248 for (k = 0; k < sym->nRegs; k++)
1251 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1257 /*-----------------------------------------------------------------*/
1258 /* rematStr - returns the rematerialized string for a remat var */
1259 /*-----------------------------------------------------------------*/
1261 rematStr (symbol * sym)
1264 iCode *ic = sym->rematiCode;
1269 /* if plus or minus print the right hand side */
1270 if (ic->op == '+' || ic->op == '-')
1272 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1275 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1279 /* cast then continue */
1280 if (IS_CAST_ICODE(ic)) {
1281 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1284 /* we reached the end */
1285 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1292 /*-----------------------------------------------------------------*/
1293 /* regTypeNum - computes the type & number of registers required */
1294 /*-----------------------------------------------------------------*/
1296 regTypeNum (eBBlock *ebbs)
1302 /* for each live range do */
1303 for (sym = hTabFirstItem (liveRanges, &k); sym;
1304 sym = hTabNextItem (liveRanges, &k))
1307 /* if used zero times then no registers needed */
1308 if ((sym->liveTo - sym->liveFrom) == 0)
1312 /* if the live range is a temporary */
1316 /* if the type is marked as a conditional */
1317 if (sym->regType == REG_CND)
1320 /* if used in return only then we don't
1323 if (sym->ruonly || sym->accuse)
1325 if (IS_AGGREGATE (sym->type) || sym->isptr)
1326 sym->type = aggrToPtr (sym->type, FALSE);
1331 /* if the symbol has only one definition &
1332 that definition is a get_pointer */
1333 if (bitVectnBitsOn (sym->defs) == 1 &&
1334 (ic = hTabItemWithKey (iCodehTab,
1335 bitVectFirstBit (sym->defs))) &&
1338 !IS_BITVAR (sym->etype))
1340 /* and that pointer is remat in data space */
1341 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1342 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1343 DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1345 /* create a psuedo symbol & force a spil */
1346 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1347 psym->type = sym->type;
1348 psym->etype = sym->etype;
1349 strcpy (psym->rname, psym->name);
1351 sym->usl.spillLoc = psym;
1352 #if 0 // an alternative fix for bug #480076
1353 /* now this is a useless assignment to itself */
1354 remiCodeFromeBBlock (ebbs, ic);
1356 /* now this really is an assignment to itself, make it so;
1357 it will be optimized out later */
1359 IC_RIGHT(ic)=IC_RESULT(ic);
1365 /* if in data space or idata space then try to
1366 allocate pointer register */
1370 /* if not then we require registers */
1372 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1373 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1374 getSize (sym->type));
1377 int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1378 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1379 getSize (sym->type));
1383 case 2: // word or pointer
1386 case 3: // generic pointer
1389 case 4: // dword or float
1393 fprintf (stderr, "regTypeNum: unknown size\n");
1401 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1402 printTypeChain (sym->type, stderr);
1403 fprintf (stderr, "\n");
1407 /* determine the type of register required */
1408 if (IS_PTR (sym->type))
1409 sym->regType = REG_PTR;
1411 sym->regType = REG_GPR;
1415 /* for the first run we don't provide */
1416 /* registers for true symbols we will */
1417 /* see how things go */
1423 /*-----------------------------------------------------------------*/
1424 /* deallocStackSpil - this will set the stack pointer back */
1425 /*-----------------------------------------------------------------*/
1427 DEFSETFUNC (deallocStackSpil)
1435 /*-----------------------------------------------------------------*/
1436 /* packRegsForAssign - register reduction for assignment */
1437 /*-----------------------------------------------------------------*/
1439 packRegsForAssign (iCode * ic, eBBlock * ebp)
1443 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1444 OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1448 /* find the definition of iTempNN scanning backwards */
1449 for (dic = ic->prev; dic; dic = dic->prev) {
1451 /* if there is a function call then don't pack it */
1452 if ((dic->op == CALL || dic->op == PCALL)) {
1460 if (IS_SYMOP (IC_RESULT (dic)) &&
1461 IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1468 return 0; /* did not find */
1470 /* found the definition */
1471 /* replace the result with the result of */
1472 /* this assignment and remove this assignment */
1473 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1474 IC_RESULT (dic) = IC_RESULT (ic);
1476 if (IS_ITEMP (IC_RESULT (dic)) &&
1477 OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1479 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1481 /* delete from liverange table also
1482 delete from all the points inbetween and the new
1484 for (sic = dic; sic != ic; sic = sic->next)
1486 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1487 if (IS_ITEMP (IC_RESULT (dic)))
1488 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1491 remiCodeFromeBBlock (ebp, ic);
1492 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1493 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1494 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1499 /*-----------------------------------------------------------------*/
1500 /* findAssignToSym : scanning backwards looks for first assig found */
1501 /*-----------------------------------------------------------------*/
1503 findAssignToSym (operand * op, iCode * ic)
1507 for (dic = ic->prev; dic; dic = dic->prev)
1510 /* if definition by assignment */
1511 if (dic->op == '=' &&
1512 !POINTER_SET (dic) &&
1513 IC_RESULT (dic)->key == op->key
1514 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1518 /* we are interested only if defined in far space */
1519 /* or in stack space in case of + & - */
1521 /* if assigned to a non-symbol then return
1523 if (!IS_SYMOP (IC_RIGHT (dic)))
1526 /* if the symbol is in far space then
1528 if (isOperandInFarSpace (IC_RIGHT (dic)))
1531 /* for + & - operations make sure that
1532 if it is on the stack it is the same
1533 as one of the three operands */
1534 if ((ic->op == '+' || ic->op == '-') &&
1535 OP_SYMBOL (IC_RIGHT (dic))->onStack)
1538 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1539 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1540 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1548 /* if we find an usage then we cannot delete it */
1549 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1552 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1555 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1559 /* now make sure that the right side of dic
1560 is not defined between ic & dic */
1563 iCode *sic = dic->next;
1565 for (; sic != ic; sic = sic->next)
1566 if (IC_RESULT (sic) &&
1567 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1576 /*-----------------------------------------------------------------*/
1577 /* packRegsForSupport :- reduce some registers for support calls */
1578 /*-----------------------------------------------------------------*/
1580 packRegsForSupport (iCode * ic, eBBlock * ebp)
1585 /* for the left & right operand :- look to see if the
1586 left was assigned a true symbol in far space in that
1587 case replace them */
1589 if (IS_ITEMP (IC_LEFT (ic)) &&
1590 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1592 dic = findAssignToSym (IC_LEFT (ic), ic);
1597 /* found it we need to remove it from the
1599 for (sic = dic; sic != ic; sic = sic->next)
1600 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1602 OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1603 IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1604 remiCodeFromeBBlock (ebp, dic);
1605 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1606 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1610 /* do the same for the right operand */
1613 IS_ITEMP (IC_RIGHT (ic)) &&
1614 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1616 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1622 /* if this is a subtraction & the result
1623 is a true symbol in far space then don't pack */
1624 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1626 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1627 if (IN_FARSPACE (SPEC_OCLS (etype)))
1630 /* found it we need to remove it from the
1632 for (sic = dic; sic != ic; sic = sic->next)
1633 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1635 IC_RIGHT (ic)->operand.symOperand =
1636 IC_RIGHT (dic)->operand.symOperand;
1637 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1639 remiCodeFromeBBlock (ebp, dic);
1640 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1641 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1648 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1651 /*-----------------------------------------------------------------*/
1652 /* packRegsForOneuse : - will reduce some registers for single Use */
1653 /*-----------------------------------------------------------------*/
1655 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1660 /* if returning a literal then do nothing */
1664 if (ic->op != RETURN &&
1666 !POINTER_SET (ic) &&
1670 /* this routine will mark the a symbol as used in one
1671 instruction use only && if the defintion is local
1672 (ie. within the basic block) && has only one definition &&
1673 that definiion is either a return value from a
1674 function or does not contain any variables in
1676 uses = bitVectCopy (OP_USES (op));
1677 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
1678 if (!bitVectIsZero (uses)) /* has other uses */
1681 /* if it has only one defintion */
1682 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1683 return NULL; /* has more than one definition */
1685 /* get that definition */
1687 hTabItemWithKey (iCodehTab,
1688 bitVectFirstBit (OP_DEFS (op)))))
1691 /* if that only usage is a cast */
1692 if (dic->op == CAST) {
1693 /* to a bigger type */
1694 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
1695 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1696 /* than we can not, since we cannot predict the usage of b & acc */
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)
1710 if (ic->op != SEND && ic->op != RETURN &&
1711 !POINTER_SET(ic) && !POINTER_GET(ic))
1713 OP_SYMBOL (op)->ruonly = 1;
1720 /* otherwise check that the definition does
1721 not contain any symbols in far space */
1722 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1723 isOperandInFarSpace (IC_RIGHT (dic)) ||
1724 IS_OP_RUONLY (IC_LEFT (ic)) ||
1725 IS_OP_RUONLY (IC_RIGHT (ic)))
1730 /* if pointer set then make sure the pointer
1732 if (POINTER_SET (dic) &&
1733 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1736 if (POINTER_GET (dic) &&
1737 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1742 /* also make sure the intervenening instructions
1743 don't have any thing in far space */
1744 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1747 /* if there is an intervening function call then no */
1748 if (dic->op == CALL || dic->op == PCALL)
1750 /* if pointer set then make sure the pointer
1752 if (POINTER_SET (dic) &&
1753 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1756 if (POINTER_GET (dic) &&
1757 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1760 /* if address of & the result is remat the okay */
1761 if (dic->op == ADDRESS_OF &&
1762 OP_SYMBOL (IC_RESULT (dic))->remat)
1765 /* if operand has size of three or more & this
1766 operation is a '*','/' or '%' then 'b' may
1768 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1769 getSize (operandType (op)) >= 3)
1772 /* if left or right or result is in far space */
1773 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1774 isOperandInFarSpace (IC_RIGHT (dic)) ||
1775 isOperandInFarSpace (IC_RESULT (dic)) ||
1776 IS_OP_RUONLY (IC_LEFT (dic)) ||
1777 IS_OP_RUONLY (IC_RIGHT (dic)) ||
1778 IS_OP_RUONLY (IC_RESULT (dic)))
1782 /* if left or right or result is on stack */
1783 if (isOperandOnStack(IC_LEFT(dic)) ||
1784 isOperandOnStack(IC_RIGHT(dic)) ||
1785 isOperandOnStack(IC_RESULT(dic))) {
1790 OP_SYMBOL (op)->ruonly = 1;
1795 /*-----------------------------------------------------------------*/
1796 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1797 /*-----------------------------------------------------------------*/
1799 isBitwiseOptimizable (iCode * ic)
1801 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1802 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1804 /* bitwise operations are considered optimizable
1805 under the following conditions (Jean-Louis VERN)
1817 if (IS_LITERAL(rtype) ||
1818 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1824 /*-----------------------------------------------------------------*/
1825 /* packForPush - hueristics to reduce iCode for pushing */
1826 /*-----------------------------------------------------------------*/
1828 packForPush (iCode * ic, eBBlock * ebp)
1833 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1836 /* must have only definition & one usage */
1837 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1838 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1841 /* find the definition */
1842 if (!(dic = hTabItemWithKey (iCodehTab,
1843 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1846 if (dic->op != '=' || POINTER_SET (dic))
1849 /* make sure the right side does not have any definitions
1851 dbv = OP_DEFS(IC_RIGHT(dic));
1852 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1853 if (bitVectBitValue(dbv,lic->key))
1856 /* make sure they have the same type */
1858 sym_link *itype=operandType(IC_LEFT(ic));
1859 sym_link *ditype=operandType(IC_RIGHT(dic));
1861 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1862 SPEC_LONG(itype)!=SPEC_LONG(ditype))
1865 /* extend the live range of replaced operand if needed */
1866 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1867 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1869 /* we now know that it has one & only one def & use
1870 and the that the definition is an assignment */
1871 IC_LEFT (ic) = IC_RIGHT (dic);
1873 remiCodeFromeBBlock (ebp, dic);
1874 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1875 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1878 /*-----------------------------------------------------------------*/
1879 /* packRegisters - does some transformations to reduce register */
1881 /*-----------------------------------------------------------------*/
1882 static void packRegisters (eBBlock * ebp) {
1889 for (ic = ebp->sch; ic; ic = ic->next) {
1891 change += packRegsForAssign (ic, ebp);
1898 for (ic = ebp->sch; ic; ic = ic->next)
1900 /* if the condition of an if instruction
1901 is defined in the previous instruction and
1902 this is the only usage then
1903 mark the itemp as a conditional */
1904 if ((IS_CONDITIONAL (ic) ||
1905 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic)))) {
1906 if (ic->next && ic->next->op == IFX &&
1907 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1908 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1909 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) {
1910 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1915 // that's all for now
1918 /* if this is an itemp & result of an address of a true sym
1919 then mark this as rematerialisable */
1920 if (ic->op == ADDRESS_OF &&
1921 IS_ITEMP (IC_RESULT (ic)) &&
1922 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1923 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1924 !OP_SYMBOL (IC_LEFT (ic))->onStack)
1927 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1928 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1929 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1933 /* if straight assignment then carry remat flag if
1934 this is the only definition */
1935 if (ic->op == '=' &&
1936 !POINTER_SET (ic) &&
1937 IS_SYMOP (IC_RIGHT (ic)) &&
1938 OP_SYMBOL (IC_RIGHT (ic))->remat &&
1939 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1940 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1943 OP_SYMBOL (IC_RESULT (ic))->remat =
1944 OP_SYMBOL (IC_RIGHT (ic))->remat;
1945 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1946 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1949 /* if cast to a generic pointer & the pointer being
1950 cast is remat, then we can remat this cast as well */
1951 if (ic->op == CAST &&
1952 IS_SYMOP(IC_RIGHT(ic)) &&
1953 OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1954 sym_link *to_type = operandType(IC_LEFT(ic));
1955 sym_link *from_type = operandType(IC_RIGHT(ic));
1956 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
1957 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1958 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1959 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1963 /* if this is a +/- operation with a rematerizable
1964 then mark this as rematerializable as well */
1965 if ((ic->op == '+' || ic->op == '-') &&
1966 (IS_SYMOP (IC_LEFT (ic)) &&
1967 IS_ITEMP (IC_RESULT (ic)) &&
1968 IS_OP_LITERAL (IC_RIGHT (ic))) &&
1969 OP_SYMBOL (IC_LEFT (ic))->remat &&
1970 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1971 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1973 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1974 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1975 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1978 /* mark the pointer usages */
1979 if (POINTER_SET (ic))
1980 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1982 if (POINTER_GET (ic))
1983 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1985 /* reduce for support function calls */
1986 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1987 packRegsForSupport (ic, ebp);
1989 /* some cases the redundant moves can
1990 can be eliminated for return statements */
1991 if ((ic->op == RETURN || ic->op == SEND) &&
1992 !isOperandInFarSpace (IC_LEFT (ic)) &&
1993 options.model == MODEL_SMALL) {
1994 if (0 && options.stackAuto) {
1995 /* we should check here if acc will be clobbered for stack
1996 offset calculations */
1998 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2002 /* if pointer set & left has a size more than
2003 one and right is not in far space */
2004 if (POINTER_SET (ic) &&
2005 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2006 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2007 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2008 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2010 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2012 /* if pointer get */
2013 if (POINTER_GET (ic) &&
2014 !isOperandInFarSpace (IC_RESULT (ic)) &&
2015 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2016 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2017 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2019 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2022 /* if this is cast for intergral promotion then
2023 check if only use of the definition of the
2024 operand being casted/ if yes then replace
2025 the result of that arithmetic operation with
2026 this result and get rid of the cast */
2029 sym_link *fromType = operandType (IC_RIGHT (ic));
2030 sym_link *toType = operandType (IC_LEFT (ic));
2032 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2033 getSize (fromType) != getSize (toType) &&
2034 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2037 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2040 if (IS_ARITHMETIC_OP (dic))
2042 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2043 IC_RESULT (dic) = IC_RESULT (ic);
2044 remiCodeFromeBBlock (ebp, ic);
2045 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2046 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2047 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2051 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2057 /* if the type from and type to are the same
2058 then if this is the only use then packit */
2059 if (compareType (operandType (IC_RIGHT (ic)),
2060 operandType (IC_LEFT (ic))) == 1)
2062 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2065 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2066 IC_RESULT (dic) = IC_RESULT (ic);
2067 remiCodeFromeBBlock (ebp, ic);
2068 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2069 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2070 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2078 iTempNN := (some variable in farspace) V1
2083 if (ic->op == IPUSH)
2085 packForPush (ic, ebp);
2090 /*-----------------------------------------------------------------*/
2091 /* assignRegisters - assigns registers to each live range as need */
2092 /*-----------------------------------------------------------------*/
2094 xa51_assignRegisters (eBBlock ** ebbs, int count)
2099 setToNull ((void *) &_G.funcrUsed);
2100 setToNull ((void *) &_G.totRegAssigned);
2101 _G.stackExtend = _G.dataExtend = 0;
2103 /* change assignments this will remove some
2104 live ranges reducing some register pressure */
2105 for (i = 0; i < count; i++)
2106 packRegisters (ebbs[i]);
2108 if (options.dump_pack)
2109 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2111 /* first determine for each live range the number of
2112 registers & the type of registers required for each */
2115 /* and serially allocate registers */
2116 serialRegAssign (ebbs, count);
2120 /* if stack was extended then tell the user */
2123 /* werror(W_TOOMANY_SPILS,"stack", */
2124 /* _G.stackExtend,currFunc->name,""); */
2130 /* werror(W_TOOMANY_SPILS,"data space", */
2131 /* _G.dataExtend,currFunc->name,""); */
2135 /* after that create the register mask
2136 for each of the instruction */
2137 createRegMask (ebbs, count);
2139 /* redo that offsets for stacked automatic variables */
2140 redoStackOffsets ();
2142 if (options.dump_rassgn)
2144 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2145 dumpLiveRanges (DUMP_LRANGE, liveRanges);
2148 /* do the overlaysegment stuff SDCCmem.c */
2149 doOverlays (ebbs, count);
2151 /* now get back the chain */
2152 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2156 /* free up any _G.stackSpil locations allocated */
2157 applyToSet (_G.stackSpil, deallocStackSpil);
2159 setToNull ((void **) &_G.stackSpil);
2160 setToNull ((void **) &_G.spiltSet);
2161 /* mark all registers as free */