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 *);
48 extern void assignConfigWordValue(int address, int value);
58 bitVect *funcrUsed; /* registers used in a function */
64 /* Shared with gen.c */
65 int pic14_ptrRegReq; /* one byte pointer register required */
68 set *dynAllocRegs=NULL;
69 set *dynStackRegs=NULL;
70 set *dynProcessorRegs=NULL;
71 set *dynDirectRegs=NULL;
72 set *dynDirectBitRegs=NULL;
73 set *dynInternalRegs=NULL;
75 static hTab *dynDirectRegNames= NULL;
77 static int dynrIdx=0x20;
78 static int rDirectIdx=0;
80 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
82 int Gstack_base_addr=0; /* The starting address of registers that
83 * are used to pass and return parameters */
88 static void spillThis (symbol *);
90 static FILE *debugF = NULL;
91 /*-----------------------------------------------------------------*/
92 /* debugLog - open a file for debugging information */
93 /*-----------------------------------------------------------------*/
94 //static void debugLog(char *inst,char *fmt, ...)
96 debugLog (char *fmt,...)
98 static int append = 0; // First time through, open the file without append.
101 //char *bufferP=buffer;
104 if (!debug || !srcFileName)
110 /* create the file name */
111 strcpy (buffer, srcFileName);
112 strcat (buffer, ".d");
114 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
116 werror (E_FILE_OPEN_ERR, buffer);
119 append = 1; // Next time debubLog is called, we'll append the debug info
125 vsprintf (buffer, fmt, ap);
127 fprintf (debugF, "%s", buffer);
129 while (isspace(*bufferP)) bufferP++;
131 if (bufferP && *bufferP)
132 lineCurr = (lineCurr ?
133 connectLine(lineCurr,newLineNode(lb)) :
134 (lineHead = newLineNode(lb)));
135 lineCurr->isInline = _G.inLine;
136 lineCurr->isDebug = _G.debugLine;
146 fputc ('\n', debugF);
148 /*-----------------------------------------------------------------*/
149 /* debugLogClose - closes the debug log file (if opened) */
150 /*-----------------------------------------------------------------*/
160 #define AOP(op) op->aop
163 debugAopGet (char *str, operand * op)
168 printOperand (op, debugF);
176 decodeOp (unsigned int op)
179 if (op < 128 && op > ' ')
181 buffer[0] = (op & 0xff);
195 return "STRING_LITERAL";
231 return "LEFT_ASSIGN";
233 return "RIGHT_ASSIGN";
348 case GET_VALUE_AT_ADDRESS:
349 return "GET_VALUE_AT_ADDRESS";
367 return "ENDFUNCTION";
391 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
394 /*-----------------------------------------------------------------*/
395 /*-----------------------------------------------------------------*/
397 debugLogRegType (short type)
410 sprintf (buffer, "unknown reg type %d", type);
414 /*-----------------------------------------------------------------*/
415 /*-----------------------------------------------------------------*/
416 static int regname2key(char const *name)
425 key += (*name++) + 1;
429 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
433 /*-----------------------------------------------------------------*/
434 /* newReg - allocate and init memory for a new register */
435 /*-----------------------------------------------------------------*/
436 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
441 dReg = Safe_calloc(1,sizeof(regs));
443 dReg->pc_type = pc_type;
446 dReg->name = Safe_strdup(name);
448 sprintf(buffer,"r0x%02X", dReg->rIdx);
451 dReg->name = Safe_strdup(buffer);
453 //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
466 dReg->reg_alias = NULL;
467 dReg->reglives.usedpFlows = newSet();
468 dReg->reglives.assignedpFlows = newSet();
470 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
475 /*-----------------------------------------------------------------*/
476 /* regWithIdx - Search through a set of registers that matches idx */
477 /*-----------------------------------------------------------------*/
479 regWithIdx (set *dRegs, int idx, int fixed)
483 for (dReg = setFirstItem(dRegs) ; dReg ;
484 dReg = setNextItem(dRegs)) {
486 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
494 /*-----------------------------------------------------------------*/
495 /* regFindFree - Search for a free register in a set of registers */
496 /*-----------------------------------------------------------------*/
498 regFindFree (set *dRegs)
502 for (dReg = setFirstItem(dRegs) ; dReg ;
503 dReg = setNextItem(dRegs)) {
511 /*-----------------------------------------------------------------*/
512 /* initStack - allocate registers for a psuedo stack */
513 /*-----------------------------------------------------------------*/
514 void initStack(int base_address, int size)
519 Gstack_base_addr = base_address;
520 //fprintf(stderr,"initStack");
522 for(i = 0; i<size; i++)
523 addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
526 /*-----------------------------------------------------------------*
527 *-----------------------------------------------------------------*/
529 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
532 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
533 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
536 /*-----------------------------------------------------------------*
537 *-----------------------------------------------------------------*/
540 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
542 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
544 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
547 return addSet(&dynInternalRegs,reg);
552 /*-----------------------------------------------------------------*/
553 /* allocReg - allocates register of given type */
554 /*-----------------------------------------------------------------*/
556 allocReg (short type)
559 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
560 //fprintf(stderr,"allocReg\n");
563 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
568 /*-----------------------------------------------------------------*/
569 /* dirregWithName - search for register by name */
570 /*-----------------------------------------------------------------*/
572 dirregWithName (char *name)
580 /* hash the name to get a key */
582 hkey = regname2key(name);
584 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
588 if(STRCASECMP(reg->name, name) == 0) {
592 reg = hTabNextItemWK (dynDirectRegNames);
596 return NULL; // name wasn't found in the hash table
599 int IS_CONFIG_ADDRESS(int address)
602 return address == 0x2007;
605 /*-----------------------------------------------------------------*/
606 /* allocDirReg - allocates register of given type */
607 /*-----------------------------------------------------------------*/
609 allocDirReg (operand *op )
616 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
620 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
622 /* If the symbol is at a fixed address, then remove the leading underscore
623 * from the name. This is hack to allow the .asm include file named registers
624 * to match the .c declared register names */
626 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
629 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
631 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
632 debugLog(" %d const char\n",__LINE__);
633 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
636 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
637 if (IS_CODE ( OP_SYM_ETYPE(op)) )
638 debugLog(" %d code space\n",__LINE__);
640 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
641 debugLog(" %d integral\n",__LINE__);
642 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
643 debugLog(" %d literal\n",__LINE__);
644 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
645 debugLog(" %d specifier\n",__LINE__);
646 debugAopGet(NULL, op);
649 if (IS_CODE ( OP_SYM_ETYPE(op)) )
652 /* First, search the hash table to see if there is a register with this name */
653 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
654 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
657 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
658 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
660 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
661 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
664 //fprintf(stderr,"ralloc %s \n", name);
666 reg = dirregWithName(name);
672 /* if this is at an absolute address, then get the address. */
673 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
674 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
677 /* Register wasn't found in hash, so let's create
678 * a new one and put it in the hash table AND in the
679 * dynDirectRegNames set */
680 if(!IS_CONFIG_ADDRESS(address)) {
681 //fprintf(stderr,"allocating new reg %s\n",name);
683 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
684 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
686 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
688 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
690 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
694 if (IS_BITVAR (OP_SYM_ETYPE(op)))
695 addSet(&dynDirectBitRegs, reg);
697 addSet(&dynDirectRegs, reg);
700 debugLog (" -- %s is declared at address 0x2007\n",name);
705 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
707 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
708 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
714 /*-----------------------------------------------------------------*/
715 /* allocDirReg - allocates register of given type */
716 /*-----------------------------------------------------------------*/
718 allocRegByName (char *name, int size)
724 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
728 /* First, search the hash table to see if there is a register with this name */
729 reg = dirregWithName(name);
733 /* Register wasn't found in hash, so let's create
734 * a new one and put it in the hash table AND in the
735 * dynDirectRegNames set */
736 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
737 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
739 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
741 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
742 addSet(&dynDirectRegs, reg);
748 /*-----------------------------------------------------------------*/
749 /* RegWithIdx - returns pointer to register with index number */
750 /*-----------------------------------------------------------------*/
752 typeRegWithIdx (int idx, int type, int fixed)
757 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
762 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
764 debugLog ("Found a Dynamic Register!\n");
767 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
768 debugLog ("Found a Direct Register!\n");
774 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
775 debugLog ("Found a Stack Register!\n");
780 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
781 debugLog ("Found a Processor Register!\n");
795 /*-----------------------------------------------------------------*/
796 /* pic14_regWithIdx - returns pointer to register with index number*/
797 /*-----------------------------------------------------------------*/
799 pic14_regWithIdx (int idx)
803 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
806 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
809 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
815 /*-----------------------------------------------------------------*/
816 /* pic14_regWithIdx - returns pointer to register with index number */
817 /*-----------------------------------------------------------------*/
819 pic14_allocWithIdx (int idx)
824 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
826 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
828 debugLog ("Found a Dynamic Register!\n");
829 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
830 debugLog ("Found a Stack Register!\n");
831 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
832 debugLog ("Found a Processor Register!\n");
833 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
834 debugLog ("Found an Internal Register!\n");
837 debugLog ("Dynamic Register not found\n");
840 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
841 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
842 "regWithIdx not found");
852 /*-----------------------------------------------------------------*/
853 /*-----------------------------------------------------------------*/
855 pic14_findFreeReg(short type)
862 if((dReg = regFindFree(dynAllocRegs)) != NULL)
864 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
868 if((dReg = regFindFree(dynStackRegs)) != NULL)
880 /*-----------------------------------------------------------------*/
881 /* freeReg - frees a register */
882 /*-----------------------------------------------------------------*/
886 debugLog ("%s\n", __FUNCTION__);
891 /*-----------------------------------------------------------------*/
892 /* nFreeRegs - returns number of free registers */
893 /*-----------------------------------------------------------------*/
897 /* dynamically allocate as many as we need and worry about
898 * fitting them into a PIC later */
905 debugLog ("%s\n", __FUNCTION__);
906 for (i = 0; i < pic14_nRegs; i++)
907 if (regspic14[i].isFree && regspic14[i].type == type)
913 /*-----------------------------------------------------------------*/
914 /* nfreeRegsType - free registers with type */
915 /*-----------------------------------------------------------------*/
917 nfreeRegsType (int type)
920 debugLog ("%s\n", __FUNCTION__);
923 if ((nfr = nFreeRegs (type)) == 0)
924 return nFreeRegs (REG_GPR);
927 return nFreeRegs (type);
930 void writeSetUsedRegs(FILE *of, set *dRegs)
935 for (dReg = setFirstItem(dRegs) ; dReg ;
936 dReg = setNextItem(dRegs)) {
939 fprintf (of, "\t%s\n",dReg->name);
943 extern void assignFixedRegisters(set *regset);
944 extern void assignRelocatableRegisters(set *regset,int used);
945 extern void dump_map(void);
946 extern void dump_cblock(FILE *of);
949 void packBits(set *bregs)
954 regs *relocbitfield=NULL;
960 for (regset = bregs ; regset ;
961 regset = regset->next) {
964 breg->isBitField = 1;
965 //fprintf(stderr,"bit reg: %s\n",breg->name);
968 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
970 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
971 breg->rIdx = breg->address & 7;
975 sprintf (buffer, "fbitfield%02x", breg->address);
976 //fprintf(stderr,"new bit field\n");
977 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
978 bitfield->isBitField = 1;
979 bitfield->isFixed = 1;
980 bitfield->address = breg->address;
981 addSet(&dynDirectRegs,bitfield);
982 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
984 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
987 breg->reg_alias = bitfield;
991 if(!relocbitfield || bit_no >7) {
994 sprintf (buffer, "bitfield%d", byte_no);
995 //fprintf(stderr,"new relocatable bit field\n");
996 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
997 relocbitfield->isBitField = 1;
998 addSet(&dynDirectRegs,relocbitfield);
999 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1003 breg->reg_alias = relocbitfield;
1004 breg->address = rDirectIdx; /* byte_no; */
1005 breg->rIdx = bit_no++;
1013 void bitEQUs(FILE *of, set *bregs)
1015 regs *breg,*bytereg;
1018 //fprintf(stderr," %s\n",__FUNCTION__);
1019 for (breg = setFirstItem(bregs) ; breg ;
1020 breg = setNextItem(bregs)) {
1022 //fprintf(stderr,"bit reg: %s\n",breg->name);
1024 bytereg = breg->reg_alias;
1026 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1029 breg->rIdx & 0x0007);
1032 fprintf(stderr, "bit field is not assigned to a register\n");
1033 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1043 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1048 for (reg = setFirstItem(fregs) ; reg ;
1049 reg = setNextItem(fregs)) {
1051 if(!reg->isEmitted && reg->wasUsed) {
1053 fprintf (of, "%s\tEQU\t0x%03x\n",
1057 fprintf (of, "%s\tEQU\t0x%03x\n",
1065 void writeUsedRegs(FILE *of)
1067 packBits(dynDirectBitRegs);
1070 assignFixedRegisters(dynAllocRegs);
1071 assignFixedRegisters(dynStackRegs);
1072 assignFixedRegisters(dynDirectRegs);
1074 assignRelocatableRegisters(dynInternalRegs,0);
1075 assignRelocatableRegisters(dynAllocRegs,0);
1076 assignRelocatableRegisters(dynStackRegs,0);
1077 assignRelocatableRegisters(dynDirectRegs,0);
1082 bitEQUs(of,dynDirectBitRegs);
1083 aliasEQUs(of,dynAllocRegs,0);
1084 aliasEQUs(of,dynDirectRegs,0);
1085 aliasEQUs(of,dynStackRegs,0);
1086 aliasEQUs(of,dynProcessorRegs,1);
1091 /*-----------------------------------------------------------------*/
1092 /* allDefsOutOfRange - all definitions are out of a range */
1093 /*-----------------------------------------------------------------*/
1095 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1099 debugLog ("%s\n", __FUNCTION__);
1103 for (i = 0; i < defs->size; i++)
1107 if (bitVectBitValue (defs, i) &&
1108 (ic = hTabItemWithKey (iCodehTab, i)) &&
1109 (ic->seq >= fseq && ic->seq <= toseq))
1119 /*-----------------------------------------------------------------*/
1120 /* computeSpillable - given a point find the spillable live ranges */
1121 /*-----------------------------------------------------------------*/
1123 computeSpillable (iCode * ic)
1127 debugLog ("%s\n", __FUNCTION__);
1128 /* spillable live ranges are those that are live at this
1129 point . the following categories need to be subtracted
1131 a) - those that are already spilt
1132 b) - if being used by this one
1133 c) - defined by this one */
1135 spillable = bitVectCopy (ic->rlive);
1137 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1139 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1140 bitVectUnSetBit (spillable, ic->defKey);
1141 spillable = bitVectIntersect (spillable, _G.regAssigned);
1146 /*-----------------------------------------------------------------*/
1147 /* noSpilLoc - return true if a variable has no spil location */
1148 /*-----------------------------------------------------------------*/
1150 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1152 debugLog ("%s\n", __FUNCTION__);
1153 return (sym->usl.spillLoc ? 0 : 1);
1156 /*-----------------------------------------------------------------*/
1157 /* hasSpilLoc - will return 1 if the symbol has spil location */
1158 /*-----------------------------------------------------------------*/
1160 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1162 debugLog ("%s\n", __FUNCTION__);
1163 return (sym->usl.spillLoc ? 1 : 0);
1166 /*-----------------------------------------------------------------*/
1167 /* directSpilLoc - will return 1 if the splilocation is in direct */
1168 /*-----------------------------------------------------------------*/
1170 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1172 debugLog ("%s\n", __FUNCTION__);
1173 if (sym->usl.spillLoc &&
1174 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1180 /*-----------------------------------------------------------------*/
1181 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1182 /* but is not used as a pointer */
1183 /*-----------------------------------------------------------------*/
1185 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1187 debugLog ("%s\n", __FUNCTION__);
1188 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1191 /*-----------------------------------------------------------------*/
1192 /* rematable - will return 1 if the remat flag is set */
1193 /*-----------------------------------------------------------------*/
1195 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1197 debugLog ("%s\n", __FUNCTION__);
1201 /*-----------------------------------------------------------------*/
1202 /* notUsedInRemaining - not used or defined in remain of the block */
1203 /*-----------------------------------------------------------------*/
1205 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1207 debugLog ("%s\n", __FUNCTION__);
1208 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1209 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1212 /*-----------------------------------------------------------------*/
1213 /* allLRs - return true for all */
1214 /*-----------------------------------------------------------------*/
1216 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1218 debugLog ("%s\n", __FUNCTION__);
1222 /*-----------------------------------------------------------------*/
1223 /* liveRangesWith - applies function to a given set of live range */
1224 /*-----------------------------------------------------------------*/
1226 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1227 eBBlock * ebp, iCode * ic)
1232 debugLog ("%s\n", __FUNCTION__);
1233 if (!lrs || !lrs->size)
1236 for (i = 1; i < lrs->size; i++)
1239 if (!bitVectBitValue (lrs, i))
1242 /* if we don't find it in the live range
1243 hash table we are in serious trouble */
1244 if (!(sym = hTabItemWithKey (liveRanges, i)))
1246 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1247 "liveRangesWith could not find liveRange");
1251 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1252 addSetHead (&rset, sym);
1259 /*-----------------------------------------------------------------*/
1260 /* leastUsedLR - given a set determines which is the least used */
1261 /*-----------------------------------------------------------------*/
1263 leastUsedLR (set * sset)
1265 symbol *sym = NULL, *lsym = NULL;
1267 debugLog ("%s\n", __FUNCTION__);
1268 sym = lsym = setFirstItem (sset);
1273 for (; lsym; lsym = setNextItem (sset))
1276 /* if usage is the same then prefer
1277 the spill the smaller of the two */
1278 if (lsym->used == sym->used)
1279 if (getSize (lsym->type) < getSize (sym->type))
1283 if (lsym->used < sym->used)
1288 setToNull ((void **) &sset);
1293 /*-----------------------------------------------------------------*/
1294 /* noOverLap - will iterate through the list looking for over lap */
1295 /*-----------------------------------------------------------------*/
1297 noOverLap (set * itmpStack, symbol * fsym)
1300 debugLog ("%s\n", __FUNCTION__);
1303 for (sym = setFirstItem (itmpStack); sym;
1304 sym = setNextItem (itmpStack))
1306 if (sym->liveTo > fsym->liveFrom)
1314 /*-----------------------------------------------------------------*/
1315 /* isFree - will return 1 if the a free spil location is found */
1316 /*-----------------------------------------------------------------*/
1321 V_ARG (symbol **, sloc);
1322 V_ARG (symbol *, fsym);
1324 debugLog ("%s\n", __FUNCTION__);
1325 /* if already found */
1329 /* if it is free && and the itmp assigned to
1330 this does not have any overlapping live ranges
1331 with the one currently being assigned and
1332 the size can be accomodated */
1334 noOverLap (sym->usl.itmpStack, fsym) &&
1335 getSize (sym->type) >= getSize (fsym->type))
1344 /*-----------------------------------------------------------------*/
1345 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1346 /*-----------------------------------------------------------------*/
1348 spillLRWithPtrReg (symbol * forSym)
1354 debugLog ("%s\n", __FUNCTION__);
1355 if (!_G.regAssigned ||
1356 bitVectIsZero (_G.regAssigned))
1359 r0 = pic14_regWithIdx (R0_IDX);
1360 r1 = pic14_regWithIdx (R1_IDX);
1362 /* for all live ranges */
1363 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1364 lrsym = hTabNextItem (liveRanges, &k))
1368 /* if no registers assigned to it or
1370 /* if it does not overlap with this then
1371 not need to spill it */
1373 if (lrsym->isspilt || !lrsym->nRegs ||
1374 (lrsym->liveTo < forSym->liveFrom))
1377 /* go thru the registers : if it is either
1378 r0 or r1 then spil it */
1379 for (j = 0; j < lrsym->nRegs; j++)
1380 if (lrsym->regs[j] == r0 ||
1381 lrsym->regs[j] == r1)
1390 /*-----------------------------------------------------------------*/
1391 /* createStackSpil - create a location on the stack to spil */
1392 /*-----------------------------------------------------------------*/
1394 createStackSpil (symbol * sym)
1396 symbol *sloc = NULL;
1397 int useXstack, model, noOverlay;
1399 char slocBuffer[30];
1400 debugLog ("%s\n", __FUNCTION__);
1402 /* first go try and find a free one that is already
1403 existing on the stack */
1404 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1406 /* found a free one : just update & return */
1407 sym->usl.spillLoc = sloc;
1410 addSetHead (&sloc->usl.itmpStack, sym);
1414 /* could not then have to create one , this is the hard part
1415 we need to allocate this on the stack : this is really a
1416 hack!! but cannot think of anything better at this time */
1418 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1420 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1421 __FILE__, __LINE__);
1425 sloc = newiTemp (slocBuffer);
1427 /* set the type to the spilling symbol */
1428 sloc->type = copyLinkChain (sym->type);
1429 sloc->etype = getSpec (sloc->type);
1430 SPEC_SCLS (sloc->etype) = S_DATA;
1431 SPEC_EXTR (sloc->etype) = 0;
1432 SPEC_STAT (sloc->etype) = 0;
1434 /* we don't allow it to be allocated`
1435 onto the external stack since : so we
1436 temporarily turn it off ; we also
1437 turn off memory model to prevent
1438 the spil from going to the external storage
1439 and turn off overlaying
1442 useXstack = options.useXstack;
1443 model = options.model;
1444 noOverlay = options.noOverlay;
1445 options.noOverlay = 1;
1446 options.model = options.useXstack = 0;
1450 options.useXstack = useXstack;
1451 options.model = model;
1452 options.noOverlay = noOverlay;
1453 sloc->isref = 1; /* to prevent compiler warning */
1455 /* if it is on the stack then update the stack */
1456 if (IN_STACK (sloc->etype))
1458 currFunc->stack += getSize (sloc->type);
1459 _G.stackExtend += getSize (sloc->type);
1462 _G.dataExtend += getSize (sloc->type);
1464 /* add it to the _G.stackSpil set */
1465 addSetHead (&_G.stackSpil, sloc);
1466 sym->usl.spillLoc = sloc;
1469 /* add it to the set of itempStack set
1470 of the spill location */
1471 addSetHead (&sloc->usl.itmpStack, sym);
1475 /*-----------------------------------------------------------------*/
1476 /* isSpiltOnStack - returns true if the spil location is on stack */
1477 /*-----------------------------------------------------------------*/
1479 isSpiltOnStack (symbol * sym)
1483 debugLog ("%s\n", __FUNCTION__);
1490 /* if (sym->_G.stackSpil) */
1493 if (!sym->usl.spillLoc)
1496 etype = getSpec (sym->usl.spillLoc->type);
1497 if (IN_STACK (etype))
1503 /*-----------------------------------------------------------------*/
1504 /* spillThis - spils a specific operand */
1505 /*-----------------------------------------------------------------*/
1507 spillThis (symbol * sym)
1510 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1512 /* if this is rematerializable or has a spillLocation
1513 we are okay, else we need to create a spillLocation
1515 if (!(sym->remat || sym->usl.spillLoc))
1516 createStackSpil (sym);
1519 /* mark it has spilt & put it in the spilt set */
1521 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1523 bitVectUnSetBit (_G.regAssigned, sym->key);
1525 for (i = 0; i < sym->nRegs; i++)
1529 freeReg (sym->regs[i]);
1530 sym->regs[i] = NULL;
1533 /* if spilt on stack then free up r0 & r1
1534 if they could have been assigned to some
1536 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1539 spillLRWithPtrReg (sym);
1542 if (sym->usl.spillLoc && !sym->remat)
1543 sym->usl.spillLoc->allocreq = 1;
1547 /*-----------------------------------------------------------------*/
1548 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1549 /*-----------------------------------------------------------------*/
1551 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1553 bitVect *lrcs = NULL;
1557 debugLog ("%s\n", __FUNCTION__);
1558 /* get the spillable live ranges */
1559 lrcs = computeSpillable (ic);
1561 /* get all live ranges that are rematerizable */
1562 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1565 /* return the least used of these */
1566 return leastUsedLR (selectS);
1569 /* get live ranges with spillLocations in direct space */
1570 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1572 sym = leastUsedLR (selectS);
1573 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1574 sym->usl.spillLoc->rname :
1575 sym->usl.spillLoc->name));
1577 /* mark it as allocation required */
1578 sym->usl.spillLoc->allocreq = 1;
1582 /* if the symbol is local to the block then */
1583 if (forSym->liveTo < ebp->lSeq)
1586 /* check if there are any live ranges allocated
1587 to registers that are not used in this block */
1588 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1590 sym = leastUsedLR (selectS);
1591 /* if this is not rematerializable */
1600 /* check if there are any live ranges that not
1601 used in the remainder of the block */
1602 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1604 sym = leastUsedLR (selectS);
1607 sym->remainSpil = 1;
1614 /* find live ranges with spillocation && not used as pointers */
1615 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1618 sym = leastUsedLR (selectS);
1619 /* mark this as allocation required */
1620 sym->usl.spillLoc->allocreq = 1;
1624 /* find live ranges with spillocation */
1625 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1628 sym = leastUsedLR (selectS);
1629 sym->usl.spillLoc->allocreq = 1;
1633 /* couldn't find then we need to create a spil
1634 location on the stack , for which one? the least
1636 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1639 /* return a created spil location */
1640 sym = createStackSpil (leastUsedLR (selectS));
1641 sym->usl.spillLoc->allocreq = 1;
1645 /* this is an extreme situation we will spill
1646 this one : happens very rarely but it does happen */
1652 /*-----------------------------------------------------------------*/
1653 /* spilSomething - spil some variable & mark registers as free */
1654 /*-----------------------------------------------------------------*/
1656 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1661 debugLog ("%s\n", __FUNCTION__);
1662 /* get something we can spil */
1663 ssym = selectSpil (ic, ebp, forSym);
1665 /* mark it as spilt */
1667 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1669 /* mark it as not register assigned &
1670 take it away from the set */
1671 bitVectUnSetBit (_G.regAssigned, ssym->key);
1673 /* mark the registers as free */
1674 for (i = 0; i < ssym->nRegs; i++)
1676 freeReg (ssym->regs[i]);
1678 /* if spilt on stack then free up r0 & r1
1679 if they could have been assigned to as gprs */
1680 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1683 spillLRWithPtrReg (ssym);
1686 /* if this was a block level spil then insert push & pop
1687 at the start & end of block respectively */
1688 if (ssym->blockSpil)
1690 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1691 /* add push to the start of the block */
1692 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1693 ebp->sch->next : ebp->sch));
1694 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1695 /* add pop to the end of the block */
1696 addiCodeToeBBlock (ebp, nic, NULL);
1699 /* if spilt because not used in the remainder of the
1700 block then add a push before this instruction and
1701 a pop at the end of the block */
1702 if (ssym->remainSpil)
1705 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1706 /* add push just before this instruction */
1707 addiCodeToeBBlock (ebp, nic, ic);
1709 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1710 /* add pop to the end of the block */
1711 addiCodeToeBBlock (ebp, nic, NULL);
1720 /*-----------------------------------------------------------------*/
1721 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1722 /*-----------------------------------------------------------------*/
1724 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1728 debugLog ("%s\n", __FUNCTION__);
1730 /* try for a ptr type */
1731 if ((reg = allocReg (REG_PTR)))
1734 /* try for gpr type */
1735 if ((reg = allocReg (REG_GPR)))
1738 /* we have to spil */
1739 if (!spilSomething (ic, ebp, sym))
1742 /* this looks like an infinite loop but
1743 in really selectSpil will abort */
1747 /*-----------------------------------------------------------------*/
1748 /* getRegGpr - will try for GPR if not spil */
1749 /*-----------------------------------------------------------------*/
1751 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1755 debugLog ("%s\n", __FUNCTION__);
1757 /* try for gpr type */
1758 if ((reg = allocReg (REG_GPR)))
1761 if (!pic14_ptrRegReq)
1762 if ((reg = allocReg (REG_PTR)))
1765 /* we have to spil */
1766 if (!spilSomething (ic, ebp, sym))
1769 /* this looks like an infinite loop but
1770 in really selectSpil will abort */
1774 /*-----------------------------------------------------------------*/
1775 /* symHasReg - symbol has a given register */
1776 /*-----------------------------------------------------------------*/
1778 symHasReg (symbol * sym, regs * reg)
1782 debugLog ("%s\n", __FUNCTION__);
1783 for (i = 0; i < sym->nRegs; i++)
1784 if (sym->regs[i] == reg)
1790 /*-----------------------------------------------------------------*/
1791 /* deassignLRs - check the live to and if they have registers & are */
1792 /* not spilt then free up the registers */
1793 /*-----------------------------------------------------------------*/
1795 deassignLRs (iCode * ic, eBBlock * ebp)
1801 debugLog ("%s\n", __FUNCTION__);
1802 for (sym = hTabFirstItem (liveRanges, &k); sym;
1803 sym = hTabNextItem (liveRanges, &k))
1806 symbol *psym = NULL;
1807 /* if it does not end here */
1808 if (sym->liveTo > ic->seq)
1811 /* if it was spilt on stack then we can
1812 mark the stack spil location as free */
1817 sym->usl.spillLoc->isFree = 1;
1823 if (!bitVectBitValue (_G.regAssigned, sym->key))
1826 /* special case check if this is an IFX &
1827 the privious one was a pop and the
1828 previous one was not spilt then keep track
1830 if (ic->op == IFX && ic->prev &&
1831 ic->prev->op == IPOP &&
1832 !ic->prev->parmPush &&
1833 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1834 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1840 bitVectUnSetBit (_G.regAssigned, sym->key);
1842 /* if the result of this one needs registers
1843 and does not have it then assign it right
1845 if (IC_RESULT (ic) &&
1846 !(SKIP_IC2 (ic) || /* not a special icode */
1847 ic->op == JUMPTABLE ||
1852 POINTER_SET (ic)) &&
1853 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1854 result->liveTo > ic->seq && /* and will live beyond this */
1855 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1856 result->regType == sym->regType && /* same register types */
1857 result->nRegs && /* which needs registers */
1858 !result->isspilt && /* and does not already have them */
1860 !bitVectBitValue (_G.regAssigned, result->key) &&
1861 /* the number of free regs + number of regs in this LR
1862 can accomodate the what result Needs */
1863 ((nfreeRegsType (result->regType) +
1864 sym->nRegs) >= result->nRegs)
1868 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1870 result->regs[i] = sym->regs[i];
1872 result->regs[i] = getRegGpr (ic, ebp, result);
1874 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1878 /* free the remaining */
1879 for (; i < sym->nRegs; i++)
1883 if (!symHasReg (psym, sym->regs[i]))
1884 freeReg (sym->regs[i]);
1887 freeReg (sym->regs[i]);
1894 /*-----------------------------------------------------------------*/
1895 /* reassignLR - reassign this to registers */
1896 /*-----------------------------------------------------------------*/
1898 reassignLR (operand * op)
1900 symbol *sym = OP_SYMBOL (op);
1903 debugLog ("%s\n", __FUNCTION__);
1904 /* not spilt any more */
1905 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1906 bitVectUnSetBit (_G.spiltSet, sym->key);
1908 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1912 for (i = 0; i < sym->nRegs; i++)
1913 sym->regs[i]->isFree = 0;
1916 /*-----------------------------------------------------------------*/
1917 /* willCauseSpill - determines if allocating will cause a spill */
1918 /*-----------------------------------------------------------------*/
1920 willCauseSpill (int nr, int rt)
1922 debugLog ("%s\n", __FUNCTION__);
1923 /* first check if there are any avlb registers
1924 of te type required */
1927 /* special case for pointer type
1928 if pointer type not avlb then
1929 check for type gpr */
1930 if (nFreeRegs (rt) >= nr)
1932 if (nFreeRegs (REG_GPR) >= nr)
1937 if (pic14_ptrRegReq)
1939 if (nFreeRegs (rt) >= nr)
1944 if (nFreeRegs (REG_PTR) +
1945 nFreeRegs (REG_GPR) >= nr)
1950 debugLog (" ... yep it will (cause a spill)\n");
1951 /* it will cause a spil */
1955 /*-----------------------------------------------------------------*/
1956 /* positionRegs - the allocator can allocate same registers to res- */
1957 /* ult and operand, if this happens make sure they are in the same */
1958 /* position as the operand otherwise chaos results */
1959 /*-----------------------------------------------------------------*/
1961 positionRegs (symbol * result, symbol * opsym, int lineno)
1963 int count = min (result->nRegs, opsym->nRegs);
1964 int i, j = 0, shared = 0;
1966 debugLog ("%s\n", __FUNCTION__);
1967 /* if the result has been spilt then cannot share */
1972 /* first make sure that they actually share */
1973 for (i = 0; i < count; i++)
1975 for (j = 0; j < count; j++)
1977 if (result->regs[i] == opsym->regs[j] && i != j)
1987 regs *tmp = result->regs[i];
1988 result->regs[i] = result->regs[j];
1989 result->regs[j] = tmp;
1994 /*-----------------------------------------------------------------*/
1995 /* serialRegAssign - serially allocate registers to the variables */
1996 /*-----------------------------------------------------------------*/
1998 serialRegAssign (eBBlock ** ebbs, int count)
2002 debugLog ("%s\n", __FUNCTION__);
2003 /* for all blocks */
2004 for (i = 0; i < count; i++)
2009 if (ebbs[i]->noPath &&
2010 (ebbs[i]->entryLabel != entryLabel &&
2011 ebbs[i]->entryLabel != returnLabel))
2014 /* of all instructions do */
2015 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2018 debugLog (" op: %s\n", decodeOp (ic->op));
2020 /* if this is an ipop that means some live
2021 range will have to be assigned again */
2023 reassignLR (IC_LEFT (ic));
2025 /* if result is present && is a true symbol */
2026 if (IC_RESULT (ic) && ic->op != IFX &&
2027 IS_TRUE_SYMOP (IC_RESULT (ic)))
2028 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2030 /* take away registers from live
2031 ranges that end at this instruction */
2032 deassignLRs (ic, ebbs[i]);
2034 /* some don't need registers */
2035 if (SKIP_IC2 (ic) ||
2036 ic->op == JUMPTABLE ||
2040 (IC_RESULT (ic) && POINTER_SET (ic)))
2043 /* now we need to allocate registers
2044 only for the result */
2047 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2053 /* if it does not need or is spilt
2054 or is already assigned to registers
2055 or will not live beyond this instructions */
2058 bitVectBitValue (_G.regAssigned, sym->key) ||
2059 sym->liveTo <= ic->seq)
2062 /* if some liverange has been spilt at the block level
2063 and this one live beyond this block then spil this
2065 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2070 /* if trying to allocate this will cause
2071 a spill and there is nothing to spill
2072 or this one is rematerializable then
2074 willCS = willCauseSpill (sym->nRegs, sym->regType);
2075 spillable = computeSpillable (ic);
2077 (willCS && bitVectIsZero (spillable)))
2085 /* if it has a spillocation & is used less than
2086 all other live ranges then spill this */
2088 if (sym->usl.spillLoc) {
2089 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2090 allLRs, ebbs[i], ic));
2091 if (leastUsed && leastUsed->used > sym->used) {
2096 /* if none of the liveRanges have a spillLocation then better
2097 to spill this one than anything else already assigned to registers */
2098 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2099 /* if this is local to this block then we might find a block spil */
2100 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2108 if (ic->op == RECEIVE)
2109 debugLog ("When I get clever, I'll optimize the receive logic\n");
2111 /* if we need ptr regs for the right side
2113 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2114 <= (unsigned) PTRSIZE)
2119 /* else we assign registers to it */
2120 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2122 debugLog (" %d - \n", __LINE__);
2124 bitVectDebugOn(_G.regAssigned, debugF);
2126 for (j = 0; j < sym->nRegs; j++)
2128 if (sym->regType == REG_PTR)
2129 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2131 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2133 /* if the allocation falied which means
2134 this was spilt then break */
2138 debugLog (" %d - \n", __LINE__);
2140 /* if it shares registers with operands make sure
2141 that they are in the same position */
2142 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2143 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2144 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2145 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2146 /* do the same for the right operand */
2147 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2148 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2149 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2150 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2152 debugLog (" %d - \n", __LINE__);
2155 debugLog (" %d - \n", __LINE__);
2165 /*-----------------------------------------------------------------*/
2166 /* rUmaskForOp :- returns register mask for an operand */
2167 /*-----------------------------------------------------------------*/
2169 rUmaskForOp (operand * op)
2175 debugLog ("%s\n", __FUNCTION__);
2176 /* only temporaries are assigned registers */
2180 sym = OP_SYMBOL (op);
2182 /* if spilt or no registers assigned to it
2184 if (sym->isspilt || !sym->nRegs)
2187 rumask = newBitVect (pic14_nRegs);
2189 for (j = 0; j < sym->nRegs; j++)
2191 rumask = bitVectSetBit (rumask,
2192 sym->regs[j]->rIdx);
2198 /*-----------------------------------------------------------------*/
2199 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2200 /*-----------------------------------------------------------------*/
2202 regsUsedIniCode (iCode * ic)
2204 bitVect *rmask = newBitVect (pic14_nRegs);
2206 debugLog ("%s\n", __FUNCTION__);
2207 /* do the special cases first */
2210 rmask = bitVectUnion (rmask,
2211 rUmaskForOp (IC_COND (ic)));
2215 /* for the jumptable */
2216 if (ic->op == JUMPTABLE)
2218 rmask = bitVectUnion (rmask,
2219 rUmaskForOp (IC_JTCOND (ic)));
2224 /* of all other cases */
2226 rmask = bitVectUnion (rmask,
2227 rUmaskForOp (IC_LEFT (ic)));
2231 rmask = bitVectUnion (rmask,
2232 rUmaskForOp (IC_RIGHT (ic)));
2235 rmask = bitVectUnion (rmask,
2236 rUmaskForOp (IC_RESULT (ic)));
2242 /*-----------------------------------------------------------------*/
2243 /* createRegMask - for each instruction will determine the regsUsed */
2244 /*-----------------------------------------------------------------*/
2246 createRegMask (eBBlock ** ebbs, int count)
2250 debugLog ("%s\n", __FUNCTION__);
2251 /* for all blocks */
2252 for (i = 0; i < count; i++)
2256 if (ebbs[i]->noPath &&
2257 (ebbs[i]->entryLabel != entryLabel &&
2258 ebbs[i]->entryLabel != returnLabel))
2261 /* for all instructions */
2262 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2267 if (SKIP_IC2 (ic) || !ic->rlive)
2270 /* first mark the registers used in this
2272 ic->rUsed = regsUsedIniCode (ic);
2273 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2275 /* now create the register mask for those
2276 registers that are in use : this is a
2277 super set of ic->rUsed */
2278 ic->rMask = newBitVect (pic14_nRegs + 1);
2280 /* for all live Ranges alive at this point */
2281 for (j = 1; j < ic->rlive->size; j++)
2286 /* if not alive then continue */
2287 if (!bitVectBitValue (ic->rlive, j))
2290 /* find the live range we are interested in */
2291 if (!(sym = hTabItemWithKey (liveRanges, j)))
2293 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2294 "createRegMask cannot find live range");
2298 /* if no register assigned to it */
2299 if (!sym->nRegs || sym->isspilt)
2302 /* for all the registers allocated to it */
2303 for (k = 0; k < sym->nRegs; k++)
2306 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2312 /*-----------------------------------------------------------------*/
2313 /* rematStr - returns the rematerialized string for a remat var */
2314 /*-----------------------------------------------------------------*/
2316 rematStr (symbol * sym)
2319 iCode *ic = sym->rematiCode;
2320 symbol *psym = NULL;
2322 debugLog ("%s\n", __FUNCTION__);
2324 //printf ("%s\n", s);
2326 /* if plus or minus print the right hand side */
2328 if (ic->op == '+' || ic->op == '-') {
2330 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2332 sprintf (s, "(%s %c 0x%04x)",
2333 OP_SYMBOL (IC_LEFT (ric))->rname,
2335 (int) operandLitValue (IC_RIGHT (ic)));
2338 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2340 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2341 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2346 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2347 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2349 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2354 /*-----------------------------------------------------------------*/
2355 /* rematStr - returns the rematerialized string for a remat var */
2356 /*-----------------------------------------------------------------*/
2358 rematStr (symbol * sym)
2361 iCode *ic = sym->rematiCode;
2363 debugLog ("%s\n", __FUNCTION__);
2368 /* if plus or minus print the right hand side */
2370 if (ic->op == '+' || ic->op == '-') {
2371 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2374 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2378 if (ic->op == '+' || ic->op == '-')
2380 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2381 sprintf (s, "(%s %c 0x%04x)",
2382 OP_SYMBOL (IC_LEFT (ric))->rname,
2384 (int) operandLitValue (IC_RIGHT (ic)));
2387 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2389 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2393 /* we reached the end */
2394 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2398 printf ("%s\n", buffer);
2403 /*-----------------------------------------------------------------*/
2404 /* regTypeNum - computes the type & number of registers required */
2405 /*-----------------------------------------------------------------*/
2413 debugLog ("%s\n", __FUNCTION__);
2414 /* for each live range do */
2415 for (sym = hTabFirstItem (liveRanges, &k); sym;
2416 sym = hTabNextItem (liveRanges, &k)) {
2418 debugLog (" %d - %s\n", __LINE__, sym->rname);
2420 /* if used zero times then no registers needed */
2421 if ((sym->liveTo - sym->liveFrom) == 0)
2425 /* if the live range is a temporary */
2428 debugLog (" %d - itemp register\n", __LINE__);
2430 /* if the type is marked as a conditional */
2431 if (sym->regType == REG_CND)
2434 /* if used in return only then we don't
2436 if (sym->ruonly || sym->accuse) {
2437 if (IS_AGGREGATE (sym->type) || sym->isptr)
2438 sym->type = aggrToPtr (sym->type, FALSE);
2439 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2444 /* if the symbol has only one definition &
2445 that definition is a get_pointer and the
2446 pointer we are getting is rematerializable and
2449 if (bitVectnBitsOn (sym->defs) == 1 &&
2450 (ic = hTabItemWithKey (iCodehTab,
2451 bitVectFirstBit (sym->defs))) &&
2454 !IS_BITVAR (sym->etype)) {
2457 debugLog (" %d - \n", __LINE__);
2459 /* if remat in data space */
2460 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2461 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2463 /* create a psuedo symbol & force a spil */
2464 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2465 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2466 psym->type = sym->type;
2467 psym->etype = sym->etype;
2468 strcpy (psym->rname, psym->name);
2470 sym->usl.spillLoc = psym;
2474 /* if in data space or idata space then try to
2475 allocate pointer register */
2479 /* if not then we require registers */
2480 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2481 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2482 getSize (sym->type));
2485 if(IS_PTR_CONST (sym->type)) {
2486 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2490 if (sym->nRegs > 4) {
2491 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2492 printTypeChain (sym->type, stderr);
2493 fprintf (stderr, "\n");
2496 /* determine the type of register required */
2497 if (sym->nRegs == 1 &&
2498 IS_PTR (sym->type) &&
2500 sym->regType = REG_PTR;
2502 sym->regType = REG_GPR;
2505 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2509 /* for the first run we don't provide */
2510 /* registers for true symbols we will */
2511 /* see how things go */
2516 DEFSETFUNC (markRegFree)
2518 ((regs *)item)->isFree = 1;
2523 DEFSETFUNC (deallocReg)
2525 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2526 ((regs *)item)->isFree = 1;
2527 ((regs *)item)->wasUsed = 0;
2531 /*-----------------------------------------------------------------*/
2532 /* freeAllRegs - mark all registers as free */
2533 /*-----------------------------------------------------------------*/
2535 pic14_freeAllRegs ()
2539 debugLog ("%s\n", __FUNCTION__);
2541 applyToSet(dynAllocRegs,markRegFree);
2542 applyToSet(dynStackRegs,markRegFree);
2545 for (i = 0; i < pic14_nRegs; i++)
2546 regspic14[i].isFree = 1;
2550 /*-----------------------------------------------------------------*/
2551 /*-----------------------------------------------------------------*/
2553 pic14_deallocateAllRegs ()
2557 debugLog ("%s\n", __FUNCTION__);
2559 applyToSet(dynAllocRegs,deallocReg);
2562 for (i = 0; i < pic14_nRegs; i++) {
2563 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2564 regspic14[i].isFree = 1;
2565 regspic14[i].wasUsed = 0;
2572 /*-----------------------------------------------------------------*/
2573 /* deallocStackSpil - this will set the stack pointer back */
2574 /*-----------------------------------------------------------------*/
2576 DEFSETFUNC (deallocStackSpil)
2580 debugLog ("%s\n", __FUNCTION__);
2585 /*-----------------------------------------------------------------*/
2586 /* farSpacePackable - returns the packable icode for far variables */
2587 /*-----------------------------------------------------------------*/
2589 farSpacePackable (iCode * ic)
2593 debugLog ("%s\n", __FUNCTION__);
2594 /* go thru till we find a definition for the
2595 symbol on the right */
2596 for (dic = ic->prev; dic; dic = dic->prev)
2599 /* if the definition is a call then no */
2600 if ((dic->op == CALL || dic->op == PCALL) &&
2601 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2606 /* if shift by unknown amount then not */
2607 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2608 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2611 /* if pointer get and size > 1 */
2612 if (POINTER_GET (dic) &&
2613 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2616 if (POINTER_SET (dic) &&
2617 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2620 /* if any three is a true symbol in far space */
2621 if (IC_RESULT (dic) &&
2622 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2623 isOperandInFarSpace (IC_RESULT (dic)))
2626 if (IC_RIGHT (dic) &&
2627 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2628 isOperandInFarSpace (IC_RIGHT (dic)) &&
2629 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2632 if (IC_LEFT (dic) &&
2633 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2634 isOperandInFarSpace (IC_LEFT (dic)) &&
2635 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2638 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2640 if ((dic->op == LEFT_OP ||
2641 dic->op == RIGHT_OP ||
2643 IS_OP_LITERAL (IC_RIGHT (dic)))
2653 /*-----------------------------------------------------------------*/
2654 /* packRegsForAssign - register reduction for assignment */
2655 /*-----------------------------------------------------------------*/
2657 packRegsForAssign (iCode * ic, eBBlock * ebp)
2662 debugLog ("%s\n", __FUNCTION__);
2664 debugAopGet (" result:", IC_RESULT (ic));
2665 debugAopGet (" left:", IC_LEFT (ic));
2666 debugAopGet (" right:", IC_RIGHT (ic));
2668 /* if this is at an absolute address, then get the address. */
2669 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2670 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2671 debugLog (" %d - found config word declaration\n", __LINE__);
2672 if(IS_VALOP(IC_RIGHT(ic))) {
2673 debugLog (" setting config word to %x\n",
2674 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2675 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2676 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2679 /* remove the assignment from the iCode chain. */
2681 remiCodeFromeBBlock (ebp, ic);
2682 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2683 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2690 if (!IS_ITEMP (IC_RESULT (ic))) {
2691 allocDirReg(IC_RESULT (ic));
2692 debugLog (" %d - result is not temp\n", __LINE__);
2695 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2696 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2697 allocDirReg(IC_LEFT (ic));
2701 if (!IS_ITEMP (IC_RIGHT (ic))) {
2702 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2703 allocDirReg(IC_RIGHT (ic));
2707 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2708 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2710 debugLog (" %d - not packing - right side fails \n", __LINE__);
2714 /* if the true symbol is defined in far space or on stack
2715 then we should not since this will increase register pressure */
2716 if (isOperandInFarSpace (IC_RESULT (ic)))
2718 if ((dic = farSpacePackable (ic)))
2724 /* find the definition of iTempNN scanning backwards if we find a
2725 a use of the true symbol before we find the definition then
2727 for (dic = ic->prev; dic; dic = dic->prev)
2730 /* if there is a function call and this is
2731 a parameter & not my parameter then don't pack it */
2732 if ((dic->op == CALL || dic->op == PCALL) &&
2733 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2734 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2736 debugLog (" %d - \n", __LINE__);
2744 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2745 IS_OP_VOLATILE (IC_RESULT (dic)))
2747 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2752 if (IS_SYMOP (IC_RESULT (dic)) &&
2753 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2755 /* A previous result was assigned to the same register - we'll our definition */
2756 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2757 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2758 if (POINTER_SET (dic))
2764 if (IS_SYMOP (IC_RIGHT (dic)) &&
2765 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2766 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2768 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2773 if (IS_SYMOP (IC_LEFT (dic)) &&
2774 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2775 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2777 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2782 if (POINTER_SET (dic) &&
2783 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2785 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2793 return 0; /* did not find */
2795 /* if the result is on stack or iaccess then it must be
2796 the same atleast one of the operands */
2797 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2798 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2801 /* the operation has only one symbol
2802 operator then we can pack */
2803 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2804 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2807 if (!((IC_LEFT (dic) &&
2808 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2810 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2814 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2815 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2816 /* found the definition */
2817 /* replace the result with the result of */
2818 /* this assignment and remove this assignment */
2819 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2820 IC_RESULT (dic) = IC_RESULT (ic);
2822 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2824 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2826 /* delete from liverange table also
2827 delete from all the points inbetween and the new
2829 for (sic = dic; sic != ic; sic = sic->next)
2831 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2832 if (IS_ITEMP (IC_RESULT (dic)))
2833 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2836 remiCodeFromeBBlock (ebp, ic);
2837 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2838 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2839 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2845 /*-----------------------------------------------------------------*/
2846 /* findAssignToSym : scanning backwards looks for first assig found */
2847 /*-----------------------------------------------------------------*/
2849 findAssignToSym (operand * op, iCode * ic)
2853 debugLog ("%s\n", __FUNCTION__);
2854 for (dic = ic->prev; dic; dic = dic->prev)
2857 /* if definition by assignment */
2858 if (dic->op == '=' &&
2859 !POINTER_SET (dic) &&
2860 IC_RESULT (dic)->key == op->key
2861 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2865 /* we are interested only if defined in far space */
2866 /* or in stack space in case of + & - */
2868 /* if assigned to a non-symbol then return
2870 if (!IS_SYMOP (IC_RIGHT (dic)))
2873 /* if the symbol is in far space then
2875 if (isOperandInFarSpace (IC_RIGHT (dic)))
2878 /* for + & - operations make sure that
2879 if it is on the stack it is the same
2880 as one of the three operands */
2881 if ((ic->op == '+' || ic->op == '-') &&
2882 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2885 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2886 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2887 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2895 /* if we find an usage then we cannot delete it */
2896 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2899 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2902 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2906 /* now make sure that the right side of dic
2907 is not defined between ic & dic */
2910 iCode *sic = dic->next;
2912 for (; sic != ic; sic = sic->next)
2913 if (IC_RESULT (sic) &&
2914 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2923 /*-----------------------------------------------------------------*/
2924 /* packRegsForSupport :- reduce some registers for support calls */
2925 /*-----------------------------------------------------------------*/
2927 packRegsForSupport (iCode * ic, eBBlock * ebp)
2931 debugLog ("%s\n", __FUNCTION__);
2932 /* for the left & right operand :- look to see if the
2933 left was assigned a true symbol in far space in that
2934 case replace them */
2935 if (IS_ITEMP (IC_LEFT (ic)) &&
2936 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2938 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2944 debugAopGet ("removing left:", IC_LEFT (ic));
2946 /* found it we need to remove it from the
2948 for (sic = dic; sic != ic; sic = sic->next)
2949 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2951 IC_LEFT (ic)->operand.symOperand =
2952 IC_RIGHT (dic)->operand.symOperand;
2953 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2954 remiCodeFromeBBlock (ebp, dic);
2955 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2956 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2960 /* do the same for the right operand */
2963 IS_ITEMP (IC_RIGHT (ic)) &&
2964 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2966 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2972 /* if this is a subtraction & the result
2973 is a true symbol in far space then don't pack */
2974 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2976 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2977 if (IN_FARSPACE (SPEC_OCLS (etype)))
2981 debugAopGet ("removing right:", IC_RIGHT (ic));
2983 /* found it we need to remove it from the
2985 for (sic = dic; sic != ic; sic = sic->next)
2986 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2988 IC_RIGHT (ic)->operand.symOperand =
2989 IC_RIGHT (dic)->operand.symOperand;
2990 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2992 remiCodeFromeBBlock (ebp, dic);
2993 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2994 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3001 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3004 /*-----------------------------------------------------------------*/
3005 /* packRegsForOneuse : - will reduce some registers for single Use */
3006 /*-----------------------------------------------------------------*/
3008 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3013 debugLog ("%s\n", __FUNCTION__);
3014 /* if returning a literal then do nothing */
3018 /* only upto 2 bytes since we cannot predict
3019 the usage of b, & acc */
3020 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3025 /* this routine will mark the a symbol as used in one
3026 instruction use only && if the definition is local
3027 (ie. within the basic block) && has only one definition &&
3028 that definition is either a return value from a
3029 function or does not contain any variables in
3031 uses = bitVectCopy (OP_USES (op));
3032 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3033 if (!bitVectIsZero (uses)) /* has other uses */
3036 /* if it has only one defintion */
3037 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3038 return NULL; /* has more than one definition */
3040 /* get that definition */
3042 hTabItemWithKey (iCodehTab,
3043 bitVectFirstBit (OP_DEFS (op)))))
3046 /* found the definition now check if it is local */
3047 if (dic->seq < ebp->fSeq ||
3048 dic->seq > ebp->lSeq)
3049 return NULL; /* non-local */
3051 /* now check if it is the return from
3053 if (dic->op == CALL || dic->op == PCALL)
3055 if (ic->op != SEND && ic->op != RETURN &&
3056 !POINTER_SET(ic) && !POINTER_GET(ic))
3058 OP_SYMBOL (op)->ruonly = 1;
3065 /* otherwise check that the definition does
3066 not contain any symbols in far space */
3067 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3068 isOperandInFarSpace (IC_RIGHT (dic)) ||
3069 IS_OP_RUONLY (IC_LEFT (ic)) ||
3070 IS_OP_RUONLY (IC_RIGHT (ic)))
3075 /* if pointer set then make sure the pointer
3077 if (POINTER_SET (dic) &&
3078 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3081 if (POINTER_GET (dic) &&
3082 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3087 /* also make sure the intervenening instructions
3088 don't have any thing in far space */
3089 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3092 /* if there is an intervening function call then no */
3093 if (dic->op == CALL || dic->op == PCALL)
3095 /* if pointer set then make sure the pointer
3097 if (POINTER_SET (dic) &&
3098 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3101 if (POINTER_GET (dic) &&
3102 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3105 /* if address of & the result is remat then okay */
3106 if (dic->op == ADDRESS_OF &&
3107 OP_SYMBOL (IC_RESULT (dic))->remat)
3110 /* if operand has size of three or more & this
3111 operation is a '*','/' or '%' then 'b' may
3113 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3114 getSize (operandType (op)) >= 3)
3117 /* if left or right or result is in far space */
3118 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3119 isOperandInFarSpace (IC_RIGHT (dic)) ||
3120 isOperandInFarSpace (IC_RESULT (dic)) ||
3121 IS_OP_RUONLY (IC_LEFT (dic)) ||
3122 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3123 IS_OP_RUONLY (IC_RESULT (dic)))
3129 OP_SYMBOL (op)->ruonly = 1;
3134 /*-----------------------------------------------------------------*/
3135 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3136 /*-----------------------------------------------------------------*/
3138 isBitwiseOptimizable (iCode * ic)
3140 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3141 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3143 debugLog ("%s\n", __FUNCTION__);
3144 /* bitwise operations are considered optimizable
3145 under the following conditions (Jean-Louis VERN)
3157 if (IS_LITERAL (rtype) ||
3158 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3164 /*-----------------------------------------------------------------*/
3165 /* packRegsForAccUse - pack registers for acc use */
3166 /*-----------------------------------------------------------------*/
3168 packRegsForAccUse (iCode * ic)
3172 debugLog ("%s\n", __FUNCTION__);
3174 /* if this is an aggregate, e.g. a one byte char array */
3175 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3178 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3180 /* if + or - then it has to be one byte result */
3181 if ((ic->op == '+' || ic->op == '-')
3182 && getSize (operandType (IC_RESULT (ic))) > 1)
3185 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3186 /* if shift operation make sure right side is not a literal */
3187 if (ic->op == RIGHT_OP &&
3188 (isOperandLiteral (IC_RIGHT (ic)) ||
3189 getSize (operandType (IC_RESULT (ic))) > 1))
3192 if (ic->op == LEFT_OP &&
3193 (isOperandLiteral (IC_RIGHT (ic)) ||
3194 getSize (operandType (IC_RESULT (ic))) > 1))
3197 if (IS_BITWISE_OP (ic) &&
3198 getSize (operandType (IC_RESULT (ic))) > 1)
3202 /* has only one definition */
3203 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3206 /* has only one use */
3207 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3210 /* and the usage immediately follows this iCode */
3211 if (!(uic = hTabItemWithKey (iCodehTab,
3212 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3215 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3216 if (ic->next != uic)
3219 /* if it is a conditional branch then we definitely can */
3223 if (uic->op == JUMPTABLE)
3226 /* if the usage is not is an assignment
3227 or an arithmetic / bitwise / shift operation then not */
3228 if (POINTER_SET (uic) &&
3229 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3232 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3233 if (uic->op != '=' &&
3234 !IS_ARITHMETIC_OP (uic) &&
3235 !IS_BITWISE_OP (uic) &&
3236 uic->op != LEFT_OP &&
3237 uic->op != RIGHT_OP)
3240 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3241 /* if used in ^ operation then make sure right is not a
3243 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3246 /* if shift operation make sure right side is not a literal */
3247 if (uic->op == RIGHT_OP &&
3248 (isOperandLiteral (IC_RIGHT (uic)) ||
3249 getSize (operandType (IC_RESULT (uic))) > 1))
3252 if (uic->op == LEFT_OP &&
3253 (isOperandLiteral (IC_RIGHT (uic)) ||
3254 getSize (operandType (IC_RESULT (uic))) > 1))
3257 /* make sure that the result of this icode is not on the
3258 stack, since acc is used to compute stack offset */
3259 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3260 OP_SYMBOL (IC_RESULT (uic))->onStack)
3263 /* if either one of them in far space then we cannot */
3264 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3265 isOperandInFarSpace (IC_LEFT (uic))) ||
3266 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3267 isOperandInFarSpace (IC_RIGHT (uic))))
3270 /* if the usage has only one operand then we can */
3271 if (IC_LEFT (uic) == NULL ||
3272 IC_RIGHT (uic) == NULL)
3275 /* make sure this is on the left side if not
3276 a '+' since '+' is commutative */
3277 if (ic->op != '+' &&
3278 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3281 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3282 /* if one of them is a literal then we can */
3283 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3284 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3285 (getSize (operandType (IC_RESULT (uic))) <= 1))
3287 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3291 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3292 /* if the other one is not on stack then we can */
3293 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3294 (IS_ITEMP (IC_RIGHT (uic)) ||
3295 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3296 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3299 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3300 (IS_ITEMP (IC_LEFT (uic)) ||
3301 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3302 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3308 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3309 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3314 /*-----------------------------------------------------------------*/
3315 /* packForPush - hueristics to reduce iCode for pushing */
3316 /*-----------------------------------------------------------------*/
3318 packForReceive (iCode * ic, eBBlock * ebp)
3322 debugLog ("%s\n", __FUNCTION__);
3323 debugAopGet (" result:", IC_RESULT (ic));
3324 debugAopGet (" left:", IC_LEFT (ic));
3325 debugAopGet (" right:", IC_RIGHT (ic));
3330 for (dic = ic->next; dic; dic = dic->next)
3335 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3336 debugLog (" used on left\n");
3337 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3338 debugLog (" used on right\n");
3339 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3340 debugLog (" used on result\n");
3342 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3343 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3348 debugLog (" hey we can remove this unnecessary assign\n");
3350 /*-----------------------------------------------------------------*/
3351 /* packForPush - hueristics to reduce iCode for pushing */
3352 /*-----------------------------------------------------------------*/
3354 packForPush (iCode * ic, eBBlock * ebp)
3358 debugLog ("%s\n", __FUNCTION__);
3359 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3362 /* must have only definition & one usage */
3363 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3364 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3367 /* find the definition */
3368 if (!(dic = hTabItemWithKey (iCodehTab,
3369 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3372 if (dic->op != '=' || POINTER_SET (dic))
3375 /* we now we know that it has one & only one def & use
3376 and the that the definition is an assignment */
3377 IC_LEFT (ic) = IC_RIGHT (dic);
3379 remiCodeFromeBBlock (ebp, dic);
3380 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3381 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3384 void printSymType(char * str, sym_link *sl)
3386 debugLog (" %s Symbol type: ",str);
3387 printTypeChain( sl, debugF);
3392 /*-----------------------------------------------------------------*/
3393 /* packRegisters - does some transformations to reduce register */
3395 /*-----------------------------------------------------------------*/
3397 packRegisters (eBBlock * ebp)
3402 debugLog ("%s\n", __FUNCTION__);
3408 /* look for assignments of the form */
3409 /* iTempNN = TRueSym (someoperation) SomeOperand */
3411 /* TrueSym := iTempNN:1 */
3412 for (ic = ebp->sch; ic; ic = ic->next)
3415 /* find assignment of the form TrueSym := iTempNN:1 */
3416 if (ic->op == '=' && !POINTER_SET (ic))
3417 change += packRegsForAssign (ic, ebp);
3421 if (POINTER_SET (ic))
3422 debugLog ("pointer is set\n");
3423 debugAopGet (" result:", IC_RESULT (ic));
3424 debugAopGet (" left:", IC_LEFT (ic));
3425 debugAopGet (" right:", IC_RIGHT (ic));
3434 for (ic = ebp->sch; ic; ic = ic->next) {
3436 if(IS_SYMOP ( IC_LEFT(ic))) {
3437 //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3439 debugAopGet (" left:", IC_LEFT (ic));
3440 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3441 debugLog (" is a pointer");
3443 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3446 if(IS_SYMOP ( IC_RIGHT(ic))) {
3447 debugAopGet (" right:", IC_RIGHT (ic));
3448 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3451 if(IS_SYMOP ( IC_RESULT(ic))) {
3452 debugAopGet (" result:", IC_RESULT (ic));
3453 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3456 if (POINTER_SET (ic))
3457 debugLog (" %d - Pointer set\n", __LINE__);
3460 /* if this is an itemp & result of a address of a true sym
3461 then mark this as rematerialisable */
3462 if (ic->op == ADDRESS_OF &&
3463 IS_ITEMP (IC_RESULT (ic)) &&
3464 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3465 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3466 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3469 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3471 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3472 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3473 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3477 /* if straight assignment then carry remat flag if
3478 this is the only definition */
3479 if (ic->op == '=' &&
3480 !POINTER_SET (ic) &&
3481 IS_SYMOP (IC_RIGHT (ic)) &&
3482 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3483 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3485 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3487 OP_SYMBOL (IC_RESULT (ic))->remat =
3488 OP_SYMBOL (IC_RIGHT (ic))->remat;
3489 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3490 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3493 /* if this is a +/- operation with a rematerizable
3494 then mark this as rematerializable as well */
3495 if ((ic->op == '+' || ic->op == '-') &&
3496 (IS_SYMOP (IC_LEFT (ic)) &&
3497 IS_ITEMP (IC_RESULT (ic)) &&
3498 OP_SYMBOL (IC_LEFT (ic))->remat &&
3499 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3500 IS_OP_LITERAL (IC_RIGHT (ic))))
3502 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3504 operandLitValue (IC_RIGHT (ic));
3505 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3506 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3507 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3510 /* mark the pointer usages */
3511 if (POINTER_SET (ic))
3513 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3514 debugLog (" marking as a pointer (set) =>");
3515 debugAopGet (" result:", IC_RESULT (ic));
3517 if (POINTER_GET (ic))
3519 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3520 debugLog (" marking as a pointer (get) =>");
3521 debugAopGet (" left:", IC_LEFT (ic));
3526 /* if we are using a symbol on the stack
3527 then we should say pic14_ptrRegReq */
3528 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3529 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3530 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3531 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3532 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3533 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3536 if (IS_SYMOP (IC_LEFT (ic)))
3537 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3538 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3539 if (IS_SYMOP (IC_RIGHT (ic)))
3540 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3541 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3542 if (IS_SYMOP (IC_RESULT (ic)))
3543 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3544 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3547 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3551 /* if the condition of an if instruction
3552 is defined in the previous instruction then
3553 mark the itemp as a conditional */
3554 if ((IS_CONDITIONAL (ic) ||
3555 ((ic->op == BITWISEAND ||
3558 isBitwiseOptimizable (ic))) &&
3559 ic->next && ic->next->op == IFX &&
3560 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3561 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3564 debugLog (" %d\n", __LINE__);
3565 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3569 /* reduce for support function calls */
3570 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3571 packRegsForSupport (ic, ebp);
3573 /* if a parameter is passed, it's in W, so we may not
3574 need to place a copy in a register */
3575 if (ic->op == RECEIVE)
3576 packForReceive (ic, ebp);
3578 /* some cases the redundant moves can
3579 can be eliminated for return statements */
3580 if ((ic->op == RETURN || ic->op == SEND) &&
3581 !isOperandInFarSpace (IC_LEFT (ic)) &&
3583 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3585 /* if pointer set & left has a size more than
3586 one and right is not in far space */
3587 if (POINTER_SET (ic) &&
3588 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3589 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3590 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3591 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3593 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3595 /* if pointer get */
3596 if (POINTER_GET (ic) &&
3597 !isOperandInFarSpace (IC_RESULT (ic)) &&
3598 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3599 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3600 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3602 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3605 /* if this is cast for intergral promotion then
3606 check if only use of the definition of the
3607 operand being casted/ if yes then replace
3608 the result of that arithmetic operation with
3609 this result and get rid of the cast */
3610 if (ic->op == CAST) {
3612 sym_link *fromType = operandType (IC_RIGHT (ic));
3613 sym_link *toType = operandType (IC_LEFT (ic));
3615 debugLog (" %d - casting\n", __LINE__);
3617 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3618 getSize (fromType) != getSize (toType)) {
3621 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3624 if (IS_ARITHMETIC_OP (dic)) {
3626 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3627 IC_RESULT (dic) = IC_RESULT (ic);
3628 remiCodeFromeBBlock (ebp, ic);
3629 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3630 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3631 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3635 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3639 /* if the type from and type to are the same
3640 then if this is the only use then packit */
3641 if (compareType (operandType (IC_RIGHT (ic)),
3642 operandType (IC_LEFT (ic))) == 1) {
3644 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3647 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3648 IC_RESULT (dic) = IC_RESULT (ic);
3649 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3650 remiCodeFromeBBlock (ebp, ic);
3651 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3652 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3660 iTempNN := (some variable in farspace) V1
3665 if (ic->op == IPUSH)
3667 packForPush (ic, ebp);
3671 /* pack registers for accumulator use, when the
3672 result of an arithmetic or bit wise operation
3673 has only one use, that use is immediately following
3674 the defintion and the using iCode has only one
3675 operand or has two operands but one is literal &
3676 the result of that operation is not on stack then
3677 we can leave the result of this operation in acc:b
3679 if ((IS_ARITHMETIC_OP (ic)
3681 || IS_BITWISE_OP (ic)
3683 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3686 IS_ITEMP (IC_RESULT (ic)) &&
3687 getSize (operandType (IC_RESULT (ic))) <= 2)
3689 packRegsForAccUse (ic);
3695 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3699 if (!debug || !debugF)
3702 for (i = 0; i < count; i++)
3704 fprintf (debugF, "\n----------------------------------------------------------------\n");
3705 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3706 ebbs[i]->entryLabel->name,
3709 ebbs[i]->isLastInLoop);
3710 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3715 fprintf (debugF, "visited %d : hasFcall = %d\n",
3719 fprintf (debugF, "\ndefines bitVector :");
3720 bitVectDebugOn (ebbs[i]->defSet, debugF);
3721 fprintf (debugF, "\nlocal defines bitVector :");
3722 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3723 fprintf (debugF, "\npointers Set bitvector :");
3724 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3725 fprintf (debugF, "\nin pointers Set bitvector :");
3726 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3727 fprintf (debugF, "\ninDefs Set bitvector :");
3728 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3729 fprintf (debugF, "\noutDefs Set bitvector :");
3730 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3731 fprintf (debugF, "\nusesDefs Set bitvector :");
3732 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3733 fprintf (debugF, "\n----------------------------------------------------------------\n");
3734 printiCChain (ebbs[i]->sch, debugF);
3737 /*-----------------------------------------------------------------*/
3738 /* assignRegisters - assigns registers to each live range as need */
3739 /*-----------------------------------------------------------------*/
3741 pic14_assignRegisters (eBBlock ** ebbs, int count)
3746 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3747 debugLog ("\nebbs before optimizing:\n");
3748 dumpEbbsToDebug (ebbs, count);
3750 setToNull ((void *) &_G.funcrUsed);
3751 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3754 /* change assignments this will remove some
3755 live ranges reducing some register pressure */
3756 for (i = 0; i < count; i++)
3757 packRegisters (ebbs[i]);
3764 debugLog("dir registers allocated so far:\n");
3765 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3768 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3769 reg = hTabNextItem(dynDirectRegNames, &hkey);
3774 if (options.dump_pack)
3775 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3777 /* first determine for each live range the number of
3778 registers & the type of registers required for each */
3781 /* and serially allocate registers */
3782 serialRegAssign (ebbs, count);
3784 /* if stack was extended then tell the user */
3787 /* werror(W_TOOMANY_SPILS,"stack", */
3788 /* _G.stackExtend,currFunc->name,""); */
3794 /* werror(W_TOOMANY_SPILS,"data space", */
3795 /* _G.dataExtend,currFunc->name,""); */
3799 /* after that create the register mask
3800 for each of the instruction */
3801 createRegMask (ebbs, count);
3803 /* redo that offsets for stacked automatic variables */
3804 redoStackOffsets ();
3806 if (options.dump_rassgn)
3807 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3809 /* now get back the chain */
3810 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3812 debugLog ("ebbs after optimizing:\n");
3813 dumpEbbsToDebug (ebbs, count);
3818 /* free up any _G.stackSpil locations allocated */
3819 applyToSet (_G.stackSpil, deallocStackSpil);
3821 setToNull ((void **) &_G.stackSpil);
3822 setToNull ((void **) &_G.spiltSet);
3823 /* mark all registers as free */
3824 //pic14_freeAllRegs ();
3826 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");