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 and the
1333 pointer we are getting is rematerializable and
1336 if (bitVectnBitsOn (sym->defs) == 1 &&
1337 (ic = hTabItemWithKey (iCodehTab,
1338 bitVectFirstBit (sym->defs))) &&
1341 !IS_BITVAR (sym->etype))
1345 /* if remat in data space */
1346 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1347 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1348 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1350 /* create a psuedo symbol & force a spil */
1351 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1352 psym->type = sym->type;
1353 psym->etype = sym->etype;
1354 strcpy (psym->rname, psym->name);
1356 sym->usl.spillLoc = psym;
1357 #if 0 // an alternative fix for bug #480076
1358 /* now this is a useless assignment to itself */
1359 remiCodeFromeBBlock (ebbs, ic);
1361 /* now this really is an assignment to itself, make it so;
1362 it will be optimized out later */
1364 IC_RIGHT(ic)=IC_RESULT(ic);
1370 /* if in data space or idata space then try to
1371 allocate pointer register */
1375 /* if not then we require registers */
1377 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1378 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1379 getSize (sym->type));
1382 int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1383 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1384 getSize (sym->type));
1388 case 2: // word or pointer
1391 case 3: // generic pointer
1394 case 4: // dword or float
1398 fprintf (stderr, "regTypeNum: unknown size\n");
1406 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1407 printTypeChain (sym->type, stderr);
1408 fprintf (stderr, "\n");
1412 /* determine the type of register required */
1413 if (IS_PTR (sym->type))
1414 sym->regType = REG_PTR;
1416 sym->regType = REG_GPR;
1420 /* for the first run we don't provide */
1421 /* registers for true symbols we will */
1422 /* see how things go */
1428 /*-----------------------------------------------------------------*/
1429 /* deallocStackSpil - this will set the stack pointer back */
1430 /*-----------------------------------------------------------------*/
1432 DEFSETFUNC (deallocStackSpil)
1440 /*-----------------------------------------------------------------*/
1441 /* packRegsForAssign - register reduction for assignment */
1442 /*-----------------------------------------------------------------*/
1444 packRegsForAssign (iCode * ic, eBBlock * ebp)
1448 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1449 OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1453 /* find the definition of iTempNN scanning backwards */
1454 for (dic = ic->prev; dic; dic = dic->prev) {
1456 /* if there is a function call then don't pack it */
1457 if ((dic->op == CALL || dic->op == PCALL)) {
1465 if (IS_SYMOP (IC_RESULT (dic)) &&
1466 IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1473 return 0; /* did not find */
1475 /* found the definition */
1476 /* replace the result with the result of */
1477 /* this assignment and remove this assignment */
1478 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1479 IC_RESULT (dic) = IC_RESULT (ic);
1481 if (IS_ITEMP (IC_RESULT (dic)) &&
1482 OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1484 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1486 /* delete from liverange table also
1487 delete from all the points inbetween and the new
1489 for (sic = dic; sic != ic; sic = sic->next)
1491 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1492 if (IS_ITEMP (IC_RESULT (dic)))
1493 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1496 remiCodeFromeBBlock (ebp, ic);
1497 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1498 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1499 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1504 /*-----------------------------------------------------------------*/
1505 /* findAssignToSym : scanning backwards looks for first assig found */
1506 /*-----------------------------------------------------------------*/
1508 findAssignToSym (operand * op, iCode * ic)
1512 for (dic = ic->prev; dic; dic = dic->prev)
1515 /* if definition by assignment */
1516 if (dic->op == '=' &&
1517 !POINTER_SET (dic) &&
1518 IC_RESULT (dic)->key == op->key
1519 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1523 /* we are interested only if defined in far space */
1524 /* or in stack space in case of + & - */
1526 /* if assigned to a non-symbol then return
1528 if (!IS_SYMOP (IC_RIGHT (dic)))
1531 /* if the symbol is in far space then
1533 if (isOperandInFarSpace (IC_RIGHT (dic)))
1536 /* for + & - operations make sure that
1537 if it is on the stack it is the same
1538 as one of the three operands */
1539 if ((ic->op == '+' || ic->op == '-') &&
1540 OP_SYMBOL (IC_RIGHT (dic))->onStack)
1543 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1544 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1545 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1553 /* if we find an usage then we cannot delete it */
1554 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1557 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1560 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1564 /* now make sure that the right side of dic
1565 is not defined between ic & dic */
1568 iCode *sic = dic->next;
1570 for (; sic != ic; sic = sic->next)
1571 if (IC_RESULT (sic) &&
1572 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1581 /*-----------------------------------------------------------------*/
1582 /* packRegsForSupport :- reduce some registers for support calls */
1583 /*-----------------------------------------------------------------*/
1585 packRegsForSupport (iCode * ic, eBBlock * ebp)
1590 /* for the left & right operand :- look to see if the
1591 left was assigned a true symbol in far space in that
1592 case replace them */
1594 if (IS_ITEMP (IC_LEFT (ic)) &&
1595 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1597 dic = findAssignToSym (IC_LEFT (ic), ic);
1602 /* found it we need to remove it from the
1604 for (sic = dic; sic != ic; sic = sic->next)
1605 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1607 OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1608 IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1609 remiCodeFromeBBlock (ebp, dic);
1610 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1611 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1615 /* do the same for the right operand */
1618 IS_ITEMP (IC_RIGHT (ic)) &&
1619 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1621 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1627 /* if this is a subtraction & the result
1628 is a true symbol in far space then don't pack */
1629 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1631 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1632 if (IN_FARSPACE (SPEC_OCLS (etype)))
1635 /* found it we need to remove it from the
1637 for (sic = dic; sic != ic; sic = sic->next)
1638 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1640 IC_RIGHT (ic)->operand.symOperand =
1641 IC_RIGHT (dic)->operand.symOperand;
1642 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1644 remiCodeFromeBBlock (ebp, dic);
1645 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1646 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1653 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1656 /*-----------------------------------------------------------------*/
1657 /* packRegsForOneuse : - will reduce some registers for single Use */
1658 /*-----------------------------------------------------------------*/
1660 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1665 /* if returning a literal then do nothing */
1669 if (ic->op != RETURN &&
1671 !POINTER_SET (ic) &&
1675 /* this routine will mark the a symbol as used in one
1676 instruction use only && if the defintion is local
1677 (ie. within the basic block) && has only one definition &&
1678 that definiion is either a return value from a
1679 function or does not contain any variables in
1681 uses = bitVectCopy (OP_USES (op));
1682 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
1683 if (!bitVectIsZero (uses)) /* has other uses */
1686 /* if it has only one defintion */
1687 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1688 return NULL; /* has more than one definition */
1690 /* get that definition */
1692 hTabItemWithKey (iCodehTab,
1693 bitVectFirstBit (OP_DEFS (op)))))
1696 /* if that only usage is a cast */
1697 if (dic->op == CAST) {
1698 /* to a bigger type */
1699 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
1700 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1701 /* than we can not, since we cannot predict the usage of b & acc */
1706 /* found the definition now check if it is local */
1707 if (dic->seq < ebp->fSeq ||
1708 dic->seq > ebp->lSeq)
1709 return NULL; /* non-local */
1711 /* now check if it is the return from
1713 if (dic->op == CALL || dic->op == PCALL)
1715 if (ic->op != SEND && ic->op != RETURN &&
1716 !POINTER_SET(ic) && !POINTER_GET(ic))
1718 OP_SYMBOL (op)->ruonly = 1;
1725 /* otherwise check that the definition does
1726 not contain any symbols in far space */
1727 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1728 isOperandInFarSpace (IC_RIGHT (dic)) ||
1729 IS_OP_RUONLY (IC_LEFT (ic)) ||
1730 IS_OP_RUONLY (IC_RIGHT (ic)))
1735 /* if pointer set then make sure the pointer
1737 if (POINTER_SET (dic) &&
1738 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1741 if (POINTER_GET (dic) &&
1742 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1747 /* also make sure the intervenening instructions
1748 don't have any thing in far space */
1749 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1752 /* if there is an intervening function call then no */
1753 if (dic->op == CALL || dic->op == PCALL)
1755 /* if pointer set then make sure the pointer
1757 if (POINTER_SET (dic) &&
1758 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1761 if (POINTER_GET (dic) &&
1762 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1765 /* if address of & the result is remat the okay */
1766 if (dic->op == ADDRESS_OF &&
1767 OP_SYMBOL (IC_RESULT (dic))->remat)
1770 /* if operand has size of three or more & this
1771 operation is a '*','/' or '%' then 'b' may
1773 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1774 getSize (operandType (op)) >= 3)
1777 /* if left or right or result is in far space */
1778 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1779 isOperandInFarSpace (IC_RIGHT (dic)) ||
1780 isOperandInFarSpace (IC_RESULT (dic)) ||
1781 IS_OP_RUONLY (IC_LEFT (dic)) ||
1782 IS_OP_RUONLY (IC_RIGHT (dic)) ||
1783 IS_OP_RUONLY (IC_RESULT (dic)))
1787 /* if left or right or result is on stack */
1788 if (isOperandOnStack(IC_LEFT(dic)) ||
1789 isOperandOnStack(IC_RIGHT(dic)) ||
1790 isOperandOnStack(IC_RESULT(dic))) {
1795 OP_SYMBOL (op)->ruonly = 1;
1800 /*-----------------------------------------------------------------*/
1801 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1802 /*-----------------------------------------------------------------*/
1804 isBitwiseOptimizable (iCode * ic)
1806 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1807 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1809 /* bitwise operations are considered optimizable
1810 under the following conditions (Jean-Louis VERN)
1822 if (IS_LITERAL(rtype) ||
1823 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1829 /*-----------------------------------------------------------------*/
1830 /* packForPush - hueristics to reduce iCode for pushing */
1831 /*-----------------------------------------------------------------*/
1833 packForPush (iCode * ic, eBBlock * ebp)
1838 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1841 /* must have only definition & one usage */
1842 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1843 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1846 /* find the definition */
1847 if (!(dic = hTabItemWithKey (iCodehTab,
1848 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1851 if (dic->op != '=' || POINTER_SET (dic))
1854 /* make sure the right side does not have any definitions
1856 dbv = OP_DEFS(IC_RIGHT(dic));
1857 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1858 if (bitVectBitValue(dbv,lic->key))
1861 /* make sure they have the same type */
1863 sym_link *itype=operandType(IC_LEFT(ic));
1864 sym_link *ditype=operandType(IC_RIGHT(dic));
1866 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1867 SPEC_LONG(itype)!=SPEC_LONG(ditype))
1870 /* extend the live range of replaced operand if needed */
1871 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1872 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1874 /* we now know that it has one & only one def & use
1875 and the that the definition is an assignment */
1876 IC_LEFT (ic) = IC_RIGHT (dic);
1878 remiCodeFromeBBlock (ebp, dic);
1879 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1880 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1883 /*-----------------------------------------------------------------*/
1884 /* packRegisters - does some transformations to reduce register */
1886 /*-----------------------------------------------------------------*/
1887 static void packRegisters (eBBlock * ebp) {
1891 return; // that's it for now
1896 for (ic = ebp->sch; ic; ic = ic->next) {
1898 change += packRegsForAssign (ic, ebp);
1905 for (ic = ebp->sch; ic; ic = ic->next)
1907 /* if this is an itemp & result of an address of a true sym
1908 then mark this as rematerialisable */
1909 if (ic->op == ADDRESS_OF &&
1910 IS_ITEMP (IC_RESULT (ic)) &&
1911 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1912 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1913 !OP_SYMBOL (IC_LEFT (ic))->onStack)
1916 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1917 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1918 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1922 /* if straight assignment then carry remat flag if
1923 this is the only definition */
1924 if (ic->op == '=' &&
1925 !POINTER_SET (ic) &&
1926 IS_SYMOP (IC_RIGHT (ic)) &&
1927 OP_SYMBOL (IC_RIGHT (ic))->remat &&
1928 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1929 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1932 OP_SYMBOL (IC_RESULT (ic))->remat =
1933 OP_SYMBOL (IC_RIGHT (ic))->remat;
1934 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1935 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1938 /* if cast to a generic pointer & the pointer being
1939 cast is remat, then we can remat this cast as well */
1940 if (ic->op == CAST &&
1941 IS_SYMOP(IC_RIGHT(ic)) &&
1942 OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1943 sym_link *to_type = operandType(IC_LEFT(ic));
1944 sym_link *from_type = operandType(IC_RIGHT(ic));
1945 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
1946 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1947 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1948 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1952 /* if this is a +/- operation with a rematerizable
1953 then mark this as rematerializable as well */
1954 if ((ic->op == '+' || ic->op == '-') &&
1955 (IS_SYMOP (IC_LEFT (ic)) &&
1956 IS_ITEMP (IC_RESULT (ic)) &&
1957 IS_OP_LITERAL (IC_RIGHT (ic))) &&
1958 OP_SYMBOL (IC_LEFT (ic))->remat &&
1959 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1960 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1962 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1963 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1964 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1967 /* mark the pointer usages */
1968 if (POINTER_SET (ic))
1969 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1971 if (POINTER_GET (ic))
1972 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1974 /* if the condition of an if instruction
1975 is defined in the previous instruction and
1976 this is the only usage then
1977 mark the itemp as a conditional */
1978 if ((IS_CONDITIONAL (ic) ||
1979 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
1980 ic->next && ic->next->op == IFX &&
1981 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1982 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1983 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
1985 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1989 /* reduce for support function calls */
1990 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1991 packRegsForSupport (ic, ebp);
1993 /* some cases the redundant moves can
1994 can be eliminated for return statements */
1995 if ((ic->op == RETURN || ic->op == SEND) &&
1996 !isOperandInFarSpace (IC_LEFT (ic)) &&
1997 options.model == MODEL_SMALL) {
1998 if (0 && options.stackAuto) {
1999 /* we should check here if acc will be clobbered for stack
2000 offset calculations */
2002 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2006 /* if pointer set & left has a size more than
2007 one and right is not in far space */
2008 if (POINTER_SET (ic) &&
2009 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2010 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2011 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2012 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2014 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2016 /* if pointer get */
2017 if (POINTER_GET (ic) &&
2018 !isOperandInFarSpace (IC_RESULT (ic)) &&
2019 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2020 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2021 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2023 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2026 /* if this is cast for intergral promotion then
2027 check if only use of the definition of the
2028 operand being casted/ if yes then replace
2029 the result of that arithmetic operation with
2030 this result and get rid of the cast */
2033 sym_link *fromType = operandType (IC_RIGHT (ic));
2034 sym_link *toType = operandType (IC_LEFT (ic));
2036 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2037 getSize (fromType) != getSize (toType) &&
2038 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2041 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2044 if (IS_ARITHMETIC_OP (dic))
2046 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2047 IC_RESULT (dic) = IC_RESULT (ic);
2048 remiCodeFromeBBlock (ebp, ic);
2049 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2050 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2051 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2055 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2061 /* if the type from and type to are the same
2062 then if this is the only use then packit */
2063 if (compareType (operandType (IC_RIGHT (ic)),
2064 operandType (IC_LEFT (ic))) == 1)
2066 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2069 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2070 IC_RESULT (dic) = IC_RESULT (ic);
2071 remiCodeFromeBBlock (ebp, ic);
2072 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2073 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2074 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2082 iTempNN := (some variable in farspace) V1
2087 if (ic->op == IPUSH)
2089 packForPush (ic, ebp);
2094 /*-----------------------------------------------------------------*/
2095 /* assignRegisters - assigns registers to each live range as need */
2096 /*-----------------------------------------------------------------*/
2098 xa51_assignRegisters (eBBlock ** ebbs, int count)
2103 setToNull ((void *) &_G.funcrUsed);
2104 setToNull ((void *) &_G.totRegAssigned);
2105 _G.stackExtend = _G.dataExtend = 0;
2107 /* change assignments this will remove some
2108 live ranges reducing some register pressure */
2109 for (i = 0; i < count; i++)
2110 packRegisters (ebbs[i]);
2112 if (options.dump_pack)
2113 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2115 /* first determine for each live range the number of
2116 registers & the type of registers required for each */
2119 /* and serially allocate registers */
2120 serialRegAssign (ebbs, count);
2124 /* if stack was extended then tell the user */
2127 /* werror(W_TOOMANY_SPILS,"stack", */
2128 /* _G.stackExtend,currFunc->name,""); */
2134 /* werror(W_TOOMANY_SPILS,"data space", */
2135 /* _G.dataExtend,currFunc->name,""); */
2139 /* after that create the register mask
2140 for each of the instruction */
2141 createRegMask (ebbs, count);
2143 /* redo that offsets for stacked automatic variables */
2144 redoStackOffsets ();
2146 if (options.dump_rassgn)
2148 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2149 dumpLiveRanges (DUMP_LRANGE, liveRanges);
2152 /* do the overlaysegment stuff SDCCmem.c */
2153 doOverlays (ebbs, count);
2155 /* now get back the chain */
2156 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2160 /* free up any _G.stackSpil locations allocated */
2161 applyToSet (_G.stackSpil, deallocStackSpil);
2163 setToNull ((void **) &_G.stackSpil);
2164 setToNull ((void **) &_G.spiltSet);
2165 /* mark all registers as free */