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);
666 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
668 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
669 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
675 /*-----------------------------------------------------------------*/
676 /* allocDirReg - allocates register of given type */
677 /*-----------------------------------------------------------------*/
679 allocRegByName (char *name, int size)
685 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
689 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
691 /* First, search the hash table to see if there is a register with this name */
692 reg = dirregWithName(name);
696 /* Register wasn't found in hash, so let's create
697 * a new one and put it in the hash table AND in the
698 * dynDirectRegNames set */
700 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
702 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
704 hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
705 addSet(&dynDirectRegs, reg);
711 /*-----------------------------------------------------------------*/
712 /* RegWithIdx - returns pointer to register with index number */
713 /*-----------------------------------------------------------------*/
715 typeRegWithIdx (int idx, int type, int fixed)
720 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
722 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
724 debugLog ("Found a Dynamic Register!\n");
728 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
729 debugLog ("Found a Stack Register!\n");
733 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
734 debugLog ("Found a Direct Register!\n");
738 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
739 debugLog ("Found a Processor Register!\n");
743 if( (dReg = regWithIdx ( dynDirectBitRegs, idx, fixed)) != NULL ) {
744 debugLog ("Found a bit Register!\n");
749 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
750 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
751 "regWithIdx not found");
757 /*-----------------------------------------------------------------*/
758 /* pic14_regWithIdx - returns pointer to register with index number*/
759 /*-----------------------------------------------------------------*/
761 pic14_regWithIdx (int idx)
764 return typeRegWithIdx(idx,-1,0);
767 /*-----------------------------------------------------------------*/
768 /* pic14_regWithIdx - returns pointer to register with index number */
769 /*-----------------------------------------------------------------*/
771 pic14_allocWithIdx (int idx)
776 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
778 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
780 debugLog ("Found a Dynamic Register!\n");
781 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
782 debugLog ("Found a Stack Register!\n");
783 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
784 debugLog ("Found a Processor Register!\n");
785 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
786 debugLog ("Found an Internal Register!\n");
789 debugLog ("Dynamic Register not found\n");
792 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
793 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
794 "regWithIdx not found");
804 /*-----------------------------------------------------------------*/
805 /*-----------------------------------------------------------------*/
807 pic14_findFreeReg(short type)
814 if((dReg = regFindFree(dynAllocRegs)) != NULL)
817 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
821 if((dReg = regFindFree(dynStackRegs)) != NULL)
833 /*-----------------------------------------------------------------*/
834 /* freeReg - frees a register */
835 /*-----------------------------------------------------------------*/
839 debugLog ("%s\n", __FUNCTION__);
844 /*-----------------------------------------------------------------*/
845 /* nFreeRegs - returns number of free registers */
846 /*-----------------------------------------------------------------*/
850 /* dynamically allocate as many as we need and worry about
851 * fitting them into a PIC later */
858 debugLog ("%s\n", __FUNCTION__);
859 for (i = 0; i < pic14_nRegs; i++)
860 if (regspic14[i].isFree && regspic14[i].type == type)
866 /*-----------------------------------------------------------------*/
867 /* nfreeRegsType - free registers with type */
868 /*-----------------------------------------------------------------*/
870 nfreeRegsType (int type)
873 debugLog ("%s\n", __FUNCTION__);
876 if ((nfr = nFreeRegs (type)) == 0)
877 return nFreeRegs (REG_GPR);
880 return nFreeRegs (type);
884 void writeSetUsedRegs(FILE *of, set *dRegs)
889 for (dReg = setFirstItem(dRegs) ; dReg ;
890 dReg = setNextItem(dRegs)) {
893 fprintf (of, "\t%s\n",dReg->name);
897 extern void assignFixedRegisters(set *regset);
898 extern void assignRelocatableRegisters(set *regset,int used);
899 extern void dump_map(void);
900 extern void dump_cblock(FILE *of);
903 void packBits(set *bregs)
908 regs *relocbitfield=NULL;
913 for (regset = bregs ; regset ;
914 regset = regset->next) {
917 breg->isBitField = 1;
918 //fprintf(stderr,"bit reg: %s\n",breg->name);
921 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
923 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
924 breg->rIdx = breg->address & 7;
928 sprintf (buffer, "fbitfield%02x", breg->address);
929 //fprintf(stderr,"new bit field\n");
930 bitfield = newReg(REG_GPR, PO_GPR_BIT,breg->address,buffer,1,0);
931 bitfield->isBitField = 1;
932 bitfield->isFixed = 1;
933 bitfield->address = breg->address;
934 addSet(&dynDirectRegs,bitfield);
935 hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
937 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
940 breg->reg_alias = bitfield;
944 if(!relocbitfield || bit_no >7) {
947 sprintf (buffer, "bitfield%d", byte_no);
948 //fprintf(stderr,"new relocatable bit field\n");
949 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
950 relocbitfield->isBitField = 1;
951 addSet(&dynDirectRegs,relocbitfield);
952 hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
956 breg->reg_alias = relocbitfield;
957 breg->address = rDirectIdx; /* byte_no; */
958 breg->rIdx = bit_no++;
966 void bitEQUs(FILE *of, set *bregs)
971 //fprintf(stderr," %s\n",__FUNCTION__);
972 for (breg = setFirstItem(bregs) ; breg ;
973 breg = setNextItem(bregs)) {
975 //fprintf(stderr,"bit reg: %s\n",breg->name);
977 bytereg = breg->reg_alias;
979 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
982 breg->rIdx & 0x0007);
985 fprintf(stderr, "bit field is not assigned to a register\n");
986 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
996 void aliasEQUs(FILE *of, set *fregs)
1001 for (reg = setFirstItem(fregs) ; reg ;
1002 reg = setNextItem(fregs)) {
1005 fprintf (of, "%s\tEQU\t0x%03x\n",
1012 void writeUsedRegs(FILE *of)
1014 packBits(dynDirectBitRegs);
1016 assignFixedRegisters(dynAllocRegs);
1017 assignFixedRegisters(dynStackRegs);
1018 assignFixedRegisters(dynDirectRegs);
1020 assignRelocatableRegisters(dynInternalRegs,1);
1021 assignRelocatableRegisters(dynAllocRegs,0);
1022 assignRelocatableRegisters(dynStackRegs,0);
1023 assignRelocatableRegisters(dynDirectRegs,0);
1028 bitEQUs(of,dynDirectBitRegs);
1029 aliasEQUs(of,dynAllocRegs);
1030 aliasEQUs(of,dynDirectRegs);
1031 aliasEQUs(of,dynStackRegs);
1035 /*-----------------------------------------------------------------*/
1036 /* allDefsOutOfRange - all definitions are out of a range */
1037 /*-----------------------------------------------------------------*/
1039 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1043 debugLog ("%s\n", __FUNCTION__);
1047 for (i = 0; i < defs->size; i++)
1051 if (bitVectBitValue (defs, i) &&
1052 (ic = hTabItemWithKey (iCodehTab, i)) &&
1053 (ic->seq >= fseq && ic->seq <= toseq))
1064 /*-----------------------------------------------------------------*/
1065 /* computeSpillable - given a point find the spillable live ranges */
1066 /*-----------------------------------------------------------------*/
1068 computeSpillable (iCode * ic)
1072 debugLog ("%s\n", __FUNCTION__);
1073 /* spillable live ranges are those that are live at this
1074 point . the following categories need to be subtracted
1076 a) - those that are already spilt
1077 b) - if being used by this one
1078 c) - defined by this one */
1080 spillable = bitVectCopy (ic->rlive);
1082 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1084 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1085 bitVectUnSetBit (spillable, ic->defKey);
1086 spillable = bitVectIntersect (spillable, _G.regAssigned);
1091 /*-----------------------------------------------------------------*/
1092 /* noSpilLoc - return true if a variable has no spil location */
1093 /*-----------------------------------------------------------------*/
1095 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1097 debugLog ("%s\n", __FUNCTION__);
1098 return (sym->usl.spillLoc ? 0 : 1);
1101 /*-----------------------------------------------------------------*/
1102 /* hasSpilLoc - will return 1 if the symbol has spil location */
1103 /*-----------------------------------------------------------------*/
1105 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1107 debugLog ("%s\n", __FUNCTION__);
1108 return (sym->usl.spillLoc ? 1 : 0);
1111 /*-----------------------------------------------------------------*/
1112 /* directSpilLoc - will return 1 if the splilocation is in direct */
1113 /*-----------------------------------------------------------------*/
1115 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1117 debugLog ("%s\n", __FUNCTION__);
1118 if (sym->usl.spillLoc &&
1119 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1125 /*-----------------------------------------------------------------*/
1126 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1127 /* but is not used as a pointer */
1128 /*-----------------------------------------------------------------*/
1130 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1132 debugLog ("%s\n", __FUNCTION__);
1133 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1136 /*-----------------------------------------------------------------*/
1137 /* rematable - will return 1 if the remat flag is set */
1138 /*-----------------------------------------------------------------*/
1140 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1142 debugLog ("%s\n", __FUNCTION__);
1146 /*-----------------------------------------------------------------*/
1147 /* notUsedInRemaining - not used or defined in remain of the block */
1148 /*-----------------------------------------------------------------*/
1150 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1152 debugLog ("%s\n", __FUNCTION__);
1153 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1154 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1157 /*-----------------------------------------------------------------*/
1158 /* allLRs - return true for all */
1159 /*-----------------------------------------------------------------*/
1161 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1163 debugLog ("%s\n", __FUNCTION__);
1167 /*-----------------------------------------------------------------*/
1168 /* liveRangesWith - applies function to a given set of live range */
1169 /*-----------------------------------------------------------------*/
1171 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1172 eBBlock * ebp, iCode * ic)
1177 debugLog ("%s\n", __FUNCTION__);
1178 if (!lrs || !lrs->size)
1181 for (i = 1; i < lrs->size; i++)
1184 if (!bitVectBitValue (lrs, i))
1187 /* if we don't find it in the live range
1188 hash table we are in serious trouble */
1189 if (!(sym = hTabItemWithKey (liveRanges, i)))
1191 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1192 "liveRangesWith could not find liveRange");
1196 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1197 addSetHead (&rset, sym);
1204 /*-----------------------------------------------------------------*/
1205 /* leastUsedLR - given a set determines which is the least used */
1206 /*-----------------------------------------------------------------*/
1208 leastUsedLR (set * sset)
1210 symbol *sym = NULL, *lsym = NULL;
1212 debugLog ("%s\n", __FUNCTION__);
1213 sym = lsym = setFirstItem (sset);
1218 for (; lsym; lsym = setNextItem (sset))
1221 /* if usage is the same then prefer
1222 the spill the smaller of the two */
1223 if (lsym->used == sym->used)
1224 if (getSize (lsym->type) < getSize (sym->type))
1228 if (lsym->used < sym->used)
1233 setToNull ((void **) &sset);
1238 /*-----------------------------------------------------------------*/
1239 /* noOverLap - will iterate through the list looking for over lap */
1240 /*-----------------------------------------------------------------*/
1242 noOverLap (set * itmpStack, symbol * fsym)
1245 debugLog ("%s\n", __FUNCTION__);
1248 for (sym = setFirstItem (itmpStack); sym;
1249 sym = setNextItem (itmpStack))
1251 if (sym->liveTo > fsym->liveFrom)
1259 /*-----------------------------------------------------------------*/
1260 /* isFree - will return 1 if the a free spil location is found */
1261 /*-----------------------------------------------------------------*/
1266 V_ARG (symbol **, sloc);
1267 V_ARG (symbol *, fsym);
1269 debugLog ("%s\n", __FUNCTION__);
1270 /* if already found */
1274 /* if it is free && and the itmp assigned to
1275 this does not have any overlapping live ranges
1276 with the one currently being assigned and
1277 the size can be accomodated */
1279 noOverLap (sym->usl.itmpStack, fsym) &&
1280 getSize (sym->type) >= getSize (fsym->type))
1289 /*-----------------------------------------------------------------*/
1290 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1291 /*-----------------------------------------------------------------*/
1293 spillLRWithPtrReg (symbol * forSym)
1299 debugLog ("%s\n", __FUNCTION__);
1300 if (!_G.regAssigned ||
1301 bitVectIsZero (_G.regAssigned))
1304 r0 = pic14_regWithIdx (R0_IDX);
1305 r1 = pic14_regWithIdx (R1_IDX);
1307 /* for all live ranges */
1308 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1309 lrsym = hTabNextItem (liveRanges, &k))
1313 /* if no registers assigned to it or
1315 /* if it does not overlap with this then
1316 not need to spill it */
1318 if (lrsym->isspilt || !lrsym->nRegs ||
1319 (lrsym->liveTo < forSym->liveFrom))
1322 /* go thru the registers : if it is either
1323 r0 or r1 then spil it */
1324 for (j = 0; j < lrsym->nRegs; j++)
1325 if (lrsym->regs[j] == r0 ||
1326 lrsym->regs[j] == r1)
1335 /*-----------------------------------------------------------------*/
1336 /* createStackSpil - create a location on the stack to spil */
1337 /*-----------------------------------------------------------------*/
1339 createStackSpil (symbol * sym)
1341 symbol *sloc = NULL;
1342 int useXstack, model, noOverlay;
1344 char slocBuffer[30];
1345 debugLog ("%s\n", __FUNCTION__);
1347 /* first go try and find a free one that is already
1348 existing on the stack */
1349 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1351 /* found a free one : just update & return */
1352 sym->usl.spillLoc = sloc;
1355 addSetHead (&sloc->usl.itmpStack, sym);
1359 /* could not then have to create one , this is the hard part
1360 we need to allocate this on the stack : this is really a
1361 hack!! but cannot think of anything better at this time */
1363 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1365 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1366 __FILE__, __LINE__);
1370 sloc = newiTemp (slocBuffer);
1372 /* set the type to the spilling symbol */
1373 sloc->type = copyLinkChain (sym->type);
1374 sloc->etype = getSpec (sloc->type);
1375 SPEC_SCLS (sloc->etype) = S_DATA;
1376 SPEC_EXTR (sloc->etype) = 0;
1377 SPEC_STAT (sloc->etype) = 0;
1379 /* we don't allow it to be allocated`
1380 onto the external stack since : so we
1381 temporarily turn it off ; we also
1382 turn off memory model to prevent
1383 the spil from going to the external storage
1384 and turn off overlaying
1387 useXstack = options.useXstack;
1388 model = options.model;
1389 noOverlay = options.noOverlay;
1390 options.noOverlay = 1;
1391 options.model = options.useXstack = 0;
1395 options.useXstack = useXstack;
1396 options.model = model;
1397 options.noOverlay = noOverlay;
1398 sloc->isref = 1; /* to prevent compiler warning */
1400 /* if it is on the stack then update the stack */
1401 if (IN_STACK (sloc->etype))
1403 currFunc->stack += getSize (sloc->type);
1404 _G.stackExtend += getSize (sloc->type);
1407 _G.dataExtend += getSize (sloc->type);
1409 /* add it to the _G.stackSpil set */
1410 addSetHead (&_G.stackSpil, sloc);
1411 sym->usl.spillLoc = sloc;
1414 /* add it to the set of itempStack set
1415 of the spill location */
1416 addSetHead (&sloc->usl.itmpStack, sym);
1420 /*-----------------------------------------------------------------*/
1421 /* isSpiltOnStack - returns true if the spil location is on stack */
1422 /*-----------------------------------------------------------------*/
1424 isSpiltOnStack (symbol * sym)
1428 debugLog ("%s\n", __FUNCTION__);
1435 /* if (sym->_G.stackSpil) */
1438 if (!sym->usl.spillLoc)
1441 etype = getSpec (sym->usl.spillLoc->type);
1442 if (IN_STACK (etype))
1448 /*-----------------------------------------------------------------*/
1449 /* spillThis - spils a specific operand */
1450 /*-----------------------------------------------------------------*/
1452 spillThis (symbol * sym)
1455 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1457 /* if this is rematerializable or has a spillLocation
1458 we are okay, else we need to create a spillLocation
1460 if (!(sym->remat || sym->usl.spillLoc))
1461 createStackSpil (sym);
1464 /* mark it has spilt & put it in the spilt set */
1466 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1468 bitVectUnSetBit (_G.regAssigned, sym->key);
1470 for (i = 0; i < sym->nRegs; i++)
1474 freeReg (sym->regs[i]);
1475 sym->regs[i] = NULL;
1478 /* if spilt on stack then free up r0 & r1
1479 if they could have been assigned to some
1481 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1484 spillLRWithPtrReg (sym);
1487 if (sym->usl.spillLoc && !sym->remat)
1488 sym->usl.spillLoc->allocreq = 1;
1492 /*-----------------------------------------------------------------*/
1493 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1494 /*-----------------------------------------------------------------*/
1496 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1498 bitVect *lrcs = NULL;
1502 debugLog ("%s\n", __FUNCTION__);
1503 /* get the spillable live ranges */
1504 lrcs = computeSpillable (ic);
1506 /* get all live ranges that are rematerizable */
1507 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1510 /* return the least used of these */
1511 return leastUsedLR (selectS);
1514 /* get live ranges with spillLocations in direct space */
1515 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1517 sym = leastUsedLR (selectS);
1518 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1519 sym->usl.spillLoc->rname :
1520 sym->usl.spillLoc->name));
1522 /* mark it as allocation required */
1523 sym->usl.spillLoc->allocreq = 1;
1527 /* if the symbol is local to the block then */
1528 if (forSym->liveTo < ebp->lSeq)
1531 /* check if there are any live ranges allocated
1532 to registers that are not used in this block */
1533 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1535 sym = leastUsedLR (selectS);
1536 /* if this is not rematerializable */
1545 /* check if there are any live ranges that not
1546 used in the remainder of the block */
1547 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1549 sym = leastUsedLR (selectS);
1552 sym->remainSpil = 1;
1559 /* find live ranges with spillocation && not used as pointers */
1560 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1563 sym = leastUsedLR (selectS);
1564 /* mark this as allocation required */
1565 sym->usl.spillLoc->allocreq = 1;
1569 /* find live ranges with spillocation */
1570 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1573 sym = leastUsedLR (selectS);
1574 sym->usl.spillLoc->allocreq = 1;
1578 /* couldn't find then we need to create a spil
1579 location on the stack , for which one? the least
1581 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1584 /* return a created spil location */
1585 sym = createStackSpil (leastUsedLR (selectS));
1586 sym->usl.spillLoc->allocreq = 1;
1590 /* this is an extreme situation we will spill
1591 this one : happens very rarely but it does happen */
1597 /*-----------------------------------------------------------------*/
1598 /* spilSomething - spil some variable & mark registers as free */
1599 /*-----------------------------------------------------------------*/
1601 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1606 debugLog ("%s\n", __FUNCTION__);
1607 /* get something we can spil */
1608 ssym = selectSpil (ic, ebp, forSym);
1610 /* mark it as spilt */
1612 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1614 /* mark it as not register assigned &
1615 take it away from the set */
1616 bitVectUnSetBit (_G.regAssigned, ssym->key);
1618 /* mark the registers as free */
1619 for (i = 0; i < ssym->nRegs; i++)
1621 freeReg (ssym->regs[i]);
1623 /* if spilt on stack then free up r0 & r1
1624 if they could have been assigned to as gprs */
1625 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1628 spillLRWithPtrReg (ssym);
1631 /* if this was a block level spil then insert push & pop
1632 at the start & end of block respectively */
1633 if (ssym->blockSpil)
1635 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1636 /* add push to the start of the block */
1637 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1638 ebp->sch->next : ebp->sch));
1639 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1640 /* add pop to the end of the block */
1641 addiCodeToeBBlock (ebp, nic, NULL);
1644 /* if spilt because not used in the remainder of the
1645 block then add a push before this instruction and
1646 a pop at the end of the block */
1647 if (ssym->remainSpil)
1650 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1651 /* add push just before this instruction */
1652 addiCodeToeBBlock (ebp, nic, ic);
1654 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1655 /* add pop to the end of the block */
1656 addiCodeToeBBlock (ebp, nic, NULL);
1665 /*-----------------------------------------------------------------*/
1666 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1667 /*-----------------------------------------------------------------*/
1669 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1673 debugLog ("%s\n", __FUNCTION__);
1675 /* try for a ptr type */
1676 if ((reg = allocReg (REG_PTR)))
1679 /* try for gpr type */
1680 if ((reg = allocReg (REG_GPR)))
1683 /* we have to spil */
1684 if (!spilSomething (ic, ebp, sym))
1687 /* this looks like an infinite loop but
1688 in really selectSpil will abort */
1692 /*-----------------------------------------------------------------*/
1693 /* getRegGpr - will try for GPR if not spil */
1694 /*-----------------------------------------------------------------*/
1696 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1700 debugLog ("%s\n", __FUNCTION__);
1702 /* try for gpr type */
1703 if ((reg = allocReg (REG_GPR)))
1706 if (!pic14_ptrRegReq)
1707 if ((reg = allocReg (REG_PTR)))
1710 /* we have to spil */
1711 if (!spilSomething (ic, ebp, sym))
1714 /* this looks like an infinite loop but
1715 in really selectSpil will abort */
1719 /*-----------------------------------------------------------------*/
1720 /* symHasReg - symbol has a given register */
1721 /*-----------------------------------------------------------------*/
1723 symHasReg (symbol * sym, regs * reg)
1727 debugLog ("%s\n", __FUNCTION__);
1728 for (i = 0; i < sym->nRegs; i++)
1729 if (sym->regs[i] == reg)
1735 /*-----------------------------------------------------------------*/
1736 /* deassignLRs - check the live to and if they have registers & are */
1737 /* not spilt then free up the registers */
1738 /*-----------------------------------------------------------------*/
1740 deassignLRs (iCode * ic, eBBlock * ebp)
1746 debugLog ("%s\n", __FUNCTION__);
1747 for (sym = hTabFirstItem (liveRanges, &k); sym;
1748 sym = hTabNextItem (liveRanges, &k))
1751 symbol *psym = NULL;
1752 /* if it does not end here */
1753 if (sym->liveTo > ic->seq)
1756 /* if it was spilt on stack then we can
1757 mark the stack spil location as free */
1762 sym->usl.spillLoc->isFree = 1;
1768 if (!bitVectBitValue (_G.regAssigned, sym->key))
1771 /* special case check if this is an IFX &
1772 the privious one was a pop and the
1773 previous one was not spilt then keep track
1775 if (ic->op == IFX && ic->prev &&
1776 ic->prev->op == IPOP &&
1777 !ic->prev->parmPush &&
1778 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1779 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1785 bitVectUnSetBit (_G.regAssigned, sym->key);
1787 /* if the result of this one needs registers
1788 and does not have it then assign it right
1790 if (IC_RESULT (ic) &&
1791 !(SKIP_IC2 (ic) || /* not a special icode */
1792 ic->op == JUMPTABLE ||
1797 POINTER_SET (ic)) &&
1798 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1799 result->liveTo > ic->seq && /* and will live beyond this */
1800 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1801 result->regType == sym->regType && /* same register types */
1802 result->nRegs && /* which needs registers */
1803 !result->isspilt && /* and does not already have them */
1805 !bitVectBitValue (_G.regAssigned, result->key) &&
1806 /* the number of free regs + number of regs in this LR
1807 can accomodate the what result Needs */
1808 ((nfreeRegsType (result->regType) +
1809 sym->nRegs) >= result->nRegs)
1813 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1815 result->regs[i] = sym->regs[i];
1817 result->regs[i] = getRegGpr (ic, ebp, result);
1819 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1823 /* free the remaining */
1824 for (; i < sym->nRegs; i++)
1828 if (!symHasReg (psym, sym->regs[i]))
1829 freeReg (sym->regs[i]);
1832 freeReg (sym->regs[i]);
1839 /*-----------------------------------------------------------------*/
1840 /* reassignLR - reassign this to registers */
1841 /*-----------------------------------------------------------------*/
1843 reassignLR (operand * op)
1845 symbol *sym = OP_SYMBOL (op);
1848 debugLog ("%s\n", __FUNCTION__);
1849 /* not spilt any more */
1850 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1851 bitVectUnSetBit (_G.spiltSet, sym->key);
1853 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1857 for (i = 0; i < sym->nRegs; i++)
1858 sym->regs[i]->isFree = 0;
1861 /*-----------------------------------------------------------------*/
1862 /* willCauseSpill - determines if allocating will cause a spill */
1863 /*-----------------------------------------------------------------*/
1865 willCauseSpill (int nr, int rt)
1867 debugLog ("%s\n", __FUNCTION__);
1868 /* first check if there are any avlb registers
1869 of te type required */
1872 /* special case for pointer type
1873 if pointer type not avlb then
1874 check for type gpr */
1875 if (nFreeRegs (rt) >= nr)
1877 if (nFreeRegs (REG_GPR) >= nr)
1882 if (pic14_ptrRegReq)
1884 if (nFreeRegs (rt) >= nr)
1889 if (nFreeRegs (REG_PTR) +
1890 nFreeRegs (REG_GPR) >= nr)
1895 debugLog (" ... yep it will (cause a spill)\n");
1896 /* it will cause a spil */
1900 /*-----------------------------------------------------------------*/
1901 /* positionRegs - the allocator can allocate same registers to res- */
1902 /* ult and operand, if this happens make sure they are in the same */
1903 /* position as the operand otherwise chaos results */
1904 /*-----------------------------------------------------------------*/
1906 positionRegs (symbol * result, symbol * opsym, int lineno)
1908 int count = min (result->nRegs, opsym->nRegs);
1909 int i, j = 0, shared = 0;
1911 debugLog ("%s\n", __FUNCTION__);
1912 /* if the result has been spilt then cannot share */
1917 /* first make sure that they actually share */
1918 for (i = 0; i < count; i++)
1920 for (j = 0; j < count; j++)
1922 if (result->regs[i] == opsym->regs[j] && i != j)
1932 regs *tmp = result->regs[i];
1933 result->regs[i] = result->regs[j];
1934 result->regs[j] = tmp;
1939 /*-----------------------------------------------------------------*/
1940 /* serialRegAssign - serially allocate registers to the variables */
1941 /*-----------------------------------------------------------------*/
1943 serialRegAssign (eBBlock ** ebbs, int count)
1947 debugLog ("%s\n", __FUNCTION__);
1948 /* for all blocks */
1949 for (i = 0; i < count; i++)
1954 if (ebbs[i]->noPath &&
1955 (ebbs[i]->entryLabel != entryLabel &&
1956 ebbs[i]->entryLabel != returnLabel))
1959 /* of all instructions do */
1960 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1963 debugLog (" op: %s\n", decodeOp (ic->op));
1965 /* if this is an ipop that means some live
1966 range will have to be assigned again */
1968 reassignLR (IC_LEFT (ic));
1970 /* if result is present && is a true symbol */
1971 if (IC_RESULT (ic) && ic->op != IFX &&
1972 IS_TRUE_SYMOP (IC_RESULT (ic)))
1973 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1975 /* take away registers from live
1976 ranges that end at this instruction */
1977 deassignLRs (ic, ebbs[i]);
1979 /* some don't need registers */
1980 if (SKIP_IC2 (ic) ||
1981 ic->op == JUMPTABLE ||
1985 (IC_RESULT (ic) && POINTER_SET (ic)))
1988 /* now we need to allocate registers
1989 only for the result */
1992 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1998 /* if it does not need or is spilt
1999 or is already assigned to registers
2000 or will not live beyond this instructions */
2003 bitVectBitValue (_G.regAssigned, sym->key) ||
2004 sym->liveTo <= ic->seq)
2007 /* if some liverange has been spilt at the block level
2008 and this one live beyond this block then spil this
2010 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2015 /* if trying to allocate this will cause
2016 a spill and there is nothing to spill
2017 or this one is rematerializable then
2019 willCS = willCauseSpill (sym->nRegs, sym->regType);
2020 spillable = computeSpillable (ic);
2022 (willCS && bitVectIsZero (spillable)))
2030 /* if it has a spillocation & is used less than
2031 all other live ranges then spill this */
2033 if (sym->usl.spillLoc) {
2034 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2035 allLRs, ebbs[i], ic));
2036 if (leastUsed && leastUsed->used > sym->used) {
2041 /* if none of the liveRanges have a spillLocation then better
2042 to spill this one than anything else already assigned to registers */
2043 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2044 /* if this is local to this block then we might find a block spil */
2045 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2053 if (ic->op == RECEIVE)
2054 debugLog ("When I get clever, I'll optimize the receive logic\n");
2056 /* if we need ptr regs for the right side
2058 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2059 <= (unsigned) PTRSIZE)
2064 /* else we assign registers to it */
2065 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2067 debugLog (" %d - \n", __LINE__);
2069 bitVectDebugOn(_G.regAssigned, debugF);
2071 for (j = 0; j < sym->nRegs; j++)
2073 if (sym->regType == REG_PTR)
2074 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2076 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2078 /* if the allocation falied which means
2079 this was spilt then break */
2083 debugLog (" %d - \n", __LINE__);
2085 /* if it shares registers with operands make sure
2086 that they are in the same position */
2087 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2088 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2089 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2090 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2091 /* do the same for the right operand */
2092 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2093 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2094 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2095 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2097 debugLog (" %d - \n", __LINE__);
2100 debugLog (" %d - \n", __LINE__);
2110 /*-----------------------------------------------------------------*/
2111 /* rUmaskForOp :- returns register mask for an operand */
2112 /*-----------------------------------------------------------------*/
2114 rUmaskForOp (operand * op)
2120 debugLog ("%s\n", __FUNCTION__);
2121 /* only temporaries are assigned registers */
2125 sym = OP_SYMBOL (op);
2127 /* if spilt or no registers assigned to it
2129 if (sym->isspilt || !sym->nRegs)
2132 rumask = newBitVect (pic14_nRegs);
2134 for (j = 0; j < sym->nRegs; j++)
2136 rumask = bitVectSetBit (rumask,
2137 sym->regs[j]->rIdx);
2143 /*-----------------------------------------------------------------*/
2144 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2145 /*-----------------------------------------------------------------*/
2147 regsUsedIniCode (iCode * ic)
2149 bitVect *rmask = newBitVect (pic14_nRegs);
2151 debugLog ("%s\n", __FUNCTION__);
2152 /* do the special cases first */
2155 rmask = bitVectUnion (rmask,
2156 rUmaskForOp (IC_COND (ic)));
2160 /* for the jumptable */
2161 if (ic->op == JUMPTABLE)
2163 rmask = bitVectUnion (rmask,
2164 rUmaskForOp (IC_JTCOND (ic)));
2169 /* of all other cases */
2171 rmask = bitVectUnion (rmask,
2172 rUmaskForOp (IC_LEFT (ic)));
2176 rmask = bitVectUnion (rmask,
2177 rUmaskForOp (IC_RIGHT (ic)));
2180 rmask = bitVectUnion (rmask,
2181 rUmaskForOp (IC_RESULT (ic)));
2187 /*-----------------------------------------------------------------*/
2188 /* createRegMask - for each instruction will determine the regsUsed */
2189 /*-----------------------------------------------------------------*/
2191 createRegMask (eBBlock ** ebbs, int count)
2195 debugLog ("%s\n", __FUNCTION__);
2196 /* for all blocks */
2197 for (i = 0; i < count; i++)
2201 if (ebbs[i]->noPath &&
2202 (ebbs[i]->entryLabel != entryLabel &&
2203 ebbs[i]->entryLabel != returnLabel))
2206 /* for all instructions */
2207 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2212 if (SKIP_IC2 (ic) || !ic->rlive)
2215 /* first mark the registers used in this
2217 ic->rUsed = regsUsedIniCode (ic);
2218 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2220 /* now create the register mask for those
2221 registers that are in use : this is a
2222 super set of ic->rUsed */
2223 ic->rMask = newBitVect (pic14_nRegs + 1);
2225 /* for all live Ranges alive at this point */
2226 for (j = 1; j < ic->rlive->size; j++)
2231 /* if not alive then continue */
2232 if (!bitVectBitValue (ic->rlive, j))
2235 /* find the live range we are interested in */
2236 if (!(sym = hTabItemWithKey (liveRanges, j)))
2238 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2239 "createRegMask cannot find live range");
2243 /* if no register assigned to it */
2244 if (!sym->nRegs || sym->isspilt)
2247 /* for all the registers allocated to it */
2248 for (k = 0; k < sym->nRegs; k++)
2251 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2257 /*-----------------------------------------------------------------*/
2258 /* rematStr - returns the rematerialized string for a remat var */
2259 /*-----------------------------------------------------------------*/
2261 rematStr (symbol * sym)
2264 iCode *ic = sym->rematiCode;
2265 symbol *psym = NULL;
2267 debugLog ("%s\n", __FUNCTION__);
2269 //printf ("%s\n", s);
2271 /* if plus or minus print the right hand side */
2273 if (ic->op == '+' || ic->op == '-') {
2275 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2277 sprintf (s, "(%s %c 0x%04x)",
2278 OP_SYMBOL (IC_LEFT (ric))->rname,
2280 (int) operandLitValue (IC_RIGHT (ic)));
2283 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2285 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2286 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2291 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2292 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2294 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2299 /*-----------------------------------------------------------------*/
2300 /* rematStr - returns the rematerialized string for a remat var */
2301 /*-----------------------------------------------------------------*/
2303 rematStr (symbol * sym)
2306 iCode *ic = sym->rematiCode;
2308 debugLog ("%s\n", __FUNCTION__);
2313 /* if plus or minus print the right hand side */
2315 if (ic->op == '+' || ic->op == '-') {
2316 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2319 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2323 if (ic->op == '+' || ic->op == '-')
2325 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2326 sprintf (s, "(%s %c 0x%04x)",
2327 OP_SYMBOL (IC_LEFT (ric))->rname,
2329 (int) operandLitValue (IC_RIGHT (ic)));
2332 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2334 fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2338 /* we reached the end */
2339 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2343 printf ("%s\n", buffer);
2348 /*-----------------------------------------------------------------*/
2349 /* regTypeNum - computes the type & number of registers required */
2350 /*-----------------------------------------------------------------*/
2358 debugLog ("%s\n", __FUNCTION__);
2359 /* for each live range do */
2360 for (sym = hTabFirstItem (liveRanges, &k); sym;
2361 sym = hTabNextItem (liveRanges, &k)) {
2363 debugLog (" %d - %s\n", __LINE__, sym->rname);
2365 /* if used zero times then no registers needed */
2366 if ((sym->liveTo - sym->liveFrom) == 0)
2370 /* if the live range is a temporary */
2373 debugLog (" %d - itemp register\n", __LINE__);
2375 /* if the type is marked as a conditional */
2376 if (sym->regType == REG_CND)
2379 /* if used in return only then we don't
2381 if (sym->ruonly || sym->accuse) {
2382 if (IS_AGGREGATE (sym->type) || sym->isptr)
2383 sym->type = aggrToPtr (sym->type, FALSE);
2384 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2389 /* if the symbol has only one definition &
2390 that definition is a get_pointer and the
2391 pointer we are getting is rematerializable and
2394 if (bitVectnBitsOn (sym->defs) == 1 &&
2395 (ic = hTabItemWithKey (iCodehTab,
2396 bitVectFirstBit (sym->defs))) &&
2399 !IS_BITVAR (sym->etype)) {
2402 debugLog (" %d - \n", __LINE__);
2404 /* if remat in data space */
2405 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2406 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2408 /* create a psuedo symbol & force a spil */
2409 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2410 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2411 psym->type = sym->type;
2412 psym->etype = sym->etype;
2413 strcpy (psym->rname, psym->name);
2415 sym->usl.spillLoc = psym;
2419 /* if in data space or idata space then try to
2420 allocate pointer register */
2424 /* if not then we require registers */
2425 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2426 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2427 getSize (sym->type));
2430 if(IS_PTR_CONST (sym->type)) {
2431 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2435 if (sym->nRegs > 4) {
2436 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2437 printTypeChain (sym->type, stderr);
2438 fprintf (stderr, "\n");
2441 /* determine the type of register required */
2442 if (sym->nRegs == 1 &&
2443 IS_PTR (sym->type) &&
2445 sym->regType = REG_PTR;
2447 sym->regType = REG_GPR;
2450 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2454 /* for the first run we don't provide */
2455 /* registers for true symbols we will */
2456 /* see how things go */
2461 DEFSETFUNC (markRegFree)
2463 ((regs *)item)->isFree = 1;
2468 DEFSETFUNC (deallocReg)
2470 ((regs *)item)->isFree = 1;
2471 ((regs *)item)->wasUsed = 0;
2475 /*-----------------------------------------------------------------*/
2476 /* freeAllRegs - mark all registers as free */
2477 /*-----------------------------------------------------------------*/
2479 pic14_freeAllRegs ()
2483 debugLog ("%s\n", __FUNCTION__);
2485 applyToSet(dynAllocRegs,markRegFree);
2486 applyToSet(dynStackRegs,markRegFree);
2489 for (i = 0; i < pic14_nRegs; i++)
2490 regspic14[i].isFree = 1;
2494 /*-----------------------------------------------------------------*/
2495 /*-----------------------------------------------------------------*/
2497 pic14_deallocateAllRegs ()
2501 debugLog ("%s\n", __FUNCTION__);
2503 applyToSet(dynAllocRegs,deallocReg);
2506 for (i = 0; i < pic14_nRegs; i++) {
2507 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2508 regspic14[i].isFree = 1;
2509 regspic14[i].wasUsed = 0;
2516 /*-----------------------------------------------------------------*/
2517 /* deallocStackSpil - this will set the stack pointer back */
2518 /*-----------------------------------------------------------------*/
2520 DEFSETFUNC (deallocStackSpil)
2524 debugLog ("%s\n", __FUNCTION__);
2529 /*-----------------------------------------------------------------*/
2530 /* farSpacePackable - returns the packable icode for far variables */
2531 /*-----------------------------------------------------------------*/
2533 farSpacePackable (iCode * ic)
2537 debugLog ("%s\n", __FUNCTION__);
2538 /* go thru till we find a definition for the
2539 symbol on the right */
2540 for (dic = ic->prev; dic; dic = dic->prev)
2543 /* if the definition is a call then no */
2544 if ((dic->op == CALL || dic->op == PCALL) &&
2545 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2550 /* if shift by unknown amount then not */
2551 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2552 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2555 /* if pointer get and size > 1 */
2556 if (POINTER_GET (dic) &&
2557 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2560 if (POINTER_SET (dic) &&
2561 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2564 /* if any three is a true symbol in far space */
2565 if (IC_RESULT (dic) &&
2566 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2567 isOperandInFarSpace (IC_RESULT (dic)))
2570 if (IC_RIGHT (dic) &&
2571 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2572 isOperandInFarSpace (IC_RIGHT (dic)) &&
2573 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2576 if (IC_LEFT (dic) &&
2577 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2578 isOperandInFarSpace (IC_LEFT (dic)) &&
2579 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2582 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2584 if ((dic->op == LEFT_OP ||
2585 dic->op == RIGHT_OP ||
2587 IS_OP_LITERAL (IC_RIGHT (dic)))
2597 /*-----------------------------------------------------------------*/
2598 /* packRegsForAssign - register reduction for assignment */
2599 /*-----------------------------------------------------------------*/
2601 packRegsForAssign (iCode * ic, eBBlock * ebp)
2606 debugLog ("%s\n", __FUNCTION__);
2608 debugAopGet (" result:", IC_RESULT (ic));
2609 debugAopGet (" left:", IC_LEFT (ic));
2610 debugAopGet (" right:", IC_RIGHT (ic));
2612 /* if this is at an absolute address, then get the address. */
2613 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2614 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2615 debugLog (" %d - found config word declaration\n", __LINE__);
2616 if(IS_VALOP(IC_RIGHT(ic))) {
2617 debugLog (" setting config word to %x\n",
2618 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2619 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2620 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2623 /* remove the assignment from the iCode chain. */
2625 remiCodeFromeBBlock (ebp, ic);
2626 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2627 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2634 if (!IS_ITEMP (IC_RESULT (ic))) {
2635 allocDirReg(IC_RESULT (ic));
2636 debugLog (" %d - result is not temp\n", __LINE__);
2639 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2640 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2641 allocDirReg(IC_LEFT (ic));
2645 if (!IS_ITEMP (IC_RIGHT (ic))) {
2646 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2647 allocDirReg(IC_RIGHT (ic));
2651 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2652 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2654 debugLog (" %d - not packing - right side fails \n", __LINE__);
2658 /* if the true symbol is defined in far space or on stack
2659 then we should not since this will increase register pressure */
2660 if (isOperandInFarSpace (IC_RESULT (ic)))
2662 if ((dic = farSpacePackable (ic)))
2668 /* find the definition of iTempNN scanning backwards if we find a
2669 a use of the true symbol before we find the definition then
2671 for (dic = ic->prev; dic; dic = dic->prev)
2674 /* if there is a function call and this is
2675 a parameter & not my parameter then don't pack it */
2676 if ((dic->op == CALL || dic->op == PCALL) &&
2677 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2678 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2680 debugLog (" %d - \n", __LINE__);
2688 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2689 IS_OP_VOLATILE (IC_RESULT (dic)))
2691 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2696 if (IS_SYMOP (IC_RESULT (dic)) &&
2697 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2699 /* A previous result was assigned to the same register - we'll our definition */
2700 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2701 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2702 if (POINTER_SET (dic))
2708 if (IS_SYMOP (IC_RIGHT (dic)) &&
2709 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2710 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2712 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2717 if (IS_SYMOP (IC_LEFT (dic)) &&
2718 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2719 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2721 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2726 if (POINTER_SET (dic) &&
2727 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2729 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2737 return 0; /* did not find */
2739 /* if the result is on stack or iaccess then it must be
2740 the same atleast one of the operands */
2741 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2742 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2745 /* the operation has only one symbol
2746 operator then we can pack */
2747 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2748 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2751 if (!((IC_LEFT (dic) &&
2752 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2754 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2758 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2759 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2760 /* found the definition */
2761 /* replace the result with the result of */
2762 /* this assignment and remove this assignment */
2763 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2764 IC_RESULT (dic) = IC_RESULT (ic);
2766 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2768 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2770 /* delete from liverange table also
2771 delete from all the points inbetween and the new
2773 for (sic = dic; sic != ic; sic = sic->next)
2775 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2776 if (IS_ITEMP (IC_RESULT (dic)))
2777 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2780 remiCodeFromeBBlock (ebp, ic);
2781 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2782 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2783 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2789 /*-----------------------------------------------------------------*/
2790 /* findAssignToSym : scanning backwards looks for first assig found */
2791 /*-----------------------------------------------------------------*/
2793 findAssignToSym (operand * op, iCode * ic)
2797 debugLog ("%s\n", __FUNCTION__);
2798 for (dic = ic->prev; dic; dic = dic->prev)
2801 /* if definition by assignment */
2802 if (dic->op == '=' &&
2803 !POINTER_SET (dic) &&
2804 IC_RESULT (dic)->key == op->key
2805 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2809 /* we are interested only if defined in far space */
2810 /* or in stack space in case of + & - */
2812 /* if assigned to a non-symbol then return
2814 if (!IS_SYMOP (IC_RIGHT (dic)))
2817 /* if the symbol is in far space then
2819 if (isOperandInFarSpace (IC_RIGHT (dic)))
2822 /* for + & - operations make sure that
2823 if it is on the stack it is the same
2824 as one of the three operands */
2825 if ((ic->op == '+' || ic->op == '-') &&
2826 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2829 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2830 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2831 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2839 /* if we find an usage then we cannot delete it */
2840 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2843 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2846 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2850 /* now make sure that the right side of dic
2851 is not defined between ic & dic */
2854 iCode *sic = dic->next;
2856 for (; sic != ic; sic = sic->next)
2857 if (IC_RESULT (sic) &&
2858 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2867 /*-----------------------------------------------------------------*/
2868 /* packRegsForSupport :- reduce some registers for support calls */
2869 /*-----------------------------------------------------------------*/
2871 packRegsForSupport (iCode * ic, eBBlock * ebp)
2875 debugLog ("%s\n", __FUNCTION__);
2876 /* for the left & right operand :- look to see if the
2877 left was assigned a true symbol in far space in that
2878 case replace them */
2879 if (IS_ITEMP (IC_LEFT (ic)) &&
2880 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2882 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2888 debugAopGet ("removing left:", IC_LEFT (ic));
2890 /* found it we need to remove it from the
2892 for (sic = dic; sic != ic; sic = sic->next)
2893 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2895 IC_LEFT (ic)->operand.symOperand =
2896 IC_RIGHT (dic)->operand.symOperand;
2897 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2898 remiCodeFromeBBlock (ebp, dic);
2899 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2900 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2904 /* do the same for the right operand */
2907 IS_ITEMP (IC_RIGHT (ic)) &&
2908 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2910 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2916 /* if this is a subtraction & the result
2917 is a true symbol in far space then don't pack */
2918 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2920 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2921 if (IN_FARSPACE (SPEC_OCLS (etype)))
2925 debugAopGet ("removing right:", IC_RIGHT (ic));
2927 /* found it we need to remove it from the
2929 for (sic = dic; sic != ic; sic = sic->next)
2930 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2932 IC_RIGHT (ic)->operand.symOperand =
2933 IC_RIGHT (dic)->operand.symOperand;
2934 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2936 remiCodeFromeBBlock (ebp, dic);
2937 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2938 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2945 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2948 /*-----------------------------------------------------------------*/
2949 /* packRegsForOneuse : - will reduce some registers for single Use */
2950 /*-----------------------------------------------------------------*/
2952 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2957 debugLog ("%s\n", __FUNCTION__);
2958 /* if returning a literal then do nothing */
2962 /* only upto 2 bytes since we cannot predict
2963 the usage of b, & acc */
2964 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2969 /* this routine will mark the a symbol as used in one
2970 instruction use only && if the definition is local
2971 (ie. within the basic block) && has only one definition &&
2972 that definition is either a return value from a
2973 function or does not contain any variables in
2975 uses = bitVectCopy (OP_USES (op));
2976 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2977 if (!bitVectIsZero (uses)) /* has other uses */
2980 /* if it has only one defintion */
2981 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2982 return NULL; /* has more than one definition */
2984 /* get that definition */
2986 hTabItemWithKey (iCodehTab,
2987 bitVectFirstBit (OP_DEFS (op)))))
2990 /* found the definition now check if it is local */
2991 if (dic->seq < ebp->fSeq ||
2992 dic->seq > ebp->lSeq)
2993 return NULL; /* non-local */
2995 /* now check if it is the return from
2997 if (dic->op == CALL || dic->op == PCALL)
2999 if (ic->op != SEND && ic->op != RETURN &&
3000 !POINTER_SET(ic) && !POINTER_GET(ic))
3002 OP_SYMBOL (op)->ruonly = 1;
3009 /* otherwise check that the definition does
3010 not contain any symbols in far space */
3011 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3012 isOperandInFarSpace (IC_RIGHT (dic)) ||
3013 IS_OP_RUONLY (IC_LEFT (ic)) ||
3014 IS_OP_RUONLY (IC_RIGHT (ic)))
3019 /* if pointer set then make sure the pointer
3021 if (POINTER_SET (dic) &&
3022 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3025 if (POINTER_GET (dic) &&
3026 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3031 /* also make sure the intervenening instructions
3032 don't have any thing in far space */
3033 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3036 /* if there is an intervening function call then no */
3037 if (dic->op == CALL || dic->op == PCALL)
3039 /* if pointer set then make sure the pointer
3041 if (POINTER_SET (dic) &&
3042 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3045 if (POINTER_GET (dic) &&
3046 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3049 /* if address of & the result is remat then okay */
3050 if (dic->op == ADDRESS_OF &&
3051 OP_SYMBOL (IC_RESULT (dic))->remat)
3054 /* if operand has size of three or more & this
3055 operation is a '*','/' or '%' then 'b' may
3057 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3058 getSize (operandType (op)) >= 3)
3061 /* if left or right or result is in far space */
3062 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3063 isOperandInFarSpace (IC_RIGHT (dic)) ||
3064 isOperandInFarSpace (IC_RESULT (dic)) ||
3065 IS_OP_RUONLY (IC_LEFT (dic)) ||
3066 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3067 IS_OP_RUONLY (IC_RESULT (dic)))
3073 OP_SYMBOL (op)->ruonly = 1;
3078 /*-----------------------------------------------------------------*/
3079 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3080 /*-----------------------------------------------------------------*/
3082 isBitwiseOptimizable (iCode * ic)
3084 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3085 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3087 debugLog ("%s\n", __FUNCTION__);
3088 /* bitwise operations are considered optimizable
3089 under the following conditions (Jean-Louis VERN)
3101 if (IS_LITERAL (rtype) ||
3102 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3108 /*-----------------------------------------------------------------*/
3109 /* packRegsForAccUse - pack registers for acc use */
3110 /*-----------------------------------------------------------------*/
3112 packRegsForAccUse (iCode * ic)
3116 debugLog ("%s\n", __FUNCTION__);
3118 /* if this is an aggregate, e.g. a one byte char array */
3119 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3122 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3124 /* if + or - then it has to be one byte result */
3125 if ((ic->op == '+' || ic->op == '-')
3126 && getSize (operandType (IC_RESULT (ic))) > 1)
3129 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3130 /* if shift operation make sure right side is not a literal */
3131 if (ic->op == RIGHT_OP &&
3132 (isOperandLiteral (IC_RIGHT (ic)) ||
3133 getSize (operandType (IC_RESULT (ic))) > 1))
3136 if (ic->op == LEFT_OP &&
3137 (isOperandLiteral (IC_RIGHT (ic)) ||
3138 getSize (operandType (IC_RESULT (ic))) > 1))
3141 if (IS_BITWISE_OP (ic) &&
3142 getSize (operandType (IC_RESULT (ic))) > 1)
3146 /* has only one definition */
3147 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3150 /* has only one use */
3151 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3154 /* and the usage immediately follows this iCode */
3155 if (!(uic = hTabItemWithKey (iCodehTab,
3156 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3159 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3160 if (ic->next != uic)
3163 /* if it is a conditional branch then we definitely can */
3167 if (uic->op == JUMPTABLE)
3170 /* if the usage is not is an assignment
3171 or an arithmetic / bitwise / shift operation then not */
3172 if (POINTER_SET (uic) &&
3173 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3176 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3177 if (uic->op != '=' &&
3178 !IS_ARITHMETIC_OP (uic) &&
3179 !IS_BITWISE_OP (uic) &&
3180 uic->op != LEFT_OP &&
3181 uic->op != RIGHT_OP)
3184 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3185 /* if used in ^ operation then make sure right is not a
3187 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3190 /* if shift operation make sure right side is not a literal */
3191 if (uic->op == RIGHT_OP &&
3192 (isOperandLiteral (IC_RIGHT (uic)) ||
3193 getSize (operandType (IC_RESULT (uic))) > 1))
3196 if (uic->op == LEFT_OP &&
3197 (isOperandLiteral (IC_RIGHT (uic)) ||
3198 getSize (operandType (IC_RESULT (uic))) > 1))
3201 /* make sure that the result of this icode is not on the
3202 stack, since acc is used to compute stack offset */
3203 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3204 OP_SYMBOL (IC_RESULT (uic))->onStack)
3207 /* if either one of them in far space then we cannot */
3208 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3209 isOperandInFarSpace (IC_LEFT (uic))) ||
3210 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3211 isOperandInFarSpace (IC_RIGHT (uic))))
3214 /* if the usage has only one operand then we can */
3215 if (IC_LEFT (uic) == NULL ||
3216 IC_RIGHT (uic) == NULL)
3219 /* make sure this is on the left side if not
3220 a '+' since '+' is commutative */
3221 if (ic->op != '+' &&
3222 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3225 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3226 /* if one of them is a literal then we can */
3227 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3228 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3229 (getSize (operandType (IC_RESULT (uic))) <= 1))
3231 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3235 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3236 /* if the other one is not on stack then we can */
3237 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3238 (IS_ITEMP (IC_RIGHT (uic)) ||
3239 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3240 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3243 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3244 (IS_ITEMP (IC_LEFT (uic)) ||
3245 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3246 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3252 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3253 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3258 /*-----------------------------------------------------------------*/
3259 /* packForPush - hueristics to reduce iCode for pushing */
3260 /*-----------------------------------------------------------------*/
3262 packForReceive (iCode * ic, eBBlock * ebp)
3266 debugLog ("%s\n", __FUNCTION__);
3267 debugAopGet (" result:", IC_RESULT (ic));
3268 debugAopGet (" left:", IC_LEFT (ic));
3269 debugAopGet (" right:", IC_RIGHT (ic));
3274 for (dic = ic->next; dic; dic = dic->next)
3279 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3280 debugLog (" used on left\n");
3281 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3282 debugLog (" used on right\n");
3283 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3284 debugLog (" used on result\n");
3286 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3287 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3292 debugLog (" hey we can remove this unnecessary assign\n");
3294 /*-----------------------------------------------------------------*/
3295 /* packForPush - hueristics to reduce iCode for pushing */
3296 /*-----------------------------------------------------------------*/
3298 packForPush (iCode * ic, eBBlock * ebp)
3302 debugLog ("%s\n", __FUNCTION__);
3303 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3306 /* must have only definition & one usage */
3307 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3308 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3311 /* find the definition */
3312 if (!(dic = hTabItemWithKey (iCodehTab,
3313 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3316 if (dic->op != '=' || POINTER_SET (dic))
3319 /* we now we know that it has one & only one def & use
3320 and the that the definition is an assignment */
3321 IC_LEFT (ic) = IC_RIGHT (dic);
3323 remiCodeFromeBBlock (ebp, dic);
3324 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3325 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3328 void printSymType(char * str, sym_link *sl)
3330 debugLog (" %s Symbol type: ",str);
3331 printTypeChain( sl, debugF);
3336 /*-----------------------------------------------------------------*/
3337 /* packRegisters - does some transformations to reduce register */
3339 /*-----------------------------------------------------------------*/
3341 packRegisters (eBBlock * ebp)
3346 debugLog ("%s\n", __FUNCTION__);
3352 /* look for assignments of the form */
3353 /* iTempNN = TRueSym (someoperation) SomeOperand */
3355 /* TrueSym := iTempNN:1 */
3356 for (ic = ebp->sch; ic; ic = ic->next)
3359 /* find assignment of the form TrueSym := iTempNN:1 */
3360 if (ic->op == '=' && !POINTER_SET (ic))
3361 change += packRegsForAssign (ic, ebp);
3365 if (POINTER_SET (ic))
3366 debugLog ("pointer is set\n");
3367 debugAopGet (" result:", IC_RESULT (ic));
3368 debugAopGet (" left:", IC_LEFT (ic));
3369 debugAopGet (" right:", IC_RIGHT (ic));
3378 for (ic = ebp->sch; ic; ic = ic->next) {
3380 if(IS_SYMOP ( IC_LEFT(ic))) {
3381 //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3383 debugAopGet (" left:", IC_LEFT (ic));
3384 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3385 debugLog (" is a pointer");
3387 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3390 if(IS_SYMOP ( IC_RIGHT(ic))) {
3391 debugAopGet (" right:", IC_RIGHT (ic));
3392 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3395 if(IS_SYMOP ( IC_RESULT(ic))) {
3396 debugAopGet (" result:", IC_RESULT (ic));
3397 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3400 if (POINTER_SET (ic))
3401 debugLog (" %d - Pointer set\n", __LINE__);
3404 /* if this is an itemp & result of a address of a true sym
3405 then mark this as rematerialisable */
3406 if (ic->op == ADDRESS_OF &&
3407 IS_ITEMP (IC_RESULT (ic)) &&
3408 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3409 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3410 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3413 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3415 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3416 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3417 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3421 /* if straight assignment then carry remat flag if
3422 this is the only definition */
3423 if (ic->op == '=' &&
3424 !POINTER_SET (ic) &&
3425 IS_SYMOP (IC_RIGHT (ic)) &&
3426 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3427 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3429 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3431 OP_SYMBOL (IC_RESULT (ic))->remat =
3432 OP_SYMBOL (IC_RIGHT (ic))->remat;
3433 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3434 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3437 /* if this is a +/- operation with a rematerizable
3438 then mark this as rematerializable as well */
3439 if ((ic->op == '+' || ic->op == '-') &&
3440 (IS_SYMOP (IC_LEFT (ic)) &&
3441 IS_ITEMP (IC_RESULT (ic)) &&
3442 OP_SYMBOL (IC_LEFT (ic))->remat &&
3443 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3444 IS_OP_LITERAL (IC_RIGHT (ic))))
3446 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3448 operandLitValue (IC_RIGHT (ic));
3449 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3450 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3451 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3454 /* mark the pointer usages */
3455 if (POINTER_SET (ic))
3457 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3458 debugLog (" marking as a pointer (set) =>");
3459 debugAopGet (" result:", IC_RESULT (ic));
3461 if (POINTER_GET (ic))
3463 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3464 debugLog (" marking as a pointer (get) =>");
3465 debugAopGet (" left:", IC_LEFT (ic));
3470 /* if we are using a symbol on the stack
3471 then we should say pic14_ptrRegReq */
3472 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3473 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3474 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3475 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3476 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3477 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3480 if (IS_SYMOP (IC_LEFT (ic)))
3481 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3482 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3483 if (IS_SYMOP (IC_RIGHT (ic)))
3484 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3485 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3486 if (IS_SYMOP (IC_RESULT (ic)))
3487 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3488 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3491 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3495 /* if the condition of an if instruction
3496 is defined in the previous instruction then
3497 mark the itemp as a conditional */
3498 if ((IS_CONDITIONAL (ic) ||
3499 ((ic->op == BITWISEAND ||
3502 isBitwiseOptimizable (ic))) &&
3503 ic->next && ic->next->op == IFX &&
3504 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3505 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3508 debugLog (" %d\n", __LINE__);
3509 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3513 /* reduce for support function calls */
3514 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3515 packRegsForSupport (ic, ebp);
3517 /* if a parameter is passed, it's in W, so we may not
3518 need to place a copy in a register */
3519 if (ic->op == RECEIVE)
3520 packForReceive (ic, ebp);
3522 /* some cases the redundant moves can
3523 can be eliminated for return statements */
3524 if ((ic->op == RETURN || ic->op == SEND) &&
3525 !isOperandInFarSpace (IC_LEFT (ic)) &&
3527 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3529 /* if pointer set & left has a size more than
3530 one and right is not in far space */
3531 if (POINTER_SET (ic) &&
3532 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3533 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3534 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3535 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3537 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3539 /* if pointer get */
3540 if (POINTER_GET (ic) &&
3541 !isOperandInFarSpace (IC_RESULT (ic)) &&
3542 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3543 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3544 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3546 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3549 /* if this is cast for intergral promotion then
3550 check if only use of the definition of the
3551 operand being casted/ if yes then replace
3552 the result of that arithmetic operation with
3553 this result and get rid of the cast */
3554 if (ic->op == CAST) {
3556 sym_link *fromType = operandType (IC_RIGHT (ic));
3557 sym_link *toType = operandType (IC_LEFT (ic));
3559 debugLog (" %d - casting\n", __LINE__);
3561 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3562 getSize (fromType) != getSize (toType)) {
3565 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3568 if (IS_ARITHMETIC_OP (dic)) {
3570 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3571 IC_RESULT (dic) = IC_RESULT (ic);
3572 remiCodeFromeBBlock (ebp, ic);
3573 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3574 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3575 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3579 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3583 /* if the type from and type to are the same
3584 then if this is the only use then packit */
3585 if (compareType (operandType (IC_RIGHT (ic)),
3586 operandType (IC_LEFT (ic))) == 1) {
3588 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3591 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3592 IC_RESULT (dic) = IC_RESULT (ic);
3593 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3594 remiCodeFromeBBlock (ebp, ic);
3595 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3596 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3604 iTempNN := (some variable in farspace) V1
3609 if (ic->op == IPUSH)
3611 packForPush (ic, ebp);
3615 /* pack registers for accumulator use, when the
3616 result of an arithmetic or bit wise operation
3617 has only one use, that use is immediately following
3618 the defintion and the using iCode has only one
3619 operand or has two operands but one is literal &
3620 the result of that operation is not on stack then
3621 we can leave the result of this operation in acc:b
3623 if ((IS_ARITHMETIC_OP (ic)
3625 || IS_BITWISE_OP (ic)
3627 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3630 IS_ITEMP (IC_RESULT (ic)) &&
3631 getSize (operandType (IC_RESULT (ic))) <= 2)
3633 packRegsForAccUse (ic);
3639 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3643 if (!debug || !debugF)
3646 for (i = 0; i < count; i++)
3648 fprintf (debugF, "\n----------------------------------------------------------------\n");
3649 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3650 ebbs[i]->entryLabel->name,
3653 ebbs[i]->isLastInLoop);
3654 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3659 fprintf (debugF, "visited %d : hasFcall = %d\n",
3663 fprintf (debugF, "\ndefines bitVector :");
3664 bitVectDebugOn (ebbs[i]->defSet, debugF);
3665 fprintf (debugF, "\nlocal defines bitVector :");
3666 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3667 fprintf (debugF, "\npointers Set bitvector :");
3668 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3669 fprintf (debugF, "\nin pointers Set bitvector :");
3670 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3671 fprintf (debugF, "\ninDefs Set bitvector :");
3672 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3673 fprintf (debugF, "\noutDefs Set bitvector :");
3674 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3675 fprintf (debugF, "\nusesDefs Set bitvector :");
3676 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3677 fprintf (debugF, "\n----------------------------------------------------------------\n");
3678 printiCChain (ebbs[i]->sch, debugF);
3681 /*-----------------------------------------------------------------*/
3682 /* assignRegisters - assigns registers to each live range as need */
3683 /*-----------------------------------------------------------------*/
3685 pic14_assignRegisters (eBBlock ** ebbs, int count)
3690 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3691 debugLog ("\nebbs before optimizing:\n");
3692 dumpEbbsToDebug (ebbs, count);
3694 setToNull ((void *) &_G.funcrUsed);
3695 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3698 /* change assignments this will remove some
3699 live ranges reducing some register pressure */
3700 for (i = 0; i < count; i++)
3701 packRegisters (ebbs[i]);
3708 debugLog("dir registers allocated so far:\n");
3709 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3712 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3713 reg = hTabNextItem(dynDirectRegNames, &hkey);
3718 if (options.dump_pack)
3719 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3721 /* first determine for each live range the number of
3722 registers & the type of registers required for each */
3725 /* and serially allocate registers */
3726 serialRegAssign (ebbs, count);
3728 /* if stack was extended then tell the user */
3731 /* werror(W_TOOMANY_SPILS,"stack", */
3732 /* _G.stackExtend,currFunc->name,""); */
3738 /* werror(W_TOOMANY_SPILS,"data space", */
3739 /* _G.dataExtend,currFunc->name,""); */
3743 /* after that create the register mask
3744 for each of the instruction */
3745 createRegMask (ebbs, count);
3747 /* redo that offsets for stacked automatic variables */
3748 redoStackOffsets ();
3750 if (options.dump_rassgn)
3751 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3753 /* now get back the chain */
3754 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3756 debugLog ("ebbs after optimizing:\n");
3757 dumpEbbsToDebug (ebbs, count);
3762 /* free up any _G.stackSpil locations allocated */
3763 applyToSet (_G.stackSpil, deallocStackSpil);
3765 setToNull ((void **) &_G.stackSpil);
3766 setToNull ((void **) &_G.spiltSet);
3767 /* mark all registers as free */
3768 pic14_freeAllRegs ();
3770 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");