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 #define __FUNCTION__ __FILE__
35 /*-----------------------------------------------------------------*/
36 /* At this point we start getting processor specific although */
37 /* some routines are non-processor specific & can be reused when */
38 /* targetting other processors. The decision for this will have */
39 /* to be made on a routine by routine basis */
40 /* routines used to pack registers are most definitely not reusable */
41 /* since the pack the registers depending strictly on the MCU */
42 /*-----------------------------------------------------------------*/
44 extern void genpic14Code (iCode *);
54 bitVect *funcrUsed; /* registers used in a function */
60 /* Shared with gen.c */
61 int pic14_ptrRegReq; /* one byte pointer register required */
67 {REG_GPR, 0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0},
68 {REG_GPR, 0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0},
69 {REG_GPR, 0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0},
70 {REG_GPR, 0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0},
71 {REG_GPR, 0x10, "r0x10", "r0x10", 0x10, 1, 0},
72 {REG_GPR, 0x11, "r0x11", "r0x11", 0x11, 1, 0},
73 {REG_GPR, 0x12, "r0x12", "r0x12", 0x12, 1, 0},
74 {REG_GPR, 0x13, "r0x13", "r0x13", 0x13, 1, 0},
75 {REG_GPR, 0x14, "r0x14", "r0x14", 0x14, 1, 0},
76 {REG_GPR, 0x15, "r0x15", "r0x15", 0x15, 1, 0},
77 {REG_GPR, 0x16, "r0x16", "r0x16", 0x16, 1, 0},
78 {REG_GPR, 0x17, "r0x17", "r0x17", 0x17, 1, 0},
79 {REG_GPR, 0x18, "r0x18", "r0x18", 0x18, 1, 0},
80 {REG_GPR, 0x19, "r0x19", "r0x19", 0x19, 1, 0},
81 {REG_GPR, 0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0},
82 {REG_GPR, 0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0},
83 {REG_GPR, 0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0},
84 {REG_GPR, 0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0},
85 {REG_GPR, 0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0},
86 {REG_GPR, 0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0},
87 {REG_PTR, 4, "FSR", "FSR", 4, 1, 0},
91 int pic14_nRegs = sizeof (regspic14) / sizeof (regs);
92 static void spillThis (symbol *);
94 static FILE *debugF = NULL;
95 /*-----------------------------------------------------------------*/
96 /* debugLog - open a file for debugging information */
97 /*-----------------------------------------------------------------*/
98 //static void debugLog(char *inst,char *fmt, ...)
100 debugLog (char *fmt,...)
102 static int append = 0; // First time through, open the file without append.
105 //char *bufferP=buffer;
114 /* create the file name */
115 strcpy (buffer, srcFileName);
116 strcat (buffer, ".d");
118 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
120 werror (E_FILE_OPEN_ERR, buffer);
123 append = 1; // Next time debubLog is called, we'll append the debug info
129 vsprintf (buffer, fmt, ap);
131 fprintf (debugF, "%s", buffer);
133 while (isspace(*bufferP)) bufferP++;
135 if (bufferP && *bufferP)
136 lineCurr = (lineCurr ?
137 connectLine(lineCurr,newLineNode(lb)) :
138 (lineHead = newLineNode(lb)));
139 lineCurr->isInline = _G.inLine;
140 lineCurr->isDebug = _G.debugLine;
150 fputc ('\n', debugF);
152 /*-----------------------------------------------------------------*/
153 /* debugLogClose - closes the debug log file (if opened) */
154 /*-----------------------------------------------------------------*/
164 #define AOP(op) op->aop
167 debugAopGet (char *str, operand * op)
172 printOperand (op, debugF);
180 decodeOp (unsigned int op)
183 if (op < 128 && op > ' ')
185 buffer[0] = (op & 0xff);
199 return "STRING_LITERAL";
235 return "LEFT_ASSIGN";
237 return "RIGHT_ASSIGN";
366 case GET_VALUE_AT_ADDRESS:
367 return "GET_VALUE_AT_ADDRESS";
385 return "ENDFUNCTION";
409 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
412 /*-----------------------------------------------------------------*/
413 /*-----------------------------------------------------------------*/
415 debugLogRegType (short type)
428 sprintf (buffer, "unkown reg type %d", type);
432 /*-----------------------------------------------------------------*/
433 /* allocReg - allocates register of given type */
434 /*-----------------------------------------------------------------*/
436 allocReg (short type)
440 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
442 for (i = 0; i < pic14_nRegs; i++)
445 /* if type is given as 0 then any
446 free register will do */
450 regspic14[i].isFree = 0;
451 regspic14[i].wasUsed = 1;
454 bitVectSetBit (currFunc->regsUsed, i);
455 debugLog (" returning %s\n", regspic14[i].name);
456 return ®spic14[i];
458 /* other wise look for specific type
460 if (regspic14[i].isFree &&
461 regspic14[i].type == type)
463 regspic14[i].isFree = 0;
464 regspic14[i].wasUsed = 1;
467 bitVectSetBit (currFunc->regsUsed, i);
468 debugLog (" returning %s\n", regspic14[i].name);
469 return ®spic14[i];
475 /*-----------------------------------------------------------------*/
476 /* pic14_regWithIdx - returns pointer to register wit index number */
477 /*-----------------------------------------------------------------*/
479 pic14_regWithIdx (int idx)
483 debugLog ("%s\n", __FUNCTION__);
485 for (i = 0; i < pic14_nRegs; i++)
486 if (regspic14[i].rIdx == idx)
487 return ®spic14[i];
489 return ®spic14[0];
491 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
492 "regWithIdx not found");
496 /*-----------------------------------------------------------------*/
497 /*-----------------------------------------------------------------*/
499 pic14_findFreeReg(void)
503 for (i = 0; i < pic14_nRegs; i++)
504 if (regspic14[i].isFree)
505 return ®spic14[i];
509 /*-----------------------------------------------------------------*/
510 /* freeReg - frees a register */
511 /*-----------------------------------------------------------------*/
515 debugLog ("%s\n", __FUNCTION__);
520 /*-----------------------------------------------------------------*/
521 /* nFreeRegs - returns number of free registers */
522 /*-----------------------------------------------------------------*/
529 debugLog ("%s\n", __FUNCTION__);
530 for (i = 0; i < pic14_nRegs; i++)
531 if (regspic14[i].isFree && regspic14[i].type == type)
536 /*-----------------------------------------------------------------*/
537 /* nfreeRegsType - free registers with type */
538 /*-----------------------------------------------------------------*/
540 nfreeRegsType (int type)
543 debugLog ("%s\n", __FUNCTION__);
546 if ((nfr = nFreeRegs (type)) == 0)
547 return nFreeRegs (REG_GPR);
550 return nFreeRegs (type);
554 /*-----------------------------------------------------------------*/
555 /* allDefsOutOfRange - all definitions are out of a range */
556 /*-----------------------------------------------------------------*/
558 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
562 debugLog ("%s\n", __FUNCTION__);
566 for (i = 0; i < defs->size; i++)
570 if (bitVectBitValue (defs, i) &&
571 (ic = hTabItemWithKey (iCodehTab, i)) &&
572 (ic->seq >= fseq && ic->seq <= toseq))
581 /*-----------------------------------------------------------------*/
582 /* computeSpillable - given a point find the spillable live ranges */
583 /*-----------------------------------------------------------------*/
585 computeSpillable (iCode * ic)
589 debugLog ("%s\n", __FUNCTION__);
590 /* spillable live ranges are those that are live at this
591 point . the following categories need to be subtracted
593 a) - those that are already spilt
594 b) - if being used by this one
595 c) - defined by this one */
597 spillable = bitVectCopy (ic->rlive);
599 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
601 bitVectCplAnd (spillable, ic->uses); /* used in this one */
602 bitVectUnSetBit (spillable, ic->defKey);
603 spillable = bitVectIntersect (spillable, _G.regAssigned);
608 /*-----------------------------------------------------------------*/
609 /* noSpilLoc - return true if a variable has no spil location */
610 /*-----------------------------------------------------------------*/
612 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
614 debugLog ("%s\n", __FUNCTION__);
615 return (sym->usl.spillLoc ? 0 : 1);
618 /*-----------------------------------------------------------------*/
619 /* hasSpilLoc - will return 1 if the symbol has spil location */
620 /*-----------------------------------------------------------------*/
622 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
624 debugLog ("%s\n", __FUNCTION__);
625 return (sym->usl.spillLoc ? 1 : 0);
628 /*-----------------------------------------------------------------*/
629 /* directSpilLoc - will return 1 if the splilocation is in direct */
630 /*-----------------------------------------------------------------*/
632 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
634 debugLog ("%s\n", __FUNCTION__);
635 if (sym->usl.spillLoc &&
636 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
642 /*-----------------------------------------------------------------*/
643 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
644 /* but is not used as a pointer */
645 /*-----------------------------------------------------------------*/
647 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
649 debugLog ("%s\n", __FUNCTION__);
650 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
653 /*-----------------------------------------------------------------*/
654 /* rematable - will return 1 if the remat flag is set */
655 /*-----------------------------------------------------------------*/
657 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
659 debugLog ("%s\n", __FUNCTION__);
663 /*-----------------------------------------------------------------*/
664 /* notUsedInBlock - not used in this block */
665 /*-----------------------------------------------------------------*/
667 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
669 debugLog ("%s\n", __FUNCTION__);
670 return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
671 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
672 /* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
675 /*-----------------------------------------------------------------*/
676 /* notUsedInRemaining - not used or defined in remain of the block */
677 /*-----------------------------------------------------------------*/
679 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
681 debugLog ("%s\n", __FUNCTION__);
682 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
683 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
686 /*-----------------------------------------------------------------*/
687 /* allLRs - return true for all */
688 /*-----------------------------------------------------------------*/
690 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
692 debugLog ("%s\n", __FUNCTION__);
696 /*-----------------------------------------------------------------*/
697 /* liveRangesWith - applies function to a given set of live range */
698 /*-----------------------------------------------------------------*/
700 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
701 eBBlock * ebp, iCode * ic)
706 debugLog ("%s\n", __FUNCTION__);
707 if (!lrs || !lrs->size)
710 for (i = 1; i < lrs->size; i++)
713 if (!bitVectBitValue (lrs, i))
716 /* if we don't find it in the live range
717 hash table we are in serious trouble */
718 if (!(sym = hTabItemWithKey (liveRanges, i)))
720 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
721 "liveRangesWith could not find liveRange");
725 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
726 addSetHead (&rset, sym);
733 /*-----------------------------------------------------------------*/
734 /* leastUsedLR - given a set determines which is the least used */
735 /*-----------------------------------------------------------------*/
737 leastUsedLR (set * sset)
739 symbol *sym = NULL, *lsym = NULL;
741 debugLog ("%s\n", __FUNCTION__);
742 sym = lsym = setFirstItem (sset);
747 for (; lsym; lsym = setNextItem (sset))
750 /* if usage is the same then prefer
751 the spill the smaller of the two */
752 if (lsym->used == sym->used)
753 if (getSize (lsym->type) < getSize (sym->type))
757 if (lsym->used < sym->used)
762 setToNull ((void **) &sset);
767 /*-----------------------------------------------------------------*/
768 /* noOverLap - will iterate through the list looking for over lap */
769 /*-----------------------------------------------------------------*/
771 noOverLap (set * itmpStack, symbol * fsym)
774 debugLog ("%s\n", __FUNCTION__);
777 for (sym = setFirstItem (itmpStack); sym;
778 sym = setNextItem (itmpStack))
780 if (sym->liveTo > fsym->liveFrom)
788 /*-----------------------------------------------------------------*/
789 /* isFree - will return 1 if the a free spil location is found */
790 /*-----------------------------------------------------------------*/
795 V_ARG (symbol **, sloc);
796 V_ARG (symbol *, fsym);
798 debugLog ("%s\n", __FUNCTION__);
799 /* if already found */
803 /* if it is free && and the itmp assigned to
804 this does not have any overlapping live ranges
805 with the one currently being assigned and
806 the size can be accomodated */
808 noOverLap (sym->usl.itmpStack, fsym) &&
809 getSize (sym->type) >= getSize (fsym->type))
818 /*-----------------------------------------------------------------*/
819 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
820 /*-----------------------------------------------------------------*/
822 spillLRWithPtrReg (symbol * forSym)
828 debugLog ("%s\n", __FUNCTION__);
829 if (!_G.regAssigned ||
830 bitVectIsZero (_G.regAssigned))
833 r0 = pic14_regWithIdx (R0_IDX);
834 r1 = pic14_regWithIdx (R1_IDX);
836 /* for all live ranges */
837 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
838 lrsym = hTabNextItem (liveRanges, &k))
842 /* if no registers assigned to it or
844 /* if it does not overlap with this then
845 not need to spill it */
847 if (lrsym->isspilt || !lrsym->nRegs ||
848 (lrsym->liveTo < forSym->liveFrom))
851 /* go thru the registers : if it is either
852 r0 or r1 then spil it */
853 for (j = 0; j < lrsym->nRegs; j++)
854 if (lrsym->regs[j] == r0 ||
855 lrsym->regs[j] == r1)
864 /*-----------------------------------------------------------------*/
865 /* createStackSpil - create a location on the stack to spil */
866 /*-----------------------------------------------------------------*/
868 createStackSpil (symbol * sym)
871 int useXstack, model, noOverlay;
874 debugLog ("%s\n", __FUNCTION__);
876 /* first go try and find a free one that is already
877 existing on the stack */
878 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
880 /* found a free one : just update & return */
881 sym->usl.spillLoc = sloc;
884 addSetHead (&sloc->usl.itmpStack, sym);
888 /* could not then have to create one , this is the hard part
889 we need to allocate this on the stack : this is really a
890 hack!! but cannot think of anything better at this time */
892 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
894 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
899 sloc = newiTemp (slocBuffer);
901 /* set the type to the spilling symbol */
902 sloc->type = copyLinkChain (sym->type);
903 sloc->etype = getSpec (sloc->type);
904 SPEC_SCLS (sloc->etype) = S_DATA;
905 SPEC_EXTR (sloc->etype) = 0;
907 /* we don't allow it to be allocated`
908 onto the external stack since : so we
909 temporarily turn it off ; we also
910 turn off memory model to prevent
911 the spil from going to the external storage
912 and turn off overlaying
915 useXstack = options.useXstack;
916 model = options.model;
917 noOverlay = options.noOverlay;
918 options.noOverlay = 1;
919 options.model = options.useXstack = 0;
923 options.useXstack = useXstack;
924 options.model = model;
925 options.noOverlay = noOverlay;
926 sloc->isref = 1; /* to prevent compiler warning */
928 /* if it is on the stack then update the stack */
929 if (IN_STACK (sloc->etype))
931 currFunc->stack += getSize (sloc->type);
932 _G.stackExtend += getSize (sloc->type);
935 _G.dataExtend += getSize (sloc->type);
937 /* add it to the _G.stackSpil set */
938 addSetHead (&_G.stackSpil, sloc);
939 sym->usl.spillLoc = sloc;
942 /* add it to the set of itempStack set
943 of the spill location */
944 addSetHead (&sloc->usl.itmpStack, sym);
948 /*-----------------------------------------------------------------*/
949 /* isSpiltOnStack - returns true if the spil location is on stack */
950 /*-----------------------------------------------------------------*/
952 isSpiltOnStack (symbol * sym)
956 debugLog ("%s\n", __FUNCTION__);
963 /* if (sym->_G.stackSpil) */
966 if (!sym->usl.spillLoc)
969 etype = getSpec (sym->usl.spillLoc->type);
970 if (IN_STACK (etype))
976 /*-----------------------------------------------------------------*/
977 /* spillThis - spils a specific operand */
978 /*-----------------------------------------------------------------*/
980 spillThis (symbol * sym)
983 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
985 /* if this is rematerializable or has a spillLocation
986 we are okay, else we need to create a spillLocation
988 if (!(sym->remat || sym->usl.spillLoc))
989 createStackSpil (sym);
992 /* mark it has spilt & put it in the spilt set */
994 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
996 bitVectUnSetBit (_G.regAssigned, sym->key);
998 for (i = 0; i < sym->nRegs; i++)
1002 freeReg (sym->regs[i]);
1003 sym->regs[i] = NULL;
1006 /* if spilt on stack then free up r0 & r1
1007 if they could have been assigned to some
1009 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1012 spillLRWithPtrReg (sym);
1015 if (sym->usl.spillLoc && !sym->remat)
1016 sym->usl.spillLoc->allocreq = 1;
1020 /*-----------------------------------------------------------------*/
1021 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1022 /*-----------------------------------------------------------------*/
1024 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1026 bitVect *lrcs = NULL;
1030 debugLog ("%s\n", __FUNCTION__);
1031 /* get the spillable live ranges */
1032 lrcs = computeSpillable (ic);
1034 /* get all live ranges that are rematerizable */
1035 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1038 /* return the least used of these */
1039 return leastUsedLR (selectS);
1042 /* get live ranges with spillLocations in direct space */
1043 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1045 sym = leastUsedLR (selectS);
1046 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1047 sym->usl.spillLoc->rname :
1048 sym->usl.spillLoc->name));
1050 /* mark it as allocation required */
1051 sym->usl.spillLoc->allocreq = 1;
1055 /* if the symbol is local to the block then */
1056 if (forSym->liveTo < ebp->lSeq)
1059 /* check if there are any live ranges allocated
1060 to registers that are not used in this block */
1061 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1063 sym = leastUsedLR (selectS);
1064 /* if this is not rematerializable */
1073 /* check if there are any live ranges that not
1074 used in the remainder of the block */
1075 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1077 sym = leastUsedLR (selectS);
1080 sym->remainSpil = 1;
1087 /* find live ranges with spillocation && not used as pointers */
1088 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1091 sym = leastUsedLR (selectS);
1092 /* mark this as allocation required */
1093 sym->usl.spillLoc->allocreq = 1;
1097 /* find live ranges with spillocation */
1098 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1101 sym = leastUsedLR (selectS);
1102 sym->usl.spillLoc->allocreq = 1;
1106 /* couldn't find then we need to create a spil
1107 location on the stack , for which one? the least
1109 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1112 /* return a created spil location */
1113 sym = createStackSpil (leastUsedLR (selectS));
1114 sym->usl.spillLoc->allocreq = 1;
1118 /* this is an extreme situation we will spill
1119 this one : happens very rarely but it does happen */
1125 /*-----------------------------------------------------------------*/
1126 /* spilSomething - spil some variable & mark registers as free */
1127 /*-----------------------------------------------------------------*/
1129 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1134 debugLog ("%s\n", __FUNCTION__);
1135 /* get something we can spil */
1136 ssym = selectSpil (ic, ebp, forSym);
1138 /* mark it as spilt */
1140 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1142 /* mark it as not register assigned &
1143 take it away from the set */
1144 bitVectUnSetBit (_G.regAssigned, ssym->key);
1146 /* mark the registers as free */
1147 for (i = 0; i < ssym->nRegs; i++)
1149 freeReg (ssym->regs[i]);
1151 /* if spilt on stack then free up r0 & r1
1152 if they could have been assigned to as gprs */
1153 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1156 spillLRWithPtrReg (ssym);
1159 /* if this was a block level spil then insert push & pop
1160 at the start & end of block respectively */
1161 if (ssym->blockSpil)
1163 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1164 /* add push to the start of the block */
1165 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1166 ebp->sch->next : ebp->sch));
1167 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1168 /* add pop to the end of the block */
1169 addiCodeToeBBlock (ebp, nic, NULL);
1172 /* if spilt because not used in the remainder of the
1173 block then add a push before this instruction and
1174 a pop at the end of the block */
1175 if (ssym->remainSpil)
1178 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1179 /* add push just before this instruction */
1180 addiCodeToeBBlock (ebp, nic, ic);
1182 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1183 /* add pop to the end of the block */
1184 addiCodeToeBBlock (ebp, nic, NULL);
1193 /*-----------------------------------------------------------------*/
1194 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1195 /*-----------------------------------------------------------------*/
1197 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1201 debugLog ("%s\n", __FUNCTION__);
1203 /* try for a ptr type */
1204 if ((reg = allocReg (REG_PTR)))
1207 /* try for gpr type */
1208 if ((reg = allocReg (REG_GPR)))
1211 /* we have to spil */
1212 if (!spilSomething (ic, ebp, sym))
1215 /* this looks like an infinite loop but
1216 in really selectSpil will abort */
1220 /*-----------------------------------------------------------------*/
1221 /* getRegGpr - will try for GPR if not spil */
1222 /*-----------------------------------------------------------------*/
1224 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1228 debugLog ("%s\n", __FUNCTION__);
1230 /* try for gpr type */
1231 if ((reg = allocReg (REG_GPR)))
1234 if (!pic14_ptrRegReq)
1235 if ((reg = allocReg (REG_PTR)))
1238 /* we have to spil */
1239 if (!spilSomething (ic, ebp, sym))
1242 /* this looks like an infinite loop but
1243 in really selectSpil will abort */
1247 /*-----------------------------------------------------------------*/
1248 /* symHasReg - symbol has a given register */
1249 /*-----------------------------------------------------------------*/
1251 symHasReg (symbol * sym, regs * reg)
1255 debugLog ("%s\n", __FUNCTION__);
1256 for (i = 0; i < sym->nRegs; i++)
1257 if (sym->regs[i] == reg)
1263 /*-----------------------------------------------------------------*/
1264 /* deassignLRs - check the live to and if they have registers & are */
1265 /* not spilt then free up the registers */
1266 /*-----------------------------------------------------------------*/
1268 deassignLRs (iCode * ic, eBBlock * ebp)
1274 debugLog ("%s\n", __FUNCTION__);
1275 for (sym = hTabFirstItem (liveRanges, &k); sym;
1276 sym = hTabNextItem (liveRanges, &k))
1279 symbol *psym = NULL;
1280 /* if it does not end here */
1281 if (sym->liveTo > ic->seq)
1284 /* if it was spilt on stack then we can
1285 mark the stack spil location as free */
1290 sym->usl.spillLoc->isFree = 1;
1296 if (!bitVectBitValue (_G.regAssigned, sym->key))
1299 /* special case check if this is an IFX &
1300 the privious one was a pop and the
1301 previous one was not spilt then keep track
1303 if (ic->op == IFX && ic->prev &&
1304 ic->prev->op == IPOP &&
1305 !ic->prev->parmPush &&
1306 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1307 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1313 bitVectUnSetBit (_G.regAssigned, sym->key);
1315 /* if the result of this one needs registers
1316 and does not have it then assign it right
1318 if (IC_RESULT (ic) &&
1319 !(SKIP_IC2 (ic) || /* not a special icode */
1320 ic->op == JUMPTABLE ||
1325 POINTER_SET (ic)) &&
1326 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1327 result->liveTo > ic->seq && /* and will live beyond this */
1328 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1329 result->regType == sym->regType && /* same register types */
1330 result->nRegs && /* which needs registers */
1331 !result->isspilt && /* and does not already have them */
1333 !bitVectBitValue (_G.regAssigned, result->key) &&
1334 /* the number of free regs + number of regs in this LR
1335 can accomodate the what result Needs */
1336 ((nfreeRegsType (result->regType) +
1337 sym->nRegs) >= result->nRegs)
1341 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1343 result->regs[i] = sym->regs[i];
1345 result->regs[i] = getRegGpr (ic, ebp, result);
1347 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1351 /* free the remaining */
1352 for (; i < sym->nRegs; i++)
1356 if (!symHasReg (psym, sym->regs[i]))
1357 freeReg (sym->regs[i]);
1360 freeReg (sym->regs[i]);
1367 /*-----------------------------------------------------------------*/
1368 /* reassignLR - reassign this to registers */
1369 /*-----------------------------------------------------------------*/
1371 reassignLR (operand * op)
1373 symbol *sym = OP_SYMBOL (op);
1376 debugLog ("%s\n", __FUNCTION__);
1377 /* not spilt any more */
1378 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1379 bitVectUnSetBit (_G.spiltSet, sym->key);
1381 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1385 for (i = 0; i < sym->nRegs; i++)
1386 sym->regs[i]->isFree = 0;
1389 /*-----------------------------------------------------------------*/
1390 /* willCauseSpill - determines if allocating will cause a spill */
1391 /*-----------------------------------------------------------------*/
1393 willCauseSpill (int nr, int rt)
1395 debugLog ("%s\n", __FUNCTION__);
1396 /* first check if there are any avlb registers
1397 of te type required */
1400 /* special case for pointer type
1401 if pointer type not avlb then
1402 check for type gpr */
1403 if (nFreeRegs (rt) >= nr)
1405 if (nFreeRegs (REG_GPR) >= nr)
1410 if (pic14_ptrRegReq)
1412 if (nFreeRegs (rt) >= nr)
1417 if (nFreeRegs (REG_PTR) +
1418 nFreeRegs (REG_GPR) >= nr)
1423 debugLog (" ... yep it will (cause a spill)\n");
1424 /* it will cause a spil */
1428 /*-----------------------------------------------------------------*/
1429 /* positionRegs - the allocator can allocate same registers to res- */
1430 /* ult and operand, if this happens make sure they are in the same */
1431 /* position as the operand otherwise chaos results */
1432 /*-----------------------------------------------------------------*/
1434 positionRegs (symbol * result, symbol * opsym, int lineno)
1436 int count = min (result->nRegs, opsym->nRegs);
1437 int i, j = 0, shared = 0;
1439 debugLog ("%s\n", __FUNCTION__);
1440 /* if the result has been spilt then cannot share */
1445 /* first make sure that they actually share */
1446 for (i = 0; i < count; i++)
1448 for (j = 0; j < count; j++)
1450 if (result->regs[i] == opsym->regs[j] && i != j)
1460 regs *tmp = result->regs[i];
1461 result->regs[i] = result->regs[j];
1462 result->regs[j] = tmp;
1467 /*-----------------------------------------------------------------*/
1468 /* serialRegAssign - serially allocate registers to the variables */
1469 /*-----------------------------------------------------------------*/
1471 serialRegAssign (eBBlock ** ebbs, int count)
1475 debugLog ("%s\n", __FUNCTION__);
1476 /* for all blocks */
1477 for (i = 0; i < count; i++)
1482 if (ebbs[i]->noPath &&
1483 (ebbs[i]->entryLabel != entryLabel &&
1484 ebbs[i]->entryLabel != returnLabel))
1487 /* of all instructions do */
1488 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1491 debugLog (" op: %s\n", decodeOp (ic->op));
1493 /* if this is an ipop that means some live
1494 range will have to be assigned again */
1496 reassignLR (IC_LEFT (ic));
1498 /* if result is present && is a true symbol */
1499 if (IC_RESULT (ic) && ic->op != IFX &&
1500 IS_TRUE_SYMOP (IC_RESULT (ic)))
1501 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1503 /* take away registers from live
1504 ranges that end at this instruction */
1505 deassignLRs (ic, ebbs[i]);
1507 /* some don't need registers */
1508 if (SKIP_IC2 (ic) ||
1509 ic->op == JUMPTABLE ||
1513 (IC_RESULT (ic) && POINTER_SET (ic)))
1516 /* now we need to allocate registers
1517 only for the result */
1520 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1526 /* if it does not need or is spilt
1527 or is already assigned to registers
1528 or will not live beyond this instructions */
1531 bitVectBitValue (_G.regAssigned, sym->key) ||
1532 sym->liveTo <= ic->seq)
1535 /* if some liverange has been spilt at the block level
1536 and this one live beyond this block then spil this
1538 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1543 /* if trying to allocate this will cause
1544 a spill and there is nothing to spill
1545 or this one is rematerializable then
1547 willCS = willCauseSpill (sym->nRegs, sym->regType);
1548 spillable = computeSpillable (ic);
1550 (willCS && bitVectIsZero (spillable)))
1558 /* if it has a spillocation & is used less than
1559 all other live ranges then spill this */
1560 if (willCS && sym->usl.spillLoc)
1564 leastUsedLR (liveRangesWith (spillable,
1569 leastUsed->used > sym->used)
1576 if (ic->op == RECEIVE)
1577 debugLog ("When I get clever, I'll optimize the receive logic\n");
1579 /* if we need ptr regs for the right side
1581 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
1587 /* else we assign registers to it */
1588 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1590 debugLog (" %d - \n", __LINE__);
1592 for (j = 0; j < sym->nRegs; j++)
1594 if (sym->regType == REG_PTR)
1595 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1597 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1599 /* if the allocation falied which means
1600 this was spilt then break */
1604 debugLog (" %d - \n", __LINE__);
1606 /* if it shares registers with operands make sure
1607 that they are in the same position */
1608 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1609 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1610 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1611 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1612 /* do the same for the right operand */
1613 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1614 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
1615 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1616 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1618 debugLog (" %d - \n", __LINE__);
1621 debugLog (" %d - \n", __LINE__);
1631 /*-----------------------------------------------------------------*/
1632 /* rUmaskForOp :- returns register mask for an operand */
1633 /*-----------------------------------------------------------------*/
1635 rUmaskForOp (operand * op)
1641 debugLog ("%s\n", __FUNCTION__);
1642 /* only temporaries are assigned registers */
1646 sym = OP_SYMBOL (op);
1648 /* if spilt or no registers assigned to it
1650 if (sym->isspilt || !sym->nRegs)
1653 rumask = newBitVect (pic14_nRegs);
1655 for (j = 0; j < sym->nRegs; j++)
1657 rumask = bitVectSetBit (rumask,
1658 sym->regs[j]->rIdx);
1664 /*-----------------------------------------------------------------*/
1665 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1666 /*-----------------------------------------------------------------*/
1668 regsUsedIniCode (iCode * ic)
1670 bitVect *rmask = newBitVect (pic14_nRegs);
1672 debugLog ("%s\n", __FUNCTION__);
1673 /* do the special cases first */
1676 rmask = bitVectUnion (rmask,
1677 rUmaskForOp (IC_COND (ic)));
1681 /* for the jumptable */
1682 if (ic->op == JUMPTABLE)
1684 rmask = bitVectUnion (rmask,
1685 rUmaskForOp (IC_JTCOND (ic)));
1690 /* of all other cases */
1692 rmask = bitVectUnion (rmask,
1693 rUmaskForOp (IC_LEFT (ic)));
1697 rmask = bitVectUnion (rmask,
1698 rUmaskForOp (IC_RIGHT (ic)));
1701 rmask = bitVectUnion (rmask,
1702 rUmaskForOp (IC_RESULT (ic)));
1708 /*-----------------------------------------------------------------*/
1709 /* createRegMask - for each instruction will determine the regsUsed */
1710 /*-----------------------------------------------------------------*/
1712 createRegMask (eBBlock ** ebbs, int count)
1716 debugLog ("%s\n", __FUNCTION__);
1717 /* for all blocks */
1718 for (i = 0; i < count; i++)
1722 if (ebbs[i]->noPath &&
1723 (ebbs[i]->entryLabel != entryLabel &&
1724 ebbs[i]->entryLabel != returnLabel))
1727 /* for all instructions */
1728 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1733 if (SKIP_IC2 (ic) || !ic->rlive)
1736 /* first mark the registers used in this
1738 ic->rUsed = regsUsedIniCode (ic);
1739 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1741 /* now create the register mask for those
1742 registers that are in use : this is a
1743 super set of ic->rUsed */
1744 ic->rMask = newBitVect (pic14_nRegs + 1);
1746 /* for all live Ranges alive at this point */
1747 for (j = 1; j < ic->rlive->size; j++)
1752 /* if not alive then continue */
1753 if (!bitVectBitValue (ic->rlive, j))
1756 /* find the live range we are interested in */
1757 if (!(sym = hTabItemWithKey (liveRanges, j)))
1759 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1760 "createRegMask cannot find live range");
1764 /* if no register assigned to it */
1765 if (!sym->nRegs || sym->isspilt)
1768 /* for all the registers allocated to it */
1769 for (k = 0; k < sym->nRegs; k++)
1772 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1778 /*-----------------------------------------------------------------*/
1779 /* rematStr - returns the rematerialized string for a remat var */
1780 /*-----------------------------------------------------------------*/
1782 rematStr (symbol * sym)
1785 iCode *ic = sym->rematiCode;
1787 debugLog ("%s\n", __FUNCTION__);
1792 /* if plus or minus print the right hand side */
1794 if (ic->op == '+' || ic->op == '-') {
1795 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1798 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1802 if (ic->op == '+' || ic->op == '-')
1804 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1805 sprintf (s, "(%s %c 0x%04x)",
1806 OP_SYMBOL (IC_LEFT (ric))->rname,
1808 (int) operandLitValue (IC_RIGHT (ic)));
1811 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1816 /* we reached the end */
1817 sprintf (s, "%s\n", OP_SYMBOL (IC_LEFT (ic))->rname);
1821 printf ("%s\n", buffer);
1825 /*-----------------------------------------------------------------*/
1826 /* regTypeNum - computes the type & number of registers required */
1827 /*-----------------------------------------------------------------*/
1835 debugLog ("%s\n", __FUNCTION__);
1836 /* for each live range do */
1837 for (sym = hTabFirstItem (liveRanges, &k); sym;
1838 sym = hTabNextItem (liveRanges, &k))
1841 debugLog (" %d - %s\n", __LINE__, sym->rname);
1843 /* if used zero times then no registers needed */
1844 if ((sym->liveTo - sym->liveFrom) == 0)
1848 /* if the live range is a temporary */
1852 debugLog (" %d - \n", __LINE__);
1854 /* if the type is marked as a conditional */
1855 if (sym->regType == REG_CND)
1858 /* if used in return only then we don't
1860 if (sym->ruonly || sym->accuse)
1862 if (IS_AGGREGATE (sym->type) || sym->isptr)
1863 sym->type = aggrToPtr (sym->type, FALSE);
1864 debugLog (" %d - \n", __LINE__);
1869 /* if the symbol has only one definition &
1870 that definition is a get_pointer and the
1871 pointer we are getting is rematerializable and
1874 if (bitVectnBitsOn (sym->defs) == 1 &&
1875 (ic = hTabItemWithKey (iCodehTab,
1876 bitVectFirstBit (sym->defs))) &&
1878 !IS_BITVAR (sym->etype))
1881 debugLog (" %d - \n", __LINE__);
1883 /* if remat in data space */
1884 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1885 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1888 /* create a psuedo symbol & force a spil */
1889 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1890 psym->type = sym->type;
1891 psym->etype = sym->etype;
1892 strcpy (psym->rname, psym->name);
1894 sym->usl.spillLoc = psym;
1898 /* if in data space or idata space then try to
1899 allocate pointer register */
1903 /* if not then we require registers */
1904 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1905 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1906 getSize (sym->type));
1910 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1911 printTypeChain (sym->type, stderr);
1912 fprintf (stderr, "\n");
1915 debugLog (" %d - \n", __LINE__);
1917 /* determine the type of register required */
1918 if (sym->nRegs == 1 &&
1919 IS_PTR (sym->type) &&
1921 sym->regType = REG_PTR;
1923 sym->regType = REG_GPR;
1924 debugLog (" reg type %s\n", debugLogRegType (sym->regType));
1928 /* for the first run we don't provide */
1929 /* registers for true symbols we will */
1930 /* see how things go */
1936 /*-----------------------------------------------------------------*/
1937 /* freeAllRegs - mark all registers as free */
1938 /*-----------------------------------------------------------------*/
1940 pic14_freeAllRegs ()
1944 debugLog ("%s\n", __FUNCTION__);
1945 for (i = 0; i < pic14_nRegs; i++)
1946 regspic14[i].isFree = 1;
1949 /*-----------------------------------------------------------------*/
1950 /*-----------------------------------------------------------------*/
1952 pic14_deallocateAllRegs ()
1956 debugLog ("%s\n", __FUNCTION__);
1957 for (i = 0; i < pic14_nRegs; i++) {
1958 regspic14[i].isFree = 1;
1959 regspic14[i].wasUsed = 0;
1964 /*-----------------------------------------------------------------*/
1965 /* deallocStackSpil - this will set the stack pointer back */
1966 /*-----------------------------------------------------------------*/
1968 DEFSETFUNC (deallocStackSpil)
1972 debugLog ("%s\n", __FUNCTION__);
1977 /*-----------------------------------------------------------------*/
1978 /* farSpacePackable - returns the packable icode for far variables */
1979 /*-----------------------------------------------------------------*/
1981 farSpacePackable (iCode * ic)
1985 debugLog ("%s\n", __FUNCTION__);
1986 /* go thru till we find a definition for the
1987 symbol on the right */
1988 for (dic = ic->prev; dic; dic = dic->prev)
1991 /* if the definition is a call then no */
1992 if ((dic->op == CALL || dic->op == PCALL) &&
1993 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1998 /* if shift by unknown amount then not */
1999 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2000 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2003 /* if pointer get and size > 1 */
2004 if (POINTER_GET (dic) &&
2005 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2008 if (POINTER_SET (dic) &&
2009 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2012 /* if any three is a true symbol in far space */
2013 if (IC_RESULT (dic) &&
2014 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2015 isOperandInFarSpace (IC_RESULT (dic)))
2018 if (IC_RIGHT (dic) &&
2019 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2020 isOperandInFarSpace (IC_RIGHT (dic)) &&
2021 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2024 if (IC_LEFT (dic) &&
2025 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2026 isOperandInFarSpace (IC_LEFT (dic)) &&
2027 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2030 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2032 if ((dic->op == LEFT_OP ||
2033 dic->op == RIGHT_OP ||
2035 IS_OP_LITERAL (IC_RIGHT (dic)))
2045 /*-----------------------------------------------------------------*/
2046 /* packRegsForAssign - register reduction for assignment */
2047 /*-----------------------------------------------------------------*/
2049 packRegsForAssign (iCode * ic, eBBlock * ebp)
2054 debugLog ("%s\n", __FUNCTION__);
2056 debugAopGet (" result:", IC_RESULT (ic));
2057 debugAopGet (" left:", IC_LEFT (ic));
2058 debugAopGet (" right:", IC_RIGHT (ic));
2060 if (!IS_ITEMP (IC_RIGHT (ic)) ||
2061 OP_SYMBOL (IC_RIGHT (ic))->isind ||
2062 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2067 /* if the true symbol is defined in far space or on stack
2068 then we should not since this will increase register pressure */
2069 if (isOperandInFarSpace (IC_RESULT (ic)))
2071 if ((dic = farSpacePackable (ic)))
2077 /* find the definition of iTempNN scanning backwards if we find a
2078 a use of the true symbol before we find the definition then
2080 for (dic = ic->prev; dic; dic = dic->prev)
2083 /* if there is a function call and this is
2084 a parameter & not my parameter then don't pack it */
2085 if ((dic->op == CALL || dic->op == PCALL) &&
2086 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2087 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2089 debugLog (" %d - \n", __LINE__);
2097 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2098 IS_OP_VOLATILE (IC_RESULT (dic)))
2100 debugLog (" %d - \n", __LINE__);
2105 if (IS_SYMOP (IC_RESULT (dic)) &&
2106 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2108 debugLog (" %d - dic key == ic key -- pointer set=%c\n", __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2109 if (POINTER_SET (dic))
2115 if (IS_SYMOP (IC_RIGHT (dic)) &&
2116 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2117 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2119 debugLog (" %d - \n", __LINE__);
2124 if (IS_SYMOP (IC_LEFT (dic)) &&
2125 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2126 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2128 debugLog (" %d - \n", __LINE__);
2133 if (POINTER_SET (dic) &&
2134 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2136 debugLog (" %d - \n", __LINE__);
2143 return 0; /* did not find */
2145 /* if the result is on stack or iaccess then it must be
2146 the same atleast one of the operands */
2147 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2148 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2151 /* the operation has only one symbol
2152 operator then we can pack */
2153 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2154 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2157 if (!((IC_LEFT (dic) &&
2158 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2160 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2164 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2165 /* found the definition */
2166 /* replace the result with the result of */
2167 /* this assignment and remove this assignment */
2168 IC_RESULT (dic) = IC_RESULT (ic);
2170 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2172 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2174 /* delete from liverange table also
2175 delete from all the points inbetween and the new
2177 for (sic = dic; sic != ic; sic = sic->next)
2179 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2180 if (IS_ITEMP (IC_RESULT (dic)))
2181 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2184 remiCodeFromeBBlock (ebp, ic);
2185 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2186 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2192 /*-----------------------------------------------------------------*/
2193 /* findAssignToSym : scanning backwards looks for first assig found */
2194 /*-----------------------------------------------------------------*/
2196 findAssignToSym (operand * op, iCode * ic)
2200 debugLog ("%s\n", __FUNCTION__);
2201 for (dic = ic->prev; dic; dic = dic->prev)
2204 /* if definition by assignment */
2205 if (dic->op == '=' &&
2206 !POINTER_SET (dic) &&
2207 IC_RESULT (dic)->key == op->key
2208 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2212 /* we are interested only if defined in far space */
2213 /* or in stack space in case of + & - */
2215 /* if assigned to a non-symbol then return
2217 if (!IS_SYMOP (IC_RIGHT (dic)))
2220 /* if the symbol is in far space then
2222 if (isOperandInFarSpace (IC_RIGHT (dic)))
2225 /* for + & - operations make sure that
2226 if it is on the stack it is the same
2227 as one of the three operands */
2228 if ((ic->op == '+' || ic->op == '-') &&
2229 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2232 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2233 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2234 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2242 /* if we find an usage then we cannot delete it */
2243 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2246 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2249 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2253 /* now make sure that the right side of dic
2254 is not defined between ic & dic */
2257 iCode *sic = dic->next;
2259 for (; sic != ic; sic = sic->next)
2260 if (IC_RESULT (sic) &&
2261 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2270 /*-----------------------------------------------------------------*/
2271 /* packRegsForSupport :- reduce some registers for support calls */
2272 /*-----------------------------------------------------------------*/
2274 packRegsForSupport (iCode * ic, eBBlock * ebp)
2278 debugLog ("%s\n", __FUNCTION__);
2279 /* for the left & right operand :- look to see if the
2280 left was assigned a true symbol in far space in that
2281 case replace them */
2282 if (IS_ITEMP (IC_LEFT (ic)) &&
2283 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2285 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2291 debugAopGet ("removing left:", IC_LEFT (ic));
2293 /* found it we need to remove it from the
2295 for (sic = dic; sic != ic; sic = sic->next)
2296 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2298 IC_LEFT (ic)->operand.symOperand =
2299 IC_RIGHT (dic)->operand.symOperand;
2300 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2301 remiCodeFromeBBlock (ebp, dic);
2302 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2306 /* do the same for the right operand */
2309 IS_ITEMP (IC_RIGHT (ic)) &&
2310 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2312 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2318 /* if this is a subtraction & the result
2319 is a true symbol in far space then don't pack */
2320 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2322 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2323 if (IN_FARSPACE (SPEC_OCLS (etype)))
2327 debugAopGet ("removing right:", IC_RIGHT (ic));
2329 /* found it we need to remove it from the
2331 for (sic = dic; sic != ic; sic = sic->next)
2332 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2334 IC_RIGHT (ic)->operand.symOperand =
2335 IC_RIGHT (dic)->operand.symOperand;
2336 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2338 remiCodeFromeBBlock (ebp, dic);
2339 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2346 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2349 /*-----------------------------------------------------------------*/
2350 /* packRegsForOneuse : - will reduce some registers for single Use */
2351 /*-----------------------------------------------------------------*/
2353 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2358 debugLog ("%s\n", __FUNCTION__);
2359 /* if returning a literal then do nothing */
2363 /* only upto 2 bytes since we cannot predict
2364 the usage of b, & acc */
2365 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2370 /* this routine will mark the a symbol as used in one
2371 instruction use only && if the definition is local
2372 (ie. within the basic block) && has only one definition &&
2373 that definition is either a return value from a
2374 function or does not contain any variables in
2376 uses = bitVectCopy (OP_USES (op));
2377 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2378 if (!bitVectIsZero (uses)) /* has other uses */
2381 /* if it has only one defintion */
2382 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2383 return NULL; /* has more than one definition */
2385 /* get that definition */
2387 hTabItemWithKey (iCodehTab,
2388 bitVectFirstBit (OP_DEFS (op)))))
2391 /* found the definition now check if it is local */
2392 if (dic->seq < ebp->fSeq ||
2393 dic->seq > ebp->lSeq)
2394 return NULL; /* non-local */
2396 /* now check if it is the return from
2398 if (dic->op == CALL || dic->op == PCALL)
2400 if (ic->op != SEND && ic->op != RETURN)
2402 OP_SYMBOL (op)->ruonly = 1;
2409 /* otherwise check that the definition does
2410 not contain any symbols in far space */
2411 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2412 isOperandInFarSpace (IC_RIGHT (dic)) ||
2413 IS_OP_RUONLY (IC_LEFT (ic)) ||
2414 IS_OP_RUONLY (IC_RIGHT (ic)))
2419 /* if pointer set then make sure the pointer
2421 if (POINTER_SET (dic) &&
2422 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2425 if (POINTER_GET (dic) &&
2426 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2431 /* also make sure the intervenening instructions
2432 don't have any thing in far space */
2433 for (dic = dic->next; dic && dic != ic; dic = dic->next)
2436 /* if there is an intervening function call then no */
2437 if (dic->op == CALL || dic->op == PCALL)
2439 /* if pointer set then make sure the pointer
2441 if (POINTER_SET (dic) &&
2442 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2445 if (POINTER_GET (dic) &&
2446 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2449 /* if address of & the result is remat then okay */
2450 if (dic->op == ADDRESS_OF &&
2451 OP_SYMBOL (IC_RESULT (dic))->remat)
2454 /* if operand has size of three or more & this
2455 operation is a '*','/' or '%' then 'b' may
2457 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2458 getSize (operandType (op)) >= 3)
2461 /* if left or right or result is in far space */
2462 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2463 isOperandInFarSpace (IC_RIGHT (dic)) ||
2464 isOperandInFarSpace (IC_RESULT (dic)) ||
2465 IS_OP_RUONLY (IC_LEFT (dic)) ||
2466 IS_OP_RUONLY (IC_RIGHT (dic)) ||
2467 IS_OP_RUONLY (IC_RESULT (dic)))
2473 OP_SYMBOL (op)->ruonly = 1;
2478 /*-----------------------------------------------------------------*/
2479 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2480 /*-----------------------------------------------------------------*/
2482 isBitwiseOptimizable (iCode * ic)
2484 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2485 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2487 debugLog ("%s\n", __FUNCTION__);
2488 /* bitwise operations are considered optimizable
2489 under the following conditions (Jean-Louis VERN)
2501 if (IS_LITERAL (rtype) ||
2502 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2508 /*-----------------------------------------------------------------*/
2509 /* packRegsForAccUse - pack registers for acc use */
2510 /*-----------------------------------------------------------------*/
2512 packRegsForAccUse (iCode * ic)
2516 debugLog ("%s\n", __FUNCTION__);
2517 /* if + or - then it has to be one byte result */
2518 if ((ic->op == '+' || ic->op == '-')
2519 && getSize (operandType (IC_RESULT (ic))) > 1)
2522 /* if shift operation make sure right side is not a literal */
2523 if (ic->op == RIGHT_OP &&
2524 (isOperandLiteral (IC_RIGHT (ic)) ||
2525 getSize (operandType (IC_RESULT (ic))) > 1))
2528 if (ic->op == LEFT_OP &&
2529 (isOperandLiteral (IC_RIGHT (ic)) ||
2530 getSize (operandType (IC_RESULT (ic))) > 1))
2533 if (IS_BITWISE_OP (ic) &&
2534 getSize (operandType (IC_RESULT (ic))) > 1)
2538 /* has only one definition */
2539 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2542 /* has only one use */
2543 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2546 /* and the usage immediately follows this iCode */
2547 if (!(uic = hTabItemWithKey (iCodehTab,
2548 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2551 if (ic->next != uic)
2554 /* if it is a conditional branch then we definitely can */
2558 if (uic->op == JUMPTABLE)
2561 /* if the usage is not is an assignment
2562 or an arithmetic / bitwise / shift operation then not */
2563 if (POINTER_SET (uic) &&
2564 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2567 if (uic->op != '=' &&
2568 !IS_ARITHMETIC_OP (uic) &&
2569 !IS_BITWISE_OP (uic) &&
2570 uic->op != LEFT_OP &&
2571 uic->op != RIGHT_OP)
2574 /* if used in ^ operation then make sure right is not a
2576 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2579 /* if shift operation make sure right side is not a literal */
2580 if (uic->op == RIGHT_OP &&
2581 (isOperandLiteral (IC_RIGHT (uic)) ||
2582 getSize (operandType (IC_RESULT (uic))) > 1))
2585 if (uic->op == LEFT_OP &&
2586 (isOperandLiteral (IC_RIGHT (uic)) ||
2587 getSize (operandType (IC_RESULT (uic))) > 1))
2590 /* make sure that the result of this icode is not on the
2591 stack, since acc is used to compute stack offset */
2592 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2593 OP_SYMBOL (IC_RESULT (uic))->onStack)
2596 /* if either one of them in far space then we cannot */
2597 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2598 isOperandInFarSpace (IC_LEFT (uic))) ||
2599 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2600 isOperandInFarSpace (IC_RIGHT (uic))))
2603 /* if the usage has only one operand then we can */
2604 if (IC_LEFT (uic) == NULL ||
2605 IC_RIGHT (uic) == NULL)
2608 /* make sure this is on the left side if not
2609 a '+' since '+' is commutative */
2610 if (ic->op != '+' &&
2611 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2614 /* if one of them is a literal then we can */
2615 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2616 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2618 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2622 /* if the other one is not on stack then we can */
2623 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2624 (IS_ITEMP (IC_RIGHT (uic)) ||
2625 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2626 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2629 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2630 (IS_ITEMP (IC_LEFT (uic)) ||
2631 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2632 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2638 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2643 /*-----------------------------------------------------------------*/
2644 /* packForPush - hueristics to reduce iCode for pushing */
2645 /*-----------------------------------------------------------------*/
2647 packForReceive (iCode * ic, eBBlock * ebp)
2650 bool can_remove = 1; // assume that we can remove temporary
2652 debugLog ("%s\n", __FUNCTION__);
2653 debugAopGet (" result:", IC_RESULT (ic));
2654 debugAopGet (" left:", IC_LEFT (ic));
2655 debugAopGet (" right:", IC_RIGHT (ic));
2660 for (dic = ic->next; dic; dic = dic->next)
2665 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
2666 debugLog (" used on left\n");
2667 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
2668 debugLog (" used on right\n");
2669 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
2670 debugLog (" used on result\n");
2672 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
2673 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
2678 debugLog (" hey we can remove this unnecessary assign\n");
2680 /*-----------------------------------------------------------------*/
2681 /* packForPush - hueristics to reduce iCode for pushing */
2682 /*-----------------------------------------------------------------*/
2684 packForPush (iCode * ic, eBBlock * ebp)
2688 debugLog ("%s\n", __FUNCTION__);
2689 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2692 /* must have only definition & one usage */
2693 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2694 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2697 /* find the definition */
2698 if (!(dic = hTabItemWithKey (iCodehTab,
2699 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2702 if (dic->op != '=' || POINTER_SET (dic))
2705 /* we now we know that it has one & only one def & use
2706 and the that the definition is an assignment */
2707 IC_LEFT (ic) = IC_RIGHT (dic);
2709 remiCodeFromeBBlock (ebp, dic);
2710 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2713 /*-----------------------------------------------------------------*/
2714 /* packRegisters - does some transformations to reduce register */
2716 /*-----------------------------------------------------------------*/
2718 packRegisters (eBBlock * ebp)
2723 debugLog ("%s\n", __FUNCTION__);
2730 /* look for assignments of the form */
2731 /* iTempNN = TRueSym (someoperation) SomeOperand */
2733 /* TrueSym := iTempNN:1 */
2734 for (ic = ebp->sch; ic; ic = ic->next)
2737 /* find assignment of the form TrueSym := iTempNN:1 */
2738 if (ic->op == '=' && !POINTER_SET (ic))
2739 change += packRegsForAssign (ic, ebp);
2743 if (POINTER_SET (ic))
2744 debugLog ("pointer is set\n");
2745 debugAopGet (" result:", IC_RESULT (ic));
2746 debugAopGet (" left:", IC_LEFT (ic));
2747 debugAopGet (" right:", IC_RIGHT (ic));
2756 for (ic = ebp->sch; ic; ic = ic->next)
2759 /* if this is an itemp & result of a address of a true sym
2760 then mark this as rematerialisable */
2761 if (ic->op == ADDRESS_OF &&
2762 IS_ITEMP (IC_RESULT (ic)) &&
2763 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2764 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2765 !OP_SYMBOL (IC_LEFT (ic))->onStack)
2768 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2769 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2770 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2774 /* if straight assignment then carry remat flag if
2775 this is the only definition */
2776 if (ic->op == '=' &&
2777 !POINTER_SET (ic) &&
2778 IS_SYMOP (IC_RIGHT (ic)) &&
2779 OP_SYMBOL (IC_RIGHT (ic))->remat &&
2780 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2783 OP_SYMBOL (IC_RESULT (ic))->remat =
2784 OP_SYMBOL (IC_RIGHT (ic))->remat;
2785 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2786 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2789 /* if this is a +/- operation with a rematerizable
2790 then mark this as rematerializable as well */
2791 if ((ic->op == '+' || ic->op == '-') &&
2792 (IS_SYMOP (IC_LEFT (ic)) &&
2793 IS_ITEMP (IC_RESULT (ic)) &&
2794 OP_SYMBOL (IC_LEFT (ic))->remat &&
2795 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2796 IS_OP_LITERAL (IC_RIGHT (ic))))
2800 operandLitValue (IC_RIGHT (ic));
2801 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2802 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2803 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2806 /* mark the pointer usages */
2807 if (POINTER_SET (ic))
2809 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2810 debugLog (" marking as a pointer (set)\n");
2812 if (POINTER_GET (ic))
2814 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2815 debugLog (" marking as a pointer (get)\n");
2820 /* if we are using a symbol on the stack
2821 then we should say pic14_ptrRegReq */
2822 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2823 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2824 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2825 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2826 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2827 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2830 if (IS_SYMOP (IC_LEFT (ic)))
2831 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2832 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2833 if (IS_SYMOP (IC_RIGHT (ic)))
2834 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2835 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2836 if (IS_SYMOP (IC_RESULT (ic)))
2837 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2838 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2842 /* if the condition of an if instruction
2843 is defined in the previous instruction then
2844 mark the itemp as a conditional */
2845 if ((IS_CONDITIONAL (ic) ||
2846 ((ic->op == BITWISEAND ||
2849 isBitwiseOptimizable (ic))) &&
2850 ic->next && ic->next->op == IFX &&
2851 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2852 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2855 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2859 /* reduce for support function calls */
2860 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2861 packRegsForSupport (ic, ebp);
2863 /* if a parameter is passed, it's in W, so we may not
2864 need to place a copy in a register */
2865 if (ic->op == RECEIVE)
2866 packForReceive (ic, ebp);
2868 /* some cases the redundant moves can
2869 can be eliminated for return statements */
2870 if ((ic->op == RETURN || ic->op == SEND) &&
2871 !isOperandInFarSpace (IC_LEFT (ic)) &&
2873 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2875 /* if pointer set & left has a size more than
2876 one and right is not in far space */
2877 if (POINTER_SET (ic) &&
2878 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2879 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2880 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2881 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2883 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2885 /* if pointer get */
2886 if (POINTER_GET (ic) &&
2887 !isOperandInFarSpace (IC_RESULT (ic)) &&
2888 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2889 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2890 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2892 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2895 /* if this is cast for intergral promotion then
2896 check if only use of the definition of the
2897 operand being casted/ if yes then replace
2898 the result of that arithmetic operation with
2899 this result and get rid of the cast */
2902 sym_link *fromType = operandType (IC_RIGHT (ic));
2903 sym_link *toType = operandType (IC_LEFT (ic));
2905 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2906 getSize (fromType) != getSize (toType))
2909 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2912 if (IS_ARITHMETIC_OP (dic))
2914 IC_RESULT (dic) = IC_RESULT (ic);
2915 remiCodeFromeBBlock (ebp, ic);
2916 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2917 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2921 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2927 /* if the type from and type to are the same
2928 then if this is the only use then packit */
2929 if (checkType (operandType (IC_RIGHT (ic)),
2930 operandType (IC_LEFT (ic))) == 1)
2932 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2935 IC_RESULT (dic) = IC_RESULT (ic);
2936 remiCodeFromeBBlock (ebp, ic);
2937 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2938 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2946 iTempNN := (some variable in farspace) V1
2951 if (ic->op == IPUSH)
2953 packForPush (ic, ebp);
2957 /* pack registers for accumulator use, when the
2958 result of an arithmetic or bit wise operation
2959 has only one use, that use is immediately following
2960 the defintion and the using iCode has only one
2961 operand or has two operands but one is literal &
2962 the result of that operation is not on stack then
2963 we can leave the result of this operation in acc:b
2965 if ((IS_ARITHMETIC_OP (ic)
2967 || IS_BITWISE_OP (ic)
2969 || ic->op == LEFT_OP || ic->op == RIGHT_OP
2972 IS_ITEMP (IC_RESULT (ic)) &&
2973 getSize (operandType (IC_RESULT (ic))) <= 2)
2975 packRegsForAccUse (ic);
2981 dumpEbbsToDebug (eBBlock ** ebbs, int count)
2985 if (!debug || !debugF)
2988 for (i = 0; i < count; i++)
2990 fprintf (debugF, "\n----------------------------------------------------------------\n");
2991 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
2992 ebbs[i]->entryLabel->name,
2995 ebbs[i]->isLastInLoop);
2996 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3001 fprintf (debugF, "visited %d : hasFcall = %d\n",
3005 fprintf (debugF, "\ndefines bitVector :");
3006 bitVectDebugOn (ebbs[i]->defSet, debugF);
3007 fprintf (debugF, "\nlocal defines bitVector :");
3008 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3009 fprintf (debugF, "\npointers Set bitvector :");
3010 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3011 fprintf (debugF, "\nin pointers Set bitvector :");
3012 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3013 fprintf (debugF, "\ninDefs Set bitvector :");
3014 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3015 fprintf (debugF, "\noutDefs Set bitvector :");
3016 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3017 fprintf (debugF, "\nusesDefs Set bitvector :");
3018 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3019 fprintf (debugF, "\n----------------------------------------------------------------\n");
3020 printiCChain (ebbs[i]->sch, debugF);
3023 /*-----------------------------------------------------------------*/
3024 /* assignRegisters - assigns registers to each live range as need */
3025 /*-----------------------------------------------------------------*/
3027 pic14_assignRegisters (eBBlock ** ebbs, int count)
3032 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3033 debugLog ("ebbs before optimizing:\n");
3034 dumpEbbsToDebug (ebbs, count);
3036 setToNull ((void *) &_G.funcrUsed);
3037 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3040 /* change assignments this will remove some
3041 live ranges reducing some register pressure */
3042 for (i = 0; i < count; i++)
3043 packRegisters (ebbs[i]);
3045 if (options.dump_pack)
3046 dumpEbbsToFileExt (".dumppack", ebbs, count);
3048 /* first determine for each live range the number of
3049 registers & the type of registers required for each */
3052 /* and serially allocate registers */
3053 serialRegAssign (ebbs, count);
3055 /* if stack was extended then tell the user */
3058 /* werror(W_TOOMANY_SPILS,"stack", */
3059 /* _G.stackExtend,currFunc->name,""); */
3065 /* werror(W_TOOMANY_SPILS,"data space", */
3066 /* _G.dataExtend,currFunc->name,""); */
3070 /* after that create the register mask
3071 for each of the instruction */
3072 createRegMask (ebbs, count);
3074 /* redo that offsets for stacked automatic variables */
3075 redoStackOffsets ();
3077 if (options.dump_rassgn)
3078 dumpEbbsToFileExt (".dumprassgn", ebbs, count);
3080 /* now get back the chain */
3081 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3083 debugLog ("ebbs after optimizing:\n");
3084 dumpEbbsToDebug (ebbs, count);
3089 /* free up any _G.stackSpil locations allocated */
3090 applyToSet (_G.stackSpil, deallocStackSpil);
3092 setToNull ((void **) &_G.stackSpil);
3093 setToNull ((void **) &_G.spiltSet);
3094 /* mark all registers as free */
3095 pic14_freeAllRegs ();
3097 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");