1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (8051) specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
32 #if defined(__BORLANDC__) || defined(_MSC_VER)
33 #define STRCASECMP stricmp
35 #define STRCASECMP strcasecmp
38 /*-----------------------------------------------------------------*/
39 /* At this point we start getting processor specific although */
40 /* some routines are non-processor specific & can be reused when */
41 /* targetting other processors. The decision for this will have */
42 /* to be made on a routine by routine basis */
43 /* routines used to pack registers are most definitely not reusable */
44 /* since the pack the registers depending strictly on the MCU */
45 /*-----------------------------------------------------------------*/
47 extern void genpic14Code (iCode *);
57 bitVect *funcrUsed; /* registers used in a function */
63 /* Shared with gen.c */
64 int pic14_ptrRegReq; /* one byte pointer register required */
67 static set *dynAllocRegs=NULL;
68 static set *dynStackRegs=NULL;
69 static set *dynProcessorRegs=NULL;
70 static set *dynDirectRegs=NULL;
71 static set *dynDirectBitRegs=NULL;
72 static set *dynInternalRegs=NULL;
74 static hTab *dynDirectRegNames= NULL;
76 static int dynrIdx=0x20;
77 static int rDirectIdx=0;
79 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
81 int Gstack_base_addr=0; /* The starting address of registers that
82 * are used to pass and return parameters */
87 static void spillThis (symbol *);
89 static FILE *debugF = NULL;
90 /*-----------------------------------------------------------------*/
91 /* debugLog - open a file for debugging information */
92 /*-----------------------------------------------------------------*/
93 //static void debugLog(char *inst,char *fmt, ...)
95 debugLog (char *fmt,...)
97 static int append = 0; // First time through, open the file without append.
100 //char *bufferP=buffer;
103 if (!debug || !srcFileName)
109 /* create the file name */
110 strcpy (buffer, srcFileName);
111 strcat (buffer, ".d");
113 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
115 werror (E_FILE_OPEN_ERR, buffer);
118 append = 1; // Next time debubLog is called, we'll append the debug info
124 vsprintf (buffer, fmt, ap);
126 fprintf (debugF, "%s", buffer);
128 while (isspace(*bufferP)) bufferP++;
130 if (bufferP && *bufferP)
131 lineCurr = (lineCurr ?
132 connectLine(lineCurr,newLineNode(lb)) :
133 (lineHead = newLineNode(lb)));
134 lineCurr->isInline = _G.inLine;
135 lineCurr->isDebug = _G.debugLine;
145 fputc ('\n', debugF);
147 /*-----------------------------------------------------------------*/
148 /* debugLogClose - closes the debug log file (if opened) */
149 /*-----------------------------------------------------------------*/
159 #define AOP(op) op->aop
162 debugAopGet (char *str, operand * op)
167 printOperand (op, debugF);
175 decodeOp (unsigned int op)
178 if (op < 128 && op > ' ')
180 buffer[0] = (op & 0xff);
194 return "STRING_LITERAL";
230 return "LEFT_ASSIGN";
232 return "RIGHT_ASSIGN";
347 case GET_VALUE_AT_ADDRESS:
348 return "GET_VALUE_AT_ADDRESS";
366 return "ENDFUNCTION";
390 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
393 /*-----------------------------------------------------------------*/
394 /*-----------------------------------------------------------------*/
396 debugLogRegType (short type)
409 sprintf (buffer, "unkown reg type %d", type);
413 /*-----------------------------------------------------------------*/
414 /* newReg - allocate and init memory for a new register */
415 /*-----------------------------------------------------------------*/
416 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
421 dReg = Safe_calloc(1,sizeof(regs));
423 dReg->pc_type = pc_type;
426 dReg->name = Safe_strdup(name);
428 sprintf(buffer,"r0x%02X", dReg->rIdx);
431 dReg->name = Safe_strdup(buffer);
433 //fprintf(stderr,"newReg: %s\n",dReg->name);
442 dReg->reg_alias = NULL;
447 /*-----------------------------------------------------------------*/
448 /* regWithIdx - Search through a set of registers that matches idx */
449 /*-----------------------------------------------------------------*/
451 regWithIdx (set *dRegs, int idx, int fixed)
455 for (dReg = setFirstItem(dRegs) ; dReg ;
456 dReg = setNextItem(dRegs)) {
458 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
466 /*-----------------------------------------------------------------*/
467 /* regFindFree - Search for a free register in a set of registers */
468 /*-----------------------------------------------------------------*/
470 regFindFree (set *dRegs)
474 for (dReg = setFirstItem(dRegs) ; dReg ;
475 dReg = setNextItem(dRegs)) {
483 /*-----------------------------------------------------------------*/
484 /* initStack - allocate registers for a psuedo stack */
485 /*-----------------------------------------------------------------*/
486 void initStack(int base_address, int size)
491 Gstack_base_addr = base_address;
492 for(i = 0; i<size; i++)
493 addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
497 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
499 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
503 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
505 regs * reg = newReg(REG_SFR, po_type, rIdx, name,1,alias);
509 return addSet(&dynInternalRegs,reg);
514 /*-----------------------------------------------------------------*/
515 /* allocReg - allocates register of given type */
516 /*-----------------------------------------------------------------*/
518 allocReg (short type)
521 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
524 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
528 /*-----------------------------------------------------------------*/
529 /*-----------------------------------------------------------------*/
530 static int regname2key(char const *name)
539 key += (*name++) + 1;
543 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
547 /*-----------------------------------------------------------------*/
548 /* dirregWithName - search for register by name */
549 /*-----------------------------------------------------------------*/
551 dirregWithName (char *name )
559 /* hash the name to get a key */
561 hkey = regname2key(name);
563 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
567 if(STRCASECMP(reg->name, name) == 0) {
571 reg = hTabNextItemWK (dynDirectRegNames);
575 return NULL; // name wasn't found in the hash table
578 /*-----------------------------------------------------------------*/
579 /* allocDirReg - allocates register of given type */
580 /*-----------------------------------------------------------------*/
582 allocDirReg (operand *op )
589 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
593 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
595 /* If the symbol is at a fixed address, then remove the leading underscore
596 * from the name. This is hack to allow the .asm include file named registers
597 * to match the .c declared register names */
599 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
602 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
604 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
605 debugLog(" %d const char\n",__LINE__);
606 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
609 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
610 if (IS_CODE ( OP_SYM_ETYPE(op)) )
611 debugLog(" %d code space\n",__LINE__);
613 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
614 debugLog(" %d integral\n",__LINE__);
615 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
616 debugLog(" %d literal\n",__LINE__);
617 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
618 debugLog(" %d specifier\n",__LINE__);
619 debugAopGet(NULL, op);
622 if (IS_CODE ( OP_SYM_ETYPE(op)) )
625 /* First, search the hash table to see if there is a register with this name */
626 reg = dirregWithName(name);
630 /* Register wasn't found in hash, so let's create
631 * a new one and put it in the hash table AND in the
632 * dynDirectRegNames set */
634 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
635 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
637 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
639 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
640 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
643 hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
644 if (IS_BITVAR (OP_SYM_ETYPE(op)))
645 addSet(&dynDirectBitRegs, reg);
647 addSet(&dynDirectRegs, reg);
653 /*-----------------------------------------------------------------*/
654 /* allocDirReg - allocates register of given type */
655 /*-----------------------------------------------------------------*/
657 allocRegByName (char *name )
663 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
667 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
669 /* First, search the hash table to see if there is a register with this name */
670 reg = dirregWithName(name);
674 /* Register wasn't found in hash, so let's create
675 * a new one and put it in the hash table AND in the
676 * dynDirectRegNames set */
678 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,1,0 );
680 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
682 hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
683 addSet(&dynDirectRegs, reg);
689 /*-----------------------------------------------------------------*/
690 /* RegWithIdx - returns pointer to register with index number */
691 /*-----------------------------------------------------------------*/
693 typeRegWithIdx (int idx, int type, int fixed)
698 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
700 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
702 debugLog ("Found a Dynamic Register!\n");
706 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
707 debugLog ("Found a Stack Register!\n");
711 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
712 debugLog ("Found a Direct Register!\n");
716 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
717 debugLog ("Found a Processor Register!\n");
721 if( (dReg = regWithIdx ( dynDirectBitRegs, idx, fixed)) != NULL ) {
722 debugLog ("Found a bit Register!\n");
727 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
728 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
729 "regWithIdx not found");
735 /*-----------------------------------------------------------------*/
736 /* pic14_regWithIdx - returns pointer to register with index number*/
737 /*-----------------------------------------------------------------*/
739 pic14_regWithIdx (int idx)
742 return typeRegWithIdx(idx,-1,0);
745 /*-----------------------------------------------------------------*/
746 /* pic14_regWithIdx - returns pointer to register with index number */
747 /*-----------------------------------------------------------------*/
749 pic14_allocWithIdx (int idx)
754 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
756 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
758 debugLog ("Found a Dynamic Register!\n");
759 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
760 debugLog ("Found a Stack Register!\n");
761 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
762 debugLog ("Found a Processor Register!\n");
765 debugLog ("Dynamic Register not found\n");
768 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
769 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
770 "regWithIdx not found");
780 /*-----------------------------------------------------------------*/
781 /*-----------------------------------------------------------------*/
783 pic14_findFreeReg(short type)
790 if((dReg = regFindFree(dynAllocRegs)) != NULL)
793 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,0,0));
797 if((dReg = regFindFree(dynStackRegs)) != NULL)
809 /*-----------------------------------------------------------------*/
810 /* freeReg - frees a register */
811 /*-----------------------------------------------------------------*/
815 debugLog ("%s\n", __FUNCTION__);
820 /*-----------------------------------------------------------------*/
821 /* nFreeRegs - returns number of free registers */
822 /*-----------------------------------------------------------------*/
826 /* dynamically allocate as many as we need and worry about
827 * fitting them into a PIC later */
834 debugLog ("%s\n", __FUNCTION__);
835 for (i = 0; i < pic14_nRegs; i++)
836 if (regspic14[i].isFree && regspic14[i].type == type)
842 /*-----------------------------------------------------------------*/
843 /* nfreeRegsType - free registers with type */
844 /*-----------------------------------------------------------------*/
846 nfreeRegsType (int type)
849 debugLog ("%s\n", __FUNCTION__);
852 if ((nfr = nFreeRegs (type)) == 0)
853 return nFreeRegs (REG_GPR);
856 return nFreeRegs (type);
860 void writeSetUsedRegs(FILE *of, set *dRegs)
865 for (dReg = setFirstItem(dRegs) ; dReg ;
866 dReg = setNextItem(dRegs)) {
869 fprintf (of, "\t%s\n",dReg->name);
873 extern void assignFixedRegisters(set *regset);
874 extern void assignRelocatableRegisters(set *regset);
875 extern void dump_map(void);
876 extern void dump_cblock(FILE *of);
879 void packBits(set *bregs)
884 regs *relocbitfield=NULL;
889 for (regset = bregs ; regset ;
890 regset = regset->next) {
893 breg->isBitField = 1;
894 //fprintf(stderr,"bit reg: %s\n",breg->name);
897 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
899 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
900 breg->rIdx = breg->address & 7;
904 sprintf (buffer, "fbitfield%02x", breg->address);
905 //fprintf(stderr,"new bit field\n");
906 bitfield = newReg(REG_GPR, PO_GPR_BIT,breg->address,buffer,1,0);
907 bitfield->isBitField = 1;
908 bitfield->isFixed = 1;
909 bitfield->address = breg->address;
910 addSet(&dynDirectRegs,bitfield);
911 hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
913 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
916 breg->reg_alias = bitfield;
920 if(!relocbitfield || bit_no >7) {
923 sprintf (buffer, "bitfield%d", byte_no);
924 //fprintf(stderr,"new relocatable bit field\n");
925 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
926 relocbitfield->isBitField = 1;
927 addSet(&dynDirectRegs,relocbitfield);
928 hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
932 breg->reg_alias = relocbitfield;
933 breg->address = rDirectIdx; /* byte_no; */
934 breg->rIdx = bit_no++;
942 void bitEQUs(FILE *of, set *bregs)
947 //fprintf(stderr," %s\n",__FUNCTION__);
948 for (breg = setFirstItem(bregs) ; breg ;
949 breg = setNextItem(bregs)) {
951 //fprintf(stderr,"bit reg: %s\n",breg->name);
953 bytereg = breg->reg_alias;
955 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
958 breg->rIdx & 0x0007);
961 fprintf(stderr, "bit field is not assigned to a register\n");
962 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
972 void aliasEQUs(FILE *of, set *fregs)
977 for (reg = setFirstItem(fregs) ; reg ;
978 reg = setNextItem(fregs)) {
981 fprintf (of, "%s\tEQU\t0x%03x\n",
988 void writeUsedRegs(FILE *of)
990 packBits(dynDirectBitRegs);
992 assignFixedRegisters(dynAllocRegs);
993 assignFixedRegisters(dynStackRegs);
994 assignFixedRegisters(dynDirectRegs);
996 assignRelocatableRegisters(dynAllocRegs);
997 assignRelocatableRegisters(dynStackRegs);
998 assignRelocatableRegisters(dynDirectRegs);
1003 bitEQUs(of,dynDirectBitRegs);
1004 aliasEQUs(of,dynAllocRegs);
1005 aliasEQUs(of,dynDirectRegs);
1006 aliasEQUs(of,dynStackRegs);
1010 /*-----------------------------------------------------------------*/
1011 /* allDefsOutOfRange - all definitions are out of a range */
1012 /*-----------------------------------------------------------------*/
1014 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1018 debugLog ("%s\n", __FUNCTION__);
1022 for (i = 0; i < defs->size; i++)
1026 if (bitVectBitValue (defs, i) &&
1027 (ic = hTabItemWithKey (iCodehTab, i)) &&
1028 (ic->seq >= fseq && ic->seq <= toseq))
1039 /*-----------------------------------------------------------------*/
1040 /* computeSpillable - given a point find the spillable live ranges */
1041 /*-----------------------------------------------------------------*/
1043 computeSpillable (iCode * ic)
1047 debugLog ("%s\n", __FUNCTION__);
1048 /* spillable live ranges are those that are live at this
1049 point . the following categories need to be subtracted
1051 a) - those that are already spilt
1052 b) - if being used by this one
1053 c) - defined by this one */
1055 spillable = bitVectCopy (ic->rlive);
1057 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1059 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1060 bitVectUnSetBit (spillable, ic->defKey);
1061 spillable = bitVectIntersect (spillable, _G.regAssigned);
1066 /*-----------------------------------------------------------------*/
1067 /* noSpilLoc - return true if a variable has no spil location */
1068 /*-----------------------------------------------------------------*/
1070 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1072 debugLog ("%s\n", __FUNCTION__);
1073 return (sym->usl.spillLoc ? 0 : 1);
1076 /*-----------------------------------------------------------------*/
1077 /* hasSpilLoc - will return 1 if the symbol has spil location */
1078 /*-----------------------------------------------------------------*/
1080 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1082 debugLog ("%s\n", __FUNCTION__);
1083 return (sym->usl.spillLoc ? 1 : 0);
1086 /*-----------------------------------------------------------------*/
1087 /* directSpilLoc - will return 1 if the splilocation is in direct */
1088 /*-----------------------------------------------------------------*/
1090 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1092 debugLog ("%s\n", __FUNCTION__);
1093 if (sym->usl.spillLoc &&
1094 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1100 /*-----------------------------------------------------------------*/
1101 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1102 /* but is not used as a pointer */
1103 /*-----------------------------------------------------------------*/
1105 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1107 debugLog ("%s\n", __FUNCTION__);
1108 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1111 /*-----------------------------------------------------------------*/
1112 /* rematable - will return 1 if the remat flag is set */
1113 /*-----------------------------------------------------------------*/
1115 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1117 debugLog ("%s\n", __FUNCTION__);
1121 /*-----------------------------------------------------------------*/
1122 /* notUsedInRemaining - not used or defined in remain of the block */
1123 /*-----------------------------------------------------------------*/
1125 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1127 debugLog ("%s\n", __FUNCTION__);
1128 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1129 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1132 /*-----------------------------------------------------------------*/
1133 /* allLRs - return true for all */
1134 /*-----------------------------------------------------------------*/
1136 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1138 debugLog ("%s\n", __FUNCTION__);
1142 /*-----------------------------------------------------------------*/
1143 /* liveRangesWith - applies function to a given set of live range */
1144 /*-----------------------------------------------------------------*/
1146 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1147 eBBlock * ebp, iCode * ic)
1152 debugLog ("%s\n", __FUNCTION__);
1153 if (!lrs || !lrs->size)
1156 for (i = 1; i < lrs->size; i++)
1159 if (!bitVectBitValue (lrs, i))
1162 /* if we don't find it in the live range
1163 hash table we are in serious trouble */
1164 if (!(sym = hTabItemWithKey (liveRanges, i)))
1166 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1167 "liveRangesWith could not find liveRange");
1171 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1172 addSetHead (&rset, sym);
1179 /*-----------------------------------------------------------------*/
1180 /* leastUsedLR - given a set determines which is the least used */
1181 /*-----------------------------------------------------------------*/
1183 leastUsedLR (set * sset)
1185 symbol *sym = NULL, *lsym = NULL;
1187 debugLog ("%s\n", __FUNCTION__);
1188 sym = lsym = setFirstItem (sset);
1193 for (; lsym; lsym = setNextItem (sset))
1196 /* if usage is the same then prefer
1197 the spill the smaller of the two */
1198 if (lsym->used == sym->used)
1199 if (getSize (lsym->type) < getSize (sym->type))
1203 if (lsym->used < sym->used)
1208 setToNull ((void **) &sset);
1213 /*-----------------------------------------------------------------*/
1214 /* noOverLap - will iterate through the list looking for over lap */
1215 /*-----------------------------------------------------------------*/
1217 noOverLap (set * itmpStack, symbol * fsym)
1220 debugLog ("%s\n", __FUNCTION__);
1223 for (sym = setFirstItem (itmpStack); sym;
1224 sym = setNextItem (itmpStack))
1226 if (sym->liveTo > fsym->liveFrom)
1234 /*-----------------------------------------------------------------*/
1235 /* isFree - will return 1 if the a free spil location is found */
1236 /*-----------------------------------------------------------------*/
1241 V_ARG (symbol **, sloc);
1242 V_ARG (symbol *, fsym);
1244 debugLog ("%s\n", __FUNCTION__);
1245 /* if already found */
1249 /* if it is free && and the itmp assigned to
1250 this does not have any overlapping live ranges
1251 with the one currently being assigned and
1252 the size can be accomodated */
1254 noOverLap (sym->usl.itmpStack, fsym) &&
1255 getSize (sym->type) >= getSize (fsym->type))
1264 /*-----------------------------------------------------------------*/
1265 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1266 /*-----------------------------------------------------------------*/
1268 spillLRWithPtrReg (symbol * forSym)
1274 debugLog ("%s\n", __FUNCTION__);
1275 if (!_G.regAssigned ||
1276 bitVectIsZero (_G.regAssigned))
1279 r0 = pic14_regWithIdx (R0_IDX);
1280 r1 = pic14_regWithIdx (R1_IDX);
1282 /* for all live ranges */
1283 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1284 lrsym = hTabNextItem (liveRanges, &k))
1288 /* if no registers assigned to it or
1290 /* if it does not overlap with this then
1291 not need to spill it */
1293 if (lrsym->isspilt || !lrsym->nRegs ||
1294 (lrsym->liveTo < forSym->liveFrom))
1297 /* go thru the registers : if it is either
1298 r0 or r1 then spil it */
1299 for (j = 0; j < lrsym->nRegs; j++)
1300 if (lrsym->regs[j] == r0 ||
1301 lrsym->regs[j] == r1)
1310 /*-----------------------------------------------------------------*/
1311 /* createStackSpil - create a location on the stack to spil */
1312 /*-----------------------------------------------------------------*/
1314 createStackSpil (symbol * sym)
1316 symbol *sloc = NULL;
1317 int useXstack, model, noOverlay;
1319 char slocBuffer[30];
1320 debugLog ("%s\n", __FUNCTION__);
1322 /* first go try and find a free one that is already
1323 existing on the stack */
1324 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1326 /* found a free one : just update & return */
1327 sym->usl.spillLoc = sloc;
1330 addSetHead (&sloc->usl.itmpStack, sym);
1334 /* could not then have to create one , this is the hard part
1335 we need to allocate this on the stack : this is really a
1336 hack!! but cannot think of anything better at this time */
1338 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1340 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1341 __FILE__, __LINE__);
1345 sloc = newiTemp (slocBuffer);
1347 /* set the type to the spilling symbol */
1348 sloc->type = copyLinkChain (sym->type);
1349 sloc->etype = getSpec (sloc->type);
1350 SPEC_SCLS (sloc->etype) = S_DATA;
1351 SPEC_EXTR (sloc->etype) = 0;
1352 SPEC_STAT (sloc->etype) = 0;
1354 /* we don't allow it to be allocated`
1355 onto the external stack since : so we
1356 temporarily turn it off ; we also
1357 turn off memory model to prevent
1358 the spil from going to the external storage
1359 and turn off overlaying
1362 useXstack = options.useXstack;
1363 model = options.model;
1364 noOverlay = options.noOverlay;
1365 options.noOverlay = 1;
1366 options.model = options.useXstack = 0;
1370 options.useXstack = useXstack;
1371 options.model = model;
1372 options.noOverlay = noOverlay;
1373 sloc->isref = 1; /* to prevent compiler warning */
1375 /* if it is on the stack then update the stack */
1376 if (IN_STACK (sloc->etype))
1378 currFunc->stack += getSize (sloc->type);
1379 _G.stackExtend += getSize (sloc->type);
1382 _G.dataExtend += getSize (sloc->type);
1384 /* add it to the _G.stackSpil set */
1385 addSetHead (&_G.stackSpil, sloc);
1386 sym->usl.spillLoc = sloc;
1389 /* add it to the set of itempStack set
1390 of the spill location */
1391 addSetHead (&sloc->usl.itmpStack, sym);
1395 /*-----------------------------------------------------------------*/
1396 /* isSpiltOnStack - returns true if the spil location is on stack */
1397 /*-----------------------------------------------------------------*/
1399 isSpiltOnStack (symbol * sym)
1403 debugLog ("%s\n", __FUNCTION__);
1410 /* if (sym->_G.stackSpil) */
1413 if (!sym->usl.spillLoc)
1416 etype = getSpec (sym->usl.spillLoc->type);
1417 if (IN_STACK (etype))
1423 /*-----------------------------------------------------------------*/
1424 /* spillThis - spils a specific operand */
1425 /*-----------------------------------------------------------------*/
1427 spillThis (symbol * sym)
1430 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1432 /* if this is rematerializable or has a spillLocation
1433 we are okay, else we need to create a spillLocation
1435 if (!(sym->remat || sym->usl.spillLoc))
1436 createStackSpil (sym);
1439 /* mark it has spilt & put it in the spilt set */
1441 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1443 bitVectUnSetBit (_G.regAssigned, sym->key);
1445 for (i = 0; i < sym->nRegs; i++)
1449 freeReg (sym->regs[i]);
1450 sym->regs[i] = NULL;
1453 /* if spilt on stack then free up r0 & r1
1454 if they could have been assigned to some
1456 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1459 spillLRWithPtrReg (sym);
1462 if (sym->usl.spillLoc && !sym->remat)
1463 sym->usl.spillLoc->allocreq = 1;
1467 /*-----------------------------------------------------------------*/
1468 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1469 /*-----------------------------------------------------------------*/
1471 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1473 bitVect *lrcs = NULL;
1477 debugLog ("%s\n", __FUNCTION__);
1478 /* get the spillable live ranges */
1479 lrcs = computeSpillable (ic);
1481 /* get all live ranges that are rematerizable */
1482 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1485 /* return the least used of these */
1486 return leastUsedLR (selectS);
1489 /* get live ranges with spillLocations in direct space */
1490 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1492 sym = leastUsedLR (selectS);
1493 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1494 sym->usl.spillLoc->rname :
1495 sym->usl.spillLoc->name));
1497 /* mark it as allocation required */
1498 sym->usl.spillLoc->allocreq = 1;
1502 /* if the symbol is local to the block then */
1503 if (forSym->liveTo < ebp->lSeq)
1506 /* check if there are any live ranges allocated
1507 to registers that are not used in this block */
1508 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1510 sym = leastUsedLR (selectS);
1511 /* if this is not rematerializable */
1520 /* check if there are any live ranges that not
1521 used in the remainder of the block */
1522 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1524 sym = leastUsedLR (selectS);
1527 sym->remainSpil = 1;
1534 /* find live ranges with spillocation && not used as pointers */
1535 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1538 sym = leastUsedLR (selectS);
1539 /* mark this as allocation required */
1540 sym->usl.spillLoc->allocreq = 1;
1544 /* find live ranges with spillocation */
1545 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1548 sym = leastUsedLR (selectS);
1549 sym->usl.spillLoc->allocreq = 1;
1553 /* couldn't find then we need to create a spil
1554 location on the stack , for which one? the least
1556 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1559 /* return a created spil location */
1560 sym = createStackSpil (leastUsedLR (selectS));
1561 sym->usl.spillLoc->allocreq = 1;
1565 /* this is an extreme situation we will spill
1566 this one : happens very rarely but it does happen */
1572 /*-----------------------------------------------------------------*/
1573 /* spilSomething - spil some variable & mark registers as free */
1574 /*-----------------------------------------------------------------*/
1576 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1581 debugLog ("%s\n", __FUNCTION__);
1582 /* get something we can spil */
1583 ssym = selectSpil (ic, ebp, forSym);
1585 /* mark it as spilt */
1587 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1589 /* mark it as not register assigned &
1590 take it away from the set */
1591 bitVectUnSetBit (_G.regAssigned, ssym->key);
1593 /* mark the registers as free */
1594 for (i = 0; i < ssym->nRegs; i++)
1596 freeReg (ssym->regs[i]);
1598 /* if spilt on stack then free up r0 & r1
1599 if they could have been assigned to as gprs */
1600 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1603 spillLRWithPtrReg (ssym);
1606 /* if this was a block level spil then insert push & pop
1607 at the start & end of block respectively */
1608 if (ssym->blockSpil)
1610 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1611 /* add push to the start of the block */
1612 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1613 ebp->sch->next : ebp->sch));
1614 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1615 /* add pop to the end of the block */
1616 addiCodeToeBBlock (ebp, nic, NULL);
1619 /* if spilt because not used in the remainder of the
1620 block then add a push before this instruction and
1621 a pop at the end of the block */
1622 if (ssym->remainSpil)
1625 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1626 /* add push just before this instruction */
1627 addiCodeToeBBlock (ebp, nic, ic);
1629 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1630 /* add pop to the end of the block */
1631 addiCodeToeBBlock (ebp, nic, NULL);
1640 /*-----------------------------------------------------------------*/
1641 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1642 /*-----------------------------------------------------------------*/
1644 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1648 debugLog ("%s\n", __FUNCTION__);
1650 /* try for a ptr type */
1651 if ((reg = allocReg (REG_PTR)))
1654 /* try for gpr type */
1655 if ((reg = allocReg (REG_GPR)))
1658 /* we have to spil */
1659 if (!spilSomething (ic, ebp, sym))
1662 /* this looks like an infinite loop but
1663 in really selectSpil will abort */
1667 /*-----------------------------------------------------------------*/
1668 /* getRegGpr - will try for GPR if not spil */
1669 /*-----------------------------------------------------------------*/
1671 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1675 debugLog ("%s\n", __FUNCTION__);
1677 /* try for gpr type */
1678 if ((reg = allocReg (REG_GPR)))
1681 if (!pic14_ptrRegReq)
1682 if ((reg = allocReg (REG_PTR)))
1685 /* we have to spil */
1686 if (!spilSomething (ic, ebp, sym))
1689 /* this looks like an infinite loop but
1690 in really selectSpil will abort */
1694 /*-----------------------------------------------------------------*/
1695 /* symHasReg - symbol has a given register */
1696 /*-----------------------------------------------------------------*/
1698 symHasReg (symbol * sym, regs * reg)
1702 debugLog ("%s\n", __FUNCTION__);
1703 for (i = 0; i < sym->nRegs; i++)
1704 if (sym->regs[i] == reg)
1710 /*-----------------------------------------------------------------*/
1711 /* deassignLRs - check the live to and if they have registers & are */
1712 /* not spilt then free up the registers */
1713 /*-----------------------------------------------------------------*/
1715 deassignLRs (iCode * ic, eBBlock * ebp)
1721 debugLog ("%s\n", __FUNCTION__);
1722 for (sym = hTabFirstItem (liveRanges, &k); sym;
1723 sym = hTabNextItem (liveRanges, &k))
1726 symbol *psym = NULL;
1727 /* if it does not end here */
1728 if (sym->liveTo > ic->seq)
1731 /* if it was spilt on stack then we can
1732 mark the stack spil location as free */
1737 sym->usl.spillLoc->isFree = 1;
1743 if (!bitVectBitValue (_G.regAssigned, sym->key))
1746 /* special case check if this is an IFX &
1747 the privious one was a pop and the
1748 previous one was not spilt then keep track
1750 if (ic->op == IFX && ic->prev &&
1751 ic->prev->op == IPOP &&
1752 !ic->prev->parmPush &&
1753 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1754 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1760 bitVectUnSetBit (_G.regAssigned, sym->key);
1762 /* if the result of this one needs registers
1763 and does not have it then assign it right
1765 if (IC_RESULT (ic) &&
1766 !(SKIP_IC2 (ic) || /* not a special icode */
1767 ic->op == JUMPTABLE ||
1772 POINTER_SET (ic)) &&
1773 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1774 result->liveTo > ic->seq && /* and will live beyond this */
1775 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1776 result->regType == sym->regType && /* same register types */
1777 result->nRegs && /* which needs registers */
1778 !result->isspilt && /* and does not already have them */
1780 !bitVectBitValue (_G.regAssigned, result->key) &&
1781 /* the number of free regs + number of regs in this LR
1782 can accomodate the what result Needs */
1783 ((nfreeRegsType (result->regType) +
1784 sym->nRegs) >= result->nRegs)
1788 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1790 result->regs[i] = sym->regs[i];
1792 result->regs[i] = getRegGpr (ic, ebp, result);
1794 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1798 /* free the remaining */
1799 for (; i < sym->nRegs; i++)
1803 if (!symHasReg (psym, sym->regs[i]))
1804 freeReg (sym->regs[i]);
1807 freeReg (sym->regs[i]);
1814 /*-----------------------------------------------------------------*/
1815 /* reassignLR - reassign this to registers */
1816 /*-----------------------------------------------------------------*/
1818 reassignLR (operand * op)
1820 symbol *sym = OP_SYMBOL (op);
1823 debugLog ("%s\n", __FUNCTION__);
1824 /* not spilt any more */
1825 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1826 bitVectUnSetBit (_G.spiltSet, sym->key);
1828 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1832 for (i = 0; i < sym->nRegs; i++)
1833 sym->regs[i]->isFree = 0;
1836 /*-----------------------------------------------------------------*/
1837 /* willCauseSpill - determines if allocating will cause a spill */
1838 /*-----------------------------------------------------------------*/
1840 willCauseSpill (int nr, int rt)
1842 debugLog ("%s\n", __FUNCTION__);
1843 /* first check if there are any avlb registers
1844 of te type required */
1847 /* special case for pointer type
1848 if pointer type not avlb then
1849 check for type gpr */
1850 if (nFreeRegs (rt) >= nr)
1852 if (nFreeRegs (REG_GPR) >= nr)
1857 if (pic14_ptrRegReq)
1859 if (nFreeRegs (rt) >= nr)
1864 if (nFreeRegs (REG_PTR) +
1865 nFreeRegs (REG_GPR) >= nr)
1870 debugLog (" ... yep it will (cause a spill)\n");
1871 /* it will cause a spil */
1875 /*-----------------------------------------------------------------*/
1876 /* positionRegs - the allocator can allocate same registers to res- */
1877 /* ult and operand, if this happens make sure they are in the same */
1878 /* position as the operand otherwise chaos results */
1879 /*-----------------------------------------------------------------*/
1881 positionRegs (symbol * result, symbol * opsym, int lineno)
1883 int count = min (result->nRegs, opsym->nRegs);
1884 int i, j = 0, shared = 0;
1886 debugLog ("%s\n", __FUNCTION__);
1887 /* if the result has been spilt then cannot share */
1892 /* first make sure that they actually share */
1893 for (i = 0; i < count; i++)
1895 for (j = 0; j < count; j++)
1897 if (result->regs[i] == opsym->regs[j] && i != j)
1907 regs *tmp = result->regs[i];
1908 result->regs[i] = result->regs[j];
1909 result->regs[j] = tmp;
1914 /*-----------------------------------------------------------------*/
1915 /* serialRegAssign - serially allocate registers to the variables */
1916 /*-----------------------------------------------------------------*/
1918 serialRegAssign (eBBlock ** ebbs, int count)
1922 debugLog ("%s\n", __FUNCTION__);
1923 /* for all blocks */
1924 for (i = 0; i < count; i++)
1929 if (ebbs[i]->noPath &&
1930 (ebbs[i]->entryLabel != entryLabel &&
1931 ebbs[i]->entryLabel != returnLabel))
1934 /* of all instructions do */
1935 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1938 debugLog (" op: %s\n", decodeOp (ic->op));
1940 /* if this is an ipop that means some live
1941 range will have to be assigned again */
1943 reassignLR (IC_LEFT (ic));
1945 /* if result is present && is a true symbol */
1946 if (IC_RESULT (ic) && ic->op != IFX &&
1947 IS_TRUE_SYMOP (IC_RESULT (ic)))
1948 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1950 /* take away registers from live
1951 ranges that end at this instruction */
1952 deassignLRs (ic, ebbs[i]);
1954 /* some don't need registers */
1955 if (SKIP_IC2 (ic) ||
1956 ic->op == JUMPTABLE ||
1960 (IC_RESULT (ic) && POINTER_SET (ic)))
1963 /* now we need to allocate registers
1964 only for the result */
1967 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1973 /* if it does not need or is spilt
1974 or is already assigned to registers
1975 or will not live beyond this instructions */
1978 bitVectBitValue (_G.regAssigned, sym->key) ||
1979 sym->liveTo <= ic->seq)
1982 /* if some liverange has been spilt at the block level
1983 and this one live beyond this block then spil this
1985 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1990 /* if trying to allocate this will cause
1991 a spill and there is nothing to spill
1992 or this one is rematerializable then
1994 willCS = willCauseSpill (sym->nRegs, sym->regType);
1995 spillable = computeSpillable (ic);
1997 (willCS && bitVectIsZero (spillable)))
2005 /* if it has a spillocation & is used less than
2006 all other live ranges then spill this */
2008 if (sym->usl.spillLoc) {
2009 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2010 allLRs, ebbs[i], ic));
2011 if (leastUsed && leastUsed->used > sym->used) {
2016 /* if none of the liveRanges have a spillLocation then better
2017 to spill this one than anything else already assigned to registers */
2018 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2019 /* if this is local to this block then we might find a block spil */
2020 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2028 if (ic->op == RECEIVE)
2029 debugLog ("When I get clever, I'll optimize the receive logic\n");
2031 /* if we need ptr regs for the right side
2033 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2034 <= (unsigned) PTRSIZE)
2039 /* else we assign registers to it */
2040 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2042 debugLog (" %d - \n", __LINE__);
2044 bitVectDebugOn(_G.regAssigned, debugF);
2046 for (j = 0; j < sym->nRegs; j++)
2048 if (sym->regType == REG_PTR)
2049 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2051 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2053 /* if the allocation falied which means
2054 this was spilt then break */
2058 debugLog (" %d - \n", __LINE__);
2060 /* if it shares registers with operands make sure
2061 that they are in the same position */
2062 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2063 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2064 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2065 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2066 /* do the same for the right operand */
2067 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2068 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2069 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2070 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2072 debugLog (" %d - \n", __LINE__);
2075 debugLog (" %d - \n", __LINE__);
2085 /*-----------------------------------------------------------------*/
2086 /* rUmaskForOp :- returns register mask for an operand */
2087 /*-----------------------------------------------------------------*/
2089 rUmaskForOp (operand * op)
2095 debugLog ("%s\n", __FUNCTION__);
2096 /* only temporaries are assigned registers */
2100 sym = OP_SYMBOL (op);
2102 /* if spilt or no registers assigned to it
2104 if (sym->isspilt || !sym->nRegs)
2107 rumask = newBitVect (pic14_nRegs);
2109 for (j = 0; j < sym->nRegs; j++)
2111 rumask = bitVectSetBit (rumask,
2112 sym->regs[j]->rIdx);
2118 /*-----------------------------------------------------------------*/
2119 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2120 /*-----------------------------------------------------------------*/
2122 regsUsedIniCode (iCode * ic)
2124 bitVect *rmask = newBitVect (pic14_nRegs);
2126 debugLog ("%s\n", __FUNCTION__);
2127 /* do the special cases first */
2130 rmask = bitVectUnion (rmask,
2131 rUmaskForOp (IC_COND (ic)));
2135 /* for the jumptable */
2136 if (ic->op == JUMPTABLE)
2138 rmask = bitVectUnion (rmask,
2139 rUmaskForOp (IC_JTCOND (ic)));
2144 /* of all other cases */
2146 rmask = bitVectUnion (rmask,
2147 rUmaskForOp (IC_LEFT (ic)));
2151 rmask = bitVectUnion (rmask,
2152 rUmaskForOp (IC_RIGHT (ic)));
2155 rmask = bitVectUnion (rmask,
2156 rUmaskForOp (IC_RESULT (ic)));
2162 /*-----------------------------------------------------------------*/
2163 /* createRegMask - for each instruction will determine the regsUsed */
2164 /*-----------------------------------------------------------------*/
2166 createRegMask (eBBlock ** ebbs, int count)
2170 debugLog ("%s\n", __FUNCTION__);
2171 /* for all blocks */
2172 for (i = 0; i < count; i++)
2176 if (ebbs[i]->noPath &&
2177 (ebbs[i]->entryLabel != entryLabel &&
2178 ebbs[i]->entryLabel != returnLabel))
2181 /* for all instructions */
2182 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2187 if (SKIP_IC2 (ic) || !ic->rlive)
2190 /* first mark the registers used in this
2192 ic->rUsed = regsUsedIniCode (ic);
2193 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2195 /* now create the register mask for those
2196 registers that are in use : this is a
2197 super set of ic->rUsed */
2198 ic->rMask = newBitVect (pic14_nRegs + 1);
2200 /* for all live Ranges alive at this point */
2201 for (j = 1; j < ic->rlive->size; j++)
2206 /* if not alive then continue */
2207 if (!bitVectBitValue (ic->rlive, j))
2210 /* find the live range we are interested in */
2211 if (!(sym = hTabItemWithKey (liveRanges, j)))
2213 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2214 "createRegMask cannot find live range");
2218 /* if no register assigned to it */
2219 if (!sym->nRegs || sym->isspilt)
2222 /* for all the registers allocated to it */
2223 for (k = 0; k < sym->nRegs; k++)
2226 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2232 /*-----------------------------------------------------------------*/
2233 /* rematStr - returns the rematerialized string for a remat var */
2234 /*-----------------------------------------------------------------*/
2236 rematStr (symbol * sym)
2239 iCode *ic = sym->rematiCode;
2241 debugLog ("%s\n", __FUNCTION__);
2246 /* if plus or minus print the right hand side */
2248 if (ic->op == '+' || ic->op == '-') {
2249 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2252 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2256 if (ic->op == '+' || ic->op == '-')
2258 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2259 sprintf (s, "(%s %c 0x%04x)",
2260 OP_SYMBOL (IC_LEFT (ric))->rname,
2262 (int) operandLitValue (IC_RIGHT (ic)));
2265 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2270 /* we reached the end */
2271 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2275 printf ("%s\n", buffer);
2279 /*-----------------------------------------------------------------*/
2280 /* regTypeNum - computes the type & number of registers required */
2281 /*-----------------------------------------------------------------*/
2289 debugLog ("%s\n", __FUNCTION__);
2290 /* for each live range do */
2291 for (sym = hTabFirstItem (liveRanges, &k); sym;
2292 sym = hTabNextItem (liveRanges, &k)) {
2294 debugLog (" %d - %s\n", __LINE__, sym->rname);
2296 /* if used zero times then no registers needed */
2297 if ((sym->liveTo - sym->liveFrom) == 0)
2301 /* if the live range is a temporary */
2304 debugLog (" %d - itemp register\n", __LINE__);
2306 /* if the type is marked as a conditional */
2307 if (sym->regType == REG_CND)
2310 /* if used in return only then we don't
2312 if (sym->ruonly || sym->accuse) {
2313 if (IS_AGGREGATE (sym->type) || sym->isptr)
2314 sym->type = aggrToPtr (sym->type, FALSE);
2315 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2320 /* if the symbol has only one definition &
2321 that definition is a get_pointer and the
2322 pointer we are getting is rematerializable and
2325 if (bitVectnBitsOn (sym->defs) == 1 &&
2326 (ic = hTabItemWithKey (iCodehTab,
2327 bitVectFirstBit (sym->defs))) &&
2330 !IS_BITVAR (sym->etype)) {
2333 debugLog (" %d - \n", __LINE__);
2335 /* if remat in data space */
2336 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2337 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2339 /* create a psuedo symbol & force a spil */
2340 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2341 psym->type = sym->type;
2342 psym->etype = sym->etype;
2343 strcpy (psym->rname, psym->name);
2345 sym->usl.spillLoc = psym;
2349 /* if in data space or idata space then try to
2350 allocate pointer register */
2354 /* if not then we require registers */
2355 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2356 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2357 getSize (sym->type));
2360 if(IS_PTR_CONST (sym->type)) {
2361 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2365 if (sym->nRegs > 4) {
2366 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2367 printTypeChain (sym->type, stderr);
2368 fprintf (stderr, "\n");
2371 /* determine the type of register required */
2372 if (sym->nRegs == 1 &&
2373 IS_PTR (sym->type) &&
2375 sym->regType = REG_PTR;
2377 sym->regType = REG_GPR;
2380 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2384 /* for the first run we don't provide */
2385 /* registers for true symbols we will */
2386 /* see how things go */
2391 DEFSETFUNC (markRegFree)
2393 ((regs *)item)->isFree = 1;
2398 DEFSETFUNC (deallocReg)
2400 ((regs *)item)->isFree = 1;
2401 ((regs *)item)->wasUsed = 0;
2405 /*-----------------------------------------------------------------*/
2406 /* freeAllRegs - mark all registers as free */
2407 /*-----------------------------------------------------------------*/
2409 pic14_freeAllRegs ()
2413 debugLog ("%s\n", __FUNCTION__);
2415 applyToSet(dynAllocRegs,markRegFree);
2416 applyToSet(dynStackRegs,markRegFree);
2419 for (i = 0; i < pic14_nRegs; i++)
2420 regspic14[i].isFree = 1;
2424 /*-----------------------------------------------------------------*/
2425 /*-----------------------------------------------------------------*/
2427 pic14_deallocateAllRegs ()
2431 debugLog ("%s\n", __FUNCTION__);
2433 applyToSet(dynAllocRegs,deallocReg);
2436 for (i = 0; i < pic14_nRegs; i++) {
2437 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2438 regspic14[i].isFree = 1;
2439 regspic14[i].wasUsed = 0;
2446 /*-----------------------------------------------------------------*/
2447 /* deallocStackSpil - this will set the stack pointer back */
2448 /*-----------------------------------------------------------------*/
2450 DEFSETFUNC (deallocStackSpil)
2454 debugLog ("%s\n", __FUNCTION__);
2459 /*-----------------------------------------------------------------*/
2460 /* farSpacePackable - returns the packable icode for far variables */
2461 /*-----------------------------------------------------------------*/
2463 farSpacePackable (iCode * ic)
2467 debugLog ("%s\n", __FUNCTION__);
2468 /* go thru till we find a definition for the
2469 symbol on the right */
2470 for (dic = ic->prev; dic; dic = dic->prev)
2473 /* if the definition is a call then no */
2474 if ((dic->op == CALL || dic->op == PCALL) &&
2475 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2480 /* if shift by unknown amount then not */
2481 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2482 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2485 /* if pointer get and size > 1 */
2486 if (POINTER_GET (dic) &&
2487 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2490 if (POINTER_SET (dic) &&
2491 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2494 /* if any three is a true symbol in far space */
2495 if (IC_RESULT (dic) &&
2496 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2497 isOperandInFarSpace (IC_RESULT (dic)))
2500 if (IC_RIGHT (dic) &&
2501 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2502 isOperandInFarSpace (IC_RIGHT (dic)) &&
2503 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2506 if (IC_LEFT (dic) &&
2507 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2508 isOperandInFarSpace (IC_LEFT (dic)) &&
2509 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2512 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2514 if ((dic->op == LEFT_OP ||
2515 dic->op == RIGHT_OP ||
2517 IS_OP_LITERAL (IC_RIGHT (dic)))
2527 /*-----------------------------------------------------------------*/
2528 /* packRegsForAssign - register reduction for assignment */
2529 /*-----------------------------------------------------------------*/
2531 packRegsForAssign (iCode * ic, eBBlock * ebp)
2536 debugLog ("%s\n", __FUNCTION__);
2538 debugAopGet (" result:", IC_RESULT (ic));
2539 debugAopGet (" left:", IC_LEFT (ic));
2540 debugAopGet (" right:", IC_RIGHT (ic));
2542 if (!IS_ITEMP (IC_RESULT (ic))) {
2543 allocDirReg(IC_RESULT (ic));
2544 debugLog (" %d - result is not temp\n", __LINE__);
2547 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2548 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2549 allocDirReg(IC_LEFT (ic));
2553 if (!IS_ITEMP (IC_RIGHT (ic))) {
2554 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2555 allocDirReg(IC_RIGHT (ic));
2559 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2560 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2562 debugLog (" %d - not packing - right side fails \n", __LINE__);
2566 /* if the true symbol is defined in far space or on stack
2567 then we should not since this will increase register pressure */
2568 if (isOperandInFarSpace (IC_RESULT (ic)))
2570 if ((dic = farSpacePackable (ic)))
2576 /* find the definition of iTempNN scanning backwards if we find a
2577 a use of the true symbol before we find the definition then
2579 for (dic = ic->prev; dic; dic = dic->prev)
2582 /* if there is a function call and this is
2583 a parameter & not my parameter then don't pack it */
2584 if ((dic->op == CALL || dic->op == PCALL) &&
2585 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2586 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2588 debugLog (" %d - \n", __LINE__);
2596 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2597 IS_OP_VOLATILE (IC_RESULT (dic)))
2599 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2604 if (IS_SYMOP (IC_RESULT (dic)) &&
2605 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2607 /* A previous result was assigned to the same register - we'll our definition */
2608 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2609 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2610 if (POINTER_SET (dic))
2616 if (IS_SYMOP (IC_RIGHT (dic)) &&
2617 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2618 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2620 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2625 if (IS_SYMOP (IC_LEFT (dic)) &&
2626 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2627 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2629 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2634 if (POINTER_SET (dic) &&
2635 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2637 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2645 return 0; /* did not find */
2647 /* if the result is on stack or iaccess then it must be
2648 the same atleast one of the operands */
2649 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2650 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2653 /* the operation has only one symbol
2654 operator then we can pack */
2655 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2656 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2659 if (!((IC_LEFT (dic) &&
2660 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2662 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2666 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2667 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2668 /* found the definition */
2669 /* replace the result with the result of */
2670 /* this assignment and remove this assignment */
2671 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2672 IC_RESULT (dic) = IC_RESULT (ic);
2674 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2676 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2678 /* delete from liverange table also
2679 delete from all the points inbetween and the new
2681 for (sic = dic; sic != ic; sic = sic->next)
2683 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2684 if (IS_ITEMP (IC_RESULT (dic)))
2685 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2688 remiCodeFromeBBlock (ebp, ic);
2689 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2690 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2691 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2697 /*-----------------------------------------------------------------*/
2698 /* findAssignToSym : scanning backwards looks for first assig found */
2699 /*-----------------------------------------------------------------*/
2701 findAssignToSym (operand * op, iCode * ic)
2705 debugLog ("%s\n", __FUNCTION__);
2706 for (dic = ic->prev; dic; dic = dic->prev)
2709 /* if definition by assignment */
2710 if (dic->op == '=' &&
2711 !POINTER_SET (dic) &&
2712 IC_RESULT (dic)->key == op->key
2713 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2717 /* we are interested only if defined in far space */
2718 /* or in stack space in case of + & - */
2720 /* if assigned to a non-symbol then return
2722 if (!IS_SYMOP (IC_RIGHT (dic)))
2725 /* if the symbol is in far space then
2727 if (isOperandInFarSpace (IC_RIGHT (dic)))
2730 /* for + & - operations make sure that
2731 if it is on the stack it is the same
2732 as one of the three operands */
2733 if ((ic->op == '+' || ic->op == '-') &&
2734 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2737 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2738 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2739 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2747 /* if we find an usage then we cannot delete it */
2748 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2751 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2754 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2758 /* now make sure that the right side of dic
2759 is not defined between ic & dic */
2762 iCode *sic = dic->next;
2764 for (; sic != ic; sic = sic->next)
2765 if (IC_RESULT (sic) &&
2766 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2775 /*-----------------------------------------------------------------*/
2776 /* packRegsForSupport :- reduce some registers for support calls */
2777 /*-----------------------------------------------------------------*/
2779 packRegsForSupport (iCode * ic, eBBlock * ebp)
2783 debugLog ("%s\n", __FUNCTION__);
2784 /* for the left & right operand :- look to see if the
2785 left was assigned a true symbol in far space in that
2786 case replace them */
2787 if (IS_ITEMP (IC_LEFT (ic)) &&
2788 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2790 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2796 debugAopGet ("removing left:", IC_LEFT (ic));
2798 /* found it we need to remove it from the
2800 for (sic = dic; sic != ic; sic = sic->next)
2801 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2803 IC_LEFT (ic)->operand.symOperand =
2804 IC_RIGHT (dic)->operand.symOperand;
2805 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2806 remiCodeFromeBBlock (ebp, dic);
2807 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2808 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2812 /* do the same for the right operand */
2815 IS_ITEMP (IC_RIGHT (ic)) &&
2816 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2818 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2824 /* if this is a subtraction & the result
2825 is a true symbol in far space then don't pack */
2826 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2828 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2829 if (IN_FARSPACE (SPEC_OCLS (etype)))
2833 debugAopGet ("removing right:", IC_RIGHT (ic));
2835 /* found it we need to remove it from the
2837 for (sic = dic; sic != ic; sic = sic->next)
2838 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2840 IC_RIGHT (ic)->operand.symOperand =
2841 IC_RIGHT (dic)->operand.symOperand;
2842 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2844 remiCodeFromeBBlock (ebp, dic);
2845 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2846 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2853 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2856 /*-----------------------------------------------------------------*/
2857 /* packRegsForOneuse : - will reduce some registers for single Use */
2858 /*-----------------------------------------------------------------*/
2860 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2865 debugLog ("%s\n", __FUNCTION__);
2866 /* if returning a literal then do nothing */
2870 /* only upto 2 bytes since we cannot predict
2871 the usage of b, & acc */
2872 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2877 /* this routine will mark the a symbol as used in one
2878 instruction use only && if the definition is local
2879 (ie. within the basic block) && has only one definition &&
2880 that definition is either a return value from a
2881 function or does not contain any variables in
2883 uses = bitVectCopy (OP_USES (op));
2884 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2885 if (!bitVectIsZero (uses)) /* has other uses */
2888 /* if it has only one defintion */
2889 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2890 return NULL; /* has more than one definition */
2892 /* get that definition */
2894 hTabItemWithKey (iCodehTab,
2895 bitVectFirstBit (OP_DEFS (op)))))
2898 /* found the definition now check if it is local */
2899 if (dic->seq < ebp->fSeq ||
2900 dic->seq > ebp->lSeq)
2901 return NULL; /* non-local */
2903 /* now check if it is the return from
2905 if (dic->op == CALL || dic->op == PCALL)
2907 if (ic->op != SEND && ic->op != RETURN &&
2908 !POINTER_SET(ic) && !POINTER_GET(ic))
2910 OP_SYMBOL (op)->ruonly = 1;
2917 /* otherwise check that the definition does
2918 not contain any symbols in far space */
2919 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2920 isOperandInFarSpace (IC_RIGHT (dic)) ||
2921 IS_OP_RUONLY (IC_LEFT (ic)) ||
2922 IS_OP_RUONLY (IC_RIGHT (ic)))
2927 /* if pointer set then make sure the pointer
2929 if (POINTER_SET (dic) &&
2930 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2933 if (POINTER_GET (dic) &&
2934 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2939 /* also make sure the intervenening instructions
2940 don't have any thing in far space */
2941 for (dic = dic->next; dic && dic != ic; dic = dic->next)
2944 /* if there is an intervening function call then no */
2945 if (dic->op == CALL || dic->op == PCALL)
2947 /* if pointer set then make sure the pointer
2949 if (POINTER_SET (dic) &&
2950 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2953 if (POINTER_GET (dic) &&
2954 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2957 /* if address of & the result is remat then okay */
2958 if (dic->op == ADDRESS_OF &&
2959 OP_SYMBOL (IC_RESULT (dic))->remat)
2962 /* if operand has size of three or more & this
2963 operation is a '*','/' or '%' then 'b' may
2965 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2966 getSize (operandType (op)) >= 3)
2969 /* if left or right or result is in far space */
2970 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2971 isOperandInFarSpace (IC_RIGHT (dic)) ||
2972 isOperandInFarSpace (IC_RESULT (dic)) ||
2973 IS_OP_RUONLY (IC_LEFT (dic)) ||
2974 IS_OP_RUONLY (IC_RIGHT (dic)) ||
2975 IS_OP_RUONLY (IC_RESULT (dic)))
2981 OP_SYMBOL (op)->ruonly = 1;
2986 /*-----------------------------------------------------------------*/
2987 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2988 /*-----------------------------------------------------------------*/
2990 isBitwiseOptimizable (iCode * ic)
2992 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2993 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2995 debugLog ("%s\n", __FUNCTION__);
2996 /* bitwise operations are considered optimizable
2997 under the following conditions (Jean-Louis VERN)
3009 if (IS_LITERAL (rtype) ||
3010 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3016 /*-----------------------------------------------------------------*/
3017 /* packRegsForAccUse - pack registers for acc use */
3018 /*-----------------------------------------------------------------*/
3020 packRegsForAccUse (iCode * ic)
3024 debugLog ("%s\n", __FUNCTION__);
3026 /* if this is an aggregate, e.g. a one byte char array */
3027 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3031 /* if + or - then it has to be one byte result */
3032 if ((ic->op == '+' || ic->op == '-')
3033 && getSize (operandType (IC_RESULT (ic))) > 1)
3036 /* if shift operation make sure right side is not a literal */
3037 if (ic->op == RIGHT_OP &&
3038 (isOperandLiteral (IC_RIGHT (ic)) ||
3039 getSize (operandType (IC_RESULT (ic))) > 1))
3042 if (ic->op == LEFT_OP &&
3043 (isOperandLiteral (IC_RIGHT (ic)) ||
3044 getSize (operandType (IC_RESULT (ic))) > 1))
3047 if (IS_BITWISE_OP (ic) &&
3048 getSize (operandType (IC_RESULT (ic))) > 1)
3052 /* has only one definition */
3053 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3056 /* has only one use */
3057 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3060 /* and the usage immediately follows this iCode */
3061 if (!(uic = hTabItemWithKey (iCodehTab,
3062 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3065 if (ic->next != uic)
3068 /* if it is a conditional branch then we definitely can */
3072 if (uic->op == JUMPTABLE)
3075 /* if the usage is not is an assignment
3076 or an arithmetic / bitwise / shift operation then not */
3077 if (POINTER_SET (uic) &&
3078 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3081 if (uic->op != '=' &&
3082 !IS_ARITHMETIC_OP (uic) &&
3083 !IS_BITWISE_OP (uic) &&
3084 uic->op != LEFT_OP &&
3085 uic->op != RIGHT_OP)
3088 /* if used in ^ operation then make sure right is not a
3090 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3093 /* if shift operation make sure right side is not a literal */
3094 if (uic->op == RIGHT_OP &&
3095 (isOperandLiteral (IC_RIGHT (uic)) ||
3096 getSize (operandType (IC_RESULT (uic))) > 1))
3099 if (uic->op == LEFT_OP &&
3100 (isOperandLiteral (IC_RIGHT (uic)) ||
3101 getSize (operandType (IC_RESULT (uic))) > 1))
3104 /* make sure that the result of this icode is not on the
3105 stack, since acc is used to compute stack offset */
3106 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3107 OP_SYMBOL (IC_RESULT (uic))->onStack)
3110 /* if either one of them in far space then we cannot */
3111 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3112 isOperandInFarSpace (IC_LEFT (uic))) ||
3113 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3114 isOperandInFarSpace (IC_RIGHT (uic))))
3117 /* if the usage has only one operand then we can */
3118 if (IC_LEFT (uic) == NULL ||
3119 IC_RIGHT (uic) == NULL)
3122 /* make sure this is on the left side if not
3123 a '+' since '+' is commutative */
3124 if (ic->op != '+' &&
3125 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3128 /* if one of them is a literal then we can */
3129 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3130 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
3132 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3136 /* if the other one is not on stack then we can */
3137 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3138 (IS_ITEMP (IC_RIGHT (uic)) ||
3139 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3140 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3143 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3144 (IS_ITEMP (IC_LEFT (uic)) ||
3145 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3146 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3152 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3153 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3158 /*-----------------------------------------------------------------*/
3159 /* packForPush - hueristics to reduce iCode for pushing */
3160 /*-----------------------------------------------------------------*/
3162 packForReceive (iCode * ic, eBBlock * ebp)
3166 debugLog ("%s\n", __FUNCTION__);
3167 debugAopGet (" result:", IC_RESULT (ic));
3168 debugAopGet (" left:", IC_LEFT (ic));
3169 debugAopGet (" right:", IC_RIGHT (ic));
3174 for (dic = ic->next; dic; dic = dic->next)
3179 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3180 debugLog (" used on left\n");
3181 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3182 debugLog (" used on right\n");
3183 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3184 debugLog (" used on result\n");
3186 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3187 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3192 debugLog (" hey we can remove this unnecessary assign\n");
3194 /*-----------------------------------------------------------------*/
3195 /* packForPush - hueristics to reduce iCode for pushing */
3196 /*-----------------------------------------------------------------*/
3198 packForPush (iCode * ic, eBBlock * ebp)
3202 debugLog ("%s\n", __FUNCTION__);
3203 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3206 /* must have only definition & one usage */
3207 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3208 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3211 /* find the definition */
3212 if (!(dic = hTabItemWithKey (iCodehTab,
3213 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3216 if (dic->op != '=' || POINTER_SET (dic))
3219 /* we now we know that it has one & only one def & use
3220 and the that the definition is an assignment */
3221 IC_LEFT (ic) = IC_RIGHT (dic);
3223 remiCodeFromeBBlock (ebp, dic);
3224 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3225 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3228 void printSymType(char * str, sym_link *sl)
3230 debugLog (" %s Symbol type: ",str);
3231 printTypeChain( sl, debugF);
3236 /*-----------------------------------------------------------------*/
3237 /* packRegisters - does some transformations to reduce register */
3239 /*-----------------------------------------------------------------*/
3241 packRegisters (eBBlock * ebp)
3246 debugLog ("%s\n", __FUNCTION__);
3252 /* look for assignments of the form */
3253 /* iTempNN = TRueSym (someoperation) SomeOperand */
3255 /* TrueSym := iTempNN:1 */
3256 for (ic = ebp->sch; ic; ic = ic->next)
3259 /* find assignment of the form TrueSym := iTempNN:1 */
3260 if (ic->op == '=' && !POINTER_SET (ic))
3261 change += packRegsForAssign (ic, ebp);
3265 if (POINTER_SET (ic))
3266 debugLog ("pointer is set\n");
3267 debugAopGet (" result:", IC_RESULT (ic));
3268 debugAopGet (" left:", IC_LEFT (ic));
3269 debugAopGet (" right:", IC_RIGHT (ic));
3278 for (ic = ebp->sch; ic; ic = ic->next) {
3280 if(IS_SYMOP ( IC_LEFT(ic))) {
3281 //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3283 debugAopGet (" left:", IC_LEFT (ic));
3284 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3285 debugLog (" is a pointer");
3287 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3290 if(IS_SYMOP ( IC_RIGHT(ic))) {
3291 debugAopGet (" right:", IC_RIGHT (ic));
3292 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3295 if(IS_SYMOP ( IC_RESULT(ic))) {
3296 debugAopGet (" result:", IC_RESULT (ic));
3297 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3300 if (POINTER_SET (ic))
3301 debugLog (" %d - Pointer set\n", __LINE__);
3304 /* if this is an itemp & result of a address of a true sym
3305 then mark this as rematerialisable */
3306 if (ic->op == ADDRESS_OF &&
3307 IS_ITEMP (IC_RESULT (ic)) &&
3308 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3309 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3310 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3313 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3315 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3316 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3317 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3321 /* if straight assignment then carry remat flag if
3322 this is the only definition */
3323 if (ic->op == '=' &&
3324 !POINTER_SET (ic) &&
3325 IS_SYMOP (IC_RIGHT (ic)) &&
3326 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3327 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3329 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3331 OP_SYMBOL (IC_RESULT (ic))->remat =
3332 OP_SYMBOL (IC_RIGHT (ic))->remat;
3333 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3334 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3337 /* if this is a +/- operation with a rematerizable
3338 then mark this as rematerializable as well */
3339 if ((ic->op == '+' || ic->op == '-') &&
3340 (IS_SYMOP (IC_LEFT (ic)) &&
3341 IS_ITEMP (IC_RESULT (ic)) &&
3342 OP_SYMBOL (IC_LEFT (ic))->remat &&
3343 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3344 IS_OP_LITERAL (IC_RIGHT (ic))))
3346 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3348 operandLitValue (IC_RIGHT (ic));
3349 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3350 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3351 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3354 /* mark the pointer usages */
3355 if (POINTER_SET (ic))
3357 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3358 debugLog (" marking as a pointer (set) =>");
3359 debugAopGet (" result:", IC_RESULT (ic));
3361 if (POINTER_GET (ic))
3363 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3364 debugLog (" marking as a pointer (get) =>");
3365 debugAopGet (" left:", IC_LEFT (ic));
3370 /* if we are using a symbol on the stack
3371 then we should say pic14_ptrRegReq */
3372 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3373 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3374 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3375 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3376 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3377 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3380 if (IS_SYMOP (IC_LEFT (ic)))
3381 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3382 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3383 if (IS_SYMOP (IC_RIGHT (ic)))
3384 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3385 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3386 if (IS_SYMOP (IC_RESULT (ic)))
3387 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3388 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3391 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3395 /* if the condition of an if instruction
3396 is defined in the previous instruction then
3397 mark the itemp as a conditional */
3398 if ((IS_CONDITIONAL (ic) ||
3399 ((ic->op == BITWISEAND ||
3402 isBitwiseOptimizable (ic))) &&
3403 ic->next && ic->next->op == IFX &&
3404 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3405 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3408 debugLog (" %d\n", __LINE__);
3409 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3413 /* reduce for support function calls */
3414 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3415 packRegsForSupport (ic, ebp);
3417 /* if a parameter is passed, it's in W, so we may not
3418 need to place a copy in a register */
3419 if (ic->op == RECEIVE)
3420 packForReceive (ic, ebp);
3422 /* some cases the redundant moves can
3423 can be eliminated for return statements */
3424 if ((ic->op == RETURN || ic->op == SEND) &&
3425 !isOperandInFarSpace (IC_LEFT (ic)) &&
3427 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3429 /* if pointer set & left has a size more than
3430 one and right is not in far space */
3431 if (POINTER_SET (ic) &&
3432 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3433 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3434 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3435 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3437 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3439 /* if pointer get */
3440 if (POINTER_GET (ic) &&
3441 !isOperandInFarSpace (IC_RESULT (ic)) &&
3442 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3443 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3444 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3446 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3449 /* if this is cast for intergral promotion then
3450 check if only use of the definition of the
3451 operand being casted/ if yes then replace
3452 the result of that arithmetic operation with
3453 this result and get rid of the cast */
3454 if (ic->op == CAST) {
3456 sym_link *fromType = operandType (IC_RIGHT (ic));
3457 sym_link *toType = operandType (IC_LEFT (ic));
3459 debugLog (" %d - casting\n", __LINE__);
3461 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3462 getSize (fromType) != getSize (toType)) {
3465 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3468 if (IS_ARITHMETIC_OP (dic)) {
3470 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3471 IC_RESULT (dic) = IC_RESULT (ic);
3472 remiCodeFromeBBlock (ebp, ic);
3473 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3474 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3475 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3479 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3483 /* if the type from and type to are the same
3484 then if this is the only use then packit */
3485 if (compareType (operandType (IC_RIGHT (ic)),
3486 operandType (IC_LEFT (ic))) == 1) {
3488 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3491 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3492 IC_RESULT (dic) = IC_RESULT (ic);
3493 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3494 remiCodeFromeBBlock (ebp, ic);
3495 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3496 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3504 iTempNN := (some variable in farspace) V1
3509 if (ic->op == IPUSH)
3511 packForPush (ic, ebp);
3515 /* pack registers for accumulator use, when the
3516 result of an arithmetic or bit wise operation
3517 has only one use, that use is immediately following
3518 the defintion and the using iCode has only one
3519 operand or has two operands but one is literal &
3520 the result of that operation is not on stack then
3521 we can leave the result of this operation in acc:b
3523 if ((IS_ARITHMETIC_OP (ic)
3525 || IS_BITWISE_OP (ic)
3527 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3530 IS_ITEMP (IC_RESULT (ic)) &&
3531 getSize (operandType (IC_RESULT (ic))) <= 2)
3533 packRegsForAccUse (ic);
3539 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3543 if (!debug || !debugF)
3546 for (i = 0; i < count; i++)
3548 fprintf (debugF, "\n----------------------------------------------------------------\n");
3549 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3550 ebbs[i]->entryLabel->name,
3553 ebbs[i]->isLastInLoop);
3554 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3559 fprintf (debugF, "visited %d : hasFcall = %d\n",
3563 fprintf (debugF, "\ndefines bitVector :");
3564 bitVectDebugOn (ebbs[i]->defSet, debugF);
3565 fprintf (debugF, "\nlocal defines bitVector :");
3566 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3567 fprintf (debugF, "\npointers Set bitvector :");
3568 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3569 fprintf (debugF, "\nin pointers Set bitvector :");
3570 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3571 fprintf (debugF, "\ninDefs Set bitvector :");
3572 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3573 fprintf (debugF, "\noutDefs Set bitvector :");
3574 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3575 fprintf (debugF, "\nusesDefs Set bitvector :");
3576 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3577 fprintf (debugF, "\n----------------------------------------------------------------\n");
3578 printiCChain (ebbs[i]->sch, debugF);
3581 /*-----------------------------------------------------------------*/
3582 /* assignRegisters - assigns registers to each live range as need */
3583 /*-----------------------------------------------------------------*/
3585 pic14_assignRegisters (eBBlock ** ebbs, int count)
3590 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3591 debugLog ("\nebbs before optimizing:\n");
3592 dumpEbbsToDebug (ebbs, count);
3594 setToNull ((void *) &_G.funcrUsed);
3595 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3598 /* change assignments this will remove some
3599 live ranges reducing some register pressure */
3600 for (i = 0; i < count; i++)
3601 packRegisters (ebbs[i]);
3608 debugLog("dir registers allocated so far:\n");
3609 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3612 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3613 reg = hTabNextItem(dynDirectRegNames, &hkey);
3618 if (options.dump_pack)
3619 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3621 /* first determine for each live range the number of
3622 registers & the type of registers required for each */
3625 /* and serially allocate registers */
3626 serialRegAssign (ebbs, count);
3628 /* if stack was extended then tell the user */
3631 /* werror(W_TOOMANY_SPILS,"stack", */
3632 /* _G.stackExtend,currFunc->name,""); */
3638 /* werror(W_TOOMANY_SPILS,"data space", */
3639 /* _G.dataExtend,currFunc->name,""); */
3643 /* after that create the register mask
3644 for each of the instruction */
3645 createRegMask (ebbs, count);
3647 /* redo that offsets for stacked automatic variables */
3648 redoStackOffsets ();
3650 if (options.dump_rassgn)
3651 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3653 /* now get back the chain */
3654 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3656 debugLog ("ebbs after optimizing:\n");
3657 dumpEbbsToDebug (ebbs, count);
3662 /* free up any _G.stackSpil locations allocated */
3663 applyToSet (_G.stackSpil, deallocStackSpil);
3665 setToNull ((void **) &_G.stackSpil);
3666 setToNull ((void **) &_G.spiltSet);
3667 /* mark all registers as free */
3668 pic14_freeAllRegs ();
3670 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");