1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (8051) specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
32 #if defined(__BORLANDC__) || defined(_MSC_VER)
33 #define STRCASECMP stricmp
35 #define STRCASECMP strcasecmp
38 /*-----------------------------------------------------------------*/
39 /* At this point we start getting processor specific although */
40 /* some routines are non-processor specific & can be reused when */
41 /* targetting other processors. The decision for this will have */
42 /* to be made on a routine by routine basis */
43 /* routines used to pack registers are most definitely not reusable */
44 /* since the pack the registers depending strictly on the MCU */
45 /*-----------------------------------------------------------------*/
47 extern void genpic14Code (iCode *);
57 bitVect *funcrUsed; /* registers used in a function */
63 /* Shared with gen.c */
64 int pic14_ptrRegReq; /* one byte pointer register required */
67 static set *dynAllocRegs=NULL;
68 static set *dynStackRegs=NULL;
69 static set *dynProcessorRegs=NULL;
70 static set *dynDirectRegs=NULL;
71 static set *dynDirectBitRegs=NULL;
72 static set *dynInternalRegs=NULL;
74 static hTab *dynDirectRegNames= NULL;
76 static int dynrIdx=0x20;
77 static int rDirectIdx=0;
79 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
81 int Gstack_base_addr=0; /* The starting address of registers that
82 * are used to pass and return parameters */
87 static void spillThis (symbol *);
89 static FILE *debugF = NULL;
90 /*-----------------------------------------------------------------*/
91 /* debugLog - open a file for debugging information */
92 /*-----------------------------------------------------------------*/
93 //static void debugLog(char *inst,char *fmt, ...)
95 debugLog (char *fmt,...)
97 static int append = 0; // First time through, open the file without append.
100 //char *bufferP=buffer;
103 if (!debug || !srcFileName)
109 /* create the file name */
110 strcpy (buffer, srcFileName);
111 strcat (buffer, ".d");
113 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
115 werror (E_FILE_OPEN_ERR, buffer);
118 append = 1; // Next time debubLog is called, we'll append the debug info
124 vsprintf (buffer, fmt, ap);
126 fprintf (debugF, "%s", buffer);
128 while (isspace(*bufferP)) bufferP++;
130 if (bufferP && *bufferP)
131 lineCurr = (lineCurr ?
132 connectLine(lineCurr,newLineNode(lb)) :
133 (lineHead = newLineNode(lb)));
134 lineCurr->isInline = _G.inLine;
135 lineCurr->isDebug = _G.debugLine;
145 fputc ('\n', debugF);
147 /*-----------------------------------------------------------------*/
148 /* debugLogClose - closes the debug log file (if opened) */
149 /*-----------------------------------------------------------------*/
159 #define AOP(op) op->aop
162 debugAopGet (char *str, operand * op)
167 printOperand (op, debugF);
175 decodeOp (unsigned int op)
178 if (op < 128 && op > ' ')
180 buffer[0] = (op & 0xff);
194 return "STRING_LITERAL";
230 return "LEFT_ASSIGN";
232 return "RIGHT_ASSIGN";
347 case GET_VALUE_AT_ADDRESS:
348 return "GET_VALUE_AT_ADDRESS";
366 return "ENDFUNCTION";
390 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
393 /*-----------------------------------------------------------------*/
394 /*-----------------------------------------------------------------*/
396 debugLogRegType (short type)
409 sprintf (buffer, "unkown reg type %d", type);
413 /*-----------------------------------------------------------------*/
414 /* newReg - allocate and init memory for a new register */
415 /*-----------------------------------------------------------------*/
416 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
421 dReg = Safe_calloc(1,sizeof(regs));
423 dReg->pc_type = pc_type;
426 dReg->name = Safe_strdup(name);
428 sprintf(buffer,"r0x%02X", dReg->rIdx);
431 dReg->name = Safe_strdup(buffer);
433 //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
442 dReg->reg_alias = NULL;
447 /*-----------------------------------------------------------------*/
448 /* regWithIdx - Search through a set of registers that matches idx */
449 /*-----------------------------------------------------------------*/
451 regWithIdx (set *dRegs, int idx, int fixed)
455 for (dReg = setFirstItem(dRegs) ; dReg ;
456 dReg = setNextItem(dRegs)) {
458 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
466 /*-----------------------------------------------------------------*/
467 /* regFindFree - Search for a free register in a set of registers */
468 /*-----------------------------------------------------------------*/
470 regFindFree (set *dRegs)
474 for (dReg = setFirstItem(dRegs) ; dReg ;
475 dReg = setNextItem(dRegs)) {
483 /*-----------------------------------------------------------------*/
484 /* initStack - allocate registers for a psuedo stack */
485 /*-----------------------------------------------------------------*/
486 void initStack(int base_address, int size)
491 Gstack_base_addr = base_address;
492 for(i = 0; i<size; i++)
493 addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
497 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
499 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
503 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
505 regs * reg = newReg(REG_SFR, po_type, rIdx, name,1,alias);
509 return addSet(&dynInternalRegs,reg);
514 /*-----------------------------------------------------------------*/
515 /* allocReg - allocates register of given type */
516 /*-----------------------------------------------------------------*/
518 allocReg (short type)
521 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
524 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
528 /*-----------------------------------------------------------------*/
529 /*-----------------------------------------------------------------*/
530 static int regname2key(char const *name)
539 key += (*name++) + 1;
543 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
547 /*-----------------------------------------------------------------*/
548 /* dirregWithName - search for register by name */
549 /*-----------------------------------------------------------------*/
551 dirregWithName (char *name)
559 /* hash the name to get a key */
561 hkey = regname2key(name);
563 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
567 if(STRCASECMP(reg->name, name) == 0) {
571 reg = hTabNextItemWK (dynDirectRegNames);
575 return NULL; // name wasn't found in the hash table
578 int IS_CONFIG_ADDRESS(int address)
581 return address == 0x2007;
584 /*-----------------------------------------------------------------*/
585 /* allocDirReg - allocates register of given type */
586 /*-----------------------------------------------------------------*/
588 allocDirReg (operand *op )
595 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
599 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
601 /* If the symbol is at a fixed address, then remove the leading underscore
602 * from the name. This is hack to allow the .asm include file named registers
603 * to match the .c declared register names */
605 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
608 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
610 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
611 debugLog(" %d const char\n",__LINE__);
612 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
615 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
616 if (IS_CODE ( OP_SYM_ETYPE(op)) )
617 debugLog(" %d code space\n",__LINE__);
619 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
620 debugLog(" %d integral\n",__LINE__);
621 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
622 debugLog(" %d literal\n",__LINE__);
623 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
624 debugLog(" %d specifier\n",__LINE__);
625 debugAopGet(NULL, op);
628 if (IS_CODE ( OP_SYM_ETYPE(op)) )
631 /* First, search the hash table to see if there is a register with this name */
632 reg = dirregWithName(name);
637 /* if this is at an absolute address, then get the address. */
638 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
639 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
642 /* Register wasn't found in hash, so let's create
643 * a new one and put it in the hash table AND in the
644 * dynDirectRegNames set */
645 if(!IS_CONFIG_ADDRESS(address)) {
646 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
647 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
649 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
651 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
652 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
655 hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
656 if (IS_BITVAR (OP_SYM_ETYPE(op)))
657 addSet(&dynDirectBitRegs, reg);
659 addSet(&dynDirectRegs, reg);
661 debugLog (" -- %s is declared at address 0x2007\n",name);
669 /*-----------------------------------------------------------------*/
670 /* allocDirReg - allocates register of given type */
671 /*-----------------------------------------------------------------*/
673 allocRegByName (char *name, int size)
679 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
683 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
685 /* First, search the hash table to see if there is a register with this name */
686 reg = dirregWithName(name);
690 /* Register wasn't found in hash, so let's create
691 * a new one and put it in the hash table AND in the
692 * dynDirectRegNames set */
694 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
696 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
698 hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
699 addSet(&dynDirectRegs, reg);
705 /*-----------------------------------------------------------------*/
706 /* RegWithIdx - returns pointer to register with index number */
707 /*-----------------------------------------------------------------*/
709 typeRegWithIdx (int idx, int type, int fixed)
714 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
716 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
718 debugLog ("Found a Dynamic Register!\n");
722 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
723 debugLog ("Found a Stack Register!\n");
727 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
728 debugLog ("Found a Direct Register!\n");
732 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
733 debugLog ("Found a Processor Register!\n");
737 if( (dReg = regWithIdx ( dynDirectBitRegs, idx, fixed)) != NULL ) {
738 debugLog ("Found a bit Register!\n");
743 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
744 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
745 "regWithIdx not found");
751 /*-----------------------------------------------------------------*/
752 /* pic14_regWithIdx - returns pointer to register with index number*/
753 /*-----------------------------------------------------------------*/
755 pic14_regWithIdx (int idx)
758 return typeRegWithIdx(idx,-1,0);
761 /*-----------------------------------------------------------------*/
762 /* pic14_regWithIdx - returns pointer to register with index number */
763 /*-----------------------------------------------------------------*/
765 pic14_allocWithIdx (int idx)
770 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
772 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
774 debugLog ("Found a Dynamic Register!\n");
775 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
776 debugLog ("Found a Stack Register!\n");
777 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
778 debugLog ("Found a Processor Register!\n");
779 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
780 debugLog ("Found an Internal Register!\n");
783 debugLog ("Dynamic Register not found\n");
786 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
787 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
788 "regWithIdx not found");
798 /*-----------------------------------------------------------------*/
799 /*-----------------------------------------------------------------*/
801 pic14_findFreeReg(short type)
808 if((dReg = regFindFree(dynAllocRegs)) != NULL)
811 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
815 if((dReg = regFindFree(dynStackRegs)) != NULL)
827 /*-----------------------------------------------------------------*/
828 /* freeReg - frees a register */
829 /*-----------------------------------------------------------------*/
833 debugLog ("%s\n", __FUNCTION__);
838 /*-----------------------------------------------------------------*/
839 /* nFreeRegs - returns number of free registers */
840 /*-----------------------------------------------------------------*/
844 /* dynamically allocate as many as we need and worry about
845 * fitting them into a PIC later */
852 debugLog ("%s\n", __FUNCTION__);
853 for (i = 0; i < pic14_nRegs; i++)
854 if (regspic14[i].isFree && regspic14[i].type == type)
860 /*-----------------------------------------------------------------*/
861 /* nfreeRegsType - free registers with type */
862 /*-----------------------------------------------------------------*/
864 nfreeRegsType (int type)
867 debugLog ("%s\n", __FUNCTION__);
870 if ((nfr = nFreeRegs (type)) == 0)
871 return nFreeRegs (REG_GPR);
874 return nFreeRegs (type);
878 void writeSetUsedRegs(FILE *of, set *dRegs)
883 for (dReg = setFirstItem(dRegs) ; dReg ;
884 dReg = setNextItem(dRegs)) {
887 fprintf (of, "\t%s\n",dReg->name);
891 extern void assignFixedRegisters(set *regset);
892 extern void assignRelocatableRegisters(set *regset,int used);
893 extern void dump_map(void);
894 extern void dump_cblock(FILE *of);
897 void packBits(set *bregs)
902 regs *relocbitfield=NULL;
907 for (regset = bregs ; regset ;
908 regset = regset->next) {
911 breg->isBitField = 1;
912 //fprintf(stderr,"bit reg: %s\n",breg->name);
915 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
917 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
918 breg->rIdx = breg->address & 7;
922 sprintf (buffer, "fbitfield%02x", breg->address);
923 //fprintf(stderr,"new bit field\n");
924 bitfield = newReg(REG_GPR, PO_GPR_BIT,breg->address,buffer,1,0);
925 bitfield->isBitField = 1;
926 bitfield->isFixed = 1;
927 bitfield->address = breg->address;
928 addSet(&dynDirectRegs,bitfield);
929 hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
931 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
934 breg->reg_alias = bitfield;
938 if(!relocbitfield || bit_no >7) {
941 sprintf (buffer, "bitfield%d", byte_no);
942 //fprintf(stderr,"new relocatable bit field\n");
943 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
944 relocbitfield->isBitField = 1;
945 addSet(&dynDirectRegs,relocbitfield);
946 hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
950 breg->reg_alias = relocbitfield;
951 breg->address = rDirectIdx; /* byte_no; */
952 breg->rIdx = bit_no++;
960 void bitEQUs(FILE *of, set *bregs)
965 //fprintf(stderr," %s\n",__FUNCTION__);
966 for (breg = setFirstItem(bregs) ; breg ;
967 breg = setNextItem(bregs)) {
969 //fprintf(stderr,"bit reg: %s\n",breg->name);
971 bytereg = breg->reg_alias;
973 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
976 breg->rIdx & 0x0007);
979 fprintf(stderr, "bit field is not assigned to a register\n");
980 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
990 void aliasEQUs(FILE *of, set *fregs)
995 for (reg = setFirstItem(fregs) ; reg ;
996 reg = setNextItem(fregs)) {
999 fprintf (of, "%s\tEQU\t0x%03x\n",
1006 void writeUsedRegs(FILE *of)
1008 packBits(dynDirectBitRegs);
1010 assignFixedRegisters(dynAllocRegs);
1011 assignFixedRegisters(dynStackRegs);
1012 assignFixedRegisters(dynDirectRegs);
1014 assignRelocatableRegisters(dynInternalRegs,1);
1015 assignRelocatableRegisters(dynAllocRegs,0);
1016 assignRelocatableRegisters(dynStackRegs,0);
1017 assignRelocatableRegisters(dynDirectRegs,0);
1022 bitEQUs(of,dynDirectBitRegs);
1023 aliasEQUs(of,dynAllocRegs);
1024 aliasEQUs(of,dynDirectRegs);
1025 aliasEQUs(of,dynStackRegs);
1029 /*-----------------------------------------------------------------*/
1030 /* allDefsOutOfRange - all definitions are out of a range */
1031 /*-----------------------------------------------------------------*/
1033 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1037 debugLog ("%s\n", __FUNCTION__);
1041 for (i = 0; i < defs->size; i++)
1045 if (bitVectBitValue (defs, i) &&
1046 (ic = hTabItemWithKey (iCodehTab, i)) &&
1047 (ic->seq >= fseq && ic->seq <= toseq))
1058 /*-----------------------------------------------------------------*/
1059 /* computeSpillable - given a point find the spillable live ranges */
1060 /*-----------------------------------------------------------------*/
1062 computeSpillable (iCode * ic)
1066 debugLog ("%s\n", __FUNCTION__);
1067 /* spillable live ranges are those that are live at this
1068 point . the following categories need to be subtracted
1070 a) - those that are already spilt
1071 b) - if being used by this one
1072 c) - defined by this one */
1074 spillable = bitVectCopy (ic->rlive);
1076 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1078 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1079 bitVectUnSetBit (spillable, ic->defKey);
1080 spillable = bitVectIntersect (spillable, _G.regAssigned);
1085 /*-----------------------------------------------------------------*/
1086 /* noSpilLoc - return true if a variable has no spil location */
1087 /*-----------------------------------------------------------------*/
1089 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1091 debugLog ("%s\n", __FUNCTION__);
1092 return (sym->usl.spillLoc ? 0 : 1);
1095 /*-----------------------------------------------------------------*/
1096 /* hasSpilLoc - will return 1 if the symbol has spil location */
1097 /*-----------------------------------------------------------------*/
1099 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1101 debugLog ("%s\n", __FUNCTION__);
1102 return (sym->usl.spillLoc ? 1 : 0);
1105 /*-----------------------------------------------------------------*/
1106 /* directSpilLoc - will return 1 if the splilocation is in direct */
1107 /*-----------------------------------------------------------------*/
1109 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1111 debugLog ("%s\n", __FUNCTION__);
1112 if (sym->usl.spillLoc &&
1113 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1119 /*-----------------------------------------------------------------*/
1120 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1121 /* but is not used as a pointer */
1122 /*-----------------------------------------------------------------*/
1124 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1126 debugLog ("%s\n", __FUNCTION__);
1127 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1130 /*-----------------------------------------------------------------*/
1131 /* rematable - will return 1 if the remat flag is set */
1132 /*-----------------------------------------------------------------*/
1134 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1136 debugLog ("%s\n", __FUNCTION__);
1140 /*-----------------------------------------------------------------*/
1141 /* notUsedInRemaining - not used or defined in remain of the block */
1142 /*-----------------------------------------------------------------*/
1144 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1146 debugLog ("%s\n", __FUNCTION__);
1147 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1148 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1151 /*-----------------------------------------------------------------*/
1152 /* allLRs - return true for all */
1153 /*-----------------------------------------------------------------*/
1155 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1157 debugLog ("%s\n", __FUNCTION__);
1161 /*-----------------------------------------------------------------*/
1162 /* liveRangesWith - applies function to a given set of live range */
1163 /*-----------------------------------------------------------------*/
1165 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1166 eBBlock * ebp, iCode * ic)
1171 debugLog ("%s\n", __FUNCTION__);
1172 if (!lrs || !lrs->size)
1175 for (i = 1; i < lrs->size; i++)
1178 if (!bitVectBitValue (lrs, i))
1181 /* if we don't find it in the live range
1182 hash table we are in serious trouble */
1183 if (!(sym = hTabItemWithKey (liveRanges, i)))
1185 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1186 "liveRangesWith could not find liveRange");
1190 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1191 addSetHead (&rset, sym);
1198 /*-----------------------------------------------------------------*/
1199 /* leastUsedLR - given a set determines which is the least used */
1200 /*-----------------------------------------------------------------*/
1202 leastUsedLR (set * sset)
1204 symbol *sym = NULL, *lsym = NULL;
1206 debugLog ("%s\n", __FUNCTION__);
1207 sym = lsym = setFirstItem (sset);
1212 for (; lsym; lsym = setNextItem (sset))
1215 /* if usage is the same then prefer
1216 the spill the smaller of the two */
1217 if (lsym->used == sym->used)
1218 if (getSize (lsym->type) < getSize (sym->type))
1222 if (lsym->used < sym->used)
1227 setToNull ((void **) &sset);
1232 /*-----------------------------------------------------------------*/
1233 /* noOverLap - will iterate through the list looking for over lap */
1234 /*-----------------------------------------------------------------*/
1236 noOverLap (set * itmpStack, symbol * fsym)
1239 debugLog ("%s\n", __FUNCTION__);
1242 for (sym = setFirstItem (itmpStack); sym;
1243 sym = setNextItem (itmpStack))
1245 if (sym->liveTo > fsym->liveFrom)
1253 /*-----------------------------------------------------------------*/
1254 /* isFree - will return 1 if the a free spil location is found */
1255 /*-----------------------------------------------------------------*/
1260 V_ARG (symbol **, sloc);
1261 V_ARG (symbol *, fsym);
1263 debugLog ("%s\n", __FUNCTION__);
1264 /* if already found */
1268 /* if it is free && and the itmp assigned to
1269 this does not have any overlapping live ranges
1270 with the one currently being assigned and
1271 the size can be accomodated */
1273 noOverLap (sym->usl.itmpStack, fsym) &&
1274 getSize (sym->type) >= getSize (fsym->type))
1283 /*-----------------------------------------------------------------*/
1284 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1285 /*-----------------------------------------------------------------*/
1287 spillLRWithPtrReg (symbol * forSym)
1293 debugLog ("%s\n", __FUNCTION__);
1294 if (!_G.regAssigned ||
1295 bitVectIsZero (_G.regAssigned))
1298 r0 = pic14_regWithIdx (R0_IDX);
1299 r1 = pic14_regWithIdx (R1_IDX);
1301 /* for all live ranges */
1302 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1303 lrsym = hTabNextItem (liveRanges, &k))
1307 /* if no registers assigned to it or
1309 /* if it does not overlap with this then
1310 not need to spill it */
1312 if (lrsym->isspilt || !lrsym->nRegs ||
1313 (lrsym->liveTo < forSym->liveFrom))
1316 /* go thru the registers : if it is either
1317 r0 or r1 then spil it */
1318 for (j = 0; j < lrsym->nRegs; j++)
1319 if (lrsym->regs[j] == r0 ||
1320 lrsym->regs[j] == r1)
1329 /*-----------------------------------------------------------------*/
1330 /* createStackSpil - create a location on the stack to spil */
1331 /*-----------------------------------------------------------------*/
1333 createStackSpil (symbol * sym)
1335 symbol *sloc = NULL;
1336 int useXstack, model, noOverlay;
1338 char slocBuffer[30];
1339 debugLog ("%s\n", __FUNCTION__);
1341 /* first go try and find a free one that is already
1342 existing on the stack */
1343 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1345 /* found a free one : just update & return */
1346 sym->usl.spillLoc = sloc;
1349 addSetHead (&sloc->usl.itmpStack, sym);
1353 /* could not then have to create one , this is the hard part
1354 we need to allocate this on the stack : this is really a
1355 hack!! but cannot think of anything better at this time */
1357 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1359 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1360 __FILE__, __LINE__);
1364 sloc = newiTemp (slocBuffer);
1366 /* set the type to the spilling symbol */
1367 sloc->type = copyLinkChain (sym->type);
1368 sloc->etype = getSpec (sloc->type);
1369 SPEC_SCLS (sloc->etype) = S_DATA;
1370 SPEC_EXTR (sloc->etype) = 0;
1371 SPEC_STAT (sloc->etype) = 0;
1373 /* we don't allow it to be allocated`
1374 onto the external stack since : so we
1375 temporarily turn it off ; we also
1376 turn off memory model to prevent
1377 the spil from going to the external storage
1378 and turn off overlaying
1381 useXstack = options.useXstack;
1382 model = options.model;
1383 noOverlay = options.noOverlay;
1384 options.noOverlay = 1;
1385 options.model = options.useXstack = 0;
1389 options.useXstack = useXstack;
1390 options.model = model;
1391 options.noOverlay = noOverlay;
1392 sloc->isref = 1; /* to prevent compiler warning */
1394 /* if it is on the stack then update the stack */
1395 if (IN_STACK (sloc->etype))
1397 currFunc->stack += getSize (sloc->type);
1398 _G.stackExtend += getSize (sloc->type);
1401 _G.dataExtend += getSize (sloc->type);
1403 /* add it to the _G.stackSpil set */
1404 addSetHead (&_G.stackSpil, sloc);
1405 sym->usl.spillLoc = sloc;
1408 /* add it to the set of itempStack set
1409 of the spill location */
1410 addSetHead (&sloc->usl.itmpStack, sym);
1414 /*-----------------------------------------------------------------*/
1415 /* isSpiltOnStack - returns true if the spil location is on stack */
1416 /*-----------------------------------------------------------------*/
1418 isSpiltOnStack (symbol * sym)
1422 debugLog ("%s\n", __FUNCTION__);
1429 /* if (sym->_G.stackSpil) */
1432 if (!sym->usl.spillLoc)
1435 etype = getSpec (sym->usl.spillLoc->type);
1436 if (IN_STACK (etype))
1442 /*-----------------------------------------------------------------*/
1443 /* spillThis - spils a specific operand */
1444 /*-----------------------------------------------------------------*/
1446 spillThis (symbol * sym)
1449 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1451 /* if this is rematerializable or has a spillLocation
1452 we are okay, else we need to create a spillLocation
1454 if (!(sym->remat || sym->usl.spillLoc))
1455 createStackSpil (sym);
1458 /* mark it has spilt & put it in the spilt set */
1460 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1462 bitVectUnSetBit (_G.regAssigned, sym->key);
1464 for (i = 0; i < sym->nRegs; i++)
1468 freeReg (sym->regs[i]);
1469 sym->regs[i] = NULL;
1472 /* if spilt on stack then free up r0 & r1
1473 if they could have been assigned to some
1475 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1478 spillLRWithPtrReg (sym);
1481 if (sym->usl.spillLoc && !sym->remat)
1482 sym->usl.spillLoc->allocreq = 1;
1486 /*-----------------------------------------------------------------*/
1487 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1488 /*-----------------------------------------------------------------*/
1490 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1492 bitVect *lrcs = NULL;
1496 debugLog ("%s\n", __FUNCTION__);
1497 /* get the spillable live ranges */
1498 lrcs = computeSpillable (ic);
1500 /* get all live ranges that are rematerizable */
1501 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1504 /* return the least used of these */
1505 return leastUsedLR (selectS);
1508 /* get live ranges with spillLocations in direct space */
1509 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1511 sym = leastUsedLR (selectS);
1512 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1513 sym->usl.spillLoc->rname :
1514 sym->usl.spillLoc->name));
1516 /* mark it as allocation required */
1517 sym->usl.spillLoc->allocreq = 1;
1521 /* if the symbol is local to the block then */
1522 if (forSym->liveTo < ebp->lSeq)
1525 /* check if there are any live ranges allocated
1526 to registers that are not used in this block */
1527 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1529 sym = leastUsedLR (selectS);
1530 /* if this is not rematerializable */
1539 /* check if there are any live ranges that not
1540 used in the remainder of the block */
1541 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1543 sym = leastUsedLR (selectS);
1546 sym->remainSpil = 1;
1553 /* find live ranges with spillocation && not used as pointers */
1554 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1557 sym = leastUsedLR (selectS);
1558 /* mark this as allocation required */
1559 sym->usl.spillLoc->allocreq = 1;
1563 /* find live ranges with spillocation */
1564 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1567 sym = leastUsedLR (selectS);
1568 sym->usl.spillLoc->allocreq = 1;
1572 /* couldn't find then we need to create a spil
1573 location on the stack , for which one? the least
1575 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1578 /* return a created spil location */
1579 sym = createStackSpil (leastUsedLR (selectS));
1580 sym->usl.spillLoc->allocreq = 1;
1584 /* this is an extreme situation we will spill
1585 this one : happens very rarely but it does happen */
1591 /*-----------------------------------------------------------------*/
1592 /* spilSomething - spil some variable & mark registers as free */
1593 /*-----------------------------------------------------------------*/
1595 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1600 debugLog ("%s\n", __FUNCTION__);
1601 /* get something we can spil */
1602 ssym = selectSpil (ic, ebp, forSym);
1604 /* mark it as spilt */
1606 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1608 /* mark it as not register assigned &
1609 take it away from the set */
1610 bitVectUnSetBit (_G.regAssigned, ssym->key);
1612 /* mark the registers as free */
1613 for (i = 0; i < ssym->nRegs; i++)
1615 freeReg (ssym->regs[i]);
1617 /* if spilt on stack then free up r0 & r1
1618 if they could have been assigned to as gprs */
1619 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1622 spillLRWithPtrReg (ssym);
1625 /* if this was a block level spil then insert push & pop
1626 at the start & end of block respectively */
1627 if (ssym->blockSpil)
1629 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1630 /* add push to the start of the block */
1631 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1632 ebp->sch->next : ebp->sch));
1633 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1634 /* add pop to the end of the block */
1635 addiCodeToeBBlock (ebp, nic, NULL);
1638 /* if spilt because not used in the remainder of the
1639 block then add a push before this instruction and
1640 a pop at the end of the block */
1641 if (ssym->remainSpil)
1644 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1645 /* add push just before this instruction */
1646 addiCodeToeBBlock (ebp, nic, ic);
1648 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1649 /* add pop to the end of the block */
1650 addiCodeToeBBlock (ebp, nic, NULL);
1659 /*-----------------------------------------------------------------*/
1660 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1661 /*-----------------------------------------------------------------*/
1663 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1667 debugLog ("%s\n", __FUNCTION__);
1669 /* try for a ptr type */
1670 if ((reg = allocReg (REG_PTR)))
1673 /* try for gpr type */
1674 if ((reg = allocReg (REG_GPR)))
1677 /* we have to spil */
1678 if (!spilSomething (ic, ebp, sym))
1681 /* this looks like an infinite loop but
1682 in really selectSpil will abort */
1686 /*-----------------------------------------------------------------*/
1687 /* getRegGpr - will try for GPR if not spil */
1688 /*-----------------------------------------------------------------*/
1690 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1694 debugLog ("%s\n", __FUNCTION__);
1696 /* try for gpr type */
1697 if ((reg = allocReg (REG_GPR)))
1700 if (!pic14_ptrRegReq)
1701 if ((reg = allocReg (REG_PTR)))
1704 /* we have to spil */
1705 if (!spilSomething (ic, ebp, sym))
1708 /* this looks like an infinite loop but
1709 in really selectSpil will abort */
1713 /*-----------------------------------------------------------------*/
1714 /* symHasReg - symbol has a given register */
1715 /*-----------------------------------------------------------------*/
1717 symHasReg (symbol * sym, regs * reg)
1721 debugLog ("%s\n", __FUNCTION__);
1722 for (i = 0; i < sym->nRegs; i++)
1723 if (sym->regs[i] == reg)
1729 /*-----------------------------------------------------------------*/
1730 /* deassignLRs - check the live to and if they have registers & are */
1731 /* not spilt then free up the registers */
1732 /*-----------------------------------------------------------------*/
1734 deassignLRs (iCode * ic, eBBlock * ebp)
1740 debugLog ("%s\n", __FUNCTION__);
1741 for (sym = hTabFirstItem (liveRanges, &k); sym;
1742 sym = hTabNextItem (liveRanges, &k))
1745 symbol *psym = NULL;
1746 /* if it does not end here */
1747 if (sym->liveTo > ic->seq)
1750 /* if it was spilt on stack then we can
1751 mark the stack spil location as free */
1756 sym->usl.spillLoc->isFree = 1;
1762 if (!bitVectBitValue (_G.regAssigned, sym->key))
1765 /* special case check if this is an IFX &
1766 the privious one was a pop and the
1767 previous one was not spilt then keep track
1769 if (ic->op == IFX && ic->prev &&
1770 ic->prev->op == IPOP &&
1771 !ic->prev->parmPush &&
1772 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1773 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1779 bitVectUnSetBit (_G.regAssigned, sym->key);
1781 /* if the result of this one needs registers
1782 and does not have it then assign it right
1784 if (IC_RESULT (ic) &&
1785 !(SKIP_IC2 (ic) || /* not a special icode */
1786 ic->op == JUMPTABLE ||
1791 POINTER_SET (ic)) &&
1792 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1793 result->liveTo > ic->seq && /* and will live beyond this */
1794 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1795 result->regType == sym->regType && /* same register types */
1796 result->nRegs && /* which needs registers */
1797 !result->isspilt && /* and does not already have them */
1799 !bitVectBitValue (_G.regAssigned, result->key) &&
1800 /* the number of free regs + number of regs in this LR
1801 can accomodate the what result Needs */
1802 ((nfreeRegsType (result->regType) +
1803 sym->nRegs) >= result->nRegs)
1807 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1809 result->regs[i] = sym->regs[i];
1811 result->regs[i] = getRegGpr (ic, ebp, result);
1813 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1817 /* free the remaining */
1818 for (; i < sym->nRegs; i++)
1822 if (!symHasReg (psym, sym->regs[i]))
1823 freeReg (sym->regs[i]);
1826 freeReg (sym->regs[i]);
1833 /*-----------------------------------------------------------------*/
1834 /* reassignLR - reassign this to registers */
1835 /*-----------------------------------------------------------------*/
1837 reassignLR (operand * op)
1839 symbol *sym = OP_SYMBOL (op);
1842 debugLog ("%s\n", __FUNCTION__);
1843 /* not spilt any more */
1844 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1845 bitVectUnSetBit (_G.spiltSet, sym->key);
1847 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1851 for (i = 0; i < sym->nRegs; i++)
1852 sym->regs[i]->isFree = 0;
1855 /*-----------------------------------------------------------------*/
1856 /* willCauseSpill - determines if allocating will cause a spill */
1857 /*-----------------------------------------------------------------*/
1859 willCauseSpill (int nr, int rt)
1861 debugLog ("%s\n", __FUNCTION__);
1862 /* first check if there are any avlb registers
1863 of te type required */
1866 /* special case for pointer type
1867 if pointer type not avlb then
1868 check for type gpr */
1869 if (nFreeRegs (rt) >= nr)
1871 if (nFreeRegs (REG_GPR) >= nr)
1876 if (pic14_ptrRegReq)
1878 if (nFreeRegs (rt) >= nr)
1883 if (nFreeRegs (REG_PTR) +
1884 nFreeRegs (REG_GPR) >= nr)
1889 debugLog (" ... yep it will (cause a spill)\n");
1890 /* it will cause a spil */
1894 /*-----------------------------------------------------------------*/
1895 /* positionRegs - the allocator can allocate same registers to res- */
1896 /* ult and operand, if this happens make sure they are in the same */
1897 /* position as the operand otherwise chaos results */
1898 /*-----------------------------------------------------------------*/
1900 positionRegs (symbol * result, symbol * opsym, int lineno)
1902 int count = min (result->nRegs, opsym->nRegs);
1903 int i, j = 0, shared = 0;
1905 debugLog ("%s\n", __FUNCTION__);
1906 /* if the result has been spilt then cannot share */
1911 /* first make sure that they actually share */
1912 for (i = 0; i < count; i++)
1914 for (j = 0; j < count; j++)
1916 if (result->regs[i] == opsym->regs[j] && i != j)
1926 regs *tmp = result->regs[i];
1927 result->regs[i] = result->regs[j];
1928 result->regs[j] = tmp;
1933 /*-----------------------------------------------------------------*/
1934 /* serialRegAssign - serially allocate registers to the variables */
1935 /*-----------------------------------------------------------------*/
1937 serialRegAssign (eBBlock ** ebbs, int count)
1941 debugLog ("%s\n", __FUNCTION__);
1942 /* for all blocks */
1943 for (i = 0; i < count; i++)
1948 if (ebbs[i]->noPath &&
1949 (ebbs[i]->entryLabel != entryLabel &&
1950 ebbs[i]->entryLabel != returnLabel))
1953 /* of all instructions do */
1954 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1957 debugLog (" op: %s\n", decodeOp (ic->op));
1959 /* if this is an ipop that means some live
1960 range will have to be assigned again */
1962 reassignLR (IC_LEFT (ic));
1964 /* if result is present && is a true symbol */
1965 if (IC_RESULT (ic) && ic->op != IFX &&
1966 IS_TRUE_SYMOP (IC_RESULT (ic)))
1967 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1969 /* take away registers from live
1970 ranges that end at this instruction */
1971 deassignLRs (ic, ebbs[i]);
1973 /* some don't need registers */
1974 if (SKIP_IC2 (ic) ||
1975 ic->op == JUMPTABLE ||
1979 (IC_RESULT (ic) && POINTER_SET (ic)))
1982 /* now we need to allocate registers
1983 only for the result */
1986 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1992 /* if it does not need or is spilt
1993 or is already assigned to registers
1994 or will not live beyond this instructions */
1997 bitVectBitValue (_G.regAssigned, sym->key) ||
1998 sym->liveTo <= ic->seq)
2001 /* if some liverange has been spilt at the block level
2002 and this one live beyond this block then spil this
2004 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2009 /* if trying to allocate this will cause
2010 a spill and there is nothing to spill
2011 or this one is rematerializable then
2013 willCS = willCauseSpill (sym->nRegs, sym->regType);
2014 spillable = computeSpillable (ic);
2016 (willCS && bitVectIsZero (spillable)))
2024 /* if it has a spillocation & is used less than
2025 all other live ranges then spill this */
2027 if (sym->usl.spillLoc) {
2028 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2029 allLRs, ebbs[i], ic));
2030 if (leastUsed && leastUsed->used > sym->used) {
2035 /* if none of the liveRanges have a spillLocation then better
2036 to spill this one than anything else already assigned to registers */
2037 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2038 /* if this is local to this block then we might find a block spil */
2039 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2047 if (ic->op == RECEIVE)
2048 debugLog ("When I get clever, I'll optimize the receive logic\n");
2050 /* if we need ptr regs for the right side
2052 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2053 <= (unsigned) PTRSIZE)
2058 /* else we assign registers to it */
2059 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2061 debugLog (" %d - \n", __LINE__);
2063 bitVectDebugOn(_G.regAssigned, debugF);
2065 for (j = 0; j < sym->nRegs; j++)
2067 if (sym->regType == REG_PTR)
2068 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2070 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2072 /* if the allocation falied which means
2073 this was spilt then break */
2077 debugLog (" %d - \n", __LINE__);
2079 /* if it shares registers with operands make sure
2080 that they are in the same position */
2081 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2082 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2083 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2084 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2085 /* do the same for the right operand */
2086 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2087 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2088 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2089 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2091 debugLog (" %d - \n", __LINE__);
2094 debugLog (" %d - \n", __LINE__);
2104 /*-----------------------------------------------------------------*/
2105 /* rUmaskForOp :- returns register mask for an operand */
2106 /*-----------------------------------------------------------------*/
2108 rUmaskForOp (operand * op)
2114 debugLog ("%s\n", __FUNCTION__);
2115 /* only temporaries are assigned registers */
2119 sym = OP_SYMBOL (op);
2121 /* if spilt or no registers assigned to it
2123 if (sym->isspilt || !sym->nRegs)
2126 rumask = newBitVect (pic14_nRegs);
2128 for (j = 0; j < sym->nRegs; j++)
2130 rumask = bitVectSetBit (rumask,
2131 sym->regs[j]->rIdx);
2137 /*-----------------------------------------------------------------*/
2138 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2139 /*-----------------------------------------------------------------*/
2141 regsUsedIniCode (iCode * ic)
2143 bitVect *rmask = newBitVect (pic14_nRegs);
2145 debugLog ("%s\n", __FUNCTION__);
2146 /* do the special cases first */
2149 rmask = bitVectUnion (rmask,
2150 rUmaskForOp (IC_COND (ic)));
2154 /* for the jumptable */
2155 if (ic->op == JUMPTABLE)
2157 rmask = bitVectUnion (rmask,
2158 rUmaskForOp (IC_JTCOND (ic)));
2163 /* of all other cases */
2165 rmask = bitVectUnion (rmask,
2166 rUmaskForOp (IC_LEFT (ic)));
2170 rmask = bitVectUnion (rmask,
2171 rUmaskForOp (IC_RIGHT (ic)));
2174 rmask = bitVectUnion (rmask,
2175 rUmaskForOp (IC_RESULT (ic)));
2181 /*-----------------------------------------------------------------*/
2182 /* createRegMask - for each instruction will determine the regsUsed */
2183 /*-----------------------------------------------------------------*/
2185 createRegMask (eBBlock ** ebbs, int count)
2189 debugLog ("%s\n", __FUNCTION__);
2190 /* for all blocks */
2191 for (i = 0; i < count; i++)
2195 if (ebbs[i]->noPath &&
2196 (ebbs[i]->entryLabel != entryLabel &&
2197 ebbs[i]->entryLabel != returnLabel))
2200 /* for all instructions */
2201 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2206 if (SKIP_IC2 (ic) || !ic->rlive)
2209 /* first mark the registers used in this
2211 ic->rUsed = regsUsedIniCode (ic);
2212 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2214 /* now create the register mask for those
2215 registers that are in use : this is a
2216 super set of ic->rUsed */
2217 ic->rMask = newBitVect (pic14_nRegs + 1);
2219 /* for all live Ranges alive at this point */
2220 for (j = 1; j < ic->rlive->size; j++)
2225 /* if not alive then continue */
2226 if (!bitVectBitValue (ic->rlive, j))
2229 /* find the live range we are interested in */
2230 if (!(sym = hTabItemWithKey (liveRanges, j)))
2232 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2233 "createRegMask cannot find live range");
2237 /* if no register assigned to it */
2238 if (!sym->nRegs || sym->isspilt)
2241 /* for all the registers allocated to it */
2242 for (k = 0; k < sym->nRegs; k++)
2245 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2251 /*-----------------------------------------------------------------*/
2252 /* rematStr - returns the rematerialized string for a remat var */
2253 /*-----------------------------------------------------------------*/
2255 rematStr (symbol * sym)
2258 iCode *ic = sym->rematiCode;
2259 symbol *psym = NULL;
2261 debugLog ("%s\n", __FUNCTION__);
2263 //printf ("%s\n", s);
2265 /* if plus or minus print the right hand side */
2267 if (ic->op == '+' || ic->op == '-') {
2269 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2271 sprintf (s, "(%s %c 0x%04x)",
2272 OP_SYMBOL (IC_LEFT (ric))->rname,
2274 (int) operandLitValue (IC_RIGHT (ic)));
2277 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2279 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2280 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2285 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2286 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2288 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2293 /*-----------------------------------------------------------------*/
2294 /* rematStr - returns the rematerialized string for a remat var */
2295 /*-----------------------------------------------------------------*/
2297 rematStr (symbol * sym)
2300 iCode *ic = sym->rematiCode;
2302 debugLog ("%s\n", __FUNCTION__);
2307 /* if plus or minus print the right hand side */
2309 if (ic->op == '+' || ic->op == '-') {
2310 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2313 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2317 if (ic->op == '+' || ic->op == '-')
2319 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2320 sprintf (s, "(%s %c 0x%04x)",
2321 OP_SYMBOL (IC_LEFT (ric))->rname,
2323 (int) operandLitValue (IC_RIGHT (ic)));
2326 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2328 fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2332 /* we reached the end */
2333 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2337 printf ("%s\n", buffer);
2342 /*-----------------------------------------------------------------*/
2343 /* regTypeNum - computes the type & number of registers required */
2344 /*-----------------------------------------------------------------*/
2352 debugLog ("%s\n", __FUNCTION__);
2353 /* for each live range do */
2354 for (sym = hTabFirstItem (liveRanges, &k); sym;
2355 sym = hTabNextItem (liveRanges, &k)) {
2357 debugLog (" %d - %s\n", __LINE__, sym->rname);
2359 /* if used zero times then no registers needed */
2360 if ((sym->liveTo - sym->liveFrom) == 0)
2364 /* if the live range is a temporary */
2367 debugLog (" %d - itemp register\n", __LINE__);
2369 /* if the type is marked as a conditional */
2370 if (sym->regType == REG_CND)
2373 /* if used in return only then we don't
2375 if (sym->ruonly || sym->accuse) {
2376 if (IS_AGGREGATE (sym->type) || sym->isptr)
2377 sym->type = aggrToPtr (sym->type, FALSE);
2378 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2383 /* if the symbol has only one definition &
2384 that definition is a get_pointer and the
2385 pointer we are getting is rematerializable and
2388 if (bitVectnBitsOn (sym->defs) == 1 &&
2389 (ic = hTabItemWithKey (iCodehTab,
2390 bitVectFirstBit (sym->defs))) &&
2393 !IS_BITVAR (sym->etype)) {
2396 debugLog (" %d - \n", __LINE__);
2398 /* if remat in data space */
2399 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2400 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2402 /* create a psuedo symbol & force a spil */
2403 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2404 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2405 psym->type = sym->type;
2406 psym->etype = sym->etype;
2407 strcpy (psym->rname, psym->name);
2409 sym->usl.spillLoc = psym;
2413 /* if in data space or idata space then try to
2414 allocate pointer register */
2418 /* if not then we require registers */
2419 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2420 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2421 getSize (sym->type));
2424 if(IS_PTR_CONST (sym->type)) {
2425 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2429 if (sym->nRegs > 4) {
2430 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2431 printTypeChain (sym->type, stderr);
2432 fprintf (stderr, "\n");
2435 /* determine the type of register required */
2436 if (sym->nRegs == 1 &&
2437 IS_PTR (sym->type) &&
2439 sym->regType = REG_PTR;
2441 sym->regType = REG_GPR;
2444 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2448 /* for the first run we don't provide */
2449 /* registers for true symbols we will */
2450 /* see how things go */
2455 DEFSETFUNC (markRegFree)
2457 ((regs *)item)->isFree = 1;
2462 DEFSETFUNC (deallocReg)
2464 ((regs *)item)->isFree = 1;
2465 ((regs *)item)->wasUsed = 0;
2469 /*-----------------------------------------------------------------*/
2470 /* freeAllRegs - mark all registers as free */
2471 /*-----------------------------------------------------------------*/
2473 pic14_freeAllRegs ()
2477 debugLog ("%s\n", __FUNCTION__);
2479 applyToSet(dynAllocRegs,markRegFree);
2480 applyToSet(dynStackRegs,markRegFree);
2483 for (i = 0; i < pic14_nRegs; i++)
2484 regspic14[i].isFree = 1;
2488 /*-----------------------------------------------------------------*/
2489 /*-----------------------------------------------------------------*/
2491 pic14_deallocateAllRegs ()
2495 debugLog ("%s\n", __FUNCTION__);
2497 applyToSet(dynAllocRegs,deallocReg);
2500 for (i = 0; i < pic14_nRegs; i++) {
2501 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2502 regspic14[i].isFree = 1;
2503 regspic14[i].wasUsed = 0;
2510 /*-----------------------------------------------------------------*/
2511 /* deallocStackSpil - this will set the stack pointer back */
2512 /*-----------------------------------------------------------------*/
2514 DEFSETFUNC (deallocStackSpil)
2518 debugLog ("%s\n", __FUNCTION__);
2523 /*-----------------------------------------------------------------*/
2524 /* farSpacePackable - returns the packable icode for far variables */
2525 /*-----------------------------------------------------------------*/
2527 farSpacePackable (iCode * ic)
2531 debugLog ("%s\n", __FUNCTION__);
2532 /* go thru till we find a definition for the
2533 symbol on the right */
2534 for (dic = ic->prev; dic; dic = dic->prev)
2537 /* if the definition is a call then no */
2538 if ((dic->op == CALL || dic->op == PCALL) &&
2539 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2544 /* if shift by unknown amount then not */
2545 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2546 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2549 /* if pointer get and size > 1 */
2550 if (POINTER_GET (dic) &&
2551 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2554 if (POINTER_SET (dic) &&
2555 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2558 /* if any three is a true symbol in far space */
2559 if (IC_RESULT (dic) &&
2560 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2561 isOperandInFarSpace (IC_RESULT (dic)))
2564 if (IC_RIGHT (dic) &&
2565 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2566 isOperandInFarSpace (IC_RIGHT (dic)) &&
2567 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2570 if (IC_LEFT (dic) &&
2571 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2572 isOperandInFarSpace (IC_LEFT (dic)) &&
2573 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2576 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2578 if ((dic->op == LEFT_OP ||
2579 dic->op == RIGHT_OP ||
2581 IS_OP_LITERAL (IC_RIGHT (dic)))
2591 /*-----------------------------------------------------------------*/
2592 /* packRegsForAssign - register reduction for assignment */
2593 /*-----------------------------------------------------------------*/
2595 packRegsForAssign (iCode * ic, eBBlock * ebp)
2600 debugLog ("%s\n", __FUNCTION__);
2602 debugAopGet (" result:", IC_RESULT (ic));
2603 debugAopGet (" left:", IC_LEFT (ic));
2604 debugAopGet (" right:", IC_RIGHT (ic));
2606 /* if this is at an absolute address, then get the address. */
2607 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2608 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2609 debugLog (" %d - found config word declaration\n", __LINE__);
2610 if(IS_VALOP(IC_RIGHT(ic))) {
2611 debugLog (" setting config word to %x\n",
2612 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2613 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2614 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2617 /* remove the assignment from the iCode chain. */
2619 remiCodeFromeBBlock (ebp, ic);
2620 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2621 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2628 if (!IS_ITEMP (IC_RESULT (ic))) {
2629 allocDirReg(IC_RESULT (ic));
2630 debugLog (" %d - result is not temp\n", __LINE__);
2633 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2634 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2635 allocDirReg(IC_LEFT (ic));
2639 if (!IS_ITEMP (IC_RIGHT (ic))) {
2640 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2641 allocDirReg(IC_RIGHT (ic));
2645 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2646 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2648 debugLog (" %d - not packing - right side fails \n", __LINE__);
2652 /* if the true symbol is defined in far space or on stack
2653 then we should not since this will increase register pressure */
2654 if (isOperandInFarSpace (IC_RESULT (ic)))
2656 if ((dic = farSpacePackable (ic)))
2662 /* find the definition of iTempNN scanning backwards if we find a
2663 a use of the true symbol before we find the definition then
2665 for (dic = ic->prev; dic; dic = dic->prev)
2668 /* if there is a function call and this is
2669 a parameter & not my parameter then don't pack it */
2670 if ((dic->op == CALL || dic->op == PCALL) &&
2671 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2672 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2674 debugLog (" %d - \n", __LINE__);
2682 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2683 IS_OP_VOLATILE (IC_RESULT (dic)))
2685 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2690 if (IS_SYMOP (IC_RESULT (dic)) &&
2691 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2693 /* A previous result was assigned to the same register - we'll our definition */
2694 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2695 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2696 if (POINTER_SET (dic))
2702 if (IS_SYMOP (IC_RIGHT (dic)) &&
2703 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2704 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2706 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2711 if (IS_SYMOP (IC_LEFT (dic)) &&
2712 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2713 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2715 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2720 if (POINTER_SET (dic) &&
2721 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2723 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2731 return 0; /* did not find */
2733 /* if the result is on stack or iaccess then it must be
2734 the same atleast one of the operands */
2735 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2736 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2739 /* the operation has only one symbol
2740 operator then we can pack */
2741 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2742 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2745 if (!((IC_LEFT (dic) &&
2746 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2748 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2752 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2753 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2754 /* found the definition */
2755 /* replace the result with the result of */
2756 /* this assignment and remove this assignment */
2757 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2758 IC_RESULT (dic) = IC_RESULT (ic);
2760 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2762 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2764 /* delete from liverange table also
2765 delete from all the points inbetween and the new
2767 for (sic = dic; sic != ic; sic = sic->next)
2769 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2770 if (IS_ITEMP (IC_RESULT (dic)))
2771 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2774 remiCodeFromeBBlock (ebp, ic);
2775 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2776 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2777 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2783 /*-----------------------------------------------------------------*/
2784 /* findAssignToSym : scanning backwards looks for first assig found */
2785 /*-----------------------------------------------------------------*/
2787 findAssignToSym (operand * op, iCode * ic)
2791 debugLog ("%s\n", __FUNCTION__);
2792 for (dic = ic->prev; dic; dic = dic->prev)
2795 /* if definition by assignment */
2796 if (dic->op == '=' &&
2797 !POINTER_SET (dic) &&
2798 IC_RESULT (dic)->key == op->key
2799 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2803 /* we are interested only if defined in far space */
2804 /* or in stack space in case of + & - */
2806 /* if assigned to a non-symbol then return
2808 if (!IS_SYMOP (IC_RIGHT (dic)))
2811 /* if the symbol is in far space then
2813 if (isOperandInFarSpace (IC_RIGHT (dic)))
2816 /* for + & - operations make sure that
2817 if it is on the stack it is the same
2818 as one of the three operands */
2819 if ((ic->op == '+' || ic->op == '-') &&
2820 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2823 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2824 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2825 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2833 /* if we find an usage then we cannot delete it */
2834 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2837 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2840 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2844 /* now make sure that the right side of dic
2845 is not defined between ic & dic */
2848 iCode *sic = dic->next;
2850 for (; sic != ic; sic = sic->next)
2851 if (IC_RESULT (sic) &&
2852 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2861 /*-----------------------------------------------------------------*/
2862 /* packRegsForSupport :- reduce some registers for support calls */
2863 /*-----------------------------------------------------------------*/
2865 packRegsForSupport (iCode * ic, eBBlock * ebp)
2869 debugLog ("%s\n", __FUNCTION__);
2870 /* for the left & right operand :- look to see if the
2871 left was assigned a true symbol in far space in that
2872 case replace them */
2873 if (IS_ITEMP (IC_LEFT (ic)) &&
2874 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2876 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2882 debugAopGet ("removing left:", IC_LEFT (ic));
2884 /* found it we need to remove it from the
2886 for (sic = dic; sic != ic; sic = sic->next)
2887 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2889 IC_LEFT (ic)->operand.symOperand =
2890 IC_RIGHT (dic)->operand.symOperand;
2891 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2892 remiCodeFromeBBlock (ebp, dic);
2893 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2894 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2898 /* do the same for the right operand */
2901 IS_ITEMP (IC_RIGHT (ic)) &&
2902 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2904 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2910 /* if this is a subtraction & the result
2911 is a true symbol in far space then don't pack */
2912 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2914 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2915 if (IN_FARSPACE (SPEC_OCLS (etype)))
2919 debugAopGet ("removing right:", IC_RIGHT (ic));
2921 /* found it we need to remove it from the
2923 for (sic = dic; sic != ic; sic = sic->next)
2924 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2926 IC_RIGHT (ic)->operand.symOperand =
2927 IC_RIGHT (dic)->operand.symOperand;
2928 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2930 remiCodeFromeBBlock (ebp, dic);
2931 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2932 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2939 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2942 /*-----------------------------------------------------------------*/
2943 /* packRegsForOneuse : - will reduce some registers for single Use */
2944 /*-----------------------------------------------------------------*/
2946 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2951 debugLog ("%s\n", __FUNCTION__);
2952 /* if returning a literal then do nothing */
2956 /* only upto 2 bytes since we cannot predict
2957 the usage of b, & acc */
2958 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2963 /* this routine will mark the a symbol as used in one
2964 instruction use only && if the definition is local
2965 (ie. within the basic block) && has only one definition &&
2966 that definition is either a return value from a
2967 function or does not contain any variables in
2969 uses = bitVectCopy (OP_USES (op));
2970 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2971 if (!bitVectIsZero (uses)) /* has other uses */
2974 /* if it has only one defintion */
2975 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2976 return NULL; /* has more than one definition */
2978 /* get that definition */
2980 hTabItemWithKey (iCodehTab,
2981 bitVectFirstBit (OP_DEFS (op)))))
2984 /* found the definition now check if it is local */
2985 if (dic->seq < ebp->fSeq ||
2986 dic->seq > ebp->lSeq)
2987 return NULL; /* non-local */
2989 /* now check if it is the return from
2991 if (dic->op == CALL || dic->op == PCALL)
2993 if (ic->op != SEND && ic->op != RETURN &&
2994 !POINTER_SET(ic) && !POINTER_GET(ic))
2996 OP_SYMBOL (op)->ruonly = 1;
3003 /* otherwise check that the definition does
3004 not contain any symbols in far space */
3005 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3006 isOperandInFarSpace (IC_RIGHT (dic)) ||
3007 IS_OP_RUONLY (IC_LEFT (ic)) ||
3008 IS_OP_RUONLY (IC_RIGHT (ic)))
3013 /* if pointer set then make sure the pointer
3015 if (POINTER_SET (dic) &&
3016 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3019 if (POINTER_GET (dic) &&
3020 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3025 /* also make sure the intervenening instructions
3026 don't have any thing in far space */
3027 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3030 /* if there is an intervening function call then no */
3031 if (dic->op == CALL || dic->op == PCALL)
3033 /* if pointer set then make sure the pointer
3035 if (POINTER_SET (dic) &&
3036 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3039 if (POINTER_GET (dic) &&
3040 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3043 /* if address of & the result is remat then okay */
3044 if (dic->op == ADDRESS_OF &&
3045 OP_SYMBOL (IC_RESULT (dic))->remat)
3048 /* if operand has size of three or more & this
3049 operation is a '*','/' or '%' then 'b' may
3051 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3052 getSize (operandType (op)) >= 3)
3055 /* if left or right or result is in far space */
3056 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3057 isOperandInFarSpace (IC_RIGHT (dic)) ||
3058 isOperandInFarSpace (IC_RESULT (dic)) ||
3059 IS_OP_RUONLY (IC_LEFT (dic)) ||
3060 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3061 IS_OP_RUONLY (IC_RESULT (dic)))
3067 OP_SYMBOL (op)->ruonly = 1;
3072 /*-----------------------------------------------------------------*/
3073 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3074 /*-----------------------------------------------------------------*/
3076 isBitwiseOptimizable (iCode * ic)
3078 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3079 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3081 debugLog ("%s\n", __FUNCTION__);
3082 /* bitwise operations are considered optimizable
3083 under the following conditions (Jean-Louis VERN)
3095 if (IS_LITERAL (rtype) ||
3096 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3102 /*-----------------------------------------------------------------*/
3103 /* packRegsForAccUse - pack registers for acc use */
3104 /*-----------------------------------------------------------------*/
3106 packRegsForAccUse (iCode * ic)
3110 debugLog ("%s\n", __FUNCTION__);
3112 /* if this is an aggregate, e.g. a one byte char array */
3113 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3117 /* if + or - then it has to be one byte result */
3118 if ((ic->op == '+' || ic->op == '-')
3119 && getSize (operandType (IC_RESULT (ic))) > 1)
3122 /* if shift operation make sure right side is not a literal */
3123 if (ic->op == RIGHT_OP &&
3124 (isOperandLiteral (IC_RIGHT (ic)) ||
3125 getSize (operandType (IC_RESULT (ic))) > 1))
3128 if (ic->op == LEFT_OP &&
3129 (isOperandLiteral (IC_RIGHT (ic)) ||
3130 getSize (operandType (IC_RESULT (ic))) > 1))
3133 if (IS_BITWISE_OP (ic) &&
3134 getSize (operandType (IC_RESULT (ic))) > 1)
3138 /* has only one definition */
3139 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3142 /* has only one use */
3143 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3146 /* and the usage immediately follows this iCode */
3147 if (!(uic = hTabItemWithKey (iCodehTab,
3148 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3151 if (ic->next != uic)
3154 /* if it is a conditional branch then we definitely can */
3158 if (uic->op == JUMPTABLE)
3161 /* if the usage is not is an assignment
3162 or an arithmetic / bitwise / shift operation then not */
3163 if (POINTER_SET (uic) &&
3164 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3167 if (uic->op != '=' &&
3168 !IS_ARITHMETIC_OP (uic) &&
3169 !IS_BITWISE_OP (uic) &&
3170 uic->op != LEFT_OP &&
3171 uic->op != RIGHT_OP)
3174 /* if used in ^ operation then make sure right is not a
3176 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3179 /* if shift operation make sure right side is not a literal */
3180 if (uic->op == RIGHT_OP &&
3181 (isOperandLiteral (IC_RIGHT (uic)) ||
3182 getSize (operandType (IC_RESULT (uic))) > 1))
3185 if (uic->op == LEFT_OP &&
3186 (isOperandLiteral (IC_RIGHT (uic)) ||
3187 getSize (operandType (IC_RESULT (uic))) > 1))
3190 /* make sure that the result of this icode is not on the
3191 stack, since acc is used to compute stack offset */
3192 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3193 OP_SYMBOL (IC_RESULT (uic))->onStack)
3196 /* if either one of them in far space then we cannot */
3197 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3198 isOperandInFarSpace (IC_LEFT (uic))) ||
3199 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3200 isOperandInFarSpace (IC_RIGHT (uic))))
3203 /* if the usage has only one operand then we can */
3204 if (IC_LEFT (uic) == NULL ||
3205 IC_RIGHT (uic) == NULL)
3208 /* make sure this is on the left side if not
3209 a '+' since '+' is commutative */
3210 if (ic->op != '+' &&
3211 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3214 /* if one of them is a literal then we can */
3215 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3216 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
3218 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3222 /* if the other one is not on stack then we can */
3223 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3224 (IS_ITEMP (IC_RIGHT (uic)) ||
3225 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3226 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3229 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3230 (IS_ITEMP (IC_LEFT (uic)) ||
3231 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3232 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3238 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3239 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3244 /*-----------------------------------------------------------------*/
3245 /* packForPush - hueristics to reduce iCode for pushing */
3246 /*-----------------------------------------------------------------*/
3248 packForReceive (iCode * ic, eBBlock * ebp)
3252 debugLog ("%s\n", __FUNCTION__);
3253 debugAopGet (" result:", IC_RESULT (ic));
3254 debugAopGet (" left:", IC_LEFT (ic));
3255 debugAopGet (" right:", IC_RIGHT (ic));
3260 for (dic = ic->next; dic; dic = dic->next)
3265 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3266 debugLog (" used on left\n");
3267 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3268 debugLog (" used on right\n");
3269 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3270 debugLog (" used on result\n");
3272 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3273 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3278 debugLog (" hey we can remove this unnecessary assign\n");
3280 /*-----------------------------------------------------------------*/
3281 /* packForPush - hueristics to reduce iCode for pushing */
3282 /*-----------------------------------------------------------------*/
3284 packForPush (iCode * ic, eBBlock * ebp)
3288 debugLog ("%s\n", __FUNCTION__);
3289 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3292 /* must have only definition & one usage */
3293 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3294 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3297 /* find the definition */
3298 if (!(dic = hTabItemWithKey (iCodehTab,
3299 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3302 if (dic->op != '=' || POINTER_SET (dic))
3305 /* we now we know that it has one & only one def & use
3306 and the that the definition is an assignment */
3307 IC_LEFT (ic) = IC_RIGHT (dic);
3309 remiCodeFromeBBlock (ebp, dic);
3310 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3311 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3314 void printSymType(char * str, sym_link *sl)
3316 debugLog (" %s Symbol type: ",str);
3317 printTypeChain( sl, debugF);
3322 /*-----------------------------------------------------------------*/
3323 /* packRegisters - does some transformations to reduce register */
3325 /*-----------------------------------------------------------------*/
3327 packRegisters (eBBlock * ebp)
3332 debugLog ("%s\n", __FUNCTION__);
3338 /* look for assignments of the form */
3339 /* iTempNN = TRueSym (someoperation) SomeOperand */
3341 /* TrueSym := iTempNN:1 */
3342 for (ic = ebp->sch; ic; ic = ic->next)
3345 /* find assignment of the form TrueSym := iTempNN:1 */
3346 if (ic->op == '=' && !POINTER_SET (ic))
3347 change += packRegsForAssign (ic, ebp);
3351 if (POINTER_SET (ic))
3352 debugLog ("pointer is set\n");
3353 debugAopGet (" result:", IC_RESULT (ic));
3354 debugAopGet (" left:", IC_LEFT (ic));
3355 debugAopGet (" right:", IC_RIGHT (ic));
3364 for (ic = ebp->sch; ic; ic = ic->next) {
3366 if(IS_SYMOP ( IC_LEFT(ic))) {
3367 //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3369 debugAopGet (" left:", IC_LEFT (ic));
3370 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3371 debugLog (" is a pointer");
3373 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3376 if(IS_SYMOP ( IC_RIGHT(ic))) {
3377 debugAopGet (" right:", IC_RIGHT (ic));
3378 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3381 if(IS_SYMOP ( IC_RESULT(ic))) {
3382 debugAopGet (" result:", IC_RESULT (ic));
3383 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3386 if (POINTER_SET (ic))
3387 debugLog (" %d - Pointer set\n", __LINE__);
3390 /* if this is an itemp & result of a address of a true sym
3391 then mark this as rematerialisable */
3392 if (ic->op == ADDRESS_OF &&
3393 IS_ITEMP (IC_RESULT (ic)) &&
3394 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3395 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3396 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3399 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3401 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3402 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3403 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3407 /* if straight assignment then carry remat flag if
3408 this is the only definition */
3409 if (ic->op == '=' &&
3410 !POINTER_SET (ic) &&
3411 IS_SYMOP (IC_RIGHT (ic)) &&
3412 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3413 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3415 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3417 OP_SYMBOL (IC_RESULT (ic))->remat =
3418 OP_SYMBOL (IC_RIGHT (ic))->remat;
3419 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3420 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3423 /* if this is a +/- operation with a rematerizable
3424 then mark this as rematerializable as well */
3425 if ((ic->op == '+' || ic->op == '-') &&
3426 (IS_SYMOP (IC_LEFT (ic)) &&
3427 IS_ITEMP (IC_RESULT (ic)) &&
3428 OP_SYMBOL (IC_LEFT (ic))->remat &&
3429 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3430 IS_OP_LITERAL (IC_RIGHT (ic))))
3432 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3434 operandLitValue (IC_RIGHT (ic));
3435 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3436 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3437 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3440 /* mark the pointer usages */
3441 if (POINTER_SET (ic))
3443 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3444 debugLog (" marking as a pointer (set) =>");
3445 debugAopGet (" result:", IC_RESULT (ic));
3447 if (POINTER_GET (ic))
3449 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3450 debugLog (" marking as a pointer (get) =>");
3451 debugAopGet (" left:", IC_LEFT (ic));
3456 /* if we are using a symbol on the stack
3457 then we should say pic14_ptrRegReq */
3458 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3459 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3460 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3461 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3462 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3463 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3466 if (IS_SYMOP (IC_LEFT (ic)))
3467 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3468 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3469 if (IS_SYMOP (IC_RIGHT (ic)))
3470 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3471 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3472 if (IS_SYMOP (IC_RESULT (ic)))
3473 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3474 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3477 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3481 /* if the condition of an if instruction
3482 is defined in the previous instruction then
3483 mark the itemp as a conditional */
3484 if ((IS_CONDITIONAL (ic) ||
3485 ((ic->op == BITWISEAND ||
3488 isBitwiseOptimizable (ic))) &&
3489 ic->next && ic->next->op == IFX &&
3490 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3491 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3494 debugLog (" %d\n", __LINE__);
3495 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3499 /* reduce for support function calls */
3500 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3501 packRegsForSupport (ic, ebp);
3503 /* if a parameter is passed, it's in W, so we may not
3504 need to place a copy in a register */
3505 if (ic->op == RECEIVE)
3506 packForReceive (ic, ebp);
3508 /* some cases the redundant moves can
3509 can be eliminated for return statements */
3510 if ((ic->op == RETURN || ic->op == SEND) &&
3511 !isOperandInFarSpace (IC_LEFT (ic)) &&
3513 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3515 /* if pointer set & left has a size more than
3516 one and right is not in far space */
3517 if (POINTER_SET (ic) &&
3518 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3519 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3520 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3521 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3523 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3525 /* if pointer get */
3526 if (POINTER_GET (ic) &&
3527 !isOperandInFarSpace (IC_RESULT (ic)) &&
3528 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3529 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3530 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3532 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3535 /* if this is cast for intergral promotion then
3536 check if only use of the definition of the
3537 operand being casted/ if yes then replace
3538 the result of that arithmetic operation with
3539 this result and get rid of the cast */
3540 if (ic->op == CAST) {
3542 sym_link *fromType = operandType (IC_RIGHT (ic));
3543 sym_link *toType = operandType (IC_LEFT (ic));
3545 debugLog (" %d - casting\n", __LINE__);
3547 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3548 getSize (fromType) != getSize (toType)) {
3551 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3554 if (IS_ARITHMETIC_OP (dic)) {
3556 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3557 IC_RESULT (dic) = IC_RESULT (ic);
3558 remiCodeFromeBBlock (ebp, ic);
3559 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3560 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3561 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3565 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3569 /* if the type from and type to are the same
3570 then if this is the only use then packit */
3571 if (compareType (operandType (IC_RIGHT (ic)),
3572 operandType (IC_LEFT (ic))) == 1) {
3574 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3577 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3578 IC_RESULT (dic) = IC_RESULT (ic);
3579 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3580 remiCodeFromeBBlock (ebp, ic);
3581 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3582 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3590 iTempNN := (some variable in farspace) V1
3595 if (ic->op == IPUSH)
3597 packForPush (ic, ebp);
3601 /* pack registers for accumulator use, when the
3602 result of an arithmetic or bit wise operation
3603 has only one use, that use is immediately following
3604 the defintion and the using iCode has only one
3605 operand or has two operands but one is literal &
3606 the result of that operation is not on stack then
3607 we can leave the result of this operation in acc:b
3609 if ((IS_ARITHMETIC_OP (ic)
3611 || IS_BITWISE_OP (ic)
3613 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3616 IS_ITEMP (IC_RESULT (ic)) &&
3617 getSize (operandType (IC_RESULT (ic))) <= 2)
3619 packRegsForAccUse (ic);
3625 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3629 if (!debug || !debugF)
3632 for (i = 0; i < count; i++)
3634 fprintf (debugF, "\n----------------------------------------------------------------\n");
3635 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3636 ebbs[i]->entryLabel->name,
3639 ebbs[i]->isLastInLoop);
3640 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3645 fprintf (debugF, "visited %d : hasFcall = %d\n",
3649 fprintf (debugF, "\ndefines bitVector :");
3650 bitVectDebugOn (ebbs[i]->defSet, debugF);
3651 fprintf (debugF, "\nlocal defines bitVector :");
3652 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3653 fprintf (debugF, "\npointers Set bitvector :");
3654 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3655 fprintf (debugF, "\nin pointers Set bitvector :");
3656 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3657 fprintf (debugF, "\ninDefs Set bitvector :");
3658 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3659 fprintf (debugF, "\noutDefs Set bitvector :");
3660 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3661 fprintf (debugF, "\nusesDefs Set bitvector :");
3662 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3663 fprintf (debugF, "\n----------------------------------------------------------------\n");
3664 printiCChain (ebbs[i]->sch, debugF);
3667 /*-----------------------------------------------------------------*/
3668 /* assignRegisters - assigns registers to each live range as need */
3669 /*-----------------------------------------------------------------*/
3671 pic14_assignRegisters (eBBlock ** ebbs, int count)
3676 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3677 debugLog ("\nebbs before optimizing:\n");
3678 dumpEbbsToDebug (ebbs, count);
3680 setToNull ((void *) &_G.funcrUsed);
3681 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3684 /* change assignments this will remove some
3685 live ranges reducing some register pressure */
3686 for (i = 0; i < count; i++)
3687 packRegisters (ebbs[i]);
3694 debugLog("dir registers allocated so far:\n");
3695 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3698 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3699 reg = hTabNextItem(dynDirectRegNames, &hkey);
3704 if (options.dump_pack)
3705 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3707 /* first determine for each live range the number of
3708 registers & the type of registers required for each */
3711 /* and serially allocate registers */
3712 serialRegAssign (ebbs, count);
3714 /* if stack was extended then tell the user */
3717 /* werror(W_TOOMANY_SPILS,"stack", */
3718 /* _G.stackExtend,currFunc->name,""); */
3724 /* werror(W_TOOMANY_SPILS,"data space", */
3725 /* _G.dataExtend,currFunc->name,""); */
3729 /* after that create the register mask
3730 for each of the instruction */
3731 createRegMask (ebbs, count);
3733 /* redo that offsets for stacked automatic variables */
3734 redoStackOffsets ();
3736 if (options.dump_rassgn)
3737 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3739 /* now get back the chain */
3740 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3742 debugLog ("ebbs after optimizing:\n");
3743 dumpEbbsToDebug (ebbs, count);
3748 /* free up any _G.stackSpil locations allocated */
3749 applyToSet (_G.stackSpil, deallocStackSpil);
3751 setToNull ((void **) &_G.stackSpil);
3752 setToNull ((void **) &_G.spiltSet);
3753 /* mark all registers as free */
3754 pic14_freeAllRegs ();
3756 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");