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, "unkown reg type %d", type);
414 /*-----------------------------------------------------------------*/
415 /* newReg - allocate and init memory for a new register */
416 /*-----------------------------------------------------------------*/
417 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
422 dReg = Safe_calloc(1,sizeof(regs));
424 dReg->pc_type = pc_type;
427 dReg->name = Safe_strdup(name);
429 sprintf(buffer,"r0x%02X", dReg->rIdx);
432 dReg->name = Safe_strdup(buffer);
434 //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
443 dReg->reg_alias = NULL;
444 dReg->reglives.usedpFlows = newSet();
445 dReg->reglives.assignedpFlows = newSet();
450 /*-----------------------------------------------------------------*/
451 /* regWithIdx - Search through a set of registers that matches idx */
452 /*-----------------------------------------------------------------*/
454 regWithIdx (set *dRegs, int idx, int fixed)
458 for (dReg = setFirstItem(dRegs) ; dReg ;
459 dReg = setNextItem(dRegs)) {
461 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
469 /*-----------------------------------------------------------------*/
470 /* regFindFree - Search for a free register in a set of registers */
471 /*-----------------------------------------------------------------*/
473 regFindFree (set *dRegs)
477 for (dReg = setFirstItem(dRegs) ; dReg ;
478 dReg = setNextItem(dRegs)) {
486 /*-----------------------------------------------------------------*/
487 /* initStack - allocate registers for a psuedo stack */
488 /*-----------------------------------------------------------------*/
489 void initStack(int base_address, int size)
494 Gstack_base_addr = base_address;
495 for(i = 0; i<size; i++)
496 addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
500 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
502 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
506 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
508 regs * reg = newReg(REG_SFR, po_type, rIdx, name,1,alias);
512 return addSet(&dynInternalRegs,reg);
517 /*-----------------------------------------------------------------*/
518 /* allocReg - allocates register of given type */
519 /*-----------------------------------------------------------------*/
521 allocReg (short type)
524 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
527 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
531 /*-----------------------------------------------------------------*/
532 /*-----------------------------------------------------------------*/
533 static int regname2key(char const *name)
542 key += (*name++) + 1;
546 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
550 /*-----------------------------------------------------------------*/
551 /* dirregWithName - search for register by name */
552 /*-----------------------------------------------------------------*/
554 dirregWithName (char *name)
562 /* hash the name to get a key */
564 hkey = regname2key(name);
566 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
570 if(STRCASECMP(reg->name, name) == 0) {
574 reg = hTabNextItemWK (dynDirectRegNames);
578 return NULL; // name wasn't found in the hash table
581 int IS_CONFIG_ADDRESS(int address)
584 return address == 0x2007;
587 /*-----------------------------------------------------------------*/
588 /* allocDirReg - allocates register of given type */
589 /*-----------------------------------------------------------------*/
591 allocDirReg (operand *op )
598 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
602 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
604 /* If the symbol is at a fixed address, then remove the leading underscore
605 * from the name. This is hack to allow the .asm include file named registers
606 * to match the .c declared register names */
608 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
611 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
613 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
614 debugLog(" %d const char\n",__LINE__);
615 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
618 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
619 if (IS_CODE ( OP_SYM_ETYPE(op)) )
620 debugLog(" %d code space\n",__LINE__);
622 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
623 debugLog(" %d integral\n",__LINE__);
624 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
625 debugLog(" %d literal\n",__LINE__);
626 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
627 debugLog(" %d specifier\n",__LINE__);
628 debugAopGet(NULL, op);
631 if (IS_CODE ( OP_SYM_ETYPE(op)) )
634 /* First, search the hash table to see if there is a register with this name */
635 reg = dirregWithName(name);
640 /* if this is at an absolute address, then get the address. */
641 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
642 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
645 /* Register wasn't found in hash, so let's create
646 * a new one and put it in the hash table AND in the
647 * dynDirectRegNames set */
648 if(!IS_CONFIG_ADDRESS(address)) {
649 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
650 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
652 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
654 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
655 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
658 hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
659 if (IS_BITVAR (OP_SYM_ETYPE(op)))
660 addSet(&dynDirectBitRegs, reg);
662 addSet(&dynDirectRegs, reg);
664 debugLog (" -- %s is declared at address 0x2007\n",name);
669 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
671 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
672 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
678 /*-----------------------------------------------------------------*/
679 /* allocDirReg - allocates register of given type */
680 /*-----------------------------------------------------------------*/
682 allocRegByName (char *name, int size)
688 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
692 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
694 /* First, search the hash table to see if there is a register with this name */
695 reg = dirregWithName(name);
699 /* Register wasn't found in hash, so let's create
700 * a new one and put it in the hash table AND in the
701 * dynDirectRegNames set */
703 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
705 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
707 hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
708 addSet(&dynDirectRegs, reg);
714 /*-----------------------------------------------------------------*/
715 /* RegWithIdx - returns pointer to register with index number */
716 /*-----------------------------------------------------------------*/
718 typeRegWithIdx (int idx, int type, int fixed)
723 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
728 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
730 debugLog ("Found a Dynamic Register!\n");
733 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
734 debugLog ("Found a Direct Register!\n");
740 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
741 debugLog ("Found a Stack Register!\n");
746 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
747 debugLog ("Found a Processor Register!\n");
759 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
761 debugLog ("Found a Dynamic Register!\n");
765 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
766 debugLog ("Found a Stack Register!\n");
770 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
771 debugLog ("Found a Direct Register!\n");
775 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
776 debugLog ("Found a Processor Register!\n");
782 if( (dReg = regWithIdx ( dynDirectBitRegs, idx, fixed)) != NULL ) {
783 debugLog ("Found a bit Register!\n");
791 /*-----------------------------------------------------------------*/
792 /* pic14_regWithIdx - returns pointer to register with index number*/
793 /*-----------------------------------------------------------------*/
795 pic14_regWithIdx (int idx)
799 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
802 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
805 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
811 /*-----------------------------------------------------------------*/
812 /* pic14_regWithIdx - returns pointer to register with index number */
813 /*-----------------------------------------------------------------*/
815 pic14_allocWithIdx (int idx)
820 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
822 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
824 debugLog ("Found a Dynamic Register!\n");
825 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
826 debugLog ("Found a Stack Register!\n");
827 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
828 debugLog ("Found a Processor Register!\n");
829 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
830 debugLog ("Found an Internal Register!\n");
833 debugLog ("Dynamic Register not found\n");
836 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
837 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
838 "regWithIdx not found");
848 /*-----------------------------------------------------------------*/
849 /*-----------------------------------------------------------------*/
851 pic14_findFreeReg(short type)
858 if((dReg = regFindFree(dynAllocRegs)) != NULL)
861 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
865 if((dReg = regFindFree(dynStackRegs)) != NULL)
877 /*-----------------------------------------------------------------*/
878 /* freeReg - frees a register */
879 /*-----------------------------------------------------------------*/
883 debugLog ("%s\n", __FUNCTION__);
888 /*-----------------------------------------------------------------*/
889 /* nFreeRegs - returns number of free registers */
890 /*-----------------------------------------------------------------*/
894 /* dynamically allocate as many as we need and worry about
895 * fitting them into a PIC later */
902 debugLog ("%s\n", __FUNCTION__);
903 for (i = 0; i < pic14_nRegs; i++)
904 if (regspic14[i].isFree && regspic14[i].type == type)
910 /*-----------------------------------------------------------------*/
911 /* nfreeRegsType - free registers with type */
912 /*-----------------------------------------------------------------*/
914 nfreeRegsType (int type)
917 debugLog ("%s\n", __FUNCTION__);
920 if ((nfr = nFreeRegs (type)) == 0)
921 return nFreeRegs (REG_GPR);
924 return nFreeRegs (type);
928 void writeSetUsedRegs(FILE *of, set *dRegs)
933 for (dReg = setFirstItem(dRegs) ; dReg ;
934 dReg = setNextItem(dRegs)) {
937 fprintf (of, "\t%s\n",dReg->name);
941 extern void assignFixedRegisters(set *regset);
942 extern void assignRelocatableRegisters(set *regset,int used);
943 extern void dump_map(void);
944 extern void dump_cblock(FILE *of);
947 void packBits(set *bregs)
952 regs *relocbitfield=NULL;
957 for (regset = bregs ; regset ;
958 regset = regset->next) {
961 breg->isBitField = 1;
962 //fprintf(stderr,"bit reg: %s\n",breg->name);
965 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
967 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
968 breg->rIdx = breg->address & 7;
972 sprintf (buffer, "fbitfield%02x", breg->address);
973 //fprintf(stderr,"new bit field\n");
974 bitfield = newReg(REG_GPR, PO_GPR_BIT,breg->address,buffer,1,0);
975 bitfield->isBitField = 1;
976 bitfield->isFixed = 1;
977 bitfield->address = breg->address;
978 addSet(&dynDirectRegs,bitfield);
979 hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
981 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
984 breg->reg_alias = bitfield;
988 if(!relocbitfield || bit_no >7) {
991 sprintf (buffer, "bitfield%d", byte_no);
992 //fprintf(stderr,"new relocatable bit field\n");
993 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
994 relocbitfield->isBitField = 1;
995 addSet(&dynDirectRegs,relocbitfield);
996 hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1000 breg->reg_alias = relocbitfield;
1001 breg->address = rDirectIdx; /* byte_no; */
1002 breg->rIdx = bit_no++;
1010 void bitEQUs(FILE *of, set *bregs)
1012 regs *breg,*bytereg;
1015 //fprintf(stderr," %s\n",__FUNCTION__);
1016 for (breg = setFirstItem(bregs) ; breg ;
1017 breg = setNextItem(bregs)) {
1019 //fprintf(stderr,"bit reg: %s\n",breg->name);
1021 bytereg = breg->reg_alias;
1023 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1026 breg->rIdx & 0x0007);
1029 fprintf(stderr, "bit field is not assigned to a register\n");
1030 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1040 void aliasEQUs(FILE *of, set *fregs)
1045 for (reg = setFirstItem(fregs) ; reg ;
1046 reg = setNextItem(fregs)) {
1048 if(!reg->isEmitted && reg->wasUsed)
1049 fprintf (of, "%s\tEQU\t0x%03x\n",
1056 void writeUsedRegs(FILE *of)
1058 packBits(dynDirectBitRegs);
1060 assignFixedRegisters(dynAllocRegs);
1061 assignFixedRegisters(dynStackRegs);
1062 assignFixedRegisters(dynDirectRegs);
1064 assignRelocatableRegisters(dynInternalRegs,0);
1065 assignRelocatableRegisters(dynAllocRegs,0);
1066 assignRelocatableRegisters(dynStackRegs,0);
1067 assignRelocatableRegisters(dynDirectRegs,0);
1072 bitEQUs(of,dynDirectBitRegs);
1073 aliasEQUs(of,dynAllocRegs);
1074 aliasEQUs(of,dynDirectRegs);
1075 aliasEQUs(of,dynStackRegs);
1080 /*-----------------------------------------------------------------*/
1081 /* allDefsOutOfRange - all definitions are out of a range */
1082 /*-----------------------------------------------------------------*/
1084 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1088 debugLog ("%s\n", __FUNCTION__);
1092 for (i = 0; i < defs->size; i++)
1096 if (bitVectBitValue (defs, i) &&
1097 (ic = hTabItemWithKey (iCodehTab, i)) &&
1098 (ic->seq >= fseq && ic->seq <= toseq))
1109 /*-----------------------------------------------------------------*/
1110 /* computeSpillable - given a point find the spillable live ranges */
1111 /*-----------------------------------------------------------------*/
1113 computeSpillable (iCode * ic)
1117 debugLog ("%s\n", __FUNCTION__);
1118 /* spillable live ranges are those that are live at this
1119 point . the following categories need to be subtracted
1121 a) - those that are already spilt
1122 b) - if being used by this one
1123 c) - defined by this one */
1125 spillable = bitVectCopy (ic->rlive);
1127 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1129 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1130 bitVectUnSetBit (spillable, ic->defKey);
1131 spillable = bitVectIntersect (spillable, _G.regAssigned);
1136 /*-----------------------------------------------------------------*/
1137 /* noSpilLoc - return true if a variable has no spil location */
1138 /*-----------------------------------------------------------------*/
1140 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1142 debugLog ("%s\n", __FUNCTION__);
1143 return (sym->usl.spillLoc ? 0 : 1);
1146 /*-----------------------------------------------------------------*/
1147 /* hasSpilLoc - will return 1 if the symbol has spil location */
1148 /*-----------------------------------------------------------------*/
1150 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1152 debugLog ("%s\n", __FUNCTION__);
1153 return (sym->usl.spillLoc ? 1 : 0);
1156 /*-----------------------------------------------------------------*/
1157 /* directSpilLoc - will return 1 if the splilocation is in direct */
1158 /*-----------------------------------------------------------------*/
1160 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1162 debugLog ("%s\n", __FUNCTION__);
1163 if (sym->usl.spillLoc &&
1164 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1170 /*-----------------------------------------------------------------*/
1171 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1172 /* but is not used as a pointer */
1173 /*-----------------------------------------------------------------*/
1175 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1177 debugLog ("%s\n", __FUNCTION__);
1178 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1181 /*-----------------------------------------------------------------*/
1182 /* rematable - will return 1 if the remat flag is set */
1183 /*-----------------------------------------------------------------*/
1185 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1187 debugLog ("%s\n", __FUNCTION__);
1191 /*-----------------------------------------------------------------*/
1192 /* notUsedInRemaining - not used or defined in remain of the block */
1193 /*-----------------------------------------------------------------*/
1195 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1197 debugLog ("%s\n", __FUNCTION__);
1198 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1199 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1202 /*-----------------------------------------------------------------*/
1203 /* allLRs - return true for all */
1204 /*-----------------------------------------------------------------*/
1206 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1208 debugLog ("%s\n", __FUNCTION__);
1212 /*-----------------------------------------------------------------*/
1213 /* liveRangesWith - applies function to a given set of live range */
1214 /*-----------------------------------------------------------------*/
1216 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1217 eBBlock * ebp, iCode * ic)
1222 debugLog ("%s\n", __FUNCTION__);
1223 if (!lrs || !lrs->size)
1226 for (i = 1; i < lrs->size; i++)
1229 if (!bitVectBitValue (lrs, i))
1232 /* if we don't find it in the live range
1233 hash table we are in serious trouble */
1234 if (!(sym = hTabItemWithKey (liveRanges, i)))
1236 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1237 "liveRangesWith could not find liveRange");
1241 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1242 addSetHead (&rset, sym);
1249 /*-----------------------------------------------------------------*/
1250 /* leastUsedLR - given a set determines which is the least used */
1251 /*-----------------------------------------------------------------*/
1253 leastUsedLR (set * sset)
1255 symbol *sym = NULL, *lsym = NULL;
1257 debugLog ("%s\n", __FUNCTION__);
1258 sym = lsym = setFirstItem (sset);
1263 for (; lsym; lsym = setNextItem (sset))
1266 /* if usage is the same then prefer
1267 the spill the smaller of the two */
1268 if (lsym->used == sym->used)
1269 if (getSize (lsym->type) < getSize (sym->type))
1273 if (lsym->used < sym->used)
1278 setToNull ((void **) &sset);
1283 /*-----------------------------------------------------------------*/
1284 /* noOverLap - will iterate through the list looking for over lap */
1285 /*-----------------------------------------------------------------*/
1287 noOverLap (set * itmpStack, symbol * fsym)
1290 debugLog ("%s\n", __FUNCTION__);
1293 for (sym = setFirstItem (itmpStack); sym;
1294 sym = setNextItem (itmpStack))
1296 if (sym->liveTo > fsym->liveFrom)
1304 /*-----------------------------------------------------------------*/
1305 /* isFree - will return 1 if the a free spil location is found */
1306 /*-----------------------------------------------------------------*/
1311 V_ARG (symbol **, sloc);
1312 V_ARG (symbol *, fsym);
1314 debugLog ("%s\n", __FUNCTION__);
1315 /* if already found */
1319 /* if it is free && and the itmp assigned to
1320 this does not have any overlapping live ranges
1321 with the one currently being assigned and
1322 the size can be accomodated */
1324 noOverLap (sym->usl.itmpStack, fsym) &&
1325 getSize (sym->type) >= getSize (fsym->type))
1334 /*-----------------------------------------------------------------*/
1335 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1336 /*-----------------------------------------------------------------*/
1338 spillLRWithPtrReg (symbol * forSym)
1344 debugLog ("%s\n", __FUNCTION__);
1345 if (!_G.regAssigned ||
1346 bitVectIsZero (_G.regAssigned))
1349 r0 = pic14_regWithIdx (R0_IDX);
1350 r1 = pic14_regWithIdx (R1_IDX);
1352 /* for all live ranges */
1353 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1354 lrsym = hTabNextItem (liveRanges, &k))
1358 /* if no registers assigned to it or
1360 /* if it does not overlap with this then
1361 not need to spill it */
1363 if (lrsym->isspilt || !lrsym->nRegs ||
1364 (lrsym->liveTo < forSym->liveFrom))
1367 /* go thru the registers : if it is either
1368 r0 or r1 then spil it */
1369 for (j = 0; j < lrsym->nRegs; j++)
1370 if (lrsym->regs[j] == r0 ||
1371 lrsym->regs[j] == r1)
1380 /*-----------------------------------------------------------------*/
1381 /* createStackSpil - create a location on the stack to spil */
1382 /*-----------------------------------------------------------------*/
1384 createStackSpil (symbol * sym)
1386 symbol *sloc = NULL;
1387 int useXstack, model, noOverlay;
1389 char slocBuffer[30];
1390 debugLog ("%s\n", __FUNCTION__);
1392 /* first go try and find a free one that is already
1393 existing on the stack */
1394 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1396 /* found a free one : just update & return */
1397 sym->usl.spillLoc = sloc;
1400 addSetHead (&sloc->usl.itmpStack, sym);
1404 /* could not then have to create one , this is the hard part
1405 we need to allocate this on the stack : this is really a
1406 hack!! but cannot think of anything better at this time */
1408 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1410 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1411 __FILE__, __LINE__);
1415 sloc = newiTemp (slocBuffer);
1417 /* set the type to the spilling symbol */
1418 sloc->type = copyLinkChain (sym->type);
1419 sloc->etype = getSpec (sloc->type);
1420 SPEC_SCLS (sloc->etype) = S_DATA;
1421 SPEC_EXTR (sloc->etype) = 0;
1422 SPEC_STAT (sloc->etype) = 0;
1424 /* we don't allow it to be allocated`
1425 onto the external stack since : so we
1426 temporarily turn it off ; we also
1427 turn off memory model to prevent
1428 the spil from going to the external storage
1429 and turn off overlaying
1432 useXstack = options.useXstack;
1433 model = options.model;
1434 noOverlay = options.noOverlay;
1435 options.noOverlay = 1;
1436 options.model = options.useXstack = 0;
1440 options.useXstack = useXstack;
1441 options.model = model;
1442 options.noOverlay = noOverlay;
1443 sloc->isref = 1; /* to prevent compiler warning */
1445 /* if it is on the stack then update the stack */
1446 if (IN_STACK (sloc->etype))
1448 currFunc->stack += getSize (sloc->type);
1449 _G.stackExtend += getSize (sloc->type);
1452 _G.dataExtend += getSize (sloc->type);
1454 /* add it to the _G.stackSpil set */
1455 addSetHead (&_G.stackSpil, sloc);
1456 sym->usl.spillLoc = sloc;
1459 /* add it to the set of itempStack set
1460 of the spill location */
1461 addSetHead (&sloc->usl.itmpStack, sym);
1465 /*-----------------------------------------------------------------*/
1466 /* isSpiltOnStack - returns true if the spil location is on stack */
1467 /*-----------------------------------------------------------------*/
1469 isSpiltOnStack (symbol * sym)
1473 debugLog ("%s\n", __FUNCTION__);
1480 /* if (sym->_G.stackSpil) */
1483 if (!sym->usl.spillLoc)
1486 etype = getSpec (sym->usl.spillLoc->type);
1487 if (IN_STACK (etype))
1493 /*-----------------------------------------------------------------*/
1494 /* spillThis - spils a specific operand */
1495 /*-----------------------------------------------------------------*/
1497 spillThis (symbol * sym)
1500 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1502 /* if this is rematerializable or has a spillLocation
1503 we are okay, else we need to create a spillLocation
1505 if (!(sym->remat || sym->usl.spillLoc))
1506 createStackSpil (sym);
1509 /* mark it has spilt & put it in the spilt set */
1511 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1513 bitVectUnSetBit (_G.regAssigned, sym->key);
1515 for (i = 0; i < sym->nRegs; i++)
1519 freeReg (sym->regs[i]);
1520 sym->regs[i] = NULL;
1523 /* if spilt on stack then free up r0 & r1
1524 if they could have been assigned to some
1526 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1529 spillLRWithPtrReg (sym);
1532 if (sym->usl.spillLoc && !sym->remat)
1533 sym->usl.spillLoc->allocreq = 1;
1537 /*-----------------------------------------------------------------*/
1538 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1539 /*-----------------------------------------------------------------*/
1541 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1543 bitVect *lrcs = NULL;
1547 debugLog ("%s\n", __FUNCTION__);
1548 /* get the spillable live ranges */
1549 lrcs = computeSpillable (ic);
1551 /* get all live ranges that are rematerizable */
1552 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1555 /* return the least used of these */
1556 return leastUsedLR (selectS);
1559 /* get live ranges with spillLocations in direct space */
1560 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1562 sym = leastUsedLR (selectS);
1563 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1564 sym->usl.spillLoc->rname :
1565 sym->usl.spillLoc->name));
1567 /* mark it as allocation required */
1568 sym->usl.spillLoc->allocreq = 1;
1572 /* if the symbol is local to the block then */
1573 if (forSym->liveTo < ebp->lSeq)
1576 /* check if there are any live ranges allocated
1577 to registers that are not used in this block */
1578 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1580 sym = leastUsedLR (selectS);
1581 /* if this is not rematerializable */
1590 /* check if there are any live ranges that not
1591 used in the remainder of the block */
1592 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1594 sym = leastUsedLR (selectS);
1597 sym->remainSpil = 1;
1604 /* find live ranges with spillocation && not used as pointers */
1605 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1608 sym = leastUsedLR (selectS);
1609 /* mark this as allocation required */
1610 sym->usl.spillLoc->allocreq = 1;
1614 /* find live ranges with spillocation */
1615 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1618 sym = leastUsedLR (selectS);
1619 sym->usl.spillLoc->allocreq = 1;
1623 /* couldn't find then we need to create a spil
1624 location on the stack , for which one? the least
1626 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1629 /* return a created spil location */
1630 sym = createStackSpil (leastUsedLR (selectS));
1631 sym->usl.spillLoc->allocreq = 1;
1635 /* this is an extreme situation we will spill
1636 this one : happens very rarely but it does happen */
1642 /*-----------------------------------------------------------------*/
1643 /* spilSomething - spil some variable & mark registers as free */
1644 /*-----------------------------------------------------------------*/
1646 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1651 debugLog ("%s\n", __FUNCTION__);
1652 /* get something we can spil */
1653 ssym = selectSpil (ic, ebp, forSym);
1655 /* mark it as spilt */
1657 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1659 /* mark it as not register assigned &
1660 take it away from the set */
1661 bitVectUnSetBit (_G.regAssigned, ssym->key);
1663 /* mark the registers as free */
1664 for (i = 0; i < ssym->nRegs; i++)
1666 freeReg (ssym->regs[i]);
1668 /* if spilt on stack then free up r0 & r1
1669 if they could have been assigned to as gprs */
1670 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1673 spillLRWithPtrReg (ssym);
1676 /* if this was a block level spil then insert push & pop
1677 at the start & end of block respectively */
1678 if (ssym->blockSpil)
1680 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1681 /* add push to the start of the block */
1682 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1683 ebp->sch->next : ebp->sch));
1684 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1685 /* add pop to the end of the block */
1686 addiCodeToeBBlock (ebp, nic, NULL);
1689 /* if spilt because not used in the remainder of the
1690 block then add a push before this instruction and
1691 a pop at the end of the block */
1692 if (ssym->remainSpil)
1695 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1696 /* add push just before this instruction */
1697 addiCodeToeBBlock (ebp, nic, ic);
1699 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1700 /* add pop to the end of the block */
1701 addiCodeToeBBlock (ebp, nic, NULL);
1710 /*-----------------------------------------------------------------*/
1711 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1712 /*-----------------------------------------------------------------*/
1714 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1718 debugLog ("%s\n", __FUNCTION__);
1720 /* try for a ptr type */
1721 if ((reg = allocReg (REG_PTR)))
1724 /* try for gpr type */
1725 if ((reg = allocReg (REG_GPR)))
1728 /* we have to spil */
1729 if (!spilSomething (ic, ebp, sym))
1732 /* this looks like an infinite loop but
1733 in really selectSpil will abort */
1737 /*-----------------------------------------------------------------*/
1738 /* getRegGpr - will try for GPR if not spil */
1739 /*-----------------------------------------------------------------*/
1741 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1745 debugLog ("%s\n", __FUNCTION__);
1747 /* try for gpr type */
1748 if ((reg = allocReg (REG_GPR)))
1751 if (!pic14_ptrRegReq)
1752 if ((reg = allocReg (REG_PTR)))
1755 /* we have to spil */
1756 if (!spilSomething (ic, ebp, sym))
1759 /* this looks like an infinite loop but
1760 in really selectSpil will abort */
1764 /*-----------------------------------------------------------------*/
1765 /* symHasReg - symbol has a given register */
1766 /*-----------------------------------------------------------------*/
1768 symHasReg (symbol * sym, regs * reg)
1772 debugLog ("%s\n", __FUNCTION__);
1773 for (i = 0; i < sym->nRegs; i++)
1774 if (sym->regs[i] == reg)
1780 /*-----------------------------------------------------------------*/
1781 /* deassignLRs - check the live to and if they have registers & are */
1782 /* not spilt then free up the registers */
1783 /*-----------------------------------------------------------------*/
1785 deassignLRs (iCode * ic, eBBlock * ebp)
1791 debugLog ("%s\n", __FUNCTION__);
1792 for (sym = hTabFirstItem (liveRanges, &k); sym;
1793 sym = hTabNextItem (liveRanges, &k))
1796 symbol *psym = NULL;
1797 /* if it does not end here */
1798 if (sym->liveTo > ic->seq)
1801 /* if it was spilt on stack then we can
1802 mark the stack spil location as free */
1807 sym->usl.spillLoc->isFree = 1;
1813 if (!bitVectBitValue (_G.regAssigned, sym->key))
1816 /* special case check if this is an IFX &
1817 the privious one was a pop and the
1818 previous one was not spilt then keep track
1820 if (ic->op == IFX && ic->prev &&
1821 ic->prev->op == IPOP &&
1822 !ic->prev->parmPush &&
1823 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1824 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1830 bitVectUnSetBit (_G.regAssigned, sym->key);
1832 /* if the result of this one needs registers
1833 and does not have it then assign it right
1835 if (IC_RESULT (ic) &&
1836 !(SKIP_IC2 (ic) || /* not a special icode */
1837 ic->op == JUMPTABLE ||
1842 POINTER_SET (ic)) &&
1843 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1844 result->liveTo > ic->seq && /* and will live beyond this */
1845 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1846 result->regType == sym->regType && /* same register types */
1847 result->nRegs && /* which needs registers */
1848 !result->isspilt && /* and does not already have them */
1850 !bitVectBitValue (_G.regAssigned, result->key) &&
1851 /* the number of free regs + number of regs in this LR
1852 can accomodate the what result Needs */
1853 ((nfreeRegsType (result->regType) +
1854 sym->nRegs) >= result->nRegs)
1858 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1860 result->regs[i] = sym->regs[i];
1862 result->regs[i] = getRegGpr (ic, ebp, result);
1864 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1868 /* free the remaining */
1869 for (; i < sym->nRegs; i++)
1873 if (!symHasReg (psym, sym->regs[i]))
1874 freeReg (sym->regs[i]);
1877 freeReg (sym->regs[i]);
1884 /*-----------------------------------------------------------------*/
1885 /* reassignLR - reassign this to registers */
1886 /*-----------------------------------------------------------------*/
1888 reassignLR (operand * op)
1890 symbol *sym = OP_SYMBOL (op);
1893 debugLog ("%s\n", __FUNCTION__);
1894 /* not spilt any more */
1895 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1896 bitVectUnSetBit (_G.spiltSet, sym->key);
1898 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1902 for (i = 0; i < sym->nRegs; i++)
1903 sym->regs[i]->isFree = 0;
1906 /*-----------------------------------------------------------------*/
1907 /* willCauseSpill - determines if allocating will cause a spill */
1908 /*-----------------------------------------------------------------*/
1910 willCauseSpill (int nr, int rt)
1912 debugLog ("%s\n", __FUNCTION__);
1913 /* first check if there are any avlb registers
1914 of te type required */
1917 /* special case for pointer type
1918 if pointer type not avlb then
1919 check for type gpr */
1920 if (nFreeRegs (rt) >= nr)
1922 if (nFreeRegs (REG_GPR) >= nr)
1927 if (pic14_ptrRegReq)
1929 if (nFreeRegs (rt) >= nr)
1934 if (nFreeRegs (REG_PTR) +
1935 nFreeRegs (REG_GPR) >= nr)
1940 debugLog (" ... yep it will (cause a spill)\n");
1941 /* it will cause a spil */
1945 /*-----------------------------------------------------------------*/
1946 /* positionRegs - the allocator can allocate same registers to res- */
1947 /* ult and operand, if this happens make sure they are in the same */
1948 /* position as the operand otherwise chaos results */
1949 /*-----------------------------------------------------------------*/
1951 positionRegs (symbol * result, symbol * opsym, int lineno)
1953 int count = min (result->nRegs, opsym->nRegs);
1954 int i, j = 0, shared = 0;
1956 debugLog ("%s\n", __FUNCTION__);
1957 /* if the result has been spilt then cannot share */
1962 /* first make sure that they actually share */
1963 for (i = 0; i < count; i++)
1965 for (j = 0; j < count; j++)
1967 if (result->regs[i] == opsym->regs[j] && i != j)
1977 regs *tmp = result->regs[i];
1978 result->regs[i] = result->regs[j];
1979 result->regs[j] = tmp;
1984 /*-----------------------------------------------------------------*/
1985 /* serialRegAssign - serially allocate registers to the variables */
1986 /*-----------------------------------------------------------------*/
1988 serialRegAssign (eBBlock ** ebbs, int count)
1992 debugLog ("%s\n", __FUNCTION__);
1993 /* for all blocks */
1994 for (i = 0; i < count; i++)
1999 if (ebbs[i]->noPath &&
2000 (ebbs[i]->entryLabel != entryLabel &&
2001 ebbs[i]->entryLabel != returnLabel))
2004 /* of all instructions do */
2005 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2008 debugLog (" op: %s\n", decodeOp (ic->op));
2010 /* if this is an ipop that means some live
2011 range will have to be assigned again */
2013 reassignLR (IC_LEFT (ic));
2015 /* if result is present && is a true symbol */
2016 if (IC_RESULT (ic) && ic->op != IFX &&
2017 IS_TRUE_SYMOP (IC_RESULT (ic)))
2018 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2020 /* take away registers from live
2021 ranges that end at this instruction */
2022 deassignLRs (ic, ebbs[i]);
2024 /* some don't need registers */
2025 if (SKIP_IC2 (ic) ||
2026 ic->op == JUMPTABLE ||
2030 (IC_RESULT (ic) && POINTER_SET (ic)))
2033 /* now we need to allocate registers
2034 only for the result */
2037 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2043 /* if it does not need or is spilt
2044 or is already assigned to registers
2045 or will not live beyond this instructions */
2048 bitVectBitValue (_G.regAssigned, sym->key) ||
2049 sym->liveTo <= ic->seq)
2052 /* if some liverange has been spilt at the block level
2053 and this one live beyond this block then spil this
2055 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2060 /* if trying to allocate this will cause
2061 a spill and there is nothing to spill
2062 or this one is rematerializable then
2064 willCS = willCauseSpill (sym->nRegs, sym->regType);
2065 spillable = computeSpillable (ic);
2067 (willCS && bitVectIsZero (spillable)))
2075 /* if it has a spillocation & is used less than
2076 all other live ranges then spill this */
2078 if (sym->usl.spillLoc) {
2079 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2080 allLRs, ebbs[i], ic));
2081 if (leastUsed && leastUsed->used > sym->used) {
2086 /* if none of the liveRanges have a spillLocation then better
2087 to spill this one than anything else already assigned to registers */
2088 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2089 /* if this is local to this block then we might find a block spil */
2090 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2098 if (ic->op == RECEIVE)
2099 debugLog ("When I get clever, I'll optimize the receive logic\n");
2101 /* if we need ptr regs for the right side
2103 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2104 <= (unsigned) PTRSIZE)
2109 /* else we assign registers to it */
2110 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2112 debugLog (" %d - \n", __LINE__);
2114 bitVectDebugOn(_G.regAssigned, debugF);
2116 for (j = 0; j < sym->nRegs; j++)
2118 if (sym->regType == REG_PTR)
2119 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2121 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2123 /* if the allocation falied which means
2124 this was spilt then break */
2128 debugLog (" %d - \n", __LINE__);
2130 /* if it shares registers with operands make sure
2131 that they are in the same position */
2132 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2133 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2134 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2135 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2136 /* do the same for the right operand */
2137 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2138 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2139 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2140 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2142 debugLog (" %d - \n", __LINE__);
2145 debugLog (" %d - \n", __LINE__);
2155 /*-----------------------------------------------------------------*/
2156 /* rUmaskForOp :- returns register mask for an operand */
2157 /*-----------------------------------------------------------------*/
2159 rUmaskForOp (operand * op)
2165 debugLog ("%s\n", __FUNCTION__);
2166 /* only temporaries are assigned registers */
2170 sym = OP_SYMBOL (op);
2172 /* if spilt or no registers assigned to it
2174 if (sym->isspilt || !sym->nRegs)
2177 rumask = newBitVect (pic14_nRegs);
2179 for (j = 0; j < sym->nRegs; j++)
2181 rumask = bitVectSetBit (rumask,
2182 sym->regs[j]->rIdx);
2188 /*-----------------------------------------------------------------*/
2189 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2190 /*-----------------------------------------------------------------*/
2192 regsUsedIniCode (iCode * ic)
2194 bitVect *rmask = newBitVect (pic14_nRegs);
2196 debugLog ("%s\n", __FUNCTION__);
2197 /* do the special cases first */
2200 rmask = bitVectUnion (rmask,
2201 rUmaskForOp (IC_COND (ic)));
2205 /* for the jumptable */
2206 if (ic->op == JUMPTABLE)
2208 rmask = bitVectUnion (rmask,
2209 rUmaskForOp (IC_JTCOND (ic)));
2214 /* of all other cases */
2216 rmask = bitVectUnion (rmask,
2217 rUmaskForOp (IC_LEFT (ic)));
2221 rmask = bitVectUnion (rmask,
2222 rUmaskForOp (IC_RIGHT (ic)));
2225 rmask = bitVectUnion (rmask,
2226 rUmaskForOp (IC_RESULT (ic)));
2232 /*-----------------------------------------------------------------*/
2233 /* createRegMask - for each instruction will determine the regsUsed */
2234 /*-----------------------------------------------------------------*/
2236 createRegMask (eBBlock ** ebbs, int count)
2240 debugLog ("%s\n", __FUNCTION__);
2241 /* for all blocks */
2242 for (i = 0; i < count; i++)
2246 if (ebbs[i]->noPath &&
2247 (ebbs[i]->entryLabel != entryLabel &&
2248 ebbs[i]->entryLabel != returnLabel))
2251 /* for all instructions */
2252 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2257 if (SKIP_IC2 (ic) || !ic->rlive)
2260 /* first mark the registers used in this
2262 ic->rUsed = regsUsedIniCode (ic);
2263 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2265 /* now create the register mask for those
2266 registers that are in use : this is a
2267 super set of ic->rUsed */
2268 ic->rMask = newBitVect (pic14_nRegs + 1);
2270 /* for all live Ranges alive at this point */
2271 for (j = 1; j < ic->rlive->size; j++)
2276 /* if not alive then continue */
2277 if (!bitVectBitValue (ic->rlive, j))
2280 /* find the live range we are interested in */
2281 if (!(sym = hTabItemWithKey (liveRanges, j)))
2283 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2284 "createRegMask cannot find live range");
2288 /* if no register assigned to it */
2289 if (!sym->nRegs || sym->isspilt)
2292 /* for all the registers allocated to it */
2293 for (k = 0; k < sym->nRegs; k++)
2296 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2302 /*-----------------------------------------------------------------*/
2303 /* rematStr - returns the rematerialized string for a remat var */
2304 /*-----------------------------------------------------------------*/
2306 rematStr (symbol * sym)
2309 iCode *ic = sym->rematiCode;
2310 symbol *psym = NULL;
2312 debugLog ("%s\n", __FUNCTION__);
2314 //printf ("%s\n", s);
2316 /* if plus or minus print the right hand side */
2318 if (ic->op == '+' || ic->op == '-') {
2320 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2322 sprintf (s, "(%s %c 0x%04x)",
2323 OP_SYMBOL (IC_LEFT (ric))->rname,
2325 (int) operandLitValue (IC_RIGHT (ic)));
2328 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2330 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2331 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2336 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2337 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2339 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2344 /*-----------------------------------------------------------------*/
2345 /* rematStr - returns the rematerialized string for a remat var */
2346 /*-----------------------------------------------------------------*/
2348 rematStr (symbol * sym)
2351 iCode *ic = sym->rematiCode;
2353 debugLog ("%s\n", __FUNCTION__);
2358 /* if plus or minus print the right hand side */
2360 if (ic->op == '+' || ic->op == '-') {
2361 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2364 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2368 if (ic->op == '+' || ic->op == '-')
2370 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2371 sprintf (s, "(%s %c 0x%04x)",
2372 OP_SYMBOL (IC_LEFT (ric))->rname,
2374 (int) operandLitValue (IC_RIGHT (ic)));
2377 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2379 fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2383 /* we reached the end */
2384 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2388 printf ("%s\n", buffer);
2393 /*-----------------------------------------------------------------*/
2394 /* regTypeNum - computes the type & number of registers required */
2395 /*-----------------------------------------------------------------*/
2403 debugLog ("%s\n", __FUNCTION__);
2404 /* for each live range do */
2405 for (sym = hTabFirstItem (liveRanges, &k); sym;
2406 sym = hTabNextItem (liveRanges, &k)) {
2408 debugLog (" %d - %s\n", __LINE__, sym->rname);
2410 /* if used zero times then no registers needed */
2411 if ((sym->liveTo - sym->liveFrom) == 0)
2415 /* if the live range is a temporary */
2418 debugLog (" %d - itemp register\n", __LINE__);
2420 /* if the type is marked as a conditional */
2421 if (sym->regType == REG_CND)
2424 /* if used in return only then we don't
2426 if (sym->ruonly || sym->accuse) {
2427 if (IS_AGGREGATE (sym->type) || sym->isptr)
2428 sym->type = aggrToPtr (sym->type, FALSE);
2429 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2434 /* if the symbol has only one definition &
2435 that definition is a get_pointer and the
2436 pointer we are getting is rematerializable and
2439 if (bitVectnBitsOn (sym->defs) == 1 &&
2440 (ic = hTabItemWithKey (iCodehTab,
2441 bitVectFirstBit (sym->defs))) &&
2444 !IS_BITVAR (sym->etype)) {
2447 debugLog (" %d - \n", __LINE__);
2449 /* if remat in data space */
2450 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2451 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2453 /* create a psuedo symbol & force a spil */
2454 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2455 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2456 psym->type = sym->type;
2457 psym->etype = sym->etype;
2458 strcpy (psym->rname, psym->name);
2460 sym->usl.spillLoc = psym;
2464 /* if in data space or idata space then try to
2465 allocate pointer register */
2469 /* if not then we require registers */
2470 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2471 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2472 getSize (sym->type));
2475 if(IS_PTR_CONST (sym->type)) {
2476 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2480 if (sym->nRegs > 4) {
2481 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2482 printTypeChain (sym->type, stderr);
2483 fprintf (stderr, "\n");
2486 /* determine the type of register required */
2487 if (sym->nRegs == 1 &&
2488 IS_PTR (sym->type) &&
2490 sym->regType = REG_PTR;
2492 sym->regType = REG_GPR;
2495 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2499 /* for the first run we don't provide */
2500 /* registers for true symbols we will */
2501 /* see how things go */
2506 DEFSETFUNC (markRegFree)
2508 ((regs *)item)->isFree = 1;
2513 DEFSETFUNC (deallocReg)
2515 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2516 ((regs *)item)->isFree = 1;
2517 ((regs *)item)->wasUsed = 0;
2521 /*-----------------------------------------------------------------*/
2522 /* freeAllRegs - mark all registers as free */
2523 /*-----------------------------------------------------------------*/
2525 pic14_freeAllRegs ()
2529 debugLog ("%s\n", __FUNCTION__);
2531 applyToSet(dynAllocRegs,markRegFree);
2532 applyToSet(dynStackRegs,markRegFree);
2535 for (i = 0; i < pic14_nRegs; i++)
2536 regspic14[i].isFree = 1;
2540 /*-----------------------------------------------------------------*/
2541 /*-----------------------------------------------------------------*/
2543 pic14_deallocateAllRegs ()
2547 debugLog ("%s\n", __FUNCTION__);
2549 applyToSet(dynAllocRegs,deallocReg);
2552 for (i = 0; i < pic14_nRegs; i++) {
2553 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2554 regspic14[i].isFree = 1;
2555 regspic14[i].wasUsed = 0;
2562 /*-----------------------------------------------------------------*/
2563 /* deallocStackSpil - this will set the stack pointer back */
2564 /*-----------------------------------------------------------------*/
2566 DEFSETFUNC (deallocStackSpil)
2570 debugLog ("%s\n", __FUNCTION__);
2575 /*-----------------------------------------------------------------*/
2576 /* farSpacePackable - returns the packable icode for far variables */
2577 /*-----------------------------------------------------------------*/
2579 farSpacePackable (iCode * ic)
2583 debugLog ("%s\n", __FUNCTION__);
2584 /* go thru till we find a definition for the
2585 symbol on the right */
2586 for (dic = ic->prev; dic; dic = dic->prev)
2589 /* if the definition is a call then no */
2590 if ((dic->op == CALL || dic->op == PCALL) &&
2591 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2596 /* if shift by unknown amount then not */
2597 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2598 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2601 /* if pointer get and size > 1 */
2602 if (POINTER_GET (dic) &&
2603 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2606 if (POINTER_SET (dic) &&
2607 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2610 /* if any three is a true symbol in far space */
2611 if (IC_RESULT (dic) &&
2612 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2613 isOperandInFarSpace (IC_RESULT (dic)))
2616 if (IC_RIGHT (dic) &&
2617 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2618 isOperandInFarSpace (IC_RIGHT (dic)) &&
2619 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2622 if (IC_LEFT (dic) &&
2623 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2624 isOperandInFarSpace (IC_LEFT (dic)) &&
2625 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2628 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2630 if ((dic->op == LEFT_OP ||
2631 dic->op == RIGHT_OP ||
2633 IS_OP_LITERAL (IC_RIGHT (dic)))
2643 /*-----------------------------------------------------------------*/
2644 /* packRegsForAssign - register reduction for assignment */
2645 /*-----------------------------------------------------------------*/
2647 packRegsForAssign (iCode * ic, eBBlock * ebp)
2652 debugLog ("%s\n", __FUNCTION__);
2654 debugAopGet (" result:", IC_RESULT (ic));
2655 debugAopGet (" left:", IC_LEFT (ic));
2656 debugAopGet (" right:", IC_RIGHT (ic));
2658 /* if this is at an absolute address, then get the address. */
2659 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2660 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2661 debugLog (" %d - found config word declaration\n", __LINE__);
2662 if(IS_VALOP(IC_RIGHT(ic))) {
2663 debugLog (" setting config word to %x\n",
2664 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2665 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2666 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2669 /* remove the assignment from the iCode chain. */
2671 remiCodeFromeBBlock (ebp, ic);
2672 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2673 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2680 if (!IS_ITEMP (IC_RESULT (ic))) {
2681 allocDirReg(IC_RESULT (ic));
2682 debugLog (" %d - result is not temp\n", __LINE__);
2685 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2686 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2687 allocDirReg(IC_LEFT (ic));
2691 if (!IS_ITEMP (IC_RIGHT (ic))) {
2692 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2693 allocDirReg(IC_RIGHT (ic));
2697 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2698 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2700 debugLog (" %d - not packing - right side fails \n", __LINE__);
2704 /* if the true symbol is defined in far space or on stack
2705 then we should not since this will increase register pressure */
2706 if (isOperandInFarSpace (IC_RESULT (ic)))
2708 if ((dic = farSpacePackable (ic)))
2714 /* find the definition of iTempNN scanning backwards if we find a
2715 a use of the true symbol before we find the definition then
2717 for (dic = ic->prev; dic; dic = dic->prev)
2720 /* if there is a function call and this is
2721 a parameter & not my parameter then don't pack it */
2722 if ((dic->op == CALL || dic->op == PCALL) &&
2723 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2724 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2726 debugLog (" %d - \n", __LINE__);
2734 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2735 IS_OP_VOLATILE (IC_RESULT (dic)))
2737 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2742 if (IS_SYMOP (IC_RESULT (dic)) &&
2743 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2745 /* A previous result was assigned to the same register - we'll our definition */
2746 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2747 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2748 if (POINTER_SET (dic))
2754 if (IS_SYMOP (IC_RIGHT (dic)) &&
2755 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2756 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2758 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2763 if (IS_SYMOP (IC_LEFT (dic)) &&
2764 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2765 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2767 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2772 if (POINTER_SET (dic) &&
2773 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2775 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2783 return 0; /* did not find */
2785 /* if the result is on stack or iaccess then it must be
2786 the same atleast one of the operands */
2787 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2788 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2791 /* the operation has only one symbol
2792 operator then we can pack */
2793 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2794 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2797 if (!((IC_LEFT (dic) &&
2798 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2800 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2804 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2805 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2806 /* found the definition */
2807 /* replace the result with the result of */
2808 /* this assignment and remove this assignment */
2809 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2810 IC_RESULT (dic) = IC_RESULT (ic);
2812 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2814 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2816 /* delete from liverange table also
2817 delete from all the points inbetween and the new
2819 for (sic = dic; sic != ic; sic = sic->next)
2821 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2822 if (IS_ITEMP (IC_RESULT (dic)))
2823 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2826 remiCodeFromeBBlock (ebp, ic);
2827 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2828 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2829 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2835 /*-----------------------------------------------------------------*/
2836 /* findAssignToSym : scanning backwards looks for first assig found */
2837 /*-----------------------------------------------------------------*/
2839 findAssignToSym (operand * op, iCode * ic)
2843 debugLog ("%s\n", __FUNCTION__);
2844 for (dic = ic->prev; dic; dic = dic->prev)
2847 /* if definition by assignment */
2848 if (dic->op == '=' &&
2849 !POINTER_SET (dic) &&
2850 IC_RESULT (dic)->key == op->key
2851 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2855 /* we are interested only if defined in far space */
2856 /* or in stack space in case of + & - */
2858 /* if assigned to a non-symbol then return
2860 if (!IS_SYMOP (IC_RIGHT (dic)))
2863 /* if the symbol is in far space then
2865 if (isOperandInFarSpace (IC_RIGHT (dic)))
2868 /* for + & - operations make sure that
2869 if it is on the stack it is the same
2870 as one of the three operands */
2871 if ((ic->op == '+' || ic->op == '-') &&
2872 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2875 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2876 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2877 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2885 /* if we find an usage then we cannot delete it */
2886 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2889 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2892 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2896 /* now make sure that the right side of dic
2897 is not defined between ic & dic */
2900 iCode *sic = dic->next;
2902 for (; sic != ic; sic = sic->next)
2903 if (IC_RESULT (sic) &&
2904 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2913 /*-----------------------------------------------------------------*/
2914 /* packRegsForSupport :- reduce some registers for support calls */
2915 /*-----------------------------------------------------------------*/
2917 packRegsForSupport (iCode * ic, eBBlock * ebp)
2921 debugLog ("%s\n", __FUNCTION__);
2922 /* for the left & right operand :- look to see if the
2923 left was assigned a true symbol in far space in that
2924 case replace them */
2925 if (IS_ITEMP (IC_LEFT (ic)) &&
2926 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2928 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2934 debugAopGet ("removing left:", IC_LEFT (ic));
2936 /* found it we need to remove it from the
2938 for (sic = dic; sic != ic; sic = sic->next)
2939 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2941 IC_LEFT (ic)->operand.symOperand =
2942 IC_RIGHT (dic)->operand.symOperand;
2943 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2944 remiCodeFromeBBlock (ebp, dic);
2945 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2946 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2950 /* do the same for the right operand */
2953 IS_ITEMP (IC_RIGHT (ic)) &&
2954 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2956 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2962 /* if this is a subtraction & the result
2963 is a true symbol in far space then don't pack */
2964 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2966 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2967 if (IN_FARSPACE (SPEC_OCLS (etype)))
2971 debugAopGet ("removing right:", IC_RIGHT (ic));
2973 /* found it we need to remove it from the
2975 for (sic = dic; sic != ic; sic = sic->next)
2976 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2978 IC_RIGHT (ic)->operand.symOperand =
2979 IC_RIGHT (dic)->operand.symOperand;
2980 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2982 remiCodeFromeBBlock (ebp, dic);
2983 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2984 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2991 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2994 /*-----------------------------------------------------------------*/
2995 /* packRegsForOneuse : - will reduce some registers for single Use */
2996 /*-----------------------------------------------------------------*/
2998 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3003 debugLog ("%s\n", __FUNCTION__);
3004 /* if returning a literal then do nothing */
3008 /* only upto 2 bytes since we cannot predict
3009 the usage of b, & acc */
3010 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3015 /* this routine will mark the a symbol as used in one
3016 instruction use only && if the definition is local
3017 (ie. within the basic block) && has only one definition &&
3018 that definition is either a return value from a
3019 function or does not contain any variables in
3021 uses = bitVectCopy (OP_USES (op));
3022 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3023 if (!bitVectIsZero (uses)) /* has other uses */
3026 /* if it has only one defintion */
3027 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3028 return NULL; /* has more than one definition */
3030 /* get that definition */
3032 hTabItemWithKey (iCodehTab,
3033 bitVectFirstBit (OP_DEFS (op)))))
3036 /* found the definition now check if it is local */
3037 if (dic->seq < ebp->fSeq ||
3038 dic->seq > ebp->lSeq)
3039 return NULL; /* non-local */
3041 /* now check if it is the return from
3043 if (dic->op == CALL || dic->op == PCALL)
3045 if (ic->op != SEND && ic->op != RETURN &&
3046 !POINTER_SET(ic) && !POINTER_GET(ic))
3048 OP_SYMBOL (op)->ruonly = 1;
3055 /* otherwise check that the definition does
3056 not contain any symbols in far space */
3057 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3058 isOperandInFarSpace (IC_RIGHT (dic)) ||
3059 IS_OP_RUONLY (IC_LEFT (ic)) ||
3060 IS_OP_RUONLY (IC_RIGHT (ic)))
3065 /* if pointer set then make sure the pointer
3067 if (POINTER_SET (dic) &&
3068 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3071 if (POINTER_GET (dic) &&
3072 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3077 /* also make sure the intervenening instructions
3078 don't have any thing in far space */
3079 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3082 /* if there is an intervening function call then no */
3083 if (dic->op == CALL || dic->op == PCALL)
3085 /* if pointer set then make sure the pointer
3087 if (POINTER_SET (dic) &&
3088 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3091 if (POINTER_GET (dic) &&
3092 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3095 /* if address of & the result is remat then okay */
3096 if (dic->op == ADDRESS_OF &&
3097 OP_SYMBOL (IC_RESULT (dic))->remat)
3100 /* if operand has size of three or more & this
3101 operation is a '*','/' or '%' then 'b' may
3103 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3104 getSize (operandType (op)) >= 3)
3107 /* if left or right or result is in far space */
3108 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3109 isOperandInFarSpace (IC_RIGHT (dic)) ||
3110 isOperandInFarSpace (IC_RESULT (dic)) ||
3111 IS_OP_RUONLY (IC_LEFT (dic)) ||
3112 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3113 IS_OP_RUONLY (IC_RESULT (dic)))
3119 OP_SYMBOL (op)->ruonly = 1;
3124 /*-----------------------------------------------------------------*/
3125 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3126 /*-----------------------------------------------------------------*/
3128 isBitwiseOptimizable (iCode * ic)
3130 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3131 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3133 debugLog ("%s\n", __FUNCTION__);
3134 /* bitwise operations are considered optimizable
3135 under the following conditions (Jean-Louis VERN)
3147 if (IS_LITERAL (rtype) ||
3148 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3154 /*-----------------------------------------------------------------*/
3155 /* packRegsForAccUse - pack registers for acc use */
3156 /*-----------------------------------------------------------------*/
3158 packRegsForAccUse (iCode * ic)
3162 debugLog ("%s\n", __FUNCTION__);
3164 /* if this is an aggregate, e.g. a one byte char array */
3165 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3168 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3170 /* if + or - then it has to be one byte result */
3171 if ((ic->op == '+' || ic->op == '-')
3172 && getSize (operandType (IC_RESULT (ic))) > 1)
3175 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3176 /* if shift operation make sure right side is not a literal */
3177 if (ic->op == RIGHT_OP &&
3178 (isOperandLiteral (IC_RIGHT (ic)) ||
3179 getSize (operandType (IC_RESULT (ic))) > 1))
3182 if (ic->op == LEFT_OP &&
3183 (isOperandLiteral (IC_RIGHT (ic)) ||
3184 getSize (operandType (IC_RESULT (ic))) > 1))
3187 if (IS_BITWISE_OP (ic) &&
3188 getSize (operandType (IC_RESULT (ic))) > 1)
3192 /* has only one definition */
3193 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3196 /* has only one use */
3197 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3200 /* and the usage immediately follows this iCode */
3201 if (!(uic = hTabItemWithKey (iCodehTab,
3202 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3205 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3206 if (ic->next != uic)
3209 /* if it is a conditional branch then we definitely can */
3213 if (uic->op == JUMPTABLE)
3216 /* if the usage is not is an assignment
3217 or an arithmetic / bitwise / shift operation then not */
3218 if (POINTER_SET (uic) &&
3219 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3222 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3223 if (uic->op != '=' &&
3224 !IS_ARITHMETIC_OP (uic) &&
3225 !IS_BITWISE_OP (uic) &&
3226 uic->op != LEFT_OP &&
3227 uic->op != RIGHT_OP)
3230 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3231 /* if used in ^ operation then make sure right is not a
3233 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3236 /* if shift operation make sure right side is not a literal */
3237 if (uic->op == RIGHT_OP &&
3238 (isOperandLiteral (IC_RIGHT (uic)) ||
3239 getSize (operandType (IC_RESULT (uic))) > 1))
3242 if (uic->op == LEFT_OP &&
3243 (isOperandLiteral (IC_RIGHT (uic)) ||
3244 getSize (operandType (IC_RESULT (uic))) > 1))
3247 /* make sure that the result of this icode is not on the
3248 stack, since acc is used to compute stack offset */
3249 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3250 OP_SYMBOL (IC_RESULT (uic))->onStack)
3253 /* if either one of them in far space then we cannot */
3254 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3255 isOperandInFarSpace (IC_LEFT (uic))) ||
3256 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3257 isOperandInFarSpace (IC_RIGHT (uic))))
3260 /* if the usage has only one operand then we can */
3261 if (IC_LEFT (uic) == NULL ||
3262 IC_RIGHT (uic) == NULL)
3265 /* make sure this is on the left side if not
3266 a '+' since '+' is commutative */
3267 if (ic->op != '+' &&
3268 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3271 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3272 /* if one of them is a literal then we can */
3273 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3274 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3275 (getSize (operandType (IC_RESULT (uic))) <= 1))
3277 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3281 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3282 /* if the other one is not on stack then we can */
3283 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3284 (IS_ITEMP (IC_RIGHT (uic)) ||
3285 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3286 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3289 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3290 (IS_ITEMP (IC_LEFT (uic)) ||
3291 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3292 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3298 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3299 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3304 /*-----------------------------------------------------------------*/
3305 /* packForPush - hueristics to reduce iCode for pushing */
3306 /*-----------------------------------------------------------------*/
3308 packForReceive (iCode * ic, eBBlock * ebp)
3312 debugLog ("%s\n", __FUNCTION__);
3313 debugAopGet (" result:", IC_RESULT (ic));
3314 debugAopGet (" left:", IC_LEFT (ic));
3315 debugAopGet (" right:", IC_RIGHT (ic));
3320 for (dic = ic->next; dic; dic = dic->next)
3325 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3326 debugLog (" used on left\n");
3327 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3328 debugLog (" used on right\n");
3329 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3330 debugLog (" used on result\n");
3332 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3333 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3338 debugLog (" hey we can remove this unnecessary assign\n");
3340 /*-----------------------------------------------------------------*/
3341 /* packForPush - hueristics to reduce iCode for pushing */
3342 /*-----------------------------------------------------------------*/
3344 packForPush (iCode * ic, eBBlock * ebp)
3348 debugLog ("%s\n", __FUNCTION__);
3349 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3352 /* must have only definition & one usage */
3353 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3354 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3357 /* find the definition */
3358 if (!(dic = hTabItemWithKey (iCodehTab,
3359 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3362 if (dic->op != '=' || POINTER_SET (dic))
3365 /* we now we know that it has one & only one def & use
3366 and the that the definition is an assignment */
3367 IC_LEFT (ic) = IC_RIGHT (dic);
3369 remiCodeFromeBBlock (ebp, dic);
3370 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3371 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3374 void printSymType(char * str, sym_link *sl)
3376 debugLog (" %s Symbol type: ",str);
3377 printTypeChain( sl, debugF);
3382 /*-----------------------------------------------------------------*/
3383 /* packRegisters - does some transformations to reduce register */
3385 /*-----------------------------------------------------------------*/
3387 packRegisters (eBBlock * ebp)
3392 debugLog ("%s\n", __FUNCTION__);
3398 /* look for assignments of the form */
3399 /* iTempNN = TRueSym (someoperation) SomeOperand */
3401 /* TrueSym := iTempNN:1 */
3402 for (ic = ebp->sch; ic; ic = ic->next)
3405 /* find assignment of the form TrueSym := iTempNN:1 */
3406 if (ic->op == '=' && !POINTER_SET (ic))
3407 change += packRegsForAssign (ic, ebp);
3411 if (POINTER_SET (ic))
3412 debugLog ("pointer is set\n");
3413 debugAopGet (" result:", IC_RESULT (ic));
3414 debugAopGet (" left:", IC_LEFT (ic));
3415 debugAopGet (" right:", IC_RIGHT (ic));
3424 for (ic = ebp->sch; ic; ic = ic->next) {
3426 if(IS_SYMOP ( IC_LEFT(ic))) {
3427 //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3429 debugAopGet (" left:", IC_LEFT (ic));
3430 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3431 debugLog (" is a pointer");
3433 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3436 if(IS_SYMOP ( IC_RIGHT(ic))) {
3437 debugAopGet (" right:", IC_RIGHT (ic));
3438 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3441 if(IS_SYMOP ( IC_RESULT(ic))) {
3442 debugAopGet (" result:", IC_RESULT (ic));
3443 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3446 if (POINTER_SET (ic))
3447 debugLog (" %d - Pointer set\n", __LINE__);
3450 /* if this is an itemp & result of a address of a true sym
3451 then mark this as rematerialisable */
3452 if (ic->op == ADDRESS_OF &&
3453 IS_ITEMP (IC_RESULT (ic)) &&
3454 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3455 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3456 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3459 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3461 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3462 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3463 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3467 /* if straight assignment then carry remat flag if
3468 this is the only definition */
3469 if (ic->op == '=' &&
3470 !POINTER_SET (ic) &&
3471 IS_SYMOP (IC_RIGHT (ic)) &&
3472 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3473 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3475 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3477 OP_SYMBOL (IC_RESULT (ic))->remat =
3478 OP_SYMBOL (IC_RIGHT (ic))->remat;
3479 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3480 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3483 /* if this is a +/- operation with a rematerizable
3484 then mark this as rematerializable as well */
3485 if ((ic->op == '+' || ic->op == '-') &&
3486 (IS_SYMOP (IC_LEFT (ic)) &&
3487 IS_ITEMP (IC_RESULT (ic)) &&
3488 OP_SYMBOL (IC_LEFT (ic))->remat &&
3489 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3490 IS_OP_LITERAL (IC_RIGHT (ic))))
3492 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3494 operandLitValue (IC_RIGHT (ic));
3495 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3496 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3497 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3500 /* mark the pointer usages */
3501 if (POINTER_SET (ic))
3503 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3504 debugLog (" marking as a pointer (set) =>");
3505 debugAopGet (" result:", IC_RESULT (ic));
3507 if (POINTER_GET (ic))
3509 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3510 debugLog (" marking as a pointer (get) =>");
3511 debugAopGet (" left:", IC_LEFT (ic));
3516 /* if we are using a symbol on the stack
3517 then we should say pic14_ptrRegReq */
3518 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3519 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3520 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3521 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3522 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3523 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3526 if (IS_SYMOP (IC_LEFT (ic)))
3527 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3528 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3529 if (IS_SYMOP (IC_RIGHT (ic)))
3530 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3531 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3532 if (IS_SYMOP (IC_RESULT (ic)))
3533 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3534 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3537 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3541 /* if the condition of an if instruction
3542 is defined in the previous instruction then
3543 mark the itemp as a conditional */
3544 if ((IS_CONDITIONAL (ic) ||
3545 ((ic->op == BITWISEAND ||
3548 isBitwiseOptimizable (ic))) &&
3549 ic->next && ic->next->op == IFX &&
3550 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3551 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3554 debugLog (" %d\n", __LINE__);
3555 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3559 /* reduce for support function calls */
3560 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3561 packRegsForSupport (ic, ebp);
3563 /* if a parameter is passed, it's in W, so we may not
3564 need to place a copy in a register */
3565 if (ic->op == RECEIVE)
3566 packForReceive (ic, ebp);
3568 /* some cases the redundant moves can
3569 can be eliminated for return statements */
3570 if ((ic->op == RETURN || ic->op == SEND) &&
3571 !isOperandInFarSpace (IC_LEFT (ic)) &&
3573 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3575 /* if pointer set & left has a size more than
3576 one and right is not in far space */
3577 if (POINTER_SET (ic) &&
3578 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3579 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3580 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3581 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3583 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3585 /* if pointer get */
3586 if (POINTER_GET (ic) &&
3587 !isOperandInFarSpace (IC_RESULT (ic)) &&
3588 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3589 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3590 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3592 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3595 /* if this is cast for intergral promotion then
3596 check if only use of the definition of the
3597 operand being casted/ if yes then replace
3598 the result of that arithmetic operation with
3599 this result and get rid of the cast */
3600 if (ic->op == CAST) {
3602 sym_link *fromType = operandType (IC_RIGHT (ic));
3603 sym_link *toType = operandType (IC_LEFT (ic));
3605 debugLog (" %d - casting\n", __LINE__);
3607 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3608 getSize (fromType) != getSize (toType)) {
3611 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3614 if (IS_ARITHMETIC_OP (dic)) {
3616 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3617 IC_RESULT (dic) = IC_RESULT (ic);
3618 remiCodeFromeBBlock (ebp, ic);
3619 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3620 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3621 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3625 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3629 /* if the type from and type to are the same
3630 then if this is the only use then packit */
3631 if (compareType (operandType (IC_RIGHT (ic)),
3632 operandType (IC_LEFT (ic))) == 1) {
3634 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3637 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3638 IC_RESULT (dic) = IC_RESULT (ic);
3639 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3640 remiCodeFromeBBlock (ebp, ic);
3641 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3642 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3650 iTempNN := (some variable in farspace) V1
3655 if (ic->op == IPUSH)
3657 packForPush (ic, ebp);
3661 /* pack registers for accumulator use, when the
3662 result of an arithmetic or bit wise operation
3663 has only one use, that use is immediately following
3664 the defintion and the using iCode has only one
3665 operand or has two operands but one is literal &
3666 the result of that operation is not on stack then
3667 we can leave the result of this operation in acc:b
3669 if ((IS_ARITHMETIC_OP (ic)
3671 || IS_BITWISE_OP (ic)
3673 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3676 IS_ITEMP (IC_RESULT (ic)) &&
3677 getSize (operandType (IC_RESULT (ic))) <= 2)
3679 packRegsForAccUse (ic);
3685 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3689 if (!debug || !debugF)
3692 for (i = 0; i < count; i++)
3694 fprintf (debugF, "\n----------------------------------------------------------------\n");
3695 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3696 ebbs[i]->entryLabel->name,
3699 ebbs[i]->isLastInLoop);
3700 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3705 fprintf (debugF, "visited %d : hasFcall = %d\n",
3709 fprintf (debugF, "\ndefines bitVector :");
3710 bitVectDebugOn (ebbs[i]->defSet, debugF);
3711 fprintf (debugF, "\nlocal defines bitVector :");
3712 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3713 fprintf (debugF, "\npointers Set bitvector :");
3714 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3715 fprintf (debugF, "\nin pointers Set bitvector :");
3716 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3717 fprintf (debugF, "\ninDefs Set bitvector :");
3718 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3719 fprintf (debugF, "\noutDefs Set bitvector :");
3720 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3721 fprintf (debugF, "\nusesDefs Set bitvector :");
3722 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3723 fprintf (debugF, "\n----------------------------------------------------------------\n");
3724 printiCChain (ebbs[i]->sch, debugF);
3727 /*-----------------------------------------------------------------*/
3728 /* assignRegisters - assigns registers to each live range as need */
3729 /*-----------------------------------------------------------------*/
3731 pic14_assignRegisters (eBBlock ** ebbs, int count)
3736 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3737 debugLog ("\nebbs before optimizing:\n");
3738 dumpEbbsToDebug (ebbs, count);
3740 setToNull ((void *) &_G.funcrUsed);
3741 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3744 /* change assignments this will remove some
3745 live ranges reducing some register pressure */
3746 for (i = 0; i < count; i++)
3747 packRegisters (ebbs[i]);
3754 debugLog("dir registers allocated so far:\n");
3755 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3758 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3759 reg = hTabNextItem(dynDirectRegNames, &hkey);
3764 if (options.dump_pack)
3765 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3767 /* first determine for each live range the number of
3768 registers & the type of registers required for each */
3771 /* and serially allocate registers */
3772 serialRegAssign (ebbs, count);
3774 /* if stack was extended then tell the user */
3777 /* werror(W_TOOMANY_SPILS,"stack", */
3778 /* _G.stackExtend,currFunc->name,""); */
3784 /* werror(W_TOOMANY_SPILS,"data space", */
3785 /* _G.dataExtend,currFunc->name,""); */
3789 /* after that create the register mask
3790 for each of the instruction */
3791 createRegMask (ebbs, count);
3793 /* redo that offsets for stacked automatic variables */
3794 redoStackOffsets ();
3796 if (options.dump_rassgn)
3797 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3799 /* now get back the chain */
3800 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3802 debugLog ("ebbs after optimizing:\n");
3803 dumpEbbsToDebug (ebbs, count);
3808 /* free up any _G.stackSpil locations allocated */
3809 applyToSet (_G.stackSpil, deallocStackSpil);
3811 setToNull ((void **) &_G.stackSpil);
3812 setToNull ((void **) &_G.spiltSet);
3813 /* mark all registers as free */
3814 //pic14_freeAllRegs ();
3816 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");