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 /*-----------------------------------------------------------------*/
579 /* allocDirReg - allocates register of given type */
580 /*-----------------------------------------------------------------*/
582 allocDirReg (operand *op )
589 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
593 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
595 /* If the symbol is at a fixed address, then remove the leading underscore
596 * from the name. This is hack to allow the .asm include file named registers
597 * to match the .c declared register names */
599 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
602 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
604 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
605 debugLog(" %d const char\n",__LINE__);
606 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
609 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
610 if (IS_CODE ( OP_SYM_ETYPE(op)) )
611 debugLog(" %d code space\n",__LINE__);
613 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
614 debugLog(" %d integral\n",__LINE__);
615 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
616 debugLog(" %d literal\n",__LINE__);
617 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
618 debugLog(" %d specifier\n",__LINE__);
619 debugAopGet(NULL, op);
622 if (IS_CODE ( OP_SYM_ETYPE(op)) )
625 /* First, search the hash table to see if there is a register with this name */
626 reg = dirregWithName(name);
630 /* Register wasn't found in hash, so let's create
631 * a new one and put it in the hash table AND in the
632 * dynDirectRegNames set */
634 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
635 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
637 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
639 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
640 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
643 hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
644 if (IS_BITVAR (OP_SYM_ETYPE(op)))
645 addSet(&dynDirectBitRegs, reg);
647 addSet(&dynDirectRegs, reg);
653 /*-----------------------------------------------------------------*/
654 /* allocDirReg - allocates register of given type */
655 /*-----------------------------------------------------------------*/
657 allocRegByName (char *name, int size)
663 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
667 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
669 /* First, search the hash table to see if there is a register with this name */
670 reg = dirregWithName(name);
674 /* Register wasn't found in hash, so let's create
675 * a new one and put it in the hash table AND in the
676 * dynDirectRegNames set */
678 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
680 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
682 hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
683 addSet(&dynDirectRegs, reg);
689 /*-----------------------------------------------------------------*/
690 /* RegWithIdx - returns pointer to register with index number */
691 /*-----------------------------------------------------------------*/
693 typeRegWithIdx (int idx, int type, int fixed)
698 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
700 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
702 debugLog ("Found a Dynamic Register!\n");
706 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
707 debugLog ("Found a Stack Register!\n");
711 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
712 debugLog ("Found a Direct Register!\n");
716 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
717 debugLog ("Found a Processor Register!\n");
721 if( (dReg = regWithIdx ( dynDirectBitRegs, idx, fixed)) != NULL ) {
722 debugLog ("Found a bit Register!\n");
727 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
728 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
729 "regWithIdx not found");
735 /*-----------------------------------------------------------------*/
736 /* pic14_regWithIdx - returns pointer to register with index number*/
737 /*-----------------------------------------------------------------*/
739 pic14_regWithIdx (int idx)
742 return typeRegWithIdx(idx,-1,0);
745 /*-----------------------------------------------------------------*/
746 /* pic14_regWithIdx - returns pointer to register with index number */
747 /*-----------------------------------------------------------------*/
749 pic14_allocWithIdx (int idx)
754 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
756 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
758 debugLog ("Found a Dynamic Register!\n");
759 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
760 debugLog ("Found a Stack Register!\n");
761 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
762 debugLog ("Found a Processor Register!\n");
763 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
764 debugLog ("Found an Internal Register!\n");
767 debugLog ("Dynamic Register not found\n");
770 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
771 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
772 "regWithIdx not found");
782 /*-----------------------------------------------------------------*/
783 /*-----------------------------------------------------------------*/
785 pic14_findFreeReg(short type)
792 if((dReg = regFindFree(dynAllocRegs)) != NULL)
795 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
799 if((dReg = regFindFree(dynStackRegs)) != NULL)
811 /*-----------------------------------------------------------------*/
812 /* freeReg - frees a register */
813 /*-----------------------------------------------------------------*/
817 debugLog ("%s\n", __FUNCTION__);
822 /*-----------------------------------------------------------------*/
823 /* nFreeRegs - returns number of free registers */
824 /*-----------------------------------------------------------------*/
828 /* dynamically allocate as many as we need and worry about
829 * fitting them into a PIC later */
836 debugLog ("%s\n", __FUNCTION__);
837 for (i = 0; i < pic14_nRegs; i++)
838 if (regspic14[i].isFree && regspic14[i].type == type)
844 /*-----------------------------------------------------------------*/
845 /* nfreeRegsType - free registers with type */
846 /*-----------------------------------------------------------------*/
848 nfreeRegsType (int type)
851 debugLog ("%s\n", __FUNCTION__);
854 if ((nfr = nFreeRegs (type)) == 0)
855 return nFreeRegs (REG_GPR);
858 return nFreeRegs (type);
862 void writeSetUsedRegs(FILE *of, set *dRegs)
867 for (dReg = setFirstItem(dRegs) ; dReg ;
868 dReg = setNextItem(dRegs)) {
871 fprintf (of, "\t%s\n",dReg->name);
875 extern void assignFixedRegisters(set *regset);
876 extern void assignRelocatableRegisters(set *regset,int used);
877 extern void dump_map(void);
878 extern void dump_cblock(FILE *of);
881 void packBits(set *bregs)
886 regs *relocbitfield=NULL;
891 for (regset = bregs ; regset ;
892 regset = regset->next) {
895 breg->isBitField = 1;
896 //fprintf(stderr,"bit reg: %s\n",breg->name);
899 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
901 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
902 breg->rIdx = breg->address & 7;
906 sprintf (buffer, "fbitfield%02x", breg->address);
907 //fprintf(stderr,"new bit field\n");
908 bitfield = newReg(REG_GPR, PO_GPR_BIT,breg->address,buffer,1,0);
909 bitfield->isBitField = 1;
910 bitfield->isFixed = 1;
911 bitfield->address = breg->address;
912 addSet(&dynDirectRegs,bitfield);
913 hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
915 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
918 breg->reg_alias = bitfield;
922 if(!relocbitfield || bit_no >7) {
925 sprintf (buffer, "bitfield%d", byte_no);
926 //fprintf(stderr,"new relocatable bit field\n");
927 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
928 relocbitfield->isBitField = 1;
929 addSet(&dynDirectRegs,relocbitfield);
930 hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
934 breg->reg_alias = relocbitfield;
935 breg->address = rDirectIdx; /* byte_no; */
936 breg->rIdx = bit_no++;
944 void bitEQUs(FILE *of, set *bregs)
949 //fprintf(stderr," %s\n",__FUNCTION__);
950 for (breg = setFirstItem(bregs) ; breg ;
951 breg = setNextItem(bregs)) {
953 //fprintf(stderr,"bit reg: %s\n",breg->name);
955 bytereg = breg->reg_alias;
957 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
960 breg->rIdx & 0x0007);
963 fprintf(stderr, "bit field is not assigned to a register\n");
964 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
974 void aliasEQUs(FILE *of, set *fregs)
979 for (reg = setFirstItem(fregs) ; reg ;
980 reg = setNextItem(fregs)) {
983 fprintf (of, "%s\tEQU\t0x%03x\n",
990 void writeUsedRegs(FILE *of)
992 packBits(dynDirectBitRegs);
994 assignFixedRegisters(dynAllocRegs);
995 assignFixedRegisters(dynStackRegs);
996 assignFixedRegisters(dynDirectRegs);
998 assignRelocatableRegisters(dynInternalRegs,1);
999 assignRelocatableRegisters(dynAllocRegs,0);
1000 assignRelocatableRegisters(dynStackRegs,0);
1001 assignRelocatableRegisters(dynDirectRegs,0);
1006 bitEQUs(of,dynDirectBitRegs);
1007 aliasEQUs(of,dynAllocRegs);
1008 aliasEQUs(of,dynDirectRegs);
1009 aliasEQUs(of,dynStackRegs);
1013 /*-----------------------------------------------------------------*/
1014 /* allDefsOutOfRange - all definitions are out of a range */
1015 /*-----------------------------------------------------------------*/
1017 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1021 debugLog ("%s\n", __FUNCTION__);
1025 for (i = 0; i < defs->size; i++)
1029 if (bitVectBitValue (defs, i) &&
1030 (ic = hTabItemWithKey (iCodehTab, i)) &&
1031 (ic->seq >= fseq && ic->seq <= toseq))
1042 /*-----------------------------------------------------------------*/
1043 /* computeSpillable - given a point find the spillable live ranges */
1044 /*-----------------------------------------------------------------*/
1046 computeSpillable (iCode * ic)
1050 debugLog ("%s\n", __FUNCTION__);
1051 /* spillable live ranges are those that are live at this
1052 point . the following categories need to be subtracted
1054 a) - those that are already spilt
1055 b) - if being used by this one
1056 c) - defined by this one */
1058 spillable = bitVectCopy (ic->rlive);
1060 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1062 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1063 bitVectUnSetBit (spillable, ic->defKey);
1064 spillable = bitVectIntersect (spillable, _G.regAssigned);
1069 /*-----------------------------------------------------------------*/
1070 /* noSpilLoc - return true if a variable has no spil location */
1071 /*-----------------------------------------------------------------*/
1073 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1075 debugLog ("%s\n", __FUNCTION__);
1076 return (sym->usl.spillLoc ? 0 : 1);
1079 /*-----------------------------------------------------------------*/
1080 /* hasSpilLoc - will return 1 if the symbol has spil location */
1081 /*-----------------------------------------------------------------*/
1083 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1085 debugLog ("%s\n", __FUNCTION__);
1086 return (sym->usl.spillLoc ? 1 : 0);
1089 /*-----------------------------------------------------------------*/
1090 /* directSpilLoc - will return 1 if the splilocation is in direct */
1091 /*-----------------------------------------------------------------*/
1093 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1095 debugLog ("%s\n", __FUNCTION__);
1096 if (sym->usl.spillLoc &&
1097 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1103 /*-----------------------------------------------------------------*/
1104 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1105 /* but is not used as a pointer */
1106 /*-----------------------------------------------------------------*/
1108 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1110 debugLog ("%s\n", __FUNCTION__);
1111 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1114 /*-----------------------------------------------------------------*/
1115 /* rematable - will return 1 if the remat flag is set */
1116 /*-----------------------------------------------------------------*/
1118 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1120 debugLog ("%s\n", __FUNCTION__);
1124 /*-----------------------------------------------------------------*/
1125 /* notUsedInRemaining - not used or defined in remain of the block */
1126 /*-----------------------------------------------------------------*/
1128 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1130 debugLog ("%s\n", __FUNCTION__);
1131 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1132 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1135 /*-----------------------------------------------------------------*/
1136 /* allLRs - return true for all */
1137 /*-----------------------------------------------------------------*/
1139 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1141 debugLog ("%s\n", __FUNCTION__);
1145 /*-----------------------------------------------------------------*/
1146 /* liveRangesWith - applies function to a given set of live range */
1147 /*-----------------------------------------------------------------*/
1149 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1150 eBBlock * ebp, iCode * ic)
1155 debugLog ("%s\n", __FUNCTION__);
1156 if (!lrs || !lrs->size)
1159 for (i = 1; i < lrs->size; i++)
1162 if (!bitVectBitValue (lrs, i))
1165 /* if we don't find it in the live range
1166 hash table we are in serious trouble */
1167 if (!(sym = hTabItemWithKey (liveRanges, i)))
1169 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1170 "liveRangesWith could not find liveRange");
1174 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1175 addSetHead (&rset, sym);
1182 /*-----------------------------------------------------------------*/
1183 /* leastUsedLR - given a set determines which is the least used */
1184 /*-----------------------------------------------------------------*/
1186 leastUsedLR (set * sset)
1188 symbol *sym = NULL, *lsym = NULL;
1190 debugLog ("%s\n", __FUNCTION__);
1191 sym = lsym = setFirstItem (sset);
1196 for (; lsym; lsym = setNextItem (sset))
1199 /* if usage is the same then prefer
1200 the spill the smaller of the two */
1201 if (lsym->used == sym->used)
1202 if (getSize (lsym->type) < getSize (sym->type))
1206 if (lsym->used < sym->used)
1211 setToNull ((void **) &sset);
1216 /*-----------------------------------------------------------------*/
1217 /* noOverLap - will iterate through the list looking for over lap */
1218 /*-----------------------------------------------------------------*/
1220 noOverLap (set * itmpStack, symbol * fsym)
1223 debugLog ("%s\n", __FUNCTION__);
1226 for (sym = setFirstItem (itmpStack); sym;
1227 sym = setNextItem (itmpStack))
1229 if (sym->liveTo > fsym->liveFrom)
1237 /*-----------------------------------------------------------------*/
1238 /* isFree - will return 1 if the a free spil location is found */
1239 /*-----------------------------------------------------------------*/
1244 V_ARG (symbol **, sloc);
1245 V_ARG (symbol *, fsym);
1247 debugLog ("%s\n", __FUNCTION__);
1248 /* if already found */
1252 /* if it is free && and the itmp assigned to
1253 this does not have any overlapping live ranges
1254 with the one currently being assigned and
1255 the size can be accomodated */
1257 noOverLap (sym->usl.itmpStack, fsym) &&
1258 getSize (sym->type) >= getSize (fsym->type))
1267 /*-----------------------------------------------------------------*/
1268 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1269 /*-----------------------------------------------------------------*/
1271 spillLRWithPtrReg (symbol * forSym)
1277 debugLog ("%s\n", __FUNCTION__);
1278 if (!_G.regAssigned ||
1279 bitVectIsZero (_G.regAssigned))
1282 r0 = pic14_regWithIdx (R0_IDX);
1283 r1 = pic14_regWithIdx (R1_IDX);
1285 /* for all live ranges */
1286 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1287 lrsym = hTabNextItem (liveRanges, &k))
1291 /* if no registers assigned to it or
1293 /* if it does not overlap with this then
1294 not need to spill it */
1296 if (lrsym->isspilt || !lrsym->nRegs ||
1297 (lrsym->liveTo < forSym->liveFrom))
1300 /* go thru the registers : if it is either
1301 r0 or r1 then spil it */
1302 for (j = 0; j < lrsym->nRegs; j++)
1303 if (lrsym->regs[j] == r0 ||
1304 lrsym->regs[j] == r1)
1313 /*-----------------------------------------------------------------*/
1314 /* createStackSpil - create a location on the stack to spil */
1315 /*-----------------------------------------------------------------*/
1317 createStackSpil (symbol * sym)
1319 symbol *sloc = NULL;
1320 int useXstack, model, noOverlay;
1322 char slocBuffer[30];
1323 debugLog ("%s\n", __FUNCTION__);
1325 /* first go try and find a free one that is already
1326 existing on the stack */
1327 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1329 /* found a free one : just update & return */
1330 sym->usl.spillLoc = sloc;
1333 addSetHead (&sloc->usl.itmpStack, sym);
1337 /* could not then have to create one , this is the hard part
1338 we need to allocate this on the stack : this is really a
1339 hack!! but cannot think of anything better at this time */
1341 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1343 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1344 __FILE__, __LINE__);
1348 sloc = newiTemp (slocBuffer);
1350 /* set the type to the spilling symbol */
1351 sloc->type = copyLinkChain (sym->type);
1352 sloc->etype = getSpec (sloc->type);
1353 SPEC_SCLS (sloc->etype) = S_DATA;
1354 SPEC_EXTR (sloc->etype) = 0;
1355 SPEC_STAT (sloc->etype) = 0;
1357 /* we don't allow it to be allocated`
1358 onto the external stack since : so we
1359 temporarily turn it off ; we also
1360 turn off memory model to prevent
1361 the spil from going to the external storage
1362 and turn off overlaying
1365 useXstack = options.useXstack;
1366 model = options.model;
1367 noOverlay = options.noOverlay;
1368 options.noOverlay = 1;
1369 options.model = options.useXstack = 0;
1373 options.useXstack = useXstack;
1374 options.model = model;
1375 options.noOverlay = noOverlay;
1376 sloc->isref = 1; /* to prevent compiler warning */
1378 /* if it is on the stack then update the stack */
1379 if (IN_STACK (sloc->etype))
1381 currFunc->stack += getSize (sloc->type);
1382 _G.stackExtend += getSize (sloc->type);
1385 _G.dataExtend += getSize (sloc->type);
1387 /* add it to the _G.stackSpil set */
1388 addSetHead (&_G.stackSpil, sloc);
1389 sym->usl.spillLoc = sloc;
1392 /* add it to the set of itempStack set
1393 of the spill location */
1394 addSetHead (&sloc->usl.itmpStack, sym);
1398 /*-----------------------------------------------------------------*/
1399 /* isSpiltOnStack - returns true if the spil location is on stack */
1400 /*-----------------------------------------------------------------*/
1402 isSpiltOnStack (symbol * sym)
1406 debugLog ("%s\n", __FUNCTION__);
1413 /* if (sym->_G.stackSpil) */
1416 if (!sym->usl.spillLoc)
1419 etype = getSpec (sym->usl.spillLoc->type);
1420 if (IN_STACK (etype))
1426 /*-----------------------------------------------------------------*/
1427 /* spillThis - spils a specific operand */
1428 /*-----------------------------------------------------------------*/
1430 spillThis (symbol * sym)
1433 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1435 /* if this is rematerializable or has a spillLocation
1436 we are okay, else we need to create a spillLocation
1438 if (!(sym->remat || sym->usl.spillLoc))
1439 createStackSpil (sym);
1442 /* mark it has spilt & put it in the spilt set */
1444 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1446 bitVectUnSetBit (_G.regAssigned, sym->key);
1448 for (i = 0; i < sym->nRegs; i++)
1452 freeReg (sym->regs[i]);
1453 sym->regs[i] = NULL;
1456 /* if spilt on stack then free up r0 & r1
1457 if they could have been assigned to some
1459 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1462 spillLRWithPtrReg (sym);
1465 if (sym->usl.spillLoc && !sym->remat)
1466 sym->usl.spillLoc->allocreq = 1;
1470 /*-----------------------------------------------------------------*/
1471 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1472 /*-----------------------------------------------------------------*/
1474 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1476 bitVect *lrcs = NULL;
1480 debugLog ("%s\n", __FUNCTION__);
1481 /* get the spillable live ranges */
1482 lrcs = computeSpillable (ic);
1484 /* get all live ranges that are rematerizable */
1485 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1488 /* return the least used of these */
1489 return leastUsedLR (selectS);
1492 /* get live ranges with spillLocations in direct space */
1493 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1495 sym = leastUsedLR (selectS);
1496 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1497 sym->usl.spillLoc->rname :
1498 sym->usl.spillLoc->name));
1500 /* mark it as allocation required */
1501 sym->usl.spillLoc->allocreq = 1;
1505 /* if the symbol is local to the block then */
1506 if (forSym->liveTo < ebp->lSeq)
1509 /* check if there are any live ranges allocated
1510 to registers that are not used in this block */
1511 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1513 sym = leastUsedLR (selectS);
1514 /* if this is not rematerializable */
1523 /* check if there are any live ranges that not
1524 used in the remainder of the block */
1525 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1527 sym = leastUsedLR (selectS);
1530 sym->remainSpil = 1;
1537 /* find live ranges with spillocation && not used as pointers */
1538 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1541 sym = leastUsedLR (selectS);
1542 /* mark this as allocation required */
1543 sym->usl.spillLoc->allocreq = 1;
1547 /* find live ranges with spillocation */
1548 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1551 sym = leastUsedLR (selectS);
1552 sym->usl.spillLoc->allocreq = 1;
1556 /* couldn't find then we need to create a spil
1557 location on the stack , for which one? the least
1559 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1562 /* return a created spil location */
1563 sym = createStackSpil (leastUsedLR (selectS));
1564 sym->usl.spillLoc->allocreq = 1;
1568 /* this is an extreme situation we will spill
1569 this one : happens very rarely but it does happen */
1575 /*-----------------------------------------------------------------*/
1576 /* spilSomething - spil some variable & mark registers as free */
1577 /*-----------------------------------------------------------------*/
1579 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1584 debugLog ("%s\n", __FUNCTION__);
1585 /* get something we can spil */
1586 ssym = selectSpil (ic, ebp, forSym);
1588 /* mark it as spilt */
1590 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1592 /* mark it as not register assigned &
1593 take it away from the set */
1594 bitVectUnSetBit (_G.regAssigned, ssym->key);
1596 /* mark the registers as free */
1597 for (i = 0; i < ssym->nRegs; i++)
1599 freeReg (ssym->regs[i]);
1601 /* if spilt on stack then free up r0 & r1
1602 if they could have been assigned to as gprs */
1603 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1606 spillLRWithPtrReg (ssym);
1609 /* if this was a block level spil then insert push & pop
1610 at the start & end of block respectively */
1611 if (ssym->blockSpil)
1613 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1614 /* add push to the start of the block */
1615 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1616 ebp->sch->next : ebp->sch));
1617 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1618 /* add pop to the end of the block */
1619 addiCodeToeBBlock (ebp, nic, NULL);
1622 /* if spilt because not used in the remainder of the
1623 block then add a push before this instruction and
1624 a pop at the end of the block */
1625 if (ssym->remainSpil)
1628 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1629 /* add push just before this instruction */
1630 addiCodeToeBBlock (ebp, nic, ic);
1632 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1633 /* add pop to the end of the block */
1634 addiCodeToeBBlock (ebp, nic, NULL);
1643 /*-----------------------------------------------------------------*/
1644 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1645 /*-----------------------------------------------------------------*/
1647 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1651 debugLog ("%s\n", __FUNCTION__);
1653 /* try for a ptr type */
1654 if ((reg = allocReg (REG_PTR)))
1657 /* try for gpr type */
1658 if ((reg = allocReg (REG_GPR)))
1661 /* we have to spil */
1662 if (!spilSomething (ic, ebp, sym))
1665 /* this looks like an infinite loop but
1666 in really selectSpil will abort */
1670 /*-----------------------------------------------------------------*/
1671 /* getRegGpr - will try for GPR if not spil */
1672 /*-----------------------------------------------------------------*/
1674 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1678 debugLog ("%s\n", __FUNCTION__);
1680 /* try for gpr type */
1681 if ((reg = allocReg (REG_GPR)))
1684 if (!pic14_ptrRegReq)
1685 if ((reg = allocReg (REG_PTR)))
1688 /* we have to spil */
1689 if (!spilSomething (ic, ebp, sym))
1692 /* this looks like an infinite loop but
1693 in really selectSpil will abort */
1697 /*-----------------------------------------------------------------*/
1698 /* symHasReg - symbol has a given register */
1699 /*-----------------------------------------------------------------*/
1701 symHasReg (symbol * sym, regs * reg)
1705 debugLog ("%s\n", __FUNCTION__);
1706 for (i = 0; i < sym->nRegs; i++)
1707 if (sym->regs[i] == reg)
1713 /*-----------------------------------------------------------------*/
1714 /* deassignLRs - check the live to and if they have registers & are */
1715 /* not spilt then free up the registers */
1716 /*-----------------------------------------------------------------*/
1718 deassignLRs (iCode * ic, eBBlock * ebp)
1724 debugLog ("%s\n", __FUNCTION__);
1725 for (sym = hTabFirstItem (liveRanges, &k); sym;
1726 sym = hTabNextItem (liveRanges, &k))
1729 symbol *psym = NULL;
1730 /* if it does not end here */
1731 if (sym->liveTo > ic->seq)
1734 /* if it was spilt on stack then we can
1735 mark the stack spil location as free */
1740 sym->usl.spillLoc->isFree = 1;
1746 if (!bitVectBitValue (_G.regAssigned, sym->key))
1749 /* special case check if this is an IFX &
1750 the privious one was a pop and the
1751 previous one was not spilt then keep track
1753 if (ic->op == IFX && ic->prev &&
1754 ic->prev->op == IPOP &&
1755 !ic->prev->parmPush &&
1756 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1757 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1763 bitVectUnSetBit (_G.regAssigned, sym->key);
1765 /* if the result of this one needs registers
1766 and does not have it then assign it right
1768 if (IC_RESULT (ic) &&
1769 !(SKIP_IC2 (ic) || /* not a special icode */
1770 ic->op == JUMPTABLE ||
1775 POINTER_SET (ic)) &&
1776 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1777 result->liveTo > ic->seq && /* and will live beyond this */
1778 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1779 result->regType == sym->regType && /* same register types */
1780 result->nRegs && /* which needs registers */
1781 !result->isspilt && /* and does not already have them */
1783 !bitVectBitValue (_G.regAssigned, result->key) &&
1784 /* the number of free regs + number of regs in this LR
1785 can accomodate the what result Needs */
1786 ((nfreeRegsType (result->regType) +
1787 sym->nRegs) >= result->nRegs)
1791 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1793 result->regs[i] = sym->regs[i];
1795 result->regs[i] = getRegGpr (ic, ebp, result);
1797 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1801 /* free the remaining */
1802 for (; i < sym->nRegs; i++)
1806 if (!symHasReg (psym, sym->regs[i]))
1807 freeReg (sym->regs[i]);
1810 freeReg (sym->regs[i]);
1817 /*-----------------------------------------------------------------*/
1818 /* reassignLR - reassign this to registers */
1819 /*-----------------------------------------------------------------*/
1821 reassignLR (operand * op)
1823 symbol *sym = OP_SYMBOL (op);
1826 debugLog ("%s\n", __FUNCTION__);
1827 /* not spilt any more */
1828 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1829 bitVectUnSetBit (_G.spiltSet, sym->key);
1831 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1835 for (i = 0; i < sym->nRegs; i++)
1836 sym->regs[i]->isFree = 0;
1839 /*-----------------------------------------------------------------*/
1840 /* willCauseSpill - determines if allocating will cause a spill */
1841 /*-----------------------------------------------------------------*/
1843 willCauseSpill (int nr, int rt)
1845 debugLog ("%s\n", __FUNCTION__);
1846 /* first check if there are any avlb registers
1847 of te type required */
1850 /* special case for pointer type
1851 if pointer type not avlb then
1852 check for type gpr */
1853 if (nFreeRegs (rt) >= nr)
1855 if (nFreeRegs (REG_GPR) >= nr)
1860 if (pic14_ptrRegReq)
1862 if (nFreeRegs (rt) >= nr)
1867 if (nFreeRegs (REG_PTR) +
1868 nFreeRegs (REG_GPR) >= nr)
1873 debugLog (" ... yep it will (cause a spill)\n");
1874 /* it will cause a spil */
1878 /*-----------------------------------------------------------------*/
1879 /* positionRegs - the allocator can allocate same registers to res- */
1880 /* ult and operand, if this happens make sure they are in the same */
1881 /* position as the operand otherwise chaos results */
1882 /*-----------------------------------------------------------------*/
1884 positionRegs (symbol * result, symbol * opsym, int lineno)
1886 int count = min (result->nRegs, opsym->nRegs);
1887 int i, j = 0, shared = 0;
1889 debugLog ("%s\n", __FUNCTION__);
1890 /* if the result has been spilt then cannot share */
1895 /* first make sure that they actually share */
1896 for (i = 0; i < count; i++)
1898 for (j = 0; j < count; j++)
1900 if (result->regs[i] == opsym->regs[j] && i != j)
1910 regs *tmp = result->regs[i];
1911 result->regs[i] = result->regs[j];
1912 result->regs[j] = tmp;
1917 /*-----------------------------------------------------------------*/
1918 /* serialRegAssign - serially allocate registers to the variables */
1919 /*-----------------------------------------------------------------*/
1921 serialRegAssign (eBBlock ** ebbs, int count)
1925 debugLog ("%s\n", __FUNCTION__);
1926 /* for all blocks */
1927 for (i = 0; i < count; i++)
1932 if (ebbs[i]->noPath &&
1933 (ebbs[i]->entryLabel != entryLabel &&
1934 ebbs[i]->entryLabel != returnLabel))
1937 /* of all instructions do */
1938 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1941 debugLog (" op: %s\n", decodeOp (ic->op));
1943 /* if this is an ipop that means some live
1944 range will have to be assigned again */
1946 reassignLR (IC_LEFT (ic));
1948 /* if result is present && is a true symbol */
1949 if (IC_RESULT (ic) && ic->op != IFX &&
1950 IS_TRUE_SYMOP (IC_RESULT (ic)))
1951 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1953 /* take away registers from live
1954 ranges that end at this instruction */
1955 deassignLRs (ic, ebbs[i]);
1957 /* some don't need registers */
1958 if (SKIP_IC2 (ic) ||
1959 ic->op == JUMPTABLE ||
1963 (IC_RESULT (ic) && POINTER_SET (ic)))
1966 /* now we need to allocate registers
1967 only for the result */
1970 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1976 /* if it does not need or is spilt
1977 or is already assigned to registers
1978 or will not live beyond this instructions */
1981 bitVectBitValue (_G.regAssigned, sym->key) ||
1982 sym->liveTo <= ic->seq)
1985 /* if some liverange has been spilt at the block level
1986 and this one live beyond this block then spil this
1988 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1993 /* if trying to allocate this will cause
1994 a spill and there is nothing to spill
1995 or this one is rematerializable then
1997 willCS = willCauseSpill (sym->nRegs, sym->regType);
1998 spillable = computeSpillable (ic);
2000 (willCS && bitVectIsZero (spillable)))
2008 /* if it has a spillocation & is used less than
2009 all other live ranges then spill this */
2011 if (sym->usl.spillLoc) {
2012 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2013 allLRs, ebbs[i], ic));
2014 if (leastUsed && leastUsed->used > sym->used) {
2019 /* if none of the liveRanges have a spillLocation then better
2020 to spill this one than anything else already assigned to registers */
2021 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2022 /* if this is local to this block then we might find a block spil */
2023 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2031 if (ic->op == RECEIVE)
2032 debugLog ("When I get clever, I'll optimize the receive logic\n");
2034 /* if we need ptr regs for the right side
2036 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2037 <= (unsigned) PTRSIZE)
2042 /* else we assign registers to it */
2043 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2045 debugLog (" %d - \n", __LINE__);
2047 bitVectDebugOn(_G.regAssigned, debugF);
2049 for (j = 0; j < sym->nRegs; j++)
2051 if (sym->regType == REG_PTR)
2052 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2054 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2056 /* if the allocation falied which means
2057 this was spilt then break */
2061 debugLog (" %d - \n", __LINE__);
2063 /* if it shares registers with operands make sure
2064 that they are in the same position */
2065 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2066 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2067 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2068 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2069 /* do the same for the right operand */
2070 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2071 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2072 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2073 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2075 debugLog (" %d - \n", __LINE__);
2078 debugLog (" %d - \n", __LINE__);
2088 /*-----------------------------------------------------------------*/
2089 /* rUmaskForOp :- returns register mask for an operand */
2090 /*-----------------------------------------------------------------*/
2092 rUmaskForOp (operand * op)
2098 debugLog ("%s\n", __FUNCTION__);
2099 /* only temporaries are assigned registers */
2103 sym = OP_SYMBOL (op);
2105 /* if spilt or no registers assigned to it
2107 if (sym->isspilt || !sym->nRegs)
2110 rumask = newBitVect (pic14_nRegs);
2112 for (j = 0; j < sym->nRegs; j++)
2114 rumask = bitVectSetBit (rumask,
2115 sym->regs[j]->rIdx);
2121 /*-----------------------------------------------------------------*/
2122 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2123 /*-----------------------------------------------------------------*/
2125 regsUsedIniCode (iCode * ic)
2127 bitVect *rmask = newBitVect (pic14_nRegs);
2129 debugLog ("%s\n", __FUNCTION__);
2130 /* do the special cases first */
2133 rmask = bitVectUnion (rmask,
2134 rUmaskForOp (IC_COND (ic)));
2138 /* for the jumptable */
2139 if (ic->op == JUMPTABLE)
2141 rmask = bitVectUnion (rmask,
2142 rUmaskForOp (IC_JTCOND (ic)));
2147 /* of all other cases */
2149 rmask = bitVectUnion (rmask,
2150 rUmaskForOp (IC_LEFT (ic)));
2154 rmask = bitVectUnion (rmask,
2155 rUmaskForOp (IC_RIGHT (ic)));
2158 rmask = bitVectUnion (rmask,
2159 rUmaskForOp (IC_RESULT (ic)));
2165 /*-----------------------------------------------------------------*/
2166 /* createRegMask - for each instruction will determine the regsUsed */
2167 /*-----------------------------------------------------------------*/
2169 createRegMask (eBBlock ** ebbs, int count)
2173 debugLog ("%s\n", __FUNCTION__);
2174 /* for all blocks */
2175 for (i = 0; i < count; i++)
2179 if (ebbs[i]->noPath &&
2180 (ebbs[i]->entryLabel != entryLabel &&
2181 ebbs[i]->entryLabel != returnLabel))
2184 /* for all instructions */
2185 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2190 if (SKIP_IC2 (ic) || !ic->rlive)
2193 /* first mark the registers used in this
2195 ic->rUsed = regsUsedIniCode (ic);
2196 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2198 /* now create the register mask for those
2199 registers that are in use : this is a
2200 super set of ic->rUsed */
2201 ic->rMask = newBitVect (pic14_nRegs + 1);
2203 /* for all live Ranges alive at this point */
2204 for (j = 1; j < ic->rlive->size; j++)
2209 /* if not alive then continue */
2210 if (!bitVectBitValue (ic->rlive, j))
2213 /* find the live range we are interested in */
2214 if (!(sym = hTabItemWithKey (liveRanges, j)))
2216 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2217 "createRegMask cannot find live range");
2221 /* if no register assigned to it */
2222 if (!sym->nRegs || sym->isspilt)
2225 /* for all the registers allocated to it */
2226 for (k = 0; k < sym->nRegs; k++)
2229 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2235 /*-----------------------------------------------------------------*/
2236 /* rematStr - returns the rematerialized string for a remat var */
2237 /*-----------------------------------------------------------------*/
2239 rematStr (symbol * sym)
2242 iCode *ic = sym->rematiCode;
2243 symbol *psym = NULL;
2245 debugLog ("%s\n", __FUNCTION__);
2249 /* if plus or minus print the right hand side */
2251 if (ic->op == '+' || ic->op == '-') {
2253 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2255 sprintf (s, "(%s %c 0x%04x)",
2256 OP_SYMBOL (IC_LEFT (ric))->rname,
2258 (int) operandLitValue (IC_RIGHT (ic)));
2261 fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2263 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2264 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2269 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2270 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2272 printf ("%s\n", buffer);
2277 /*-----------------------------------------------------------------*/
2278 /* rematStr - returns the rematerialized string for a remat var */
2279 /*-----------------------------------------------------------------*/
2281 rematStr (symbol * sym)
2284 iCode *ic = sym->rematiCode;
2286 debugLog ("%s\n", __FUNCTION__);
2291 /* if plus or minus print the right hand side */
2293 if (ic->op == '+' || ic->op == '-') {
2294 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2297 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2301 if (ic->op == '+' || ic->op == '-')
2303 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2304 sprintf (s, "(%s %c 0x%04x)",
2305 OP_SYMBOL (IC_LEFT (ric))->rname,
2307 (int) operandLitValue (IC_RIGHT (ic)));
2310 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2312 fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2316 /* we reached the end */
2317 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2321 printf ("%s\n", buffer);
2326 /*-----------------------------------------------------------------*/
2327 /* regTypeNum - computes the type & number of registers required */
2328 /*-----------------------------------------------------------------*/
2336 debugLog ("%s\n", __FUNCTION__);
2337 /* for each live range do */
2338 for (sym = hTabFirstItem (liveRanges, &k); sym;
2339 sym = hTabNextItem (liveRanges, &k)) {
2341 debugLog (" %d - %s\n", __LINE__, sym->rname);
2343 /* if used zero times then no registers needed */
2344 if ((sym->liveTo - sym->liveFrom) == 0)
2348 /* if the live range is a temporary */
2351 debugLog (" %d - itemp register\n", __LINE__);
2353 /* if the type is marked as a conditional */
2354 if (sym->regType == REG_CND)
2357 /* if used in return only then we don't
2359 if (sym->ruonly || sym->accuse) {
2360 if (IS_AGGREGATE (sym->type) || sym->isptr)
2361 sym->type = aggrToPtr (sym->type, FALSE);
2362 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2367 /* if the symbol has only one definition &
2368 that definition is a get_pointer and the
2369 pointer we are getting is rematerializable and
2372 if (bitVectnBitsOn (sym->defs) == 1 &&
2373 (ic = hTabItemWithKey (iCodehTab,
2374 bitVectFirstBit (sym->defs))) &&
2377 !IS_BITVAR (sym->etype)) {
2380 debugLog (" %d - \n", __LINE__);
2382 /* if remat in data space */
2383 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2384 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2386 /* create a psuedo symbol & force a spil */
2387 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2388 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2389 psym->type = sym->type;
2390 psym->etype = sym->etype;
2391 strcpy (psym->rname, psym->name);
2393 sym->usl.spillLoc = psym;
2397 /* if in data space or idata space then try to
2398 allocate pointer register */
2402 /* if not then we require registers */
2403 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2404 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2405 getSize (sym->type));
2408 if(IS_PTR_CONST (sym->type)) {
2409 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2413 if (sym->nRegs > 4) {
2414 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2415 printTypeChain (sym->type, stderr);
2416 fprintf (stderr, "\n");
2419 /* determine the type of register required */
2420 if (sym->nRegs == 1 &&
2421 IS_PTR (sym->type) &&
2423 sym->regType = REG_PTR;
2425 sym->regType = REG_GPR;
2428 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2432 /* for the first run we don't provide */
2433 /* registers for true symbols we will */
2434 /* see how things go */
2439 DEFSETFUNC (markRegFree)
2441 ((regs *)item)->isFree = 1;
2446 DEFSETFUNC (deallocReg)
2448 ((regs *)item)->isFree = 1;
2449 ((regs *)item)->wasUsed = 0;
2453 /*-----------------------------------------------------------------*/
2454 /* freeAllRegs - mark all registers as free */
2455 /*-----------------------------------------------------------------*/
2457 pic14_freeAllRegs ()
2461 debugLog ("%s\n", __FUNCTION__);
2463 applyToSet(dynAllocRegs,markRegFree);
2464 applyToSet(dynStackRegs,markRegFree);
2467 for (i = 0; i < pic14_nRegs; i++)
2468 regspic14[i].isFree = 1;
2472 /*-----------------------------------------------------------------*/
2473 /*-----------------------------------------------------------------*/
2475 pic14_deallocateAllRegs ()
2479 debugLog ("%s\n", __FUNCTION__);
2481 applyToSet(dynAllocRegs,deallocReg);
2484 for (i = 0; i < pic14_nRegs; i++) {
2485 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2486 regspic14[i].isFree = 1;
2487 regspic14[i].wasUsed = 0;
2494 /*-----------------------------------------------------------------*/
2495 /* deallocStackSpil - this will set the stack pointer back */
2496 /*-----------------------------------------------------------------*/
2498 DEFSETFUNC (deallocStackSpil)
2502 debugLog ("%s\n", __FUNCTION__);
2507 /*-----------------------------------------------------------------*/
2508 /* farSpacePackable - returns the packable icode for far variables */
2509 /*-----------------------------------------------------------------*/
2511 farSpacePackable (iCode * ic)
2515 debugLog ("%s\n", __FUNCTION__);
2516 /* go thru till we find a definition for the
2517 symbol on the right */
2518 for (dic = ic->prev; dic; dic = dic->prev)
2521 /* if the definition is a call then no */
2522 if ((dic->op == CALL || dic->op == PCALL) &&
2523 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2528 /* if shift by unknown amount then not */
2529 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2530 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2533 /* if pointer get and size > 1 */
2534 if (POINTER_GET (dic) &&
2535 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2538 if (POINTER_SET (dic) &&
2539 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2542 /* if any three is a true symbol in far space */
2543 if (IC_RESULT (dic) &&
2544 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2545 isOperandInFarSpace (IC_RESULT (dic)))
2548 if (IC_RIGHT (dic) &&
2549 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2550 isOperandInFarSpace (IC_RIGHT (dic)) &&
2551 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2554 if (IC_LEFT (dic) &&
2555 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2556 isOperandInFarSpace (IC_LEFT (dic)) &&
2557 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2560 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2562 if ((dic->op == LEFT_OP ||
2563 dic->op == RIGHT_OP ||
2565 IS_OP_LITERAL (IC_RIGHT (dic)))
2575 /*-----------------------------------------------------------------*/
2576 /* packRegsForAssign - register reduction for assignment */
2577 /*-----------------------------------------------------------------*/
2579 packRegsForAssign (iCode * ic, eBBlock * ebp)
2584 debugLog ("%s\n", __FUNCTION__);
2586 debugAopGet (" result:", IC_RESULT (ic));
2587 debugAopGet (" left:", IC_LEFT (ic));
2588 debugAopGet (" right:", IC_RIGHT (ic));
2590 if (!IS_ITEMP (IC_RESULT (ic))) {
2591 allocDirReg(IC_RESULT (ic));
2592 debugLog (" %d - result is not temp\n", __LINE__);
2595 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2596 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2597 allocDirReg(IC_LEFT (ic));
2601 if (!IS_ITEMP (IC_RIGHT (ic))) {
2602 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2603 allocDirReg(IC_RIGHT (ic));
2607 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2608 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2610 debugLog (" %d - not packing - right side fails \n", __LINE__);
2614 /* if the true symbol is defined in far space or on stack
2615 then we should not since this will increase register pressure */
2616 if (isOperandInFarSpace (IC_RESULT (ic)))
2618 if ((dic = farSpacePackable (ic)))
2624 /* find the definition of iTempNN scanning backwards if we find a
2625 a use of the true symbol before we find the definition then
2627 for (dic = ic->prev; dic; dic = dic->prev)
2630 /* if there is a function call and this is
2631 a parameter & not my parameter then don't pack it */
2632 if ((dic->op == CALL || dic->op == PCALL) &&
2633 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2634 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2636 debugLog (" %d - \n", __LINE__);
2644 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2645 IS_OP_VOLATILE (IC_RESULT (dic)))
2647 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2652 if (IS_SYMOP (IC_RESULT (dic)) &&
2653 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2655 /* A previous result was assigned to the same register - we'll our definition */
2656 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2657 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2658 if (POINTER_SET (dic))
2664 if (IS_SYMOP (IC_RIGHT (dic)) &&
2665 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2666 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2668 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2673 if (IS_SYMOP (IC_LEFT (dic)) &&
2674 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2675 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2677 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2682 if (POINTER_SET (dic) &&
2683 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2685 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2693 return 0; /* did not find */
2695 /* if the result is on stack or iaccess then it must be
2696 the same atleast one of the operands */
2697 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2698 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2701 /* the operation has only one symbol
2702 operator then we can pack */
2703 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2704 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2707 if (!((IC_LEFT (dic) &&
2708 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2710 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2714 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2715 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2716 /* found the definition */
2717 /* replace the result with the result of */
2718 /* this assignment and remove this assignment */
2719 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2720 IC_RESULT (dic) = IC_RESULT (ic);
2722 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2724 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2726 /* delete from liverange table also
2727 delete from all the points inbetween and the new
2729 for (sic = dic; sic != ic; sic = sic->next)
2731 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2732 if (IS_ITEMP (IC_RESULT (dic)))
2733 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2736 remiCodeFromeBBlock (ebp, ic);
2737 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2738 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2739 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2745 /*-----------------------------------------------------------------*/
2746 /* findAssignToSym : scanning backwards looks for first assig found */
2747 /*-----------------------------------------------------------------*/
2749 findAssignToSym (operand * op, iCode * ic)
2753 debugLog ("%s\n", __FUNCTION__);
2754 for (dic = ic->prev; dic; dic = dic->prev)
2757 /* if definition by assignment */
2758 if (dic->op == '=' &&
2759 !POINTER_SET (dic) &&
2760 IC_RESULT (dic)->key == op->key
2761 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2765 /* we are interested only if defined in far space */
2766 /* or in stack space in case of + & - */
2768 /* if assigned to a non-symbol then return
2770 if (!IS_SYMOP (IC_RIGHT (dic)))
2773 /* if the symbol is in far space then
2775 if (isOperandInFarSpace (IC_RIGHT (dic)))
2778 /* for + & - operations make sure that
2779 if it is on the stack it is the same
2780 as one of the three operands */
2781 if ((ic->op == '+' || ic->op == '-') &&
2782 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2785 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2786 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2787 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2795 /* if we find an usage then we cannot delete it */
2796 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2799 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2802 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2806 /* now make sure that the right side of dic
2807 is not defined between ic & dic */
2810 iCode *sic = dic->next;
2812 for (; sic != ic; sic = sic->next)
2813 if (IC_RESULT (sic) &&
2814 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2823 /*-----------------------------------------------------------------*/
2824 /* packRegsForSupport :- reduce some registers for support calls */
2825 /*-----------------------------------------------------------------*/
2827 packRegsForSupport (iCode * ic, eBBlock * ebp)
2831 debugLog ("%s\n", __FUNCTION__);
2832 /* for the left & right operand :- look to see if the
2833 left was assigned a true symbol in far space in that
2834 case replace them */
2835 if (IS_ITEMP (IC_LEFT (ic)) &&
2836 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2838 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2844 debugAopGet ("removing left:", IC_LEFT (ic));
2846 /* found it we need to remove it from the
2848 for (sic = dic; sic != ic; sic = sic->next)
2849 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2851 IC_LEFT (ic)->operand.symOperand =
2852 IC_RIGHT (dic)->operand.symOperand;
2853 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2854 remiCodeFromeBBlock (ebp, dic);
2855 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2856 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2860 /* do the same for the right operand */
2863 IS_ITEMP (IC_RIGHT (ic)) &&
2864 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2866 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2872 /* if this is a subtraction & the result
2873 is a true symbol in far space then don't pack */
2874 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2876 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2877 if (IN_FARSPACE (SPEC_OCLS (etype)))
2881 debugAopGet ("removing right:", IC_RIGHT (ic));
2883 /* found it we need to remove it from the
2885 for (sic = dic; sic != ic; sic = sic->next)
2886 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2888 IC_RIGHT (ic)->operand.symOperand =
2889 IC_RIGHT (dic)->operand.symOperand;
2890 IC_RIGHT (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);
2901 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2904 /*-----------------------------------------------------------------*/
2905 /* packRegsForOneuse : - will reduce some registers for single Use */
2906 /*-----------------------------------------------------------------*/
2908 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2913 debugLog ("%s\n", __FUNCTION__);
2914 /* if returning a literal then do nothing */
2918 /* only upto 2 bytes since we cannot predict
2919 the usage of b, & acc */
2920 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2925 /* this routine will mark the a symbol as used in one
2926 instruction use only && if the definition is local
2927 (ie. within the basic block) && has only one definition &&
2928 that definition is either a return value from a
2929 function or does not contain any variables in
2931 uses = bitVectCopy (OP_USES (op));
2932 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2933 if (!bitVectIsZero (uses)) /* has other uses */
2936 /* if it has only one defintion */
2937 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2938 return NULL; /* has more than one definition */
2940 /* get that definition */
2942 hTabItemWithKey (iCodehTab,
2943 bitVectFirstBit (OP_DEFS (op)))))
2946 /* found the definition now check if it is local */
2947 if (dic->seq < ebp->fSeq ||
2948 dic->seq > ebp->lSeq)
2949 return NULL; /* non-local */
2951 /* now check if it is the return from
2953 if (dic->op == CALL || dic->op == PCALL)
2955 if (ic->op != SEND && ic->op != RETURN &&
2956 !POINTER_SET(ic) && !POINTER_GET(ic))
2958 OP_SYMBOL (op)->ruonly = 1;
2965 /* otherwise check that the definition does
2966 not contain any symbols in far space */
2967 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2968 isOperandInFarSpace (IC_RIGHT (dic)) ||
2969 IS_OP_RUONLY (IC_LEFT (ic)) ||
2970 IS_OP_RUONLY (IC_RIGHT (ic)))
2975 /* if pointer set then make sure the pointer
2977 if (POINTER_SET (dic) &&
2978 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2981 if (POINTER_GET (dic) &&
2982 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2987 /* also make sure the intervenening instructions
2988 don't have any thing in far space */
2989 for (dic = dic->next; dic && dic != ic; dic = dic->next)
2992 /* if there is an intervening function call then no */
2993 if (dic->op == CALL || dic->op == PCALL)
2995 /* if pointer set then make sure the pointer
2997 if (POINTER_SET (dic) &&
2998 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3001 if (POINTER_GET (dic) &&
3002 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3005 /* if address of & the result is remat then okay */
3006 if (dic->op == ADDRESS_OF &&
3007 OP_SYMBOL (IC_RESULT (dic))->remat)
3010 /* if operand has size of three or more & this
3011 operation is a '*','/' or '%' then 'b' may
3013 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3014 getSize (operandType (op)) >= 3)
3017 /* if left or right or result is in far space */
3018 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3019 isOperandInFarSpace (IC_RIGHT (dic)) ||
3020 isOperandInFarSpace (IC_RESULT (dic)) ||
3021 IS_OP_RUONLY (IC_LEFT (dic)) ||
3022 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3023 IS_OP_RUONLY (IC_RESULT (dic)))
3029 OP_SYMBOL (op)->ruonly = 1;
3034 /*-----------------------------------------------------------------*/
3035 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3036 /*-----------------------------------------------------------------*/
3038 isBitwiseOptimizable (iCode * ic)
3040 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3041 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3043 debugLog ("%s\n", __FUNCTION__);
3044 /* bitwise operations are considered optimizable
3045 under the following conditions (Jean-Louis VERN)
3057 if (IS_LITERAL (rtype) ||
3058 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3064 /*-----------------------------------------------------------------*/
3065 /* packRegsForAccUse - pack registers for acc use */
3066 /*-----------------------------------------------------------------*/
3068 packRegsForAccUse (iCode * ic)
3072 debugLog ("%s\n", __FUNCTION__);
3074 /* if this is an aggregate, e.g. a one byte char array */
3075 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3079 /* if + or - then it has to be one byte result */
3080 if ((ic->op == '+' || ic->op == '-')
3081 && getSize (operandType (IC_RESULT (ic))) > 1)
3084 /* if shift operation make sure right side is not a literal */
3085 if (ic->op == RIGHT_OP &&
3086 (isOperandLiteral (IC_RIGHT (ic)) ||
3087 getSize (operandType (IC_RESULT (ic))) > 1))
3090 if (ic->op == LEFT_OP &&
3091 (isOperandLiteral (IC_RIGHT (ic)) ||
3092 getSize (operandType (IC_RESULT (ic))) > 1))
3095 if (IS_BITWISE_OP (ic) &&
3096 getSize (operandType (IC_RESULT (ic))) > 1)
3100 /* has only one definition */
3101 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3104 /* has only one use */
3105 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3108 /* and the usage immediately follows this iCode */
3109 if (!(uic = hTabItemWithKey (iCodehTab,
3110 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3113 if (ic->next != uic)
3116 /* if it is a conditional branch then we definitely can */
3120 if (uic->op == JUMPTABLE)
3123 /* if the usage is not is an assignment
3124 or an arithmetic / bitwise / shift operation then not */
3125 if (POINTER_SET (uic) &&
3126 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3129 if (uic->op != '=' &&
3130 !IS_ARITHMETIC_OP (uic) &&
3131 !IS_BITWISE_OP (uic) &&
3132 uic->op != LEFT_OP &&
3133 uic->op != RIGHT_OP)
3136 /* if used in ^ operation then make sure right is not a
3138 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3141 /* if shift operation make sure right side is not a literal */
3142 if (uic->op == RIGHT_OP &&
3143 (isOperandLiteral (IC_RIGHT (uic)) ||
3144 getSize (operandType (IC_RESULT (uic))) > 1))
3147 if (uic->op == LEFT_OP &&
3148 (isOperandLiteral (IC_RIGHT (uic)) ||
3149 getSize (operandType (IC_RESULT (uic))) > 1))
3152 /* make sure that the result of this icode is not on the
3153 stack, since acc is used to compute stack offset */
3154 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3155 OP_SYMBOL (IC_RESULT (uic))->onStack)
3158 /* if either one of them in far space then we cannot */
3159 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3160 isOperandInFarSpace (IC_LEFT (uic))) ||
3161 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3162 isOperandInFarSpace (IC_RIGHT (uic))))
3165 /* if the usage has only one operand then we can */
3166 if (IC_LEFT (uic) == NULL ||
3167 IC_RIGHT (uic) == NULL)
3170 /* make sure this is on the left side if not
3171 a '+' since '+' is commutative */
3172 if (ic->op != '+' &&
3173 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3176 /* if one of them is a literal then we can */
3177 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3178 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
3180 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3184 /* if the other one is not on stack then we can */
3185 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3186 (IS_ITEMP (IC_RIGHT (uic)) ||
3187 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3188 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3191 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3192 (IS_ITEMP (IC_LEFT (uic)) ||
3193 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3194 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3200 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3201 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3206 /*-----------------------------------------------------------------*/
3207 /* packForPush - hueristics to reduce iCode for pushing */
3208 /*-----------------------------------------------------------------*/
3210 packForReceive (iCode * ic, eBBlock * ebp)
3214 debugLog ("%s\n", __FUNCTION__);
3215 debugAopGet (" result:", IC_RESULT (ic));
3216 debugAopGet (" left:", IC_LEFT (ic));
3217 debugAopGet (" right:", IC_RIGHT (ic));
3222 for (dic = ic->next; dic; dic = dic->next)
3227 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3228 debugLog (" used on left\n");
3229 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3230 debugLog (" used on right\n");
3231 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3232 debugLog (" used on result\n");
3234 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3235 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3240 debugLog (" hey we can remove this unnecessary assign\n");
3242 /*-----------------------------------------------------------------*/
3243 /* packForPush - hueristics to reduce iCode for pushing */
3244 /*-----------------------------------------------------------------*/
3246 packForPush (iCode * ic, eBBlock * ebp)
3250 debugLog ("%s\n", __FUNCTION__);
3251 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3254 /* must have only definition & one usage */
3255 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3256 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3259 /* find the definition */
3260 if (!(dic = hTabItemWithKey (iCodehTab,
3261 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3264 if (dic->op != '=' || POINTER_SET (dic))
3267 /* we now we know that it has one & only one def & use
3268 and the that the definition is an assignment */
3269 IC_LEFT (ic) = IC_RIGHT (dic);
3271 remiCodeFromeBBlock (ebp, dic);
3272 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3273 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3276 void printSymType(char * str, sym_link *sl)
3278 debugLog (" %s Symbol type: ",str);
3279 printTypeChain( sl, debugF);
3284 /*-----------------------------------------------------------------*/
3285 /* packRegisters - does some transformations to reduce register */
3287 /*-----------------------------------------------------------------*/
3289 packRegisters (eBBlock * ebp)
3294 debugLog ("%s\n", __FUNCTION__);
3300 /* look for assignments of the form */
3301 /* iTempNN = TRueSym (someoperation) SomeOperand */
3303 /* TrueSym := iTempNN:1 */
3304 for (ic = ebp->sch; ic; ic = ic->next)
3307 /* find assignment of the form TrueSym := iTempNN:1 */
3308 if (ic->op == '=' && !POINTER_SET (ic))
3309 change += packRegsForAssign (ic, ebp);
3313 if (POINTER_SET (ic))
3314 debugLog ("pointer is set\n");
3315 debugAopGet (" result:", IC_RESULT (ic));
3316 debugAopGet (" left:", IC_LEFT (ic));
3317 debugAopGet (" right:", IC_RIGHT (ic));
3326 for (ic = ebp->sch; ic; ic = ic->next) {
3328 if(IS_SYMOP ( IC_LEFT(ic))) {
3329 //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3331 debugAopGet (" left:", IC_LEFT (ic));
3332 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3333 debugLog (" is a pointer");
3335 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3338 if(IS_SYMOP ( IC_RIGHT(ic))) {
3339 debugAopGet (" right:", IC_RIGHT (ic));
3340 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3343 if(IS_SYMOP ( IC_RESULT(ic))) {
3344 debugAopGet (" result:", IC_RESULT (ic));
3345 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3348 if (POINTER_SET (ic))
3349 debugLog (" %d - Pointer set\n", __LINE__);
3352 /* if this is an itemp & result of a address of a true sym
3353 then mark this as rematerialisable */
3354 if (ic->op == ADDRESS_OF &&
3355 IS_ITEMP (IC_RESULT (ic)) &&
3356 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3357 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3358 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3361 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3363 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3364 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3365 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3369 /* if straight assignment then carry remat flag if
3370 this is the only definition */
3371 if (ic->op == '=' &&
3372 !POINTER_SET (ic) &&
3373 IS_SYMOP (IC_RIGHT (ic)) &&
3374 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3375 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3377 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3379 OP_SYMBOL (IC_RESULT (ic))->remat =
3380 OP_SYMBOL (IC_RIGHT (ic))->remat;
3381 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3382 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3385 /* if this is a +/- operation with a rematerizable
3386 then mark this as rematerializable as well */
3387 if ((ic->op == '+' || ic->op == '-') &&
3388 (IS_SYMOP (IC_LEFT (ic)) &&
3389 IS_ITEMP (IC_RESULT (ic)) &&
3390 OP_SYMBOL (IC_LEFT (ic))->remat &&
3391 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3392 IS_OP_LITERAL (IC_RIGHT (ic))))
3394 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3396 operandLitValue (IC_RIGHT (ic));
3397 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3398 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3399 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3402 /* mark the pointer usages */
3403 if (POINTER_SET (ic))
3405 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3406 debugLog (" marking as a pointer (set) =>");
3407 debugAopGet (" result:", IC_RESULT (ic));
3409 if (POINTER_GET (ic))
3411 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3412 debugLog (" marking as a pointer (get) =>");
3413 debugAopGet (" left:", IC_LEFT (ic));
3418 /* if we are using a symbol on the stack
3419 then we should say pic14_ptrRegReq */
3420 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3421 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3422 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3423 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3424 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3425 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3428 if (IS_SYMOP (IC_LEFT (ic)))
3429 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3430 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3431 if (IS_SYMOP (IC_RIGHT (ic)))
3432 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3433 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3434 if (IS_SYMOP (IC_RESULT (ic)))
3435 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3436 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3439 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3443 /* if the condition of an if instruction
3444 is defined in the previous instruction then
3445 mark the itemp as a conditional */
3446 if ((IS_CONDITIONAL (ic) ||
3447 ((ic->op == BITWISEAND ||
3450 isBitwiseOptimizable (ic))) &&
3451 ic->next && ic->next->op == IFX &&
3452 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3453 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3456 debugLog (" %d\n", __LINE__);
3457 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3461 /* reduce for support function calls */
3462 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3463 packRegsForSupport (ic, ebp);
3465 /* if a parameter is passed, it's in W, so we may not
3466 need to place a copy in a register */
3467 if (ic->op == RECEIVE)
3468 packForReceive (ic, ebp);
3470 /* some cases the redundant moves can
3471 can be eliminated for return statements */
3472 if ((ic->op == RETURN || ic->op == SEND) &&
3473 !isOperandInFarSpace (IC_LEFT (ic)) &&
3475 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3477 /* if pointer set & left has a size more than
3478 one and right is not in far space */
3479 if (POINTER_SET (ic) &&
3480 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3481 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3482 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3483 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3485 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3487 /* if pointer get */
3488 if (POINTER_GET (ic) &&
3489 !isOperandInFarSpace (IC_RESULT (ic)) &&
3490 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3491 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3492 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3494 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3497 /* if this is cast for intergral promotion then
3498 check if only use of the definition of the
3499 operand being casted/ if yes then replace
3500 the result of that arithmetic operation with
3501 this result and get rid of the cast */
3502 if (ic->op == CAST) {
3504 sym_link *fromType = operandType (IC_RIGHT (ic));
3505 sym_link *toType = operandType (IC_LEFT (ic));
3507 debugLog (" %d - casting\n", __LINE__);
3509 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3510 getSize (fromType) != getSize (toType)) {
3513 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3516 if (IS_ARITHMETIC_OP (dic)) {
3518 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3519 IC_RESULT (dic) = IC_RESULT (ic);
3520 remiCodeFromeBBlock (ebp, ic);
3521 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3522 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3523 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3527 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3531 /* if the type from and type to are the same
3532 then if this is the only use then packit */
3533 if (compareType (operandType (IC_RIGHT (ic)),
3534 operandType (IC_LEFT (ic))) == 1) {
3536 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3539 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3540 IC_RESULT (dic) = IC_RESULT (ic);
3541 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3542 remiCodeFromeBBlock (ebp, ic);
3543 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3544 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3552 iTempNN := (some variable in farspace) V1
3557 if (ic->op == IPUSH)
3559 packForPush (ic, ebp);
3563 /* pack registers for accumulator use, when the
3564 result of an arithmetic or bit wise operation
3565 has only one use, that use is immediately following
3566 the defintion and the using iCode has only one
3567 operand or has two operands but one is literal &
3568 the result of that operation is not on stack then
3569 we can leave the result of this operation in acc:b
3571 if ((IS_ARITHMETIC_OP (ic)
3573 || IS_BITWISE_OP (ic)
3575 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3578 IS_ITEMP (IC_RESULT (ic)) &&
3579 getSize (operandType (IC_RESULT (ic))) <= 2)
3581 packRegsForAccUse (ic);
3587 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3591 if (!debug || !debugF)
3594 for (i = 0; i < count; i++)
3596 fprintf (debugF, "\n----------------------------------------------------------------\n");
3597 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3598 ebbs[i]->entryLabel->name,
3601 ebbs[i]->isLastInLoop);
3602 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3607 fprintf (debugF, "visited %d : hasFcall = %d\n",
3611 fprintf (debugF, "\ndefines bitVector :");
3612 bitVectDebugOn (ebbs[i]->defSet, debugF);
3613 fprintf (debugF, "\nlocal defines bitVector :");
3614 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3615 fprintf (debugF, "\npointers Set bitvector :");
3616 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3617 fprintf (debugF, "\nin pointers Set bitvector :");
3618 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3619 fprintf (debugF, "\ninDefs Set bitvector :");
3620 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3621 fprintf (debugF, "\noutDefs Set bitvector :");
3622 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3623 fprintf (debugF, "\nusesDefs Set bitvector :");
3624 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3625 fprintf (debugF, "\n----------------------------------------------------------------\n");
3626 printiCChain (ebbs[i]->sch, debugF);
3629 /*-----------------------------------------------------------------*/
3630 /* assignRegisters - assigns registers to each live range as need */
3631 /*-----------------------------------------------------------------*/
3633 pic14_assignRegisters (eBBlock ** ebbs, int count)
3638 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3639 debugLog ("\nebbs before optimizing:\n");
3640 dumpEbbsToDebug (ebbs, count);
3642 setToNull ((void *) &_G.funcrUsed);
3643 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3646 /* change assignments this will remove some
3647 live ranges reducing some register pressure */
3648 for (i = 0; i < count; i++)
3649 packRegisters (ebbs[i]);
3656 debugLog("dir registers allocated so far:\n");
3657 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3660 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3661 reg = hTabNextItem(dynDirectRegNames, &hkey);
3666 if (options.dump_pack)
3667 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3669 /* first determine for each live range the number of
3670 registers & the type of registers required for each */
3673 /* and serially allocate registers */
3674 serialRegAssign (ebbs, count);
3676 /* if stack was extended then tell the user */
3679 /* werror(W_TOOMANY_SPILS,"stack", */
3680 /* _G.stackExtend,currFunc->name,""); */
3686 /* werror(W_TOOMANY_SPILS,"data space", */
3687 /* _G.dataExtend,currFunc->name,""); */
3691 /* after that create the register mask
3692 for each of the instruction */
3693 createRegMask (ebbs, count);
3695 /* redo that offsets for stacked automatic variables */
3696 redoStackOffsets ();
3698 if (options.dump_rassgn)
3699 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3701 /* now get back the chain */
3702 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3704 debugLog ("ebbs after optimizing:\n");
3705 dumpEbbsToDebug (ebbs, count);
3710 /* free up any _G.stackSpil locations allocated */
3711 applyToSet (_G.stackSpil, deallocStackSpil);
3713 setToNull ((void **) &_G.stackSpil);
3714 setToNull ((void **) &_G.spiltSet);
3715 /* mark all registers as free */
3716 pic14_freeAllRegs ();
3718 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");