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++;
986 /* take away registers from live
987 ranges that end at this instruction */
988 deassignLRs (ic, ebbs[i]);
990 /* some don't need registers */
992 ic->op == JUMPTABLE ||
996 (IC_RESULT (ic) && POINTER_SET (ic)))
1000 /* xa51 has advance compare instructions */
1001 if (ic->op == '<' || ic->op == '>' ||
1002 ic->op == LE_OP || ic->op == GE_OP ||
1003 ic->op == NE_OP || ic->op == EQ_OP) {
1004 /* if this result is only used for an ifx, we don't
1005 need registers nor the ifx */
1006 int used=bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->uses);
1009 fprintf (stderr, "unexpected \"used\" for cmp:%d\n", ic->op);
1013 for (nic=ic->next; nic; nic=nic->next) {
1014 if (nic->op == IFX) {
1019 // we are in big trouble
1020 fprintf (stderr, "No ifx found for %d\n",
1025 nic->prev->next=nic->next;
1027 nic->next->prev=nic->prev;
1032 /* now we need to allocate registers
1033 only for the result */
1034 if (IC_RESULT (ic)) {
1035 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1039 /* if it does not need or is spilt
1040 or is already assigned to registers
1041 or will not live beyond this instructions */
1044 bitVectBitValue (_G.regAssigned, sym->key) ||
1045 sym->liveTo <= ic->seq)
1048 /* if some liverange has been spilt at the block level
1049 and this one live beyond this block then spil this
1051 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1055 /* if trying to allocate this will cause
1056 a spill and there is nothing to spill
1057 or this one is rematerializable then
1059 willCS = willCauseSpill (sym);
1060 spillable = computeSpillable (ic);
1061 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1066 /* if it has a spillocation & is used less than
1067 all other live ranges then spill this */
1069 if (sym->usl.spillLoc) {
1070 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1071 allLRs, ebbs[i], ic));
1072 if (leastUsed && leastUsed->used > sym->used) {
1077 /* if none of the liveRanges have a spillLocation then better
1078 to spill this one than anything else already assigned to registers */
1079 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1080 /* if this is local to this block then we might find a block spil */
1081 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1089 /* else we assign registers to it */
1090 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1091 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1093 if (sym->regType == REG_PTR)
1094 getRegPtr (ic, ebbs[i], sym, 0);
1096 getRegGpr (ic, ebbs[i], sym, 0);
1098 /* if it shares registers with operands make sure
1099 that they are in the same position */
1100 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1101 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1102 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1103 OP_SYMBOL (IC_LEFT (ic)));
1105 /* do the same for the right operand */
1106 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1107 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1108 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1109 OP_SYMBOL (IC_RIGHT (ic)));
1116 /*-----------------------------------------------------------------*/
1117 /* rUmaskForOp :- returns register mask for an operand */
1118 /*-----------------------------------------------------------------*/
1119 bitVect *xa51_rUmaskForOp (operand * op) {
1124 /* only temporaries are assigned registers */
1128 sym = OP_SYMBOL (op);
1130 /* if spilt or no registers assigned to it
1132 if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1135 rumask = newBitVect (xa51_nRegs);
1137 for (j = 0; j < sym->nRegs; j++) {
1138 rumask = bitVectSetBit (rumask,
1139 sym->regs[j]->rIdx);
1144 /*-----------------------------------------------------------------*/
1145 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1146 /*-----------------------------------------------------------------*/
1148 regsUsedIniCode (iCode * ic)
1150 bitVect *rmask = newBitVect (xa51_nRegs);
1152 /* do the special cases first */
1155 rmask = bitVectUnion (rmask,
1156 xa51_rUmaskForOp (IC_COND (ic)));
1160 /* for the jumptable */
1161 if (ic->op == JUMPTABLE)
1163 rmask = bitVectUnion (rmask,
1164 xa51_rUmaskForOp (IC_JTCOND (ic)));
1169 /* of all other cases */
1171 rmask = bitVectUnion (rmask,
1172 xa51_rUmaskForOp (IC_LEFT (ic)));
1176 rmask = bitVectUnion (rmask,
1177 xa51_rUmaskForOp (IC_RIGHT (ic)));
1180 rmask = bitVectUnion (rmask,
1181 xa51_rUmaskForOp (IC_RESULT (ic)));
1187 /*-----------------------------------------------------------------*/
1188 /* createRegMask - for each instruction will determine the regsUsed */
1189 /*-----------------------------------------------------------------*/
1191 createRegMask (eBBlock ** ebbs, int count)
1195 /* for all blocks */
1196 for (i = 0; i < count; i++)
1200 if (ebbs[i]->noPath &&
1201 (ebbs[i]->entryLabel != entryLabel &&
1202 ebbs[i]->entryLabel != returnLabel))
1205 /* for all instructions */
1206 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1211 if (SKIP_IC2 (ic) || !ic->rlive)
1214 /* first mark the registers used in this
1216 ic->rUsed = regsUsedIniCode (ic);
1217 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1219 /* now create the register mask for those
1220 registers that are in use : this is a
1221 super set of ic->rUsed */
1222 ic->rMask = newBitVect (xa51_nRegs + 1);
1224 /* for all live Ranges alive at this point */
1225 for (j = 1; j < ic->rlive->size; j++)
1230 /* if not alive then continue */
1231 if (!bitVectBitValue (ic->rlive, j))
1234 /* find the live range we are interested in */
1235 if (!(sym = hTabItemWithKey (liveRanges, j)))
1237 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1238 "createRegMask cannot find live range");
1242 /* if no register assigned to it */
1243 if (!sym->nRegs || sym->isspilt)
1246 /* for all the registers allocated to it */
1247 for (k = 0; k < sym->nRegs; k++)
1250 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1256 /*-----------------------------------------------------------------*/
1257 /* rematStr - returns the rematerialized string for a remat var */
1258 /*-----------------------------------------------------------------*/
1260 rematStr (symbol * sym)
1263 iCode *ic = sym->rematiCode;
1268 /* if plus or minus print the right hand side */
1269 if (ic->op == '+' || ic->op == '-')
1271 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1274 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1278 /* cast then continue */
1279 if (IS_CAST_ICODE(ic)) {
1280 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1283 /* we reached the end */
1284 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1291 /*-----------------------------------------------------------------*/
1292 /* regTypeNum - computes the type & number of registers required */
1293 /*-----------------------------------------------------------------*/
1295 regTypeNum (eBBlock *ebbs)
1301 /* for each live range do */
1302 for (sym = hTabFirstItem (liveRanges, &k); sym;
1303 sym = hTabNextItem (liveRanges, &k))
1306 /* if used zero times then no registers needed */
1307 if ((sym->liveTo - sym->liveFrom) == 0)
1311 /* if the live range is a temporary */
1315 /* if the type is marked as a conditional */
1316 if (sym->regType == REG_CND)
1319 /* if used in return only then we don't
1322 if (sym->ruonly || sym->accuse)
1324 if (IS_AGGREGATE (sym->type) || sym->isptr)
1325 sym->type = aggrToPtr (sym->type, FALSE);
1330 /* if the symbol has only one definition &
1331 that definition is a get_pointer and the
1332 pointer we are getting is rematerializable and
1335 if (bitVectnBitsOn (sym->defs) == 1 &&
1336 (ic = hTabItemWithKey (iCodehTab,
1337 bitVectFirstBit (sym->defs))) &&
1340 !IS_BITVAR (sym->etype))
1344 /* if remat in data space */
1345 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1346 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1347 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1349 /* create a psuedo symbol & force a spil */
1350 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1351 psym->type = sym->type;
1352 psym->etype = sym->etype;
1353 strcpy (psym->rname, psym->name);
1355 sym->usl.spillLoc = psym;
1356 #if 0 // an alternative fix for bug #480076
1357 /* now this is a useless assignment to itself */
1358 remiCodeFromeBBlock (ebbs, ic);
1360 /* now this really is an assignment to itself, make it so;
1361 it will be optimized out later */
1363 IC_RIGHT(ic)=IC_RESULT(ic);
1369 /* if in data space or idata space then try to
1370 allocate pointer register */
1374 /* if not then we require registers */
1376 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1377 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1378 getSize (sym->type));
1381 int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1382 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1383 getSize (sym->type));
1387 case 2: // word or pointer
1390 case 3: // generic pointer
1393 case 4: // dword or float
1397 fprintf (stderr, "regTypeNum: unknown size\n");
1405 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1406 printTypeChain (sym->type, stderr);
1407 fprintf (stderr, "\n");
1411 /* determine the type of register required */
1412 if (IS_PTR (sym->type))
1413 sym->regType = REG_PTR;
1415 sym->regType = REG_GPR;
1419 /* for the first run we don't provide */
1420 /* registers for true symbols we will */
1421 /* see how things go */
1427 /*-----------------------------------------------------------------*/
1428 /* deallocStackSpil - this will set the stack pointer back */
1429 /*-----------------------------------------------------------------*/
1431 DEFSETFUNC (deallocStackSpil)
1439 /*-----------------------------------------------------------------*/
1440 /* packRegsForAssign - register reduction for assignment */
1441 /*-----------------------------------------------------------------*/
1443 packRegsForAssign (iCode * ic, eBBlock * ebp)
1447 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1448 OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1452 /* find the definition of iTempNN scanning backwards */
1453 for (dic = ic->prev; dic; dic = dic->prev) {
1455 /* if there is a function call then don't pack it */
1456 if ((dic->op == CALL || dic->op == PCALL)) {
1464 if (IS_SYMOP (IC_RESULT (dic)) &&
1465 IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1472 return 0; /* did not find */
1474 /* found the definition */
1475 /* replace the result with the result of */
1476 /* this assignment and remove this assignment */
1477 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1478 IC_RESULT (dic) = IC_RESULT (ic);
1480 if (IS_ITEMP (IC_RESULT (dic)) &&
1481 OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1483 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1485 /* delete from liverange table also
1486 delete from all the points inbetween and the new
1488 for (sic = dic; sic != ic; sic = sic->next)
1490 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1491 if (IS_ITEMP (IC_RESULT (dic)))
1492 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1495 remiCodeFromeBBlock (ebp, ic);
1496 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1497 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1498 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1503 /*-----------------------------------------------------------------*/
1504 /* findAssignToSym : scanning backwards looks for first assig found */
1505 /*-----------------------------------------------------------------*/
1507 findAssignToSym (operand * op, iCode * ic)
1511 for (dic = ic->prev; dic; dic = dic->prev)
1514 /* if definition by assignment */
1515 if (dic->op == '=' &&
1516 !POINTER_SET (dic) &&
1517 IC_RESULT (dic)->key == op->key
1518 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1522 /* we are interested only if defined in far space */
1523 /* or in stack space in case of + & - */
1525 /* if assigned to a non-symbol then return
1527 if (!IS_SYMOP (IC_RIGHT (dic)))
1530 /* if the symbol is in far space then
1532 if (isOperandInFarSpace (IC_RIGHT (dic)))
1535 /* for + & - operations make sure that
1536 if it is on the stack it is the same
1537 as one of the three operands */
1538 if ((ic->op == '+' || ic->op == '-') &&
1539 OP_SYMBOL (IC_RIGHT (dic))->onStack)
1542 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1543 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1544 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1552 /* if we find an usage then we cannot delete it */
1553 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1556 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1559 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1563 /* now make sure that the right side of dic
1564 is not defined between ic & dic */
1567 iCode *sic = dic->next;
1569 for (; sic != ic; sic = sic->next)
1570 if (IC_RESULT (sic) &&
1571 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1580 /*-----------------------------------------------------------------*/
1581 /* packRegsForSupport :- reduce some registers for support calls */
1582 /*-----------------------------------------------------------------*/
1584 packRegsForSupport (iCode * ic, eBBlock * ebp)
1589 /* for the left & right operand :- look to see if the
1590 left was assigned a true symbol in far space in that
1591 case replace them */
1593 if (IS_ITEMP (IC_LEFT (ic)) &&
1594 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1596 dic = findAssignToSym (IC_LEFT (ic), ic);
1601 /* found it we need to remove it from the
1603 for (sic = dic; sic != ic; sic = sic->next)
1604 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1606 OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1607 IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1608 remiCodeFromeBBlock (ebp, dic);
1609 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1610 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1614 /* do the same for the right operand */
1617 IS_ITEMP (IC_RIGHT (ic)) &&
1618 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1620 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1626 /* if this is a subtraction & the result
1627 is a true symbol in far space then don't pack */
1628 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1630 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1631 if (IN_FARSPACE (SPEC_OCLS (etype)))
1634 /* found it we need to remove it from the
1636 for (sic = dic; sic != ic; sic = sic->next)
1637 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1639 IC_RIGHT (ic)->operand.symOperand =
1640 IC_RIGHT (dic)->operand.symOperand;
1641 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1643 remiCodeFromeBBlock (ebp, dic);
1644 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1645 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1652 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1655 /*-----------------------------------------------------------------*/
1656 /* packRegsForOneuse : - will reduce some registers for single Use */
1657 /*-----------------------------------------------------------------*/
1659 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1664 /* if returning a literal then do nothing */
1668 if (ic->op != RETURN &&
1670 !POINTER_SET (ic) &&
1674 /* this routine will mark the a symbol as used in one
1675 instruction use only && if the defintion is local
1676 (ie. within the basic block) && has only one definition &&
1677 that definiion is either a return value from a
1678 function or does not contain any variables in
1680 uses = bitVectCopy (OP_USES (op));
1681 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
1682 if (!bitVectIsZero (uses)) /* has other uses */
1685 /* if it has only one defintion */
1686 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1687 return NULL; /* has more than one definition */
1689 /* get that definition */
1691 hTabItemWithKey (iCodehTab,
1692 bitVectFirstBit (OP_DEFS (op)))))
1695 /* if that only usage is a cast */
1696 if (dic->op == CAST) {
1697 /* to a bigger type */
1698 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
1699 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1700 /* than we can not, since we cannot predict the usage of b & acc */
1705 /* found the definition now check if it is local */
1706 if (dic->seq < ebp->fSeq ||
1707 dic->seq > ebp->lSeq)
1708 return NULL; /* non-local */
1710 /* now check if it is the return from
1712 if (dic->op == CALL || dic->op == PCALL)
1714 if (ic->op != SEND && ic->op != RETURN &&
1715 !POINTER_SET(ic) && !POINTER_GET(ic))
1717 OP_SYMBOL (op)->ruonly = 1;
1724 /* otherwise check that the definition does
1725 not contain any symbols in far space */
1726 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1727 isOperandInFarSpace (IC_RIGHT (dic)) ||
1728 IS_OP_RUONLY (IC_LEFT (ic)) ||
1729 IS_OP_RUONLY (IC_RIGHT (ic)))
1734 /* if pointer set then make sure the pointer
1736 if (POINTER_SET (dic) &&
1737 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1740 if (POINTER_GET (dic) &&
1741 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1746 /* also make sure the intervenening instructions
1747 don't have any thing in far space */
1748 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1751 /* if there is an intervening function call then no */
1752 if (dic->op == CALL || dic->op == PCALL)
1754 /* if pointer set then make sure the pointer
1756 if (POINTER_SET (dic) &&
1757 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1760 if (POINTER_GET (dic) &&
1761 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1764 /* if address of & the result is remat the okay */
1765 if (dic->op == ADDRESS_OF &&
1766 OP_SYMBOL (IC_RESULT (dic))->remat)
1769 /* if operand has size of three or more & this
1770 operation is a '*','/' or '%' then 'b' may
1772 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1773 getSize (operandType (op)) >= 3)
1776 /* if left or right or result is in far space */
1777 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1778 isOperandInFarSpace (IC_RIGHT (dic)) ||
1779 isOperandInFarSpace (IC_RESULT (dic)) ||
1780 IS_OP_RUONLY (IC_LEFT (dic)) ||
1781 IS_OP_RUONLY (IC_RIGHT (dic)) ||
1782 IS_OP_RUONLY (IC_RESULT (dic)))
1786 /* if left or right or result is on stack */
1787 if (isOperandOnStack(IC_LEFT(dic)) ||
1788 isOperandOnStack(IC_RIGHT(dic)) ||
1789 isOperandOnStack(IC_RESULT(dic))) {
1794 OP_SYMBOL (op)->ruonly = 1;
1799 /*-----------------------------------------------------------------*/
1800 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1801 /*-----------------------------------------------------------------*/
1803 isBitwiseOptimizable (iCode * ic)
1805 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1806 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1808 /* bitwise operations are considered optimizable
1809 under the following conditions (Jean-Louis VERN)
1821 if (IS_LITERAL(rtype) ||
1822 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1828 /*-----------------------------------------------------------------*/
1829 /* packForPush - hueristics to reduce iCode for pushing */
1830 /*-----------------------------------------------------------------*/
1832 packForPush (iCode * ic, eBBlock * ebp)
1837 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1840 /* must have only definition & one usage */
1841 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1842 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1845 /* find the definition */
1846 if (!(dic = hTabItemWithKey (iCodehTab,
1847 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1850 if (dic->op != '=' || POINTER_SET (dic))
1853 /* make sure the right side does not have any definitions
1855 dbv = OP_DEFS(IC_RIGHT(dic));
1856 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1857 if (bitVectBitValue(dbv,lic->key))
1860 /* make sure they have the same type */
1862 sym_link *itype=operandType(IC_LEFT(ic));
1863 sym_link *ditype=operandType(IC_RIGHT(dic));
1865 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1866 SPEC_LONG(itype)!=SPEC_LONG(ditype))
1869 /* extend the live range of replaced operand if needed */
1870 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1871 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1873 /* we now know that it has one & only one def & use
1874 and the that the definition is an assignment */
1875 IC_LEFT (ic) = IC_RIGHT (dic);
1877 remiCodeFromeBBlock (ebp, dic);
1878 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1879 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1882 /*-----------------------------------------------------------------*/
1883 /* packRegisters - does some transformations to reduce register */
1885 /*-----------------------------------------------------------------*/
1886 static void packRegisters (eBBlock * ebp) {
1890 return; // that's it for now
1894 for (ic = ebp->sch; ic; ic = ic->next) {
1896 change += packRegsForAssign (ic, ebp);
1903 for (ic = ebp->sch; ic; ic = ic->next)
1905 /* if this is an itemp & result of an address of a true sym
1906 then mark this as rematerialisable */
1907 if (ic->op == ADDRESS_OF &&
1908 IS_ITEMP (IC_RESULT (ic)) &&
1909 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1910 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1911 !OP_SYMBOL (IC_LEFT (ic))->onStack)
1914 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1915 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1916 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1920 /* if straight assignment then carry remat flag if
1921 this is the only definition */
1922 if (ic->op == '=' &&
1923 !POINTER_SET (ic) &&
1924 IS_SYMOP (IC_RIGHT (ic)) &&
1925 OP_SYMBOL (IC_RIGHT (ic))->remat &&
1926 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1927 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1930 OP_SYMBOL (IC_RESULT (ic))->remat =
1931 OP_SYMBOL (IC_RIGHT (ic))->remat;
1932 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1933 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1936 /* if cast to a generic pointer & the pointer being
1937 cast is remat, then we can remat this cast as well */
1938 if (ic->op == CAST &&
1939 IS_SYMOP(IC_RIGHT(ic)) &&
1940 OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1941 sym_link *to_type = operandType(IC_LEFT(ic));
1942 sym_link *from_type = operandType(IC_RIGHT(ic));
1943 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
1944 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1945 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1946 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1950 /* if this is a +/- operation with a rematerizable
1951 then mark this as rematerializable as well */
1952 if ((ic->op == '+' || ic->op == '-') &&
1953 (IS_SYMOP (IC_LEFT (ic)) &&
1954 IS_ITEMP (IC_RESULT (ic)) &&
1955 IS_OP_LITERAL (IC_RIGHT (ic))) &&
1956 OP_SYMBOL (IC_LEFT (ic))->remat &&
1957 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1958 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1960 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1961 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1962 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1965 /* mark the pointer usages */
1966 if (POINTER_SET (ic))
1967 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1969 if (POINTER_GET (ic))
1970 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1972 /* if the condition of an if instruction
1973 is defined in the previous instruction and
1974 this is the only usage then
1975 mark the itemp as a conditional */
1976 if ((IS_CONDITIONAL (ic) ||
1977 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
1978 ic->next && ic->next->op == IFX &&
1979 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1980 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1981 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
1983 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1987 /* reduce for support function calls */
1988 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1989 packRegsForSupport (ic, ebp);
1991 /* some cases the redundant moves can
1992 can be eliminated for return statements */
1993 if ((ic->op == RETURN || ic->op == SEND) &&
1994 !isOperandInFarSpace (IC_LEFT (ic)) &&
1995 options.model == MODEL_SMALL) {
1996 if (0 && options.stackAuto) {
1997 /* we should check here if acc will be clobbered for stack
1998 offset calculations */
2000 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2004 /* if pointer set & left has a size more than
2005 one and right is not in far space */
2006 if (POINTER_SET (ic) &&
2007 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2008 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2009 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2010 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2012 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2014 /* if pointer get */
2015 if (POINTER_GET (ic) &&
2016 !isOperandInFarSpace (IC_RESULT (ic)) &&
2017 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2018 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2019 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2021 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2024 /* if this is cast for intergral promotion then
2025 check if only use of the definition of the
2026 operand being casted/ if yes then replace
2027 the result of that arithmetic operation with
2028 this result and get rid of the cast */
2031 sym_link *fromType = operandType (IC_RIGHT (ic));
2032 sym_link *toType = operandType (IC_LEFT (ic));
2034 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2035 getSize (fromType) != getSize (toType) &&
2036 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2039 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2042 if (IS_ARITHMETIC_OP (dic))
2044 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2045 IC_RESULT (dic) = IC_RESULT (ic);
2046 remiCodeFromeBBlock (ebp, ic);
2047 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2048 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2049 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2053 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2059 /* if the type from and type to are the same
2060 then if this is the only use then packit */
2061 if (compareType (operandType (IC_RIGHT (ic)),
2062 operandType (IC_LEFT (ic))) == 1)
2064 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2067 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2068 IC_RESULT (dic) = IC_RESULT (ic);
2069 remiCodeFromeBBlock (ebp, ic);
2070 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2071 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2072 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2080 iTempNN := (some variable in farspace) V1
2085 if (ic->op == IPUSH)
2087 packForPush (ic, ebp);
2092 /*-----------------------------------------------------------------*/
2093 /* assignRegisters - assigns registers to each live range as need */
2094 /*-----------------------------------------------------------------*/
2096 xa51_assignRegisters (eBBlock ** ebbs, int count)
2101 setToNull ((void *) &_G.funcrUsed);
2102 setToNull ((void *) &_G.totRegAssigned);
2103 _G.stackExtend = _G.dataExtend = 0;
2105 /* change assignments this will remove some
2106 live ranges reducing some register pressure */
2107 for (i = 0; i < count; i++)
2108 packRegisters (ebbs[i]);
2110 if (options.dump_pack)
2111 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2113 /* first determine for each live range the number of
2114 registers & the type of registers required for each */
2117 /* and serially allocate registers */
2118 serialRegAssign (ebbs, count);
2122 /* if stack was extended then tell the user */
2125 /* werror(W_TOOMANY_SPILS,"stack", */
2126 /* _G.stackExtend,currFunc->name,""); */
2132 /* werror(W_TOOMANY_SPILS,"data space", */
2133 /* _G.dataExtend,currFunc->name,""); */
2137 /* after that create the register mask
2138 for each of the instruction */
2139 createRegMask (ebbs, count);
2141 /* redo that offsets for stacked automatic variables */
2142 redoStackOffsets ();
2144 if (options.dump_rassgn)
2146 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2147 dumpLiveRanges (DUMP_LRANGE, liveRanges);
2150 /* do the overlaysegment stuff SDCCmem.c */
2151 doOverlays (ebbs, count);
2153 /* now get back the chain */
2154 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2158 /* free up any _G.stackSpil locations allocated */
2159 applyToSet (_G.stackSpil, deallocStackSpil);
2161 setToNull ((void **) &_G.stackSpil);
2162 setToNull ((void **) &_G.spiltSet);
2163 /* mark all registers as free */