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 /*-----------------------------------------------------------------*/
33 /* At this point we start getting processor specific although */
34 /* some routines are non-processor specific & can be reused when */
35 /* targetting other processors. The decision for this will have */
36 /* to be made on a routine by routine basis */
37 /* routines used to pack registers are most definitely not reusable */
38 /* since the pack the registers depending strictly on the MCU */
39 /*-----------------------------------------------------------------*/
41 extern void genpic14Code (iCode *);
51 bitVect *funcrUsed; /* registers used in a function */
57 /* Shared with gen.c */
58 int pic14_ptrRegReq; /* one byte pointer register required */
64 {REG_GPR, PO_GPR_TEMP, 0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0},
65 {REG_GPR, PO_GPR_TEMP, 0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0},
66 {REG_GPR, PO_GPR_TEMP, 0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0},
67 {REG_GPR, PO_GPR_TEMP, 0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0},
68 {REG_GPR, PO_GPR_TEMP, 0x10, "r0x10", "r0x10", 0x10, 1, 0},
69 {REG_GPR, PO_GPR_TEMP, 0x11, "r0x11", "r0x11", 0x11, 1, 0},
70 {REG_GPR, PO_GPR_TEMP, 0x12, "r0x12", "r0x12", 0x12, 1, 0},
71 {REG_GPR, PO_GPR_TEMP, 0x13, "r0x13", "r0x13", 0x13, 1, 0},
72 {REG_GPR, PO_GPR_TEMP, 0x14, "r0x14", "r0x14", 0x14, 1, 0},
73 {REG_GPR, PO_GPR_TEMP, 0x15, "r0x15", "r0x15", 0x15, 1, 0},
74 {REG_GPR, PO_GPR_TEMP, 0x16, "r0x16", "r0x16", 0x16, 1, 0},
75 {REG_GPR, PO_GPR_TEMP, 0x17, "r0x17", "r0x17", 0x17, 1, 0},
76 {REG_GPR, PO_GPR_TEMP, 0x18, "r0x18", "r0x18", 0x18, 1, 0},
77 {REG_GPR, PO_GPR_TEMP, 0x19, "r0x19", "r0x19", 0x19, 1, 0},
78 {REG_GPR, PO_GPR_TEMP, 0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0},
79 {REG_GPR, PO_GPR_TEMP, 0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0},
80 {REG_GPR, PO_GPR_TEMP, 0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0},
81 {REG_GPR, PO_GPR_TEMP, 0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0},
82 {REG_GPR, PO_GPR_TEMP, 0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0},
83 {REG_GPR, PO_GPR_TEMP, 0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0},
84 {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
88 int pic14_nRegs = sizeof (regspic14) / sizeof (regs);
89 static void spillThis (symbol *);
91 static FILE *debugF = NULL;
92 /*-----------------------------------------------------------------*/
93 /* debugLog - open a file for debugging information */
94 /*-----------------------------------------------------------------*/
95 //static void debugLog(char *inst,char *fmt, ...)
97 debugLog (char *fmt,...)
99 static int append = 0; // First time through, open the file without append.
102 //char *bufferP=buffer;
105 if (!debug || !srcFileName)
111 /* create the file name */
112 strcpy (buffer, srcFileName);
113 strcat (buffer, ".d");
115 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
117 werror (E_FILE_OPEN_ERR, buffer);
120 append = 1; // Next time debubLog is called, we'll append the debug info
126 vsprintf (buffer, fmt, ap);
128 fprintf (debugF, "%s", buffer);
130 while (isspace(*bufferP)) bufferP++;
132 if (bufferP && *bufferP)
133 lineCurr = (lineCurr ?
134 connectLine(lineCurr,newLineNode(lb)) :
135 (lineHead = newLineNode(lb)));
136 lineCurr->isInline = _G.inLine;
137 lineCurr->isDebug = _G.debugLine;
147 fputc ('\n', debugF);
149 /*-----------------------------------------------------------------*/
150 /* debugLogClose - closes the debug log file (if opened) */
151 /*-----------------------------------------------------------------*/
161 #define AOP(op) op->aop
164 debugAopGet (char *str, operand * op)
169 printOperand (op, debugF);
177 decodeOp (unsigned int op)
180 if (op < 128 && op > ' ')
182 buffer[0] = (op & 0xff);
196 return "STRING_LITERAL";
232 return "LEFT_ASSIGN";
234 return "RIGHT_ASSIGN";
363 case GET_VALUE_AT_ADDRESS:
364 return "GET_VALUE_AT_ADDRESS";
382 return "ENDFUNCTION";
406 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
409 /*-----------------------------------------------------------------*/
410 /*-----------------------------------------------------------------*/
412 debugLogRegType (short type)
425 sprintf (buffer, "unkown reg type %d", type);
429 /*-----------------------------------------------------------------*/
430 /* allocReg - allocates register of given type */
431 /*-----------------------------------------------------------------*/
433 allocReg (short type)
437 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
439 for (i = 0; i < pic14_nRegs; i++)
442 /* if type is given as 0 then any
443 free register will do */
447 regspic14[i].isFree = 0;
448 regspic14[i].wasUsed = 1;
451 bitVectSetBit (currFunc->regsUsed, i);
452 debugLog (" returning %s\n", regspic14[i].name);
453 return ®spic14[i];
455 /* other wise look for specific type
457 if (regspic14[i].isFree &&
458 regspic14[i].type == type)
460 regspic14[i].isFree = 0;
461 regspic14[i].wasUsed = 1;
464 bitVectSetBit (currFunc->regsUsed, i);
465 debugLog (" returning %s\n", regspic14[i].name);
466 return ®spic14[i];
472 /*-----------------------------------------------------------------*/
473 /* pic14_regWithIdx - returns pointer to register wit index number */
474 /*-----------------------------------------------------------------*/
476 pic14_regWithIdx (int idx)
480 debugLog ("%s\n", __FUNCTION__);
482 for (i = 0; i < pic14_nRegs; i++)
483 if (regspic14[i].rIdx == idx)
484 return ®spic14[i];
486 return ®spic14[0];
488 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
489 "regWithIdx not found");
493 /*-----------------------------------------------------------------*/
494 /*-----------------------------------------------------------------*/
496 pic14_findFreeReg(void)
500 for (i = 0; i < pic14_nRegs; i++)
501 if (regspic14[i].isFree)
502 return ®spic14[i];
506 /*-----------------------------------------------------------------*/
507 /* freeReg - frees a register */
508 /*-----------------------------------------------------------------*/
512 debugLog ("%s\n", __FUNCTION__);
517 /*-----------------------------------------------------------------*/
518 /* nFreeRegs - returns number of free registers */
519 /*-----------------------------------------------------------------*/
526 debugLog ("%s\n", __FUNCTION__);
527 for (i = 0; i < pic14_nRegs; i++)
528 if (regspic14[i].isFree && regspic14[i].type == type)
533 /*-----------------------------------------------------------------*/
534 /* nfreeRegsType - free registers with type */
535 /*-----------------------------------------------------------------*/
537 nfreeRegsType (int type)
540 debugLog ("%s\n", __FUNCTION__);
543 if ((nfr = nFreeRegs (type)) == 0)
544 return nFreeRegs (REG_GPR);
547 return nFreeRegs (type);
551 /*-----------------------------------------------------------------*/
552 /* allDefsOutOfRange - all definitions are out of a range */
553 /*-----------------------------------------------------------------*/
555 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
559 debugLog ("%s\n", __FUNCTION__);
563 for (i = 0; i < defs->size; i++)
567 if (bitVectBitValue (defs, i) &&
568 (ic = hTabItemWithKey (iCodehTab, i)) &&
569 (ic->seq >= fseq && ic->seq <= toseq))
578 /*-----------------------------------------------------------------*/
579 /* computeSpillable - given a point find the spillable live ranges */
580 /*-----------------------------------------------------------------*/
582 computeSpillable (iCode * ic)
586 debugLog ("%s\n", __FUNCTION__);
587 /* spillable live ranges are those that are live at this
588 point . the following categories need to be subtracted
590 a) - those that are already spilt
591 b) - if being used by this one
592 c) - defined by this one */
594 spillable = bitVectCopy (ic->rlive);
596 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
598 bitVectCplAnd (spillable, ic->uses); /* used in this one */
599 bitVectUnSetBit (spillable, ic->defKey);
600 spillable = bitVectIntersect (spillable, _G.regAssigned);
605 /*-----------------------------------------------------------------*/
606 /* noSpilLoc - return true if a variable has no spil location */
607 /*-----------------------------------------------------------------*/
609 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
611 debugLog ("%s\n", __FUNCTION__);
612 return (sym->usl.spillLoc ? 0 : 1);
615 /*-----------------------------------------------------------------*/
616 /* hasSpilLoc - will return 1 if the symbol has spil location */
617 /*-----------------------------------------------------------------*/
619 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
621 debugLog ("%s\n", __FUNCTION__);
622 return (sym->usl.spillLoc ? 1 : 0);
625 /*-----------------------------------------------------------------*/
626 /* directSpilLoc - will return 1 if the splilocation is in direct */
627 /*-----------------------------------------------------------------*/
629 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
631 debugLog ("%s\n", __FUNCTION__);
632 if (sym->usl.spillLoc &&
633 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
639 /*-----------------------------------------------------------------*/
640 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
641 /* but is not used as a pointer */
642 /*-----------------------------------------------------------------*/
644 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
646 debugLog ("%s\n", __FUNCTION__);
647 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
650 /*-----------------------------------------------------------------*/
651 /* rematable - will return 1 if the remat flag is set */
652 /*-----------------------------------------------------------------*/
654 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
656 debugLog ("%s\n", __FUNCTION__);
660 /*-----------------------------------------------------------------*/
661 /* notUsedInBlock - not used in this block */
662 /*-----------------------------------------------------------------*/
664 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
666 debugLog ("%s\n", __FUNCTION__);
667 return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
668 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
669 /* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
672 /*-----------------------------------------------------------------*/
673 /* notUsedInRemaining - not used or defined in remain of the block */
674 /*-----------------------------------------------------------------*/
676 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
678 debugLog ("%s\n", __FUNCTION__);
679 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
680 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
683 /*-----------------------------------------------------------------*/
684 /* allLRs - return true for all */
685 /*-----------------------------------------------------------------*/
687 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
689 debugLog ("%s\n", __FUNCTION__);
693 /*-----------------------------------------------------------------*/
694 /* liveRangesWith - applies function to a given set of live range */
695 /*-----------------------------------------------------------------*/
697 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
698 eBBlock * ebp, iCode * ic)
703 debugLog ("%s\n", __FUNCTION__);
704 if (!lrs || !lrs->size)
707 for (i = 1; i < lrs->size; i++)
710 if (!bitVectBitValue (lrs, i))
713 /* if we don't find it in the live range
714 hash table we are in serious trouble */
715 if (!(sym = hTabItemWithKey (liveRanges, i)))
717 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
718 "liveRangesWith could not find liveRange");
722 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
723 addSetHead (&rset, sym);
730 /*-----------------------------------------------------------------*/
731 /* leastUsedLR - given a set determines which is the least used */
732 /*-----------------------------------------------------------------*/
734 leastUsedLR (set * sset)
736 symbol *sym = NULL, *lsym = NULL;
738 debugLog ("%s\n", __FUNCTION__);
739 sym = lsym = setFirstItem (sset);
744 for (; lsym; lsym = setNextItem (sset))
747 /* if usage is the same then prefer
748 the spill the smaller of the two */
749 if (lsym->used == sym->used)
750 if (getSize (lsym->type) < getSize (sym->type))
754 if (lsym->used < sym->used)
759 setToNull ((void **) &sset);
764 /*-----------------------------------------------------------------*/
765 /* noOverLap - will iterate through the list looking for over lap */
766 /*-----------------------------------------------------------------*/
768 noOverLap (set * itmpStack, symbol * fsym)
771 debugLog ("%s\n", __FUNCTION__);
774 for (sym = setFirstItem (itmpStack); sym;
775 sym = setNextItem (itmpStack))
777 if (sym->liveTo > fsym->liveFrom)
785 /*-----------------------------------------------------------------*/
786 /* isFree - will return 1 if the a free spil location is found */
787 /*-----------------------------------------------------------------*/
792 V_ARG (symbol **, sloc);
793 V_ARG (symbol *, fsym);
795 debugLog ("%s\n", __FUNCTION__);
796 /* if already found */
800 /* if it is free && and the itmp assigned to
801 this does not have any overlapping live ranges
802 with the one currently being assigned and
803 the size can be accomodated */
805 noOverLap (sym->usl.itmpStack, fsym) &&
806 getSize (sym->type) >= getSize (fsym->type))
815 /*-----------------------------------------------------------------*/
816 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
817 /*-----------------------------------------------------------------*/
819 spillLRWithPtrReg (symbol * forSym)
825 debugLog ("%s\n", __FUNCTION__);
826 if (!_G.regAssigned ||
827 bitVectIsZero (_G.regAssigned))
830 r0 = pic14_regWithIdx (R0_IDX);
831 r1 = pic14_regWithIdx (R1_IDX);
833 /* for all live ranges */
834 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
835 lrsym = hTabNextItem (liveRanges, &k))
839 /* if no registers assigned to it or
841 /* if it does not overlap with this then
842 not need to spill it */
844 if (lrsym->isspilt || !lrsym->nRegs ||
845 (lrsym->liveTo < forSym->liveFrom))
848 /* go thru the registers : if it is either
849 r0 or r1 then spil it */
850 for (j = 0; j < lrsym->nRegs; j++)
851 if (lrsym->regs[j] == r0 ||
852 lrsym->regs[j] == r1)
861 /*-----------------------------------------------------------------*/
862 /* createStackSpil - create a location on the stack to spil */
863 /*-----------------------------------------------------------------*/
865 createStackSpil (symbol * sym)
868 int useXstack, model, noOverlay;
871 debugLog ("%s\n", __FUNCTION__);
873 /* first go try and find a free one that is already
874 existing on the stack */
875 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
877 /* found a free one : just update & return */
878 sym->usl.spillLoc = sloc;
881 addSetHead (&sloc->usl.itmpStack, sym);
885 /* could not then have to create one , this is the hard part
886 we need to allocate this on the stack : this is really a
887 hack!! but cannot think of anything better at this time */
889 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
891 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
896 sloc = newiTemp (slocBuffer);
898 /* set the type to the spilling symbol */
899 sloc->type = copyLinkChain (sym->type);
900 sloc->etype = getSpec (sloc->type);
901 SPEC_SCLS (sloc->etype) = S_DATA;
902 SPEC_EXTR (sloc->etype) = 0;
904 /* we don't allow it to be allocated`
905 onto the external stack since : so we
906 temporarily turn it off ; we also
907 turn off memory model to prevent
908 the spil from going to the external storage
909 and turn off overlaying
912 useXstack = options.useXstack;
913 model = options.model;
914 noOverlay = options.noOverlay;
915 options.noOverlay = 1;
916 options.model = options.useXstack = 0;
920 options.useXstack = useXstack;
921 options.model = model;
922 options.noOverlay = noOverlay;
923 sloc->isref = 1; /* to prevent compiler warning */
925 /* if it is on the stack then update the stack */
926 if (IN_STACK (sloc->etype))
928 currFunc->stack += getSize (sloc->type);
929 _G.stackExtend += getSize (sloc->type);
932 _G.dataExtend += getSize (sloc->type);
934 /* add it to the _G.stackSpil set */
935 addSetHead (&_G.stackSpil, sloc);
936 sym->usl.spillLoc = sloc;
939 /* add it to the set of itempStack set
940 of the spill location */
941 addSetHead (&sloc->usl.itmpStack, sym);
945 /*-----------------------------------------------------------------*/
946 /* isSpiltOnStack - returns true if the spil location is on stack */
947 /*-----------------------------------------------------------------*/
949 isSpiltOnStack (symbol * sym)
953 debugLog ("%s\n", __FUNCTION__);
960 /* if (sym->_G.stackSpil) */
963 if (!sym->usl.spillLoc)
966 etype = getSpec (sym->usl.spillLoc->type);
967 if (IN_STACK (etype))
973 /*-----------------------------------------------------------------*/
974 /* spillThis - spils a specific operand */
975 /*-----------------------------------------------------------------*/
977 spillThis (symbol * sym)
980 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
982 /* if this is rematerializable or has a spillLocation
983 we are okay, else we need to create a spillLocation
985 if (!(sym->remat || sym->usl.spillLoc))
986 createStackSpil (sym);
989 /* mark it has spilt & put it in the spilt set */
991 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
993 bitVectUnSetBit (_G.regAssigned, sym->key);
995 for (i = 0; i < sym->nRegs; i++)
999 freeReg (sym->regs[i]);
1000 sym->regs[i] = NULL;
1003 /* if spilt on stack then free up r0 & r1
1004 if they could have been assigned to some
1006 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1009 spillLRWithPtrReg (sym);
1012 if (sym->usl.spillLoc && !sym->remat)
1013 sym->usl.spillLoc->allocreq = 1;
1017 /*-----------------------------------------------------------------*/
1018 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1019 /*-----------------------------------------------------------------*/
1021 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1023 bitVect *lrcs = NULL;
1027 debugLog ("%s\n", __FUNCTION__);
1028 /* get the spillable live ranges */
1029 lrcs = computeSpillable (ic);
1031 /* get all live ranges that are rematerizable */
1032 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1035 /* return the least used of these */
1036 return leastUsedLR (selectS);
1039 /* get live ranges with spillLocations in direct space */
1040 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1042 sym = leastUsedLR (selectS);
1043 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1044 sym->usl.spillLoc->rname :
1045 sym->usl.spillLoc->name));
1047 /* mark it as allocation required */
1048 sym->usl.spillLoc->allocreq = 1;
1052 /* if the symbol is local to the block then */
1053 if (forSym->liveTo < ebp->lSeq)
1056 /* check if there are any live ranges allocated
1057 to registers that are not used in this block */
1058 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1060 sym = leastUsedLR (selectS);
1061 /* if this is not rematerializable */
1070 /* check if there are any live ranges that not
1071 used in the remainder of the block */
1072 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1074 sym = leastUsedLR (selectS);
1077 sym->remainSpil = 1;
1084 /* find live ranges with spillocation && not used as pointers */
1085 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1088 sym = leastUsedLR (selectS);
1089 /* mark this as allocation required */
1090 sym->usl.spillLoc->allocreq = 1;
1094 /* find live ranges with spillocation */
1095 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1098 sym = leastUsedLR (selectS);
1099 sym->usl.spillLoc->allocreq = 1;
1103 /* couldn't find then we need to create a spil
1104 location on the stack , for which one? the least
1106 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1109 /* return a created spil location */
1110 sym = createStackSpil (leastUsedLR (selectS));
1111 sym->usl.spillLoc->allocreq = 1;
1115 /* this is an extreme situation we will spill
1116 this one : happens very rarely but it does happen */
1122 /*-----------------------------------------------------------------*/
1123 /* spilSomething - spil some variable & mark registers as free */
1124 /*-----------------------------------------------------------------*/
1126 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1131 debugLog ("%s\n", __FUNCTION__);
1132 /* get something we can spil */
1133 ssym = selectSpil (ic, ebp, forSym);
1135 /* mark it as spilt */
1137 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1139 /* mark it as not register assigned &
1140 take it away from the set */
1141 bitVectUnSetBit (_G.regAssigned, ssym->key);
1143 /* mark the registers as free */
1144 for (i = 0; i < ssym->nRegs; i++)
1146 freeReg (ssym->regs[i]);
1148 /* if spilt on stack then free up r0 & r1
1149 if they could have been assigned to as gprs */
1150 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1153 spillLRWithPtrReg (ssym);
1156 /* if this was a block level spil then insert push & pop
1157 at the start & end of block respectively */
1158 if (ssym->blockSpil)
1160 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1161 /* add push to the start of the block */
1162 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1163 ebp->sch->next : ebp->sch));
1164 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1165 /* add pop to the end of the block */
1166 addiCodeToeBBlock (ebp, nic, NULL);
1169 /* if spilt because not used in the remainder of the
1170 block then add a push before this instruction and
1171 a pop at the end of the block */
1172 if (ssym->remainSpil)
1175 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1176 /* add push just before this instruction */
1177 addiCodeToeBBlock (ebp, nic, ic);
1179 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1180 /* add pop to the end of the block */
1181 addiCodeToeBBlock (ebp, nic, NULL);
1190 /*-----------------------------------------------------------------*/
1191 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1192 /*-----------------------------------------------------------------*/
1194 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1198 debugLog ("%s\n", __FUNCTION__);
1200 /* try for a ptr type */
1201 if ((reg = allocReg (REG_PTR)))
1204 /* try for gpr type */
1205 if ((reg = allocReg (REG_GPR)))
1208 /* we have to spil */
1209 if (!spilSomething (ic, ebp, sym))
1212 /* this looks like an infinite loop but
1213 in really selectSpil will abort */
1217 /*-----------------------------------------------------------------*/
1218 /* getRegGpr - will try for GPR if not spil */
1219 /*-----------------------------------------------------------------*/
1221 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1225 debugLog ("%s\n", __FUNCTION__);
1227 /* try for gpr type */
1228 if ((reg = allocReg (REG_GPR)))
1231 if (!pic14_ptrRegReq)
1232 if ((reg = allocReg (REG_PTR)))
1235 /* we have to spil */
1236 if (!spilSomething (ic, ebp, sym))
1239 /* this looks like an infinite loop but
1240 in really selectSpil will abort */
1244 /*-----------------------------------------------------------------*/
1245 /* symHasReg - symbol has a given register */
1246 /*-----------------------------------------------------------------*/
1248 symHasReg (symbol * sym, regs * reg)
1252 debugLog ("%s\n", __FUNCTION__);
1253 for (i = 0; i < sym->nRegs; i++)
1254 if (sym->regs[i] == reg)
1260 /*-----------------------------------------------------------------*/
1261 /* deassignLRs - check the live to and if they have registers & are */
1262 /* not spilt then free up the registers */
1263 /*-----------------------------------------------------------------*/
1265 deassignLRs (iCode * ic, eBBlock * ebp)
1271 debugLog ("%s\n", __FUNCTION__);
1272 for (sym = hTabFirstItem (liveRanges, &k); sym;
1273 sym = hTabNextItem (liveRanges, &k))
1276 symbol *psym = NULL;
1277 /* if it does not end here */
1278 if (sym->liveTo > ic->seq)
1281 /* if it was spilt on stack then we can
1282 mark the stack spil location as free */
1287 sym->usl.spillLoc->isFree = 1;
1293 if (!bitVectBitValue (_G.regAssigned, sym->key))
1296 /* special case check if this is an IFX &
1297 the privious one was a pop and the
1298 previous one was not spilt then keep track
1300 if (ic->op == IFX && ic->prev &&
1301 ic->prev->op == IPOP &&
1302 !ic->prev->parmPush &&
1303 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1304 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1310 bitVectUnSetBit (_G.regAssigned, sym->key);
1312 /* if the result of this one needs registers
1313 and does not have it then assign it right
1315 if (IC_RESULT (ic) &&
1316 !(SKIP_IC2 (ic) || /* not a special icode */
1317 ic->op == JUMPTABLE ||
1322 POINTER_SET (ic)) &&
1323 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1324 result->liveTo > ic->seq && /* and will live beyond this */
1325 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1326 result->regType == sym->regType && /* same register types */
1327 result->nRegs && /* which needs registers */
1328 !result->isspilt && /* and does not already have them */
1330 !bitVectBitValue (_G.regAssigned, result->key) &&
1331 /* the number of free regs + number of regs in this LR
1332 can accomodate the what result Needs */
1333 ((nfreeRegsType (result->regType) +
1334 sym->nRegs) >= result->nRegs)
1338 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1340 result->regs[i] = sym->regs[i];
1342 result->regs[i] = getRegGpr (ic, ebp, result);
1344 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1348 /* free the remaining */
1349 for (; i < sym->nRegs; i++)
1353 if (!symHasReg (psym, sym->regs[i]))
1354 freeReg (sym->regs[i]);
1357 freeReg (sym->regs[i]);
1364 /*-----------------------------------------------------------------*/
1365 /* reassignLR - reassign this to registers */
1366 /*-----------------------------------------------------------------*/
1368 reassignLR (operand * op)
1370 symbol *sym = OP_SYMBOL (op);
1373 debugLog ("%s\n", __FUNCTION__);
1374 /* not spilt any more */
1375 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1376 bitVectUnSetBit (_G.spiltSet, sym->key);
1378 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1382 for (i = 0; i < sym->nRegs; i++)
1383 sym->regs[i]->isFree = 0;
1386 /*-----------------------------------------------------------------*/
1387 /* willCauseSpill - determines if allocating will cause a spill */
1388 /*-----------------------------------------------------------------*/
1390 willCauseSpill (int nr, int rt)
1392 debugLog ("%s\n", __FUNCTION__);
1393 /* first check if there are any avlb registers
1394 of te type required */
1397 /* special case for pointer type
1398 if pointer type not avlb then
1399 check for type gpr */
1400 if (nFreeRegs (rt) >= nr)
1402 if (nFreeRegs (REG_GPR) >= nr)
1407 if (pic14_ptrRegReq)
1409 if (nFreeRegs (rt) >= nr)
1414 if (nFreeRegs (REG_PTR) +
1415 nFreeRegs (REG_GPR) >= nr)
1420 debugLog (" ... yep it will (cause a spill)\n");
1421 /* it will cause a spil */
1425 /*-----------------------------------------------------------------*/
1426 /* positionRegs - the allocator can allocate same registers to res- */
1427 /* ult and operand, if this happens make sure they are in the same */
1428 /* position as the operand otherwise chaos results */
1429 /*-----------------------------------------------------------------*/
1431 positionRegs (symbol * result, symbol * opsym, int lineno)
1433 int count = min (result->nRegs, opsym->nRegs);
1434 int i, j = 0, shared = 0;
1436 debugLog ("%s\n", __FUNCTION__);
1437 /* if the result has been spilt then cannot share */
1442 /* first make sure that they actually share */
1443 for (i = 0; i < count; i++)
1445 for (j = 0; j < count; j++)
1447 if (result->regs[i] == opsym->regs[j] && i != j)
1457 regs *tmp = result->regs[i];
1458 result->regs[i] = result->regs[j];
1459 result->regs[j] = tmp;
1464 /*-----------------------------------------------------------------*/
1465 /* serialRegAssign - serially allocate registers to the variables */
1466 /*-----------------------------------------------------------------*/
1468 serialRegAssign (eBBlock ** ebbs, int count)
1472 debugLog ("%s\n", __FUNCTION__);
1473 /* for all blocks */
1474 for (i = 0; i < count; i++)
1479 if (ebbs[i]->noPath &&
1480 (ebbs[i]->entryLabel != entryLabel &&
1481 ebbs[i]->entryLabel != returnLabel))
1484 /* of all instructions do */
1485 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1488 debugLog (" op: %s\n", decodeOp (ic->op));
1490 /* if this is an ipop that means some live
1491 range will have to be assigned again */
1493 reassignLR (IC_LEFT (ic));
1495 /* if result is present && is a true symbol */
1496 if (IC_RESULT (ic) && ic->op != IFX &&
1497 IS_TRUE_SYMOP (IC_RESULT (ic)))
1498 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1500 /* take away registers from live
1501 ranges that end at this instruction */
1502 deassignLRs (ic, ebbs[i]);
1504 /* some don't need registers */
1505 if (SKIP_IC2 (ic) ||
1506 ic->op == JUMPTABLE ||
1510 (IC_RESULT (ic) && POINTER_SET (ic)))
1513 /* now we need to allocate registers
1514 only for the result */
1517 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1523 /* if it does not need or is spilt
1524 or is already assigned to registers
1525 or will not live beyond this instructions */
1528 bitVectBitValue (_G.regAssigned, sym->key) ||
1529 sym->liveTo <= ic->seq)
1532 /* if some liverange has been spilt at the block level
1533 and this one live beyond this block then spil this
1535 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1540 /* if trying to allocate this will cause
1541 a spill and there is nothing to spill
1542 or this one is rematerializable then
1544 willCS = willCauseSpill (sym->nRegs, sym->regType);
1545 spillable = computeSpillable (ic);
1547 (willCS && bitVectIsZero (spillable)))
1555 /* if it has a spillocation & is used less than
1556 all other live ranges then spill this */
1558 if (sym->usl.spillLoc) {
1559 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1560 allLRs, ebbs[i], ic));
1561 if (leastUsed && leastUsed->used > sym->used) {
1566 /* if none of the liveRanges have a spillLocation then better
1567 to spill this one than anything else already assigned to registers */
1568 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1575 if (ic->op == RECEIVE)
1576 debugLog ("When I get clever, I'll optimize the receive logic\n");
1578 /* if we need ptr regs for the right side
1580 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
1581 <= (unsigned) PTRSIZE)
1586 /* else we assign registers to it */
1587 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1589 debugLog (" %d - \n", __LINE__);
1591 for (j = 0; j < sym->nRegs; j++)
1593 if (sym->regType == REG_PTR)
1594 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1596 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1598 /* if the allocation falied which means
1599 this was spilt then break */
1603 debugLog (" %d - \n", __LINE__);
1605 /* if it shares registers with operands make sure
1606 that they are in the same position */
1607 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1608 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1609 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1610 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1611 /* do the same for the right operand */
1612 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1613 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
1614 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1615 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1617 debugLog (" %d - \n", __LINE__);
1620 debugLog (" %d - \n", __LINE__);
1630 /*-----------------------------------------------------------------*/
1631 /* rUmaskForOp :- returns register mask for an operand */
1632 /*-----------------------------------------------------------------*/
1634 rUmaskForOp (operand * op)
1640 debugLog ("%s\n", __FUNCTION__);
1641 /* only temporaries are assigned registers */
1645 sym = OP_SYMBOL (op);
1647 /* if spilt or no registers assigned to it
1649 if (sym->isspilt || !sym->nRegs)
1652 rumask = newBitVect (pic14_nRegs);
1654 for (j = 0; j < sym->nRegs; j++)
1656 rumask = bitVectSetBit (rumask,
1657 sym->regs[j]->rIdx);
1663 /*-----------------------------------------------------------------*/
1664 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1665 /*-----------------------------------------------------------------*/
1667 regsUsedIniCode (iCode * ic)
1669 bitVect *rmask = newBitVect (pic14_nRegs);
1671 debugLog ("%s\n", __FUNCTION__);
1672 /* do the special cases first */
1675 rmask = bitVectUnion (rmask,
1676 rUmaskForOp (IC_COND (ic)));
1680 /* for the jumptable */
1681 if (ic->op == JUMPTABLE)
1683 rmask = bitVectUnion (rmask,
1684 rUmaskForOp (IC_JTCOND (ic)));
1689 /* of all other cases */
1691 rmask = bitVectUnion (rmask,
1692 rUmaskForOp (IC_LEFT (ic)));
1696 rmask = bitVectUnion (rmask,
1697 rUmaskForOp (IC_RIGHT (ic)));
1700 rmask = bitVectUnion (rmask,
1701 rUmaskForOp (IC_RESULT (ic)));
1707 /*-----------------------------------------------------------------*/
1708 /* createRegMask - for each instruction will determine the regsUsed */
1709 /*-----------------------------------------------------------------*/
1711 createRegMask (eBBlock ** ebbs, int count)
1715 debugLog ("%s\n", __FUNCTION__);
1716 /* for all blocks */
1717 for (i = 0; i < count; i++)
1721 if (ebbs[i]->noPath &&
1722 (ebbs[i]->entryLabel != entryLabel &&
1723 ebbs[i]->entryLabel != returnLabel))
1726 /* for all instructions */
1727 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1732 if (SKIP_IC2 (ic) || !ic->rlive)
1735 /* first mark the registers used in this
1737 ic->rUsed = regsUsedIniCode (ic);
1738 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1740 /* now create the register mask for those
1741 registers that are in use : this is a
1742 super set of ic->rUsed */
1743 ic->rMask = newBitVect (pic14_nRegs + 1);
1745 /* for all live Ranges alive at this point */
1746 for (j = 1; j < ic->rlive->size; j++)
1751 /* if not alive then continue */
1752 if (!bitVectBitValue (ic->rlive, j))
1755 /* find the live range we are interested in */
1756 if (!(sym = hTabItemWithKey (liveRanges, j)))
1758 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1759 "createRegMask cannot find live range");
1763 /* if no register assigned to it */
1764 if (!sym->nRegs || sym->isspilt)
1767 /* for all the registers allocated to it */
1768 for (k = 0; k < sym->nRegs; k++)
1771 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1777 /*-----------------------------------------------------------------*/
1778 /* rematStr - returns the rematerialized string for a remat var */
1779 /*-----------------------------------------------------------------*/
1781 rematStr (symbol * sym)
1784 iCode *ic = sym->rematiCode;
1786 debugLog ("%s\n", __FUNCTION__);
1791 /* if plus or minus print the right hand side */
1793 if (ic->op == '+' || ic->op == '-') {
1794 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1797 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1801 if (ic->op == '+' || ic->op == '-')
1803 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1804 sprintf (s, "(%s %c 0x%04x)",
1805 OP_SYMBOL (IC_LEFT (ric))->rname,
1807 (int) operandLitValue (IC_RIGHT (ic)));
1810 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1815 /* we reached the end */
1816 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1820 printf ("%s\n", buffer);
1824 /*-----------------------------------------------------------------*/
1825 /* regTypeNum - computes the type & number of registers required */
1826 /*-----------------------------------------------------------------*/
1834 debugLog ("%s\n", __FUNCTION__);
1835 /* for each live range do */
1836 for (sym = hTabFirstItem (liveRanges, &k); sym;
1837 sym = hTabNextItem (liveRanges, &k))
1840 debugLog (" %d - %s\n", __LINE__, sym->rname);
1842 /* if used zero times then no registers needed */
1843 if ((sym->liveTo - sym->liveFrom) == 0)
1847 /* if the live range is a temporary */
1851 debugLog (" %d - \n", __LINE__);
1853 /* if the type is marked as a conditional */
1854 if (sym->regType == REG_CND)
1857 /* if used in return only then we don't
1859 if (sym->ruonly || sym->accuse)
1861 if (IS_AGGREGATE (sym->type) || sym->isptr)
1862 sym->type = aggrToPtr (sym->type, FALSE);
1863 debugLog (" %d - \n", __LINE__);
1868 /* if the symbol has only one definition &
1869 that definition is a get_pointer and the
1870 pointer we are getting is rematerializable and
1873 if (bitVectnBitsOn (sym->defs) == 1 &&
1874 (ic = hTabItemWithKey (iCodehTab,
1875 bitVectFirstBit (sym->defs))) &&
1877 !IS_BITVAR (sym->etype))
1880 debugLog (" %d - \n", __LINE__);
1882 /* if remat in data space */
1883 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1884 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1887 /* create a psuedo symbol & force a spil */
1888 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1889 psym->type = sym->type;
1890 psym->etype = sym->etype;
1891 strcpy (psym->rname, psym->name);
1893 sym->usl.spillLoc = psym;
1897 /* if in data space or idata space then try to
1898 allocate pointer register */
1902 /* if not then we require registers */
1903 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1904 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1905 getSize (sym->type));
1909 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1910 printTypeChain (sym->type, stderr);
1911 fprintf (stderr, "\n");
1914 debugLog (" %d - \n", __LINE__);
1916 /* determine the type of register required */
1917 if (sym->nRegs == 1 &&
1918 IS_PTR (sym->type) &&
1920 sym->regType = REG_PTR;
1922 sym->regType = REG_GPR;
1923 debugLog (" reg type %s\n", debugLogRegType (sym->regType));
1927 /* for the first run we don't provide */
1928 /* registers for true symbols we will */
1929 /* see how things go */
1935 /*-----------------------------------------------------------------*/
1936 /* freeAllRegs - mark all registers as free */
1937 /*-----------------------------------------------------------------*/
1939 pic14_freeAllRegs ()
1943 debugLog ("%s\n", __FUNCTION__);
1944 for (i = 0; i < pic14_nRegs; i++)
1945 regspic14[i].isFree = 1;
1948 /*-----------------------------------------------------------------*/
1949 /*-----------------------------------------------------------------*/
1951 pic14_deallocateAllRegs ()
1955 debugLog ("%s\n", __FUNCTION__);
1956 for (i = 0; i < pic14_nRegs; i++) {
1957 regspic14[i].isFree = 1;
1958 regspic14[i].wasUsed = 0;
1963 /*-----------------------------------------------------------------*/
1964 /* deallocStackSpil - this will set the stack pointer back */
1965 /*-----------------------------------------------------------------*/
1967 DEFSETFUNC (deallocStackSpil)
1971 debugLog ("%s\n", __FUNCTION__);
1976 /*-----------------------------------------------------------------*/
1977 /* farSpacePackable - returns the packable icode for far variables */
1978 /*-----------------------------------------------------------------*/
1980 farSpacePackable (iCode * ic)
1984 debugLog ("%s\n", __FUNCTION__);
1985 /* go thru till we find a definition for the
1986 symbol on the right */
1987 for (dic = ic->prev; dic; dic = dic->prev)
1990 /* if the definition is a call then no */
1991 if ((dic->op == CALL || dic->op == PCALL) &&
1992 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1997 /* if shift by unknown amount then not */
1998 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1999 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2002 /* if pointer get and size > 1 */
2003 if (POINTER_GET (dic) &&
2004 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2007 if (POINTER_SET (dic) &&
2008 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2011 /* if any three is a true symbol in far space */
2012 if (IC_RESULT (dic) &&
2013 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2014 isOperandInFarSpace (IC_RESULT (dic)))
2017 if (IC_RIGHT (dic) &&
2018 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2019 isOperandInFarSpace (IC_RIGHT (dic)) &&
2020 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2023 if (IC_LEFT (dic) &&
2024 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2025 isOperandInFarSpace (IC_LEFT (dic)) &&
2026 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2029 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2031 if ((dic->op == LEFT_OP ||
2032 dic->op == RIGHT_OP ||
2034 IS_OP_LITERAL (IC_RIGHT (dic)))
2044 /*-----------------------------------------------------------------*/
2045 /* packRegsForAssign - register reduction for assignment */
2046 /*-----------------------------------------------------------------*/
2048 packRegsForAssign (iCode * ic, eBBlock * ebp)
2053 debugLog ("%s\n", __FUNCTION__);
2055 debugAopGet (" result:", IC_RESULT (ic));
2056 debugAopGet (" left:", IC_LEFT (ic));
2057 debugAopGet (" right:", IC_RIGHT (ic));
2059 if (!IS_ITEMP (IC_RIGHT (ic)) ||
2060 OP_SYMBOL (IC_RIGHT (ic))->isind ||
2061 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2066 /* if the true symbol is defined in far space or on stack
2067 then we should not since this will increase register pressure */
2068 if (isOperandInFarSpace (IC_RESULT (ic)))
2070 if ((dic = farSpacePackable (ic)))
2076 /* find the definition of iTempNN scanning backwards if we find a
2077 a use of the true symbol before we find the definition then
2079 for (dic = ic->prev; dic; dic = dic->prev)
2082 /* if there is a function call and this is
2083 a parameter & not my parameter then don't pack it */
2084 if ((dic->op == CALL || dic->op == PCALL) &&
2085 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2086 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2088 debugLog (" %d - \n", __LINE__);
2096 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2097 IS_OP_VOLATILE (IC_RESULT (dic)))
2099 debugLog (" %d - \n", __LINE__);
2104 if (IS_SYMOP (IC_RESULT (dic)) &&
2105 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2107 debugLog (" %d - dic key == ic key -- pointer set=%c\n", __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2108 if (POINTER_SET (dic))
2114 if (IS_SYMOP (IC_RIGHT (dic)) &&
2115 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2116 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2118 debugLog (" %d - \n", __LINE__);
2123 if (IS_SYMOP (IC_LEFT (dic)) &&
2124 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2125 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2127 debugLog (" %d - \n", __LINE__);
2132 if (POINTER_SET (dic) &&
2133 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2135 debugLog (" %d - \n", __LINE__);
2142 return 0; /* did not find */
2144 /* if the result is on stack or iaccess then it must be
2145 the same atleast one of the operands */
2146 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2147 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2150 /* the operation has only one symbol
2151 operator then we can pack */
2152 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2153 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2156 if (!((IC_LEFT (dic) &&
2157 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2159 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2163 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2164 /* found the definition */
2165 /* replace the result with the result of */
2166 /* this assignment and remove this assignment */
2167 IC_RESULT (dic) = IC_RESULT (ic);
2169 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2171 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2173 /* delete from liverange table also
2174 delete from all the points inbetween and the new
2176 for (sic = dic; sic != ic; sic = sic->next)
2178 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2179 if (IS_ITEMP (IC_RESULT (dic)))
2180 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2183 remiCodeFromeBBlock (ebp, ic);
2184 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2185 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2191 /*-----------------------------------------------------------------*/
2192 /* findAssignToSym : scanning backwards looks for first assig found */
2193 /*-----------------------------------------------------------------*/
2195 findAssignToSym (operand * op, iCode * ic)
2199 debugLog ("%s\n", __FUNCTION__);
2200 for (dic = ic->prev; dic; dic = dic->prev)
2203 /* if definition by assignment */
2204 if (dic->op == '=' &&
2205 !POINTER_SET (dic) &&
2206 IC_RESULT (dic)->key == op->key
2207 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2211 /* we are interested only if defined in far space */
2212 /* or in stack space in case of + & - */
2214 /* if assigned to a non-symbol then return
2216 if (!IS_SYMOP (IC_RIGHT (dic)))
2219 /* if the symbol is in far space then
2221 if (isOperandInFarSpace (IC_RIGHT (dic)))
2224 /* for + & - operations make sure that
2225 if it is on the stack it is the same
2226 as one of the three operands */
2227 if ((ic->op == '+' || ic->op == '-') &&
2228 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2231 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2232 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2233 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2241 /* if we find an usage then we cannot delete it */
2242 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2245 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2248 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2252 /* now make sure that the right side of dic
2253 is not defined between ic & dic */
2256 iCode *sic = dic->next;
2258 for (; sic != ic; sic = sic->next)
2259 if (IC_RESULT (sic) &&
2260 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2269 /*-----------------------------------------------------------------*/
2270 /* packRegsForSupport :- reduce some registers for support calls */
2271 /*-----------------------------------------------------------------*/
2273 packRegsForSupport (iCode * ic, eBBlock * ebp)
2277 debugLog ("%s\n", __FUNCTION__);
2278 /* for the left & right operand :- look to see if the
2279 left was assigned a true symbol in far space in that
2280 case replace them */
2281 if (IS_ITEMP (IC_LEFT (ic)) &&
2282 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2284 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2290 debugAopGet ("removing left:", IC_LEFT (ic));
2292 /* found it we need to remove it from the
2294 for (sic = dic; sic != ic; sic = sic->next)
2295 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2297 IC_LEFT (ic)->operand.symOperand =
2298 IC_RIGHT (dic)->operand.symOperand;
2299 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2300 remiCodeFromeBBlock (ebp, dic);
2301 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2305 /* do the same for the right operand */
2308 IS_ITEMP (IC_RIGHT (ic)) &&
2309 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2311 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2317 /* if this is a subtraction & the result
2318 is a true symbol in far space then don't pack */
2319 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2321 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2322 if (IN_FARSPACE (SPEC_OCLS (etype)))
2326 debugAopGet ("removing right:", IC_RIGHT (ic));
2328 /* found it we need to remove it from the
2330 for (sic = dic; sic != ic; sic = sic->next)
2331 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2333 IC_RIGHT (ic)->operand.symOperand =
2334 IC_RIGHT (dic)->operand.symOperand;
2335 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2337 remiCodeFromeBBlock (ebp, dic);
2338 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2345 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2348 /*-----------------------------------------------------------------*/
2349 /* packRegsForOneuse : - will reduce some registers for single Use */
2350 /*-----------------------------------------------------------------*/
2352 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2357 debugLog ("%s\n", __FUNCTION__);
2358 /* if returning a literal then do nothing */
2362 /* only upto 2 bytes since we cannot predict
2363 the usage of b, & acc */
2364 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2369 /* this routine will mark the a symbol as used in one
2370 instruction use only && if the definition is local
2371 (ie. within the basic block) && has only one definition &&
2372 that definition is either a return value from a
2373 function or does not contain any variables in
2375 uses = bitVectCopy (OP_USES (op));
2376 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2377 if (!bitVectIsZero (uses)) /* has other uses */
2380 /* if it has only one defintion */
2381 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2382 return NULL; /* has more than one definition */
2384 /* get that definition */
2386 hTabItemWithKey (iCodehTab,
2387 bitVectFirstBit (OP_DEFS (op)))))
2390 /* found the definition now check if it is local */
2391 if (dic->seq < ebp->fSeq ||
2392 dic->seq > ebp->lSeq)
2393 return NULL; /* non-local */
2395 /* now check if it is the return from
2397 if (dic->op == CALL || dic->op == PCALL)
2399 if (ic->op != SEND && ic->op != RETURN)
2401 OP_SYMBOL (op)->ruonly = 1;
2408 /* otherwise check that the definition does
2409 not contain any symbols in far space */
2410 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2411 isOperandInFarSpace (IC_RIGHT (dic)) ||
2412 IS_OP_RUONLY (IC_LEFT (ic)) ||
2413 IS_OP_RUONLY (IC_RIGHT (ic)))
2418 /* if pointer set then make sure the pointer
2420 if (POINTER_SET (dic) &&
2421 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2424 if (POINTER_GET (dic) &&
2425 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2430 /* also make sure the intervenening instructions
2431 don't have any thing in far space */
2432 for (dic = dic->next; dic && dic != ic; dic = dic->next)
2435 /* if there is an intervening function call then no */
2436 if (dic->op == CALL || dic->op == PCALL)
2438 /* if pointer set then make sure the pointer
2440 if (POINTER_SET (dic) &&
2441 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2444 if (POINTER_GET (dic) &&
2445 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2448 /* if address of & the result is remat then okay */
2449 if (dic->op == ADDRESS_OF &&
2450 OP_SYMBOL (IC_RESULT (dic))->remat)
2453 /* if operand has size of three or more & this
2454 operation is a '*','/' or '%' then 'b' may
2456 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2457 getSize (operandType (op)) >= 3)
2460 /* if left or right or result is in far space */
2461 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2462 isOperandInFarSpace (IC_RIGHT (dic)) ||
2463 isOperandInFarSpace (IC_RESULT (dic)) ||
2464 IS_OP_RUONLY (IC_LEFT (dic)) ||
2465 IS_OP_RUONLY (IC_RIGHT (dic)) ||
2466 IS_OP_RUONLY (IC_RESULT (dic)))
2472 OP_SYMBOL (op)->ruonly = 1;
2477 /*-----------------------------------------------------------------*/
2478 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2479 /*-----------------------------------------------------------------*/
2481 isBitwiseOptimizable (iCode * ic)
2483 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2484 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2486 debugLog ("%s\n", __FUNCTION__);
2487 /* bitwise operations are considered optimizable
2488 under the following conditions (Jean-Louis VERN)
2500 if (IS_LITERAL (rtype) ||
2501 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2507 /*-----------------------------------------------------------------*/
2508 /* packRegsForAccUse - pack registers for acc use */
2509 /*-----------------------------------------------------------------*/
2511 packRegsForAccUse (iCode * ic)
2515 debugLog ("%s\n", __FUNCTION__);
2516 /* if + or - then it has to be one byte result */
2517 if ((ic->op == '+' || ic->op == '-')
2518 && getSize (operandType (IC_RESULT (ic))) > 1)
2521 /* if shift operation make sure right side is not a literal */
2522 if (ic->op == RIGHT_OP &&
2523 (isOperandLiteral (IC_RIGHT (ic)) ||
2524 getSize (operandType (IC_RESULT (ic))) > 1))
2527 if (ic->op == LEFT_OP &&
2528 (isOperandLiteral (IC_RIGHT (ic)) ||
2529 getSize (operandType (IC_RESULT (ic))) > 1))
2532 if (IS_BITWISE_OP (ic) &&
2533 getSize (operandType (IC_RESULT (ic))) > 1)
2537 /* has only one definition */
2538 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2541 /* has only one use */
2542 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2545 /* and the usage immediately follows this iCode */
2546 if (!(uic = hTabItemWithKey (iCodehTab,
2547 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2550 if (ic->next != uic)
2553 /* if it is a conditional branch then we definitely can */
2557 if (uic->op == JUMPTABLE)
2560 /* if the usage is not is an assignment
2561 or an arithmetic / bitwise / shift operation then not */
2562 if (POINTER_SET (uic) &&
2563 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2566 if (uic->op != '=' &&
2567 !IS_ARITHMETIC_OP (uic) &&
2568 !IS_BITWISE_OP (uic) &&
2569 uic->op != LEFT_OP &&
2570 uic->op != RIGHT_OP)
2573 /* if used in ^ operation then make sure right is not a
2575 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2578 /* if shift operation make sure right side is not a literal */
2579 if (uic->op == RIGHT_OP &&
2580 (isOperandLiteral (IC_RIGHT (uic)) ||
2581 getSize (operandType (IC_RESULT (uic))) > 1))
2584 if (uic->op == LEFT_OP &&
2585 (isOperandLiteral (IC_RIGHT (uic)) ||
2586 getSize (operandType (IC_RESULT (uic))) > 1))
2589 /* make sure that the result of this icode is not on the
2590 stack, since acc is used to compute stack offset */
2591 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2592 OP_SYMBOL (IC_RESULT (uic))->onStack)
2595 /* if either one of them in far space then we cannot */
2596 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2597 isOperandInFarSpace (IC_LEFT (uic))) ||
2598 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2599 isOperandInFarSpace (IC_RIGHT (uic))))
2602 /* if the usage has only one operand then we can */
2603 if (IC_LEFT (uic) == NULL ||
2604 IC_RIGHT (uic) == NULL)
2607 /* make sure this is on the left side if not
2608 a '+' since '+' is commutative */
2609 if (ic->op != '+' &&
2610 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2613 /* if one of them is a literal then we can */
2614 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2615 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2617 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2621 /* if the other one is not on stack then we can */
2622 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2623 (IS_ITEMP (IC_RIGHT (uic)) ||
2624 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2625 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2628 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2629 (IS_ITEMP (IC_LEFT (uic)) ||
2630 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2631 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2637 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2642 /*-----------------------------------------------------------------*/
2643 /* packForPush - hueristics to reduce iCode for pushing */
2644 /*-----------------------------------------------------------------*/
2646 packForReceive (iCode * ic, eBBlock * ebp)
2650 debugLog ("%s\n", __FUNCTION__);
2651 debugAopGet (" result:", IC_RESULT (ic));
2652 debugAopGet (" left:", IC_LEFT (ic));
2653 debugAopGet (" right:", IC_RIGHT (ic));
2658 for (dic = ic->next; dic; dic = dic->next)
2663 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
2664 debugLog (" used on left\n");
2665 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
2666 debugLog (" used on right\n");
2667 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
2668 debugLog (" used on result\n");
2670 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
2671 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
2676 debugLog (" hey we can remove this unnecessary assign\n");
2678 /*-----------------------------------------------------------------*/
2679 /* packForPush - hueristics to reduce iCode for pushing */
2680 /*-----------------------------------------------------------------*/
2682 packForPush (iCode * ic, eBBlock * ebp)
2686 debugLog ("%s\n", __FUNCTION__);
2687 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2690 /* must have only definition & one usage */
2691 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2692 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2695 /* find the definition */
2696 if (!(dic = hTabItemWithKey (iCodehTab,
2697 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2700 if (dic->op != '=' || POINTER_SET (dic))
2703 /* we now we know that it has one & only one def & use
2704 and the that the definition is an assignment */
2705 IC_LEFT (ic) = IC_RIGHT (dic);
2707 remiCodeFromeBBlock (ebp, dic);
2708 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2711 /*-----------------------------------------------------------------*/
2712 /* packRegisters - does some transformations to reduce register */
2714 /*-----------------------------------------------------------------*/
2716 packRegisters (eBBlock * ebp)
2721 debugLog ("%s\n", __FUNCTION__);
2728 /* look for assignments of the form */
2729 /* iTempNN = TRueSym (someoperation) SomeOperand */
2731 /* TrueSym := iTempNN:1 */
2732 for (ic = ebp->sch; ic; ic = ic->next)
2735 /* find assignment of the form TrueSym := iTempNN:1 */
2736 if (ic->op == '=' && !POINTER_SET (ic))
2737 change += packRegsForAssign (ic, ebp);
2741 if (POINTER_SET (ic))
2742 debugLog ("pointer is set\n");
2743 debugAopGet (" result:", IC_RESULT (ic));
2744 debugAopGet (" left:", IC_LEFT (ic));
2745 debugAopGet (" right:", IC_RIGHT (ic));
2754 for (ic = ebp->sch; ic; ic = ic->next)
2757 /* if this is an itemp & result of a address of a true sym
2758 then mark this as rematerialisable */
2759 if (ic->op == ADDRESS_OF &&
2760 IS_ITEMP (IC_RESULT (ic)) &&
2761 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2762 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2763 !OP_SYMBOL (IC_LEFT (ic))->onStack)
2766 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2767 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2768 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2772 /* if straight assignment then carry remat flag if
2773 this is the only definition */
2774 if (ic->op == '=' &&
2775 !POINTER_SET (ic) &&
2776 IS_SYMOP (IC_RIGHT (ic)) &&
2777 OP_SYMBOL (IC_RIGHT (ic))->remat &&
2778 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2781 OP_SYMBOL (IC_RESULT (ic))->remat =
2782 OP_SYMBOL (IC_RIGHT (ic))->remat;
2783 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2784 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2787 /* if this is a +/- operation with a rematerizable
2788 then mark this as rematerializable as well */
2789 if ((ic->op == '+' || ic->op == '-') &&
2790 (IS_SYMOP (IC_LEFT (ic)) &&
2791 IS_ITEMP (IC_RESULT (ic)) &&
2792 OP_SYMBOL (IC_LEFT (ic))->remat &&
2793 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2794 IS_OP_LITERAL (IC_RIGHT (ic))))
2798 operandLitValue (IC_RIGHT (ic));
2799 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2800 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2801 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2804 /* mark the pointer usages */
2805 if (POINTER_SET (ic))
2807 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2808 debugLog (" marking as a pointer (set)\n");
2810 if (POINTER_GET (ic))
2812 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2813 debugLog (" marking as a pointer (get)\n");
2818 /* if we are using a symbol on the stack
2819 then we should say pic14_ptrRegReq */
2820 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2821 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2822 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2823 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2824 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2825 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2828 if (IS_SYMOP (IC_LEFT (ic)))
2829 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2830 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2831 if (IS_SYMOP (IC_RIGHT (ic)))
2832 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2833 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2834 if (IS_SYMOP (IC_RESULT (ic)))
2835 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2836 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2840 /* if the condition of an if instruction
2841 is defined in the previous instruction then
2842 mark the itemp as a conditional */
2843 if ((IS_CONDITIONAL (ic) ||
2844 ((ic->op == BITWISEAND ||
2847 isBitwiseOptimizable (ic))) &&
2848 ic->next && ic->next->op == IFX &&
2849 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2850 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2853 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2857 /* reduce for support function calls */
2858 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2859 packRegsForSupport (ic, ebp);
2861 /* if a parameter is passed, it's in W, so we may not
2862 need to place a copy in a register */
2863 if (ic->op == RECEIVE)
2864 packForReceive (ic, ebp);
2866 /* some cases the redundant moves can
2867 can be eliminated for return statements */
2868 if ((ic->op == RETURN || ic->op == SEND) &&
2869 !isOperandInFarSpace (IC_LEFT (ic)) &&
2871 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2873 /* if pointer set & left has a size more than
2874 one and right is not in far space */
2875 if (POINTER_SET (ic) &&
2876 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2877 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2878 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2879 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2881 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2883 /* if pointer get */
2884 if (POINTER_GET (ic) &&
2885 !isOperandInFarSpace (IC_RESULT (ic)) &&
2886 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2887 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2888 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2890 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2893 /* if this is cast for intergral promotion then
2894 check if only use of the definition of the
2895 operand being casted/ if yes then replace
2896 the result of that arithmetic operation with
2897 this result and get rid of the cast */
2900 sym_link *fromType = operandType (IC_RIGHT (ic));
2901 sym_link *toType = operandType (IC_LEFT (ic));
2903 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2904 getSize (fromType) != getSize (toType))
2907 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2910 if (IS_ARITHMETIC_OP (dic))
2912 IC_RESULT (dic) = IC_RESULT (ic);
2913 remiCodeFromeBBlock (ebp, ic);
2914 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2915 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2919 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2925 /* if the type from and type to are the same
2926 then if this is the only use then packit */
2927 if (checkType (operandType (IC_RIGHT (ic)),
2928 operandType (IC_LEFT (ic))) == 1)
2930 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2933 IC_RESULT (dic) = IC_RESULT (ic);
2934 remiCodeFromeBBlock (ebp, ic);
2935 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2936 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2944 iTempNN := (some variable in farspace) V1
2949 if (ic->op == IPUSH)
2951 packForPush (ic, ebp);
2955 /* pack registers for accumulator use, when the
2956 result of an arithmetic or bit wise operation
2957 has only one use, that use is immediately following
2958 the defintion and the using iCode has only one
2959 operand or has two operands but one is literal &
2960 the result of that operation is not on stack then
2961 we can leave the result of this operation in acc:b
2963 if ((IS_ARITHMETIC_OP (ic)
2965 || IS_BITWISE_OP (ic)
2967 || ic->op == LEFT_OP || ic->op == RIGHT_OP
2970 IS_ITEMP (IC_RESULT (ic)) &&
2971 getSize (operandType (IC_RESULT (ic))) <= 2)
2973 packRegsForAccUse (ic);
2979 dumpEbbsToDebug (eBBlock ** ebbs, int count)
2983 if (!debug || !debugF)
2986 for (i = 0; i < count; i++)
2988 fprintf (debugF, "\n----------------------------------------------------------------\n");
2989 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
2990 ebbs[i]->entryLabel->name,
2993 ebbs[i]->isLastInLoop);
2994 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
2999 fprintf (debugF, "visited %d : hasFcall = %d\n",
3003 fprintf (debugF, "\ndefines bitVector :");
3004 bitVectDebugOn (ebbs[i]->defSet, debugF);
3005 fprintf (debugF, "\nlocal defines bitVector :");
3006 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3007 fprintf (debugF, "\npointers Set bitvector :");
3008 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3009 fprintf (debugF, "\nin pointers Set bitvector :");
3010 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3011 fprintf (debugF, "\ninDefs Set bitvector :");
3012 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3013 fprintf (debugF, "\noutDefs Set bitvector :");
3014 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3015 fprintf (debugF, "\nusesDefs Set bitvector :");
3016 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3017 fprintf (debugF, "\n----------------------------------------------------------------\n");
3018 printiCChain (ebbs[i]->sch, debugF);
3021 /*-----------------------------------------------------------------*/
3022 /* assignRegisters - assigns registers to each live range as need */
3023 /*-----------------------------------------------------------------*/
3025 pic14_assignRegisters (eBBlock ** ebbs, int count)
3030 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3031 debugLog ("ebbs before optimizing:\n");
3032 dumpEbbsToDebug (ebbs, count);
3034 setToNull ((void *) &_G.funcrUsed);
3035 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3038 /* change assignments this will remove some
3039 live ranges reducing some register pressure */
3040 for (i = 0; i < count; i++)
3041 packRegisters (ebbs[i]);
3043 if (options.dump_pack)
3044 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3046 /* first determine for each live range the number of
3047 registers & the type of registers required for each */
3050 /* and serially allocate registers */
3051 serialRegAssign (ebbs, count);
3053 /* if stack was extended then tell the user */
3056 /* werror(W_TOOMANY_SPILS,"stack", */
3057 /* _G.stackExtend,currFunc->name,""); */
3063 /* werror(W_TOOMANY_SPILS,"data space", */
3064 /* _G.dataExtend,currFunc->name,""); */
3068 /* after that create the register mask
3069 for each of the instruction */
3070 createRegMask (ebbs, count);
3072 /* redo that offsets for stacked automatic variables */
3073 redoStackOffsets ();
3075 if (options.dump_rassgn)
3076 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3078 /* now get back the chain */
3079 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3081 debugLog ("ebbs after optimizing:\n");
3082 dumpEbbsToDebug (ebbs, count);
3087 /* free up any _G.stackSpil locations allocated */
3088 applyToSet (_G.stackSpil, deallocStackSpil);
3090 setToNull ((void **) &_G.stackSpil);
3091 setToNull ((void **) &_G.spiltSet);
3092 /* mark all registers as free */
3093 pic14_freeAllRegs ();
3095 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");