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 */
61 /* A nasty, awful, disgusting hack for register declarations */
67 {REG_GPR, PO_GPR_TEMP, 0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0},
68 {REG_GPR, PO_GPR_TEMP, 0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0},
69 {REG_GPR, PO_GPR_TEMP, 0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0},
70 {REG_GPR, PO_GPR_TEMP, 0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0},
71 {REG_GPR, PO_GPR_TEMP, 0x10, "r0x10", "r0x10", 0x10, 1, 0},
72 {REG_GPR, PO_GPR_TEMP, 0x11, "r0x11", "r0x11", 0x11, 1, 0},
73 {REG_GPR, PO_GPR_TEMP, 0x12, "r0x12", "r0x12", 0x12, 1, 0},
74 {REG_GPR, PO_GPR_TEMP, 0x13, "r0x13", "r0x13", 0x13, 1, 0},
75 {REG_GPR, PO_GPR_TEMP, 0x14, "r0x14", "r0x14", 0x14, 1, 0},
76 {REG_GPR, PO_GPR_TEMP, 0x15, "r0x15", "r0x15", 0x15, 1, 0},
77 {REG_GPR, PO_GPR_TEMP, 0x16, "r0x16", "r0x16", 0x16, 1, 0},
78 {REG_GPR, PO_GPR_TEMP, 0x17, "r0x17", "r0x17", 0x17, 1, 0},
79 {REG_GPR, PO_GPR_TEMP, 0x18, "r0x18", "r0x18", 0x18, 1, 0},
80 {REG_GPR, PO_GPR_TEMP, 0x19, "r0x19", "r0x19", 0x19, 1, 0},
81 {REG_GPR, PO_GPR_TEMP, 0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0},
82 {REG_GPR, PO_GPR_TEMP, 0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0},
83 {REG_GPR, PO_GPR_TEMP, 0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0},
84 {REG_GPR, PO_GPR_TEMP, 0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0},
85 {REG_GPR, PO_GPR_TEMP, 0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0},
86 {REG_GPR, PO_GPR_TEMP, 0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0},
87 {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
93 {REG_GPR, PO_GPR_TEMP, 0x20, "r0x20", "r0x20", 0x20, 1, 0},
94 {REG_GPR, PO_GPR_TEMP, 0x21, "r0x21", "r0x21", 0x21, 1, 0},
95 {REG_GPR, PO_GPR_TEMP, 0x22, "r0x22", "r0x22", 0x22, 1, 0},
96 {REG_GPR, PO_GPR_TEMP, 0x23, "r0x23", "r0x23", 0x23, 1, 0},
97 {REG_GPR, PO_GPR_TEMP, 0x24, "r0x24", "r0x24", 0x24, 1, 0},
98 {REG_GPR, PO_GPR_TEMP, 0x25, "r0x25", "r0x25", 0x25, 1, 0},
99 {REG_GPR, PO_GPR_TEMP, 0x26, "r0x26", "r0x26", 0x26, 1, 0},
100 {REG_GPR, PO_GPR_TEMP, 0x27, "r0x27", "r0x27", 0x27, 1, 0},
101 {REG_GPR, PO_GPR_TEMP, 0x28, "r0x28", "r0x28", 0x28, 1, 0},
102 {REG_GPR, PO_GPR_TEMP, 0x29, "r0x29", "r0x29", 0x29, 1, 0},
103 {REG_GPR, PO_GPR_TEMP, 0x2A, "r0x2A", "r0x2A", 0x2A, 1, 0},
104 {REG_GPR, PO_GPR_TEMP, 0x2B, "r0x2B", "r0x2B", 0x2B, 1, 0},
105 {REG_GPR, PO_GPR_TEMP, 0x2C, "r0x2C", "r0x2C", 0x2C, 1, 0},
106 {REG_GPR, PO_GPR_TEMP, 0x2D, "r0x2D", "r0x2D", 0x2D, 1, 0},
107 {REG_GPR, PO_GPR_TEMP, 0x2E, "r0x2E", "r0x2E", 0x2E, 1, 0},
108 {REG_GPR, PO_GPR_TEMP, 0x2F, "r0x2F", "r0x2F", 0x2F, 1, 0},
109 {REG_GPR, PO_GPR_TEMP, 0x30, "r0x30", "r0x30", 0x30, 1, 0},
110 {REG_GPR, PO_GPR_TEMP, 0x31, "r0x31", "r0x31", 0x31, 1, 0},
111 {REG_GPR, PO_GPR_TEMP, 0x32, "r0x32", "r0x32", 0x32, 1, 0},
112 {REG_GPR, PO_GPR_TEMP, 0x33, "r0x33", "r0x33", 0x33, 1, 0},
113 {REG_GPR, PO_GPR_TEMP, 0x34, "r0x34", "r0x34", 0x34, 1, 0},
114 {REG_GPR, PO_GPR_TEMP, 0x35, "r0x35", "r0x35", 0x35, 1, 0},
115 {REG_GPR, PO_GPR_TEMP, 0x36, "r0x36", "r0x36", 0x36, 1, 0},
116 {REG_GPR, PO_GPR_TEMP, 0x37, "r0x37", "r0x37", 0x37, 1, 0},
118 {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
124 int pic14_nRegs = sizeof (regspic14) / sizeof (regs);
125 static void spillThis (symbol *);
126 static int debug = 1;
127 static FILE *debugF = NULL;
128 /*-----------------------------------------------------------------*/
129 /* debugLog - open a file for debugging information */
130 /*-----------------------------------------------------------------*/
131 //static void debugLog(char *inst,char *fmt, ...)
133 debugLog (char *fmt,...)
135 static int append = 0; // First time through, open the file without append.
138 //char *bufferP=buffer;
141 if (!debug || !srcFileName)
147 /* create the file name */
148 strcpy (buffer, srcFileName);
149 strcat (buffer, ".d");
151 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
153 werror (E_FILE_OPEN_ERR, buffer);
156 append = 1; // Next time debubLog is called, we'll append the debug info
162 vsprintf (buffer, fmt, ap);
164 fprintf (debugF, "%s", buffer);
166 while (isspace(*bufferP)) bufferP++;
168 if (bufferP && *bufferP)
169 lineCurr = (lineCurr ?
170 connectLine(lineCurr,newLineNode(lb)) :
171 (lineHead = newLineNode(lb)));
172 lineCurr->isInline = _G.inLine;
173 lineCurr->isDebug = _G.debugLine;
183 fputc ('\n', debugF);
185 /*-----------------------------------------------------------------*/
186 /* debugLogClose - closes the debug log file (if opened) */
187 /*-----------------------------------------------------------------*/
197 #define AOP(op) op->aop
200 debugAopGet (char *str, operand * op)
205 printOperand (op, debugF);
213 decodeOp (unsigned int op)
216 if (op < 128 && op > ' ')
218 buffer[0] = (op & 0xff);
232 return "STRING_LITERAL";
268 return "LEFT_ASSIGN";
270 return "RIGHT_ASSIGN";
385 case GET_VALUE_AT_ADDRESS:
386 return "GET_VALUE_AT_ADDRESS";
404 return "ENDFUNCTION";
428 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
431 /*-----------------------------------------------------------------*/
432 /*-----------------------------------------------------------------*/
434 debugLogRegType (short type)
447 sprintf (buffer, "unkown reg type %d", type);
451 /*-----------------------------------------------------------------*/
452 /* allocReg - allocates register of given type */
453 /*-----------------------------------------------------------------*/
455 allocReg (short type)
459 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
461 for (i = 0; i < pic14_nRegs; i++)
464 /* if type is given as 0 then any
465 free register will do */
469 regspic14[i].isFree = 0;
470 regspic14[i].wasUsed = 1;
473 bitVectSetBit (currFunc->regsUsed, i);
474 debugLog (" returning %s\n", regspic14[i].name);
475 return ®spic14[i];
477 /* other wise look for specific type
479 if (regspic14[i].isFree &&
480 regspic14[i].type == type)
482 regspic14[i].isFree = 0;
483 regspic14[i].wasUsed = 1;
486 bitVectSetBit (currFunc->regsUsed, i);
487 debugLog (" returning %s\n", regspic14[i].name);
488 return ®spic14[i];
494 /*-----------------------------------------------------------------*/
495 /* pic14_regWithIdx - returns pointer to register wit index number */
496 /*-----------------------------------------------------------------*/
498 pic14_regWithIdx (int idx)
502 debugLog ("%s\n", __FUNCTION__);
504 for (i = 0; i < pic14_nRegs; i++)
505 if (regspic14[i].rIdx == idx)
506 return ®spic14[i];
508 return ®spic14[0];
510 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
511 "regWithIdx not found");
515 /*-----------------------------------------------------------------*/
516 /*-----------------------------------------------------------------*/
518 pic14_findFreeReg(void)
522 for (i = 0; i < pic14_nRegs; i++)
523 if (regspic14[i].isFree)
524 return ®spic14[i];
528 /*-----------------------------------------------------------------*/
529 /* freeReg - frees a register */
530 /*-----------------------------------------------------------------*/
534 debugLog ("%s\n", __FUNCTION__);
539 /*-----------------------------------------------------------------*/
540 /* nFreeRegs - returns number of free registers */
541 /*-----------------------------------------------------------------*/
548 debugLog ("%s\n", __FUNCTION__);
549 for (i = 0; i < pic14_nRegs; i++)
550 if (regspic14[i].isFree && regspic14[i].type == type)
555 /*-----------------------------------------------------------------*/
556 /* nfreeRegsType - free registers with type */
557 /*-----------------------------------------------------------------*/
559 nfreeRegsType (int type)
562 debugLog ("%s\n", __FUNCTION__);
565 if ((nfr = nFreeRegs (type)) == 0)
566 return nFreeRegs (REG_GPR);
569 return nFreeRegs (type);
573 /*-----------------------------------------------------------------*/
574 /* allDefsOutOfRange - all definitions are out of a range */
575 /*-----------------------------------------------------------------*/
577 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
581 debugLog ("%s\n", __FUNCTION__);
585 for (i = 0; i < defs->size; i++)
589 if (bitVectBitValue (defs, i) &&
590 (ic = hTabItemWithKey (iCodehTab, i)) &&
591 (ic->seq >= fseq && ic->seq <= toseq))
600 /*-----------------------------------------------------------------*/
601 /* computeSpillable - given a point find the spillable live ranges */
602 /*-----------------------------------------------------------------*/
604 computeSpillable (iCode * ic)
608 debugLog ("%s\n", __FUNCTION__);
609 /* spillable live ranges are those that are live at this
610 point . the following categories need to be subtracted
612 a) - those that are already spilt
613 b) - if being used by this one
614 c) - defined by this one */
616 spillable = bitVectCopy (ic->rlive);
618 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
620 bitVectCplAnd (spillable, ic->uses); /* used in this one */
621 bitVectUnSetBit (spillable, ic->defKey);
622 spillable = bitVectIntersect (spillable, _G.regAssigned);
627 /*-----------------------------------------------------------------*/
628 /* noSpilLoc - return true if a variable has no spil location */
629 /*-----------------------------------------------------------------*/
631 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
633 debugLog ("%s\n", __FUNCTION__);
634 return (sym->usl.spillLoc ? 0 : 1);
637 /*-----------------------------------------------------------------*/
638 /* hasSpilLoc - will return 1 if the symbol has spil location */
639 /*-----------------------------------------------------------------*/
641 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
643 debugLog ("%s\n", __FUNCTION__);
644 return (sym->usl.spillLoc ? 1 : 0);
647 /*-----------------------------------------------------------------*/
648 /* directSpilLoc - will return 1 if the splilocation is in direct */
649 /*-----------------------------------------------------------------*/
651 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
653 debugLog ("%s\n", __FUNCTION__);
654 if (sym->usl.spillLoc &&
655 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
661 /*-----------------------------------------------------------------*/
662 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
663 /* but is not used as a pointer */
664 /*-----------------------------------------------------------------*/
666 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
668 debugLog ("%s\n", __FUNCTION__);
669 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
672 /*-----------------------------------------------------------------*/
673 /* rematable - will return 1 if the remat flag is set */
674 /*-----------------------------------------------------------------*/
676 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
678 debugLog ("%s\n", __FUNCTION__);
682 /*-----------------------------------------------------------------*/
683 /* notUsedInBlock - not used in this block */
684 /*-----------------------------------------------------------------*/
686 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
688 debugLog ("%s\n", __FUNCTION__);
689 return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
690 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
691 /* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
694 /*-----------------------------------------------------------------*/
695 /* notUsedInRemaining - not used or defined in remain of the block */
696 /*-----------------------------------------------------------------*/
698 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
700 debugLog ("%s\n", __FUNCTION__);
701 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
702 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
705 /*-----------------------------------------------------------------*/
706 /* allLRs - return true for all */
707 /*-----------------------------------------------------------------*/
709 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
711 debugLog ("%s\n", __FUNCTION__);
715 /*-----------------------------------------------------------------*/
716 /* liveRangesWith - applies function to a given set of live range */
717 /*-----------------------------------------------------------------*/
719 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
720 eBBlock * ebp, iCode * ic)
725 debugLog ("%s\n", __FUNCTION__);
726 if (!lrs || !lrs->size)
729 for (i = 1; i < lrs->size; i++)
732 if (!bitVectBitValue (lrs, i))
735 /* if we don't find it in the live range
736 hash table we are in serious trouble */
737 if (!(sym = hTabItemWithKey (liveRanges, i)))
739 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
740 "liveRangesWith could not find liveRange");
744 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
745 addSetHead (&rset, sym);
752 /*-----------------------------------------------------------------*/
753 /* leastUsedLR - given a set determines which is the least used */
754 /*-----------------------------------------------------------------*/
756 leastUsedLR (set * sset)
758 symbol *sym = NULL, *lsym = NULL;
760 debugLog ("%s\n", __FUNCTION__);
761 sym = lsym = setFirstItem (sset);
766 for (; lsym; lsym = setNextItem (sset))
769 /* if usage is the same then prefer
770 the spill the smaller of the two */
771 if (lsym->used == sym->used)
772 if (getSize (lsym->type) < getSize (sym->type))
776 if (lsym->used < sym->used)
781 setToNull ((void **) &sset);
786 /*-----------------------------------------------------------------*/
787 /* noOverLap - will iterate through the list looking for over lap */
788 /*-----------------------------------------------------------------*/
790 noOverLap (set * itmpStack, symbol * fsym)
793 debugLog ("%s\n", __FUNCTION__);
796 for (sym = setFirstItem (itmpStack); sym;
797 sym = setNextItem (itmpStack))
799 if (sym->liveTo > fsym->liveFrom)
807 /*-----------------------------------------------------------------*/
808 /* isFree - will return 1 if the a free spil location is found */
809 /*-----------------------------------------------------------------*/
814 V_ARG (symbol **, sloc);
815 V_ARG (symbol *, fsym);
817 debugLog ("%s\n", __FUNCTION__);
818 /* if already found */
822 /* if it is free && and the itmp assigned to
823 this does not have any overlapping live ranges
824 with the one currently being assigned and
825 the size can be accomodated */
827 noOverLap (sym->usl.itmpStack, fsym) &&
828 getSize (sym->type) >= getSize (fsym->type))
837 /*-----------------------------------------------------------------*/
838 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
839 /*-----------------------------------------------------------------*/
841 spillLRWithPtrReg (symbol * forSym)
847 debugLog ("%s\n", __FUNCTION__);
848 if (!_G.regAssigned ||
849 bitVectIsZero (_G.regAssigned))
852 r0 = pic14_regWithIdx (R0_IDX);
853 r1 = pic14_regWithIdx (R1_IDX);
855 /* for all live ranges */
856 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
857 lrsym = hTabNextItem (liveRanges, &k))
861 /* if no registers assigned to it or
863 /* if it does not overlap with this then
864 not need to spill it */
866 if (lrsym->isspilt || !lrsym->nRegs ||
867 (lrsym->liveTo < forSym->liveFrom))
870 /* go thru the registers : if it is either
871 r0 or r1 then spil it */
872 for (j = 0; j < lrsym->nRegs; j++)
873 if (lrsym->regs[j] == r0 ||
874 lrsym->regs[j] == r1)
883 /*-----------------------------------------------------------------*/
884 /* createStackSpil - create a location on the stack to spil */
885 /*-----------------------------------------------------------------*/
887 createStackSpil (symbol * sym)
890 int useXstack, model, noOverlay;
893 debugLog ("%s\n", __FUNCTION__);
895 /* first go try and find a free one that is already
896 existing on the stack */
897 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
899 /* found a free one : just update & return */
900 sym->usl.spillLoc = sloc;
903 addSetHead (&sloc->usl.itmpStack, sym);
907 /* could not then have to create one , this is the hard part
908 we need to allocate this on the stack : this is really a
909 hack!! but cannot think of anything better at this time */
911 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
913 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
918 sloc = newiTemp (slocBuffer);
920 /* set the type to the spilling symbol */
921 sloc->type = copyLinkChain (sym->type);
922 sloc->etype = getSpec (sloc->type);
923 SPEC_SCLS (sloc->etype) = S_DATA;
924 SPEC_EXTR (sloc->etype) = 0;
926 /* we don't allow it to be allocated`
927 onto the external stack since : so we
928 temporarily turn it off ; we also
929 turn off memory model to prevent
930 the spil from going to the external storage
931 and turn off overlaying
934 useXstack = options.useXstack;
935 model = options.model;
936 noOverlay = options.noOverlay;
937 options.noOverlay = 1;
938 options.model = options.useXstack = 0;
942 options.useXstack = useXstack;
943 options.model = model;
944 options.noOverlay = noOverlay;
945 sloc->isref = 1; /* to prevent compiler warning */
947 /* if it is on the stack then update the stack */
948 if (IN_STACK (sloc->etype))
950 currFunc->stack += getSize (sloc->type);
951 _G.stackExtend += getSize (sloc->type);
954 _G.dataExtend += getSize (sloc->type);
956 /* add it to the _G.stackSpil set */
957 addSetHead (&_G.stackSpil, sloc);
958 sym->usl.spillLoc = sloc;
961 /* add it to the set of itempStack set
962 of the spill location */
963 addSetHead (&sloc->usl.itmpStack, sym);
967 /*-----------------------------------------------------------------*/
968 /* isSpiltOnStack - returns true if the spil location is on stack */
969 /*-----------------------------------------------------------------*/
971 isSpiltOnStack (symbol * sym)
975 debugLog ("%s\n", __FUNCTION__);
982 /* if (sym->_G.stackSpil) */
985 if (!sym->usl.spillLoc)
988 etype = getSpec (sym->usl.spillLoc->type);
989 if (IN_STACK (etype))
995 /*-----------------------------------------------------------------*/
996 /* spillThis - spils a specific operand */
997 /*-----------------------------------------------------------------*/
999 spillThis (symbol * sym)
1002 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1004 /* if this is rematerializable or has a spillLocation
1005 we are okay, else we need to create a spillLocation
1007 if (!(sym->remat || sym->usl.spillLoc))
1008 createStackSpil (sym);
1011 /* mark it has spilt & put it in the spilt set */
1013 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1015 bitVectUnSetBit (_G.regAssigned, sym->key);
1017 for (i = 0; i < sym->nRegs; i++)
1021 freeReg (sym->regs[i]);
1022 sym->regs[i] = NULL;
1025 /* if spilt on stack then free up r0 & r1
1026 if they could have been assigned to some
1028 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1031 spillLRWithPtrReg (sym);
1034 if (sym->usl.spillLoc && !sym->remat)
1035 sym->usl.spillLoc->allocreq = 1;
1039 /*-----------------------------------------------------------------*/
1040 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1041 /*-----------------------------------------------------------------*/
1043 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1045 bitVect *lrcs = NULL;
1049 debugLog ("%s\n", __FUNCTION__);
1050 /* get the spillable live ranges */
1051 lrcs = computeSpillable (ic);
1053 /* get all live ranges that are rematerizable */
1054 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1057 /* return the least used of these */
1058 return leastUsedLR (selectS);
1061 /* get live ranges with spillLocations in direct space */
1062 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1064 sym = leastUsedLR (selectS);
1065 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1066 sym->usl.spillLoc->rname :
1067 sym->usl.spillLoc->name));
1069 /* mark it as allocation required */
1070 sym->usl.spillLoc->allocreq = 1;
1074 /* if the symbol is local to the block then */
1075 if (forSym->liveTo < ebp->lSeq)
1078 /* check if there are any live ranges allocated
1079 to registers that are not used in this block */
1080 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1082 sym = leastUsedLR (selectS);
1083 /* if this is not rematerializable */
1092 /* check if there are any live ranges that not
1093 used in the remainder of the block */
1094 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1096 sym = leastUsedLR (selectS);
1099 sym->remainSpil = 1;
1106 /* find live ranges with spillocation && not used as pointers */
1107 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1110 sym = leastUsedLR (selectS);
1111 /* mark this as allocation required */
1112 sym->usl.spillLoc->allocreq = 1;
1116 /* find live ranges with spillocation */
1117 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1120 sym = leastUsedLR (selectS);
1121 sym->usl.spillLoc->allocreq = 1;
1125 /* couldn't find then we need to create a spil
1126 location on the stack , for which one? the least
1128 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1131 /* return a created spil location */
1132 sym = createStackSpil (leastUsedLR (selectS));
1133 sym->usl.spillLoc->allocreq = 1;
1137 /* this is an extreme situation we will spill
1138 this one : happens very rarely but it does happen */
1144 /*-----------------------------------------------------------------*/
1145 /* spilSomething - spil some variable & mark registers as free */
1146 /*-----------------------------------------------------------------*/
1148 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1153 debugLog ("%s\n", __FUNCTION__);
1154 /* get something we can spil */
1155 ssym = selectSpil (ic, ebp, forSym);
1157 /* mark it as spilt */
1159 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1161 /* mark it as not register assigned &
1162 take it away from the set */
1163 bitVectUnSetBit (_G.regAssigned, ssym->key);
1165 /* mark the registers as free */
1166 for (i = 0; i < ssym->nRegs; i++)
1168 freeReg (ssym->regs[i]);
1170 /* if spilt on stack then free up r0 & r1
1171 if they could have been assigned to as gprs */
1172 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1175 spillLRWithPtrReg (ssym);
1178 /* if this was a block level spil then insert push & pop
1179 at the start & end of block respectively */
1180 if (ssym->blockSpil)
1182 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1183 /* add push to the start of the block */
1184 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1185 ebp->sch->next : ebp->sch));
1186 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1187 /* add pop to the end of the block */
1188 addiCodeToeBBlock (ebp, nic, NULL);
1191 /* if spilt because not used in the remainder of the
1192 block then add a push before this instruction and
1193 a pop at the end of the block */
1194 if (ssym->remainSpil)
1197 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1198 /* add push just before this instruction */
1199 addiCodeToeBBlock (ebp, nic, ic);
1201 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1202 /* add pop to the end of the block */
1203 addiCodeToeBBlock (ebp, nic, NULL);
1212 /*-----------------------------------------------------------------*/
1213 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1214 /*-----------------------------------------------------------------*/
1216 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1220 debugLog ("%s\n", __FUNCTION__);
1222 /* try for a ptr type */
1223 if ((reg = allocReg (REG_PTR)))
1226 /* try for gpr type */
1227 if ((reg = allocReg (REG_GPR)))
1230 /* we have to spil */
1231 if (!spilSomething (ic, ebp, sym))
1234 /* this looks like an infinite loop but
1235 in really selectSpil will abort */
1239 /*-----------------------------------------------------------------*/
1240 /* getRegGpr - will try for GPR if not spil */
1241 /*-----------------------------------------------------------------*/
1243 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1247 debugLog ("%s\n", __FUNCTION__);
1249 /* try for gpr type */
1250 if ((reg = allocReg (REG_GPR)))
1253 if (!pic14_ptrRegReq)
1254 if ((reg = allocReg (REG_PTR)))
1257 /* we have to spil */
1258 if (!spilSomething (ic, ebp, sym))
1261 /* this looks like an infinite loop but
1262 in really selectSpil will abort */
1266 /*-----------------------------------------------------------------*/
1267 /* symHasReg - symbol has a given register */
1268 /*-----------------------------------------------------------------*/
1270 symHasReg (symbol * sym, regs * reg)
1274 debugLog ("%s\n", __FUNCTION__);
1275 for (i = 0; i < sym->nRegs; i++)
1276 if (sym->regs[i] == reg)
1282 /*-----------------------------------------------------------------*/
1283 /* deassignLRs - check the live to and if they have registers & are */
1284 /* not spilt then free up the registers */
1285 /*-----------------------------------------------------------------*/
1287 deassignLRs (iCode * ic, eBBlock * ebp)
1293 debugLog ("%s\n", __FUNCTION__);
1294 for (sym = hTabFirstItem (liveRanges, &k); sym;
1295 sym = hTabNextItem (liveRanges, &k))
1298 symbol *psym = NULL;
1299 /* if it does not end here */
1300 if (sym->liveTo > ic->seq)
1303 /* if it was spilt on stack then we can
1304 mark the stack spil location as free */
1309 sym->usl.spillLoc->isFree = 1;
1315 if (!bitVectBitValue (_G.regAssigned, sym->key))
1318 /* special case check if this is an IFX &
1319 the privious one was a pop and the
1320 previous one was not spilt then keep track
1322 if (ic->op == IFX && ic->prev &&
1323 ic->prev->op == IPOP &&
1324 !ic->prev->parmPush &&
1325 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1326 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1332 bitVectUnSetBit (_G.regAssigned, sym->key);
1334 /* if the result of this one needs registers
1335 and does not have it then assign it right
1337 if (IC_RESULT (ic) &&
1338 !(SKIP_IC2 (ic) || /* not a special icode */
1339 ic->op == JUMPTABLE ||
1344 POINTER_SET (ic)) &&
1345 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1346 result->liveTo > ic->seq && /* and will live beyond this */
1347 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1348 result->regType == sym->regType && /* same register types */
1349 result->nRegs && /* which needs registers */
1350 !result->isspilt && /* and does not already have them */
1352 !bitVectBitValue (_G.regAssigned, result->key) &&
1353 /* the number of free regs + number of regs in this LR
1354 can accomodate the what result Needs */
1355 ((nfreeRegsType (result->regType) +
1356 sym->nRegs) >= result->nRegs)
1360 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1362 result->regs[i] = sym->regs[i];
1364 result->regs[i] = getRegGpr (ic, ebp, result);
1366 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1370 /* free the remaining */
1371 for (; i < sym->nRegs; i++)
1375 if (!symHasReg (psym, sym->regs[i]))
1376 freeReg (sym->regs[i]);
1379 freeReg (sym->regs[i]);
1386 /*-----------------------------------------------------------------*/
1387 /* reassignLR - reassign this to registers */
1388 /*-----------------------------------------------------------------*/
1390 reassignLR (operand * op)
1392 symbol *sym = OP_SYMBOL (op);
1395 debugLog ("%s\n", __FUNCTION__);
1396 /* not spilt any more */
1397 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1398 bitVectUnSetBit (_G.spiltSet, sym->key);
1400 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1404 for (i = 0; i < sym->nRegs; i++)
1405 sym->regs[i]->isFree = 0;
1408 /*-----------------------------------------------------------------*/
1409 /* willCauseSpill - determines if allocating will cause a spill */
1410 /*-----------------------------------------------------------------*/
1412 willCauseSpill (int nr, int rt)
1414 debugLog ("%s\n", __FUNCTION__);
1415 /* first check if there are any avlb registers
1416 of te type required */
1419 /* special case for pointer type
1420 if pointer type not avlb then
1421 check for type gpr */
1422 if (nFreeRegs (rt) >= nr)
1424 if (nFreeRegs (REG_GPR) >= nr)
1429 if (pic14_ptrRegReq)
1431 if (nFreeRegs (rt) >= nr)
1436 if (nFreeRegs (REG_PTR) +
1437 nFreeRegs (REG_GPR) >= nr)
1442 debugLog (" ... yep it will (cause a spill)\n");
1443 /* it will cause a spil */
1447 /*-----------------------------------------------------------------*/
1448 /* positionRegs - the allocator can allocate same registers to res- */
1449 /* ult and operand, if this happens make sure they are in the same */
1450 /* position as the operand otherwise chaos results */
1451 /*-----------------------------------------------------------------*/
1453 positionRegs (symbol * result, symbol * opsym, int lineno)
1455 int count = min (result->nRegs, opsym->nRegs);
1456 int i, j = 0, shared = 0;
1458 debugLog ("%s\n", __FUNCTION__);
1459 /* if the result has been spilt then cannot share */
1464 /* first make sure that they actually share */
1465 for (i = 0; i < count; i++)
1467 for (j = 0; j < count; j++)
1469 if (result->regs[i] == opsym->regs[j] && i != j)
1479 regs *tmp = result->regs[i];
1480 result->regs[i] = result->regs[j];
1481 result->regs[j] = tmp;
1486 /*-----------------------------------------------------------------*/
1487 /* serialRegAssign - serially allocate registers to the variables */
1488 /*-----------------------------------------------------------------*/
1490 serialRegAssign (eBBlock ** ebbs, int count)
1494 debugLog ("%s\n", __FUNCTION__);
1495 /* for all blocks */
1496 for (i = 0; i < count; i++)
1501 if (ebbs[i]->noPath &&
1502 (ebbs[i]->entryLabel != entryLabel &&
1503 ebbs[i]->entryLabel != returnLabel))
1506 /* of all instructions do */
1507 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1510 debugLog (" op: %s\n", decodeOp (ic->op));
1512 /* if this is an ipop that means some live
1513 range will have to be assigned again */
1515 reassignLR (IC_LEFT (ic));
1517 /* if result is present && is a true symbol */
1518 if (IC_RESULT (ic) && ic->op != IFX &&
1519 IS_TRUE_SYMOP (IC_RESULT (ic)))
1520 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1522 /* take away registers from live
1523 ranges that end at this instruction */
1524 deassignLRs (ic, ebbs[i]);
1526 /* some don't need registers */
1527 if (SKIP_IC2 (ic) ||
1528 ic->op == JUMPTABLE ||
1532 (IC_RESULT (ic) && POINTER_SET (ic)))
1535 /* now we need to allocate registers
1536 only for the result */
1539 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1545 /* if it does not need or is spilt
1546 or is already assigned to registers
1547 or will not live beyond this instructions */
1550 bitVectBitValue (_G.regAssigned, sym->key) ||
1551 sym->liveTo <= ic->seq)
1554 /* if some liverange has been spilt at the block level
1555 and this one live beyond this block then spil this
1557 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1562 /* if trying to allocate this will cause
1563 a spill and there is nothing to spill
1564 or this one is rematerializable then
1566 willCS = willCauseSpill (sym->nRegs, sym->regType);
1567 spillable = computeSpillable (ic);
1569 (willCS && bitVectIsZero (spillable)))
1577 /* if it has a spillocation & is used less than
1578 all other live ranges then spill this */
1580 if (sym->usl.spillLoc) {
1581 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1582 allLRs, ebbs[i], ic));
1583 if (leastUsed && leastUsed->used > sym->used) {
1588 /* if none of the liveRanges have a spillLocation then better
1589 to spill this one than anything else already assigned to registers */
1590 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1597 if (ic->op == RECEIVE)
1598 debugLog ("When I get clever, I'll optimize the receive logic\n");
1600 /* if we need ptr regs for the right side
1602 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
1603 <= (unsigned) PTRSIZE)
1608 /* else we assign registers to it */
1609 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1611 debugLog (" %d - \n", __LINE__);
1613 for (j = 0; j < sym->nRegs; j++)
1615 if (sym->regType == REG_PTR)
1616 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1618 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1620 /* if the allocation falied which means
1621 this was spilt then break */
1625 debugLog (" %d - \n", __LINE__);
1627 /* if it shares registers with operands make sure
1628 that they are in the same position */
1629 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1630 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1631 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1632 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1633 /* do the same for the right operand */
1634 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1635 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
1636 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1637 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1639 debugLog (" %d - \n", __LINE__);
1642 debugLog (" %d - \n", __LINE__);
1652 /*-----------------------------------------------------------------*/
1653 /* rUmaskForOp :- returns register mask for an operand */
1654 /*-----------------------------------------------------------------*/
1656 rUmaskForOp (operand * op)
1662 debugLog ("%s\n", __FUNCTION__);
1663 /* only temporaries are assigned registers */
1667 sym = OP_SYMBOL (op);
1669 /* if spilt or no registers assigned to it
1671 if (sym->isspilt || !sym->nRegs)
1674 rumask = newBitVect (pic14_nRegs);
1676 for (j = 0; j < sym->nRegs; j++)
1678 rumask = bitVectSetBit (rumask,
1679 sym->regs[j]->rIdx);
1685 /*-----------------------------------------------------------------*/
1686 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1687 /*-----------------------------------------------------------------*/
1689 regsUsedIniCode (iCode * ic)
1691 bitVect *rmask = newBitVect (pic14_nRegs);
1693 debugLog ("%s\n", __FUNCTION__);
1694 /* do the special cases first */
1697 rmask = bitVectUnion (rmask,
1698 rUmaskForOp (IC_COND (ic)));
1702 /* for the jumptable */
1703 if (ic->op == JUMPTABLE)
1705 rmask = bitVectUnion (rmask,
1706 rUmaskForOp (IC_JTCOND (ic)));
1711 /* of all other cases */
1713 rmask = bitVectUnion (rmask,
1714 rUmaskForOp (IC_LEFT (ic)));
1718 rmask = bitVectUnion (rmask,
1719 rUmaskForOp (IC_RIGHT (ic)));
1722 rmask = bitVectUnion (rmask,
1723 rUmaskForOp (IC_RESULT (ic)));
1729 /*-----------------------------------------------------------------*/
1730 /* createRegMask - for each instruction will determine the regsUsed */
1731 /*-----------------------------------------------------------------*/
1733 createRegMask (eBBlock ** ebbs, int count)
1737 debugLog ("%s\n", __FUNCTION__);
1738 /* for all blocks */
1739 for (i = 0; i < count; i++)
1743 if (ebbs[i]->noPath &&
1744 (ebbs[i]->entryLabel != entryLabel &&
1745 ebbs[i]->entryLabel != returnLabel))
1748 /* for all instructions */
1749 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1754 if (SKIP_IC2 (ic) || !ic->rlive)
1757 /* first mark the registers used in this
1759 ic->rUsed = regsUsedIniCode (ic);
1760 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1762 /* now create the register mask for those
1763 registers that are in use : this is a
1764 super set of ic->rUsed */
1765 ic->rMask = newBitVect (pic14_nRegs + 1);
1767 /* for all live Ranges alive at this point */
1768 for (j = 1; j < ic->rlive->size; j++)
1773 /* if not alive then continue */
1774 if (!bitVectBitValue (ic->rlive, j))
1777 /* find the live range we are interested in */
1778 if (!(sym = hTabItemWithKey (liveRanges, j)))
1780 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1781 "createRegMask cannot find live range");
1785 /* if no register assigned to it */
1786 if (!sym->nRegs || sym->isspilt)
1789 /* for all the registers allocated to it */
1790 for (k = 0; k < sym->nRegs; k++)
1793 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1799 /*-----------------------------------------------------------------*/
1800 /* rematStr - returns the rematerialized string for a remat var */
1801 /*-----------------------------------------------------------------*/
1803 rematStr (symbol * sym)
1806 iCode *ic = sym->rematiCode;
1808 debugLog ("%s\n", __FUNCTION__);
1813 /* if plus or minus print the right hand side */
1815 if (ic->op == '+' || ic->op == '-') {
1816 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1819 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1823 if (ic->op == '+' || ic->op == '-')
1825 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1826 sprintf (s, "(%s %c 0x%04x)",
1827 OP_SYMBOL (IC_LEFT (ric))->rname,
1829 (int) operandLitValue (IC_RIGHT (ic)));
1832 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1837 /* we reached the end */
1838 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1842 printf ("%s\n", buffer);
1846 /*-----------------------------------------------------------------*/
1847 /* regTypeNum - computes the type & number of registers required */
1848 /*-----------------------------------------------------------------*/
1856 debugLog ("%s\n", __FUNCTION__);
1857 /* for each live range do */
1858 for (sym = hTabFirstItem (liveRanges, &k); sym;
1859 sym = hTabNextItem (liveRanges, &k))
1862 debugLog (" %d - %s\n", __LINE__, sym->rname);
1864 /* if used zero times then no registers needed */
1865 if ((sym->liveTo - sym->liveFrom) == 0)
1869 /* if the live range is a temporary */
1873 debugLog (" %d - \n", __LINE__);
1875 /* if the type is marked as a conditional */
1876 if (sym->regType == REG_CND)
1879 /* if used in return only then we don't
1881 if (sym->ruonly || sym->accuse)
1883 if (IS_AGGREGATE (sym->type) || sym->isptr)
1884 sym->type = aggrToPtr (sym->type, FALSE);
1885 debugLog (" %d - \n", __LINE__);
1890 /* if the symbol has only one definition &
1891 that definition is a get_pointer and the
1892 pointer we are getting is rematerializable and
1895 if (bitVectnBitsOn (sym->defs) == 1 &&
1896 (ic = hTabItemWithKey (iCodehTab,
1897 bitVectFirstBit (sym->defs))) &&
1900 !IS_BITVAR (sym->etype))
1903 debugLog (" %d - \n", __LINE__);
1905 /* if remat in data space */
1906 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1907 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1910 /* create a psuedo symbol & force a spil */
1911 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1912 psym->type = sym->type;
1913 psym->etype = sym->etype;
1914 strcpy (psym->rname, psym->name);
1916 sym->usl.spillLoc = psym;
1920 /* if in data space or idata space then try to
1921 allocate pointer register */
1925 /* if not then we require registers */
1926 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1927 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1928 getSize (sym->type));
1932 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1933 printTypeChain (sym->type, stderr);
1934 fprintf (stderr, "\n");
1937 debugLog (" %d - \n", __LINE__);
1939 /* determine the type of register required */
1940 if (sym->nRegs == 1 &&
1941 IS_PTR (sym->type) &&
1943 sym->regType = REG_PTR;
1945 sym->regType = REG_GPR;
1946 debugLog (" reg type %s\n", debugLogRegType (sym->regType));
1950 /* for the first run we don't provide */
1951 /* registers for true symbols we will */
1952 /* see how things go */
1958 /*-----------------------------------------------------------------*/
1959 /* freeAllRegs - mark all registers as free */
1960 /*-----------------------------------------------------------------*/
1962 pic14_freeAllRegs ()
1966 debugLog ("%s\n", __FUNCTION__);
1967 for (i = 0; i < pic14_nRegs; i++)
1968 regspic14[i].isFree = 1;
1971 /*-----------------------------------------------------------------*/
1972 /*-----------------------------------------------------------------*/
1974 pic14_deallocateAllRegs ()
1978 debugLog ("%s\n", __FUNCTION__);
1979 for (i = 0; i < pic14_nRegs; i++) {
1980 regspic14[i].isFree = 1;
1981 regspic14[i].wasUsed = 0;
1986 /*-----------------------------------------------------------------*/
1987 /* deallocStackSpil - this will set the stack pointer back */
1988 /*-----------------------------------------------------------------*/
1990 DEFSETFUNC (deallocStackSpil)
1994 debugLog ("%s\n", __FUNCTION__);
1999 /*-----------------------------------------------------------------*/
2000 /* farSpacePackable - returns the packable icode for far variables */
2001 /*-----------------------------------------------------------------*/
2003 farSpacePackable (iCode * ic)
2007 debugLog ("%s\n", __FUNCTION__);
2008 /* go thru till we find a definition for the
2009 symbol on the right */
2010 for (dic = ic->prev; dic; dic = dic->prev)
2013 /* if the definition is a call then no */
2014 if ((dic->op == CALL || dic->op == PCALL) &&
2015 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2020 /* if shift by unknown amount then not */
2021 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2022 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2025 /* if pointer get and size > 1 */
2026 if (POINTER_GET (dic) &&
2027 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2030 if (POINTER_SET (dic) &&
2031 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2034 /* if any three is a true symbol in far space */
2035 if (IC_RESULT (dic) &&
2036 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2037 isOperandInFarSpace (IC_RESULT (dic)))
2040 if (IC_RIGHT (dic) &&
2041 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2042 isOperandInFarSpace (IC_RIGHT (dic)) &&
2043 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2046 if (IC_LEFT (dic) &&
2047 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2048 isOperandInFarSpace (IC_LEFT (dic)) &&
2049 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2052 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2054 if ((dic->op == LEFT_OP ||
2055 dic->op == RIGHT_OP ||
2057 IS_OP_LITERAL (IC_RIGHT (dic)))
2067 /*-----------------------------------------------------------------*/
2068 /* packRegsForAssign - register reduction for assignment */
2069 /*-----------------------------------------------------------------*/
2071 packRegsForAssign (iCode * ic, eBBlock * ebp)
2076 debugLog ("%s\n", __FUNCTION__);
2078 debugAopGet (" result:", IC_RESULT (ic));
2079 debugAopGet (" left:", IC_LEFT (ic));
2080 debugAopGet (" right:", IC_RIGHT (ic));
2082 if (!IS_ITEMP (IC_RIGHT (ic)) ||
2083 OP_SYMBOL (IC_RIGHT (ic))->isind ||
2084 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2089 /* if the true symbol is defined in far space or on stack
2090 then we should not since this will increase register pressure */
2091 if (isOperandInFarSpace (IC_RESULT (ic)))
2093 if ((dic = farSpacePackable (ic)))
2099 /* find the definition of iTempNN scanning backwards if we find a
2100 a use of the true symbol before we find the definition then
2102 for (dic = ic->prev; dic; dic = dic->prev)
2105 /* if there is a function call and this is
2106 a parameter & not my parameter then don't pack it */
2107 if ((dic->op == CALL || dic->op == PCALL) &&
2108 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2109 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2111 debugLog (" %d - \n", __LINE__);
2119 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2120 IS_OP_VOLATILE (IC_RESULT (dic)))
2122 debugLog (" %d - \n", __LINE__);
2127 if (IS_SYMOP (IC_RESULT (dic)) &&
2128 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2130 debugLog (" %d - dic key == ic key -- pointer set=%c\n", __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2131 if (POINTER_SET (dic))
2137 if (IS_SYMOP (IC_RIGHT (dic)) &&
2138 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2139 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2141 debugLog (" %d - \n", __LINE__);
2146 if (IS_SYMOP (IC_LEFT (dic)) &&
2147 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2148 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2150 debugLog (" %d - \n", __LINE__);
2155 if (POINTER_SET (dic) &&
2156 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2158 debugLog (" %d - \n", __LINE__);
2165 return 0; /* did not find */
2167 /* if the result is on stack or iaccess then it must be
2168 the same atleast one of the operands */
2169 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2170 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2173 /* the operation has only one symbol
2174 operator then we can pack */
2175 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2176 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2179 if (!((IC_LEFT (dic) &&
2180 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2182 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2186 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2187 /* found the definition */
2188 /* replace the result with the result of */
2189 /* this assignment and remove this assignment */
2190 IC_RESULT (dic) = IC_RESULT (ic);
2192 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2194 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2196 /* delete from liverange table also
2197 delete from all the points inbetween and the new
2199 for (sic = dic; sic != ic; sic = sic->next)
2201 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2202 if (IS_ITEMP (IC_RESULT (dic)))
2203 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2206 remiCodeFromeBBlock (ebp, ic);
2207 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2208 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2214 /*-----------------------------------------------------------------*/
2215 /* findAssignToSym : scanning backwards looks for first assig found */
2216 /*-----------------------------------------------------------------*/
2218 findAssignToSym (operand * op, iCode * ic)
2222 debugLog ("%s\n", __FUNCTION__);
2223 for (dic = ic->prev; dic; dic = dic->prev)
2226 /* if definition by assignment */
2227 if (dic->op == '=' &&
2228 !POINTER_SET (dic) &&
2229 IC_RESULT (dic)->key == op->key
2230 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2234 /* we are interested only if defined in far space */
2235 /* or in stack space in case of + & - */
2237 /* if assigned to a non-symbol then return
2239 if (!IS_SYMOP (IC_RIGHT (dic)))
2242 /* if the symbol is in far space then
2244 if (isOperandInFarSpace (IC_RIGHT (dic)))
2247 /* for + & - operations make sure that
2248 if it is on the stack it is the same
2249 as one of the three operands */
2250 if ((ic->op == '+' || ic->op == '-') &&
2251 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2254 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2255 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2256 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2264 /* if we find an usage then we cannot delete it */
2265 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2268 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2271 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2275 /* now make sure that the right side of dic
2276 is not defined between ic & dic */
2279 iCode *sic = dic->next;
2281 for (; sic != ic; sic = sic->next)
2282 if (IC_RESULT (sic) &&
2283 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2292 /*-----------------------------------------------------------------*/
2293 /* packRegsForSupport :- reduce some registers for support calls */
2294 /*-----------------------------------------------------------------*/
2296 packRegsForSupport (iCode * ic, eBBlock * ebp)
2300 debugLog ("%s\n", __FUNCTION__);
2301 /* for the left & right operand :- look to see if the
2302 left was assigned a true symbol in far space in that
2303 case replace them */
2304 if (IS_ITEMP (IC_LEFT (ic)) &&
2305 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2307 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2313 debugAopGet ("removing left:", IC_LEFT (ic));
2315 /* found it we need to remove it from the
2317 for (sic = dic; sic != ic; sic = sic->next)
2318 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2320 IC_LEFT (ic)->operand.symOperand =
2321 IC_RIGHT (dic)->operand.symOperand;
2322 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2323 remiCodeFromeBBlock (ebp, dic);
2324 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2328 /* do the same for the right operand */
2331 IS_ITEMP (IC_RIGHT (ic)) &&
2332 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2334 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2340 /* if this is a subtraction & the result
2341 is a true symbol in far space then don't pack */
2342 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2344 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2345 if (IN_FARSPACE (SPEC_OCLS (etype)))
2349 debugAopGet ("removing right:", IC_RIGHT (ic));
2351 /* found it we need to remove it from the
2353 for (sic = dic; sic != ic; sic = sic->next)
2354 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2356 IC_RIGHT (ic)->operand.symOperand =
2357 IC_RIGHT (dic)->operand.symOperand;
2358 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2360 remiCodeFromeBBlock (ebp, dic);
2361 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2368 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2371 /*-----------------------------------------------------------------*/
2372 /* packRegsForOneuse : - will reduce some registers for single Use */
2373 /*-----------------------------------------------------------------*/
2375 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2380 debugLog ("%s\n", __FUNCTION__);
2381 /* if returning a literal then do nothing */
2385 /* only upto 2 bytes since we cannot predict
2386 the usage of b, & acc */
2387 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2392 /* this routine will mark the a symbol as used in one
2393 instruction use only && if the definition is local
2394 (ie. within the basic block) && has only one definition &&
2395 that definition is either a return value from a
2396 function or does not contain any variables in
2398 uses = bitVectCopy (OP_USES (op));
2399 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2400 if (!bitVectIsZero (uses)) /* has other uses */
2403 /* if it has only one defintion */
2404 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2405 return NULL; /* has more than one definition */
2407 /* get that definition */
2409 hTabItemWithKey (iCodehTab,
2410 bitVectFirstBit (OP_DEFS (op)))))
2413 /* found the definition now check if it is local */
2414 if (dic->seq < ebp->fSeq ||
2415 dic->seq > ebp->lSeq)
2416 return NULL; /* non-local */
2418 /* now check if it is the return from
2420 if (dic->op == CALL || dic->op == PCALL)
2422 if (ic->op != SEND && ic->op != RETURN)
2424 OP_SYMBOL (op)->ruonly = 1;
2431 /* otherwise check that the definition does
2432 not contain any symbols in far space */
2433 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2434 isOperandInFarSpace (IC_RIGHT (dic)) ||
2435 IS_OP_RUONLY (IC_LEFT (ic)) ||
2436 IS_OP_RUONLY (IC_RIGHT (ic)))
2441 /* if pointer set then make sure the pointer
2443 if (POINTER_SET (dic) &&
2444 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2447 if (POINTER_GET (dic) &&
2448 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2453 /* also make sure the intervenening instructions
2454 don't have any thing in far space */
2455 for (dic = dic->next; dic && dic != ic; dic = dic->next)
2458 /* if there is an intervening function call then no */
2459 if (dic->op == CALL || dic->op == PCALL)
2461 /* if pointer set then make sure the pointer
2463 if (POINTER_SET (dic) &&
2464 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2467 if (POINTER_GET (dic) &&
2468 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2471 /* if address of & the result is remat then okay */
2472 if (dic->op == ADDRESS_OF &&
2473 OP_SYMBOL (IC_RESULT (dic))->remat)
2476 /* if operand has size of three or more & this
2477 operation is a '*','/' or '%' then 'b' may
2479 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2480 getSize (operandType (op)) >= 3)
2483 /* if left or right or result is in far space */
2484 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2485 isOperandInFarSpace (IC_RIGHT (dic)) ||
2486 isOperandInFarSpace (IC_RESULT (dic)) ||
2487 IS_OP_RUONLY (IC_LEFT (dic)) ||
2488 IS_OP_RUONLY (IC_RIGHT (dic)) ||
2489 IS_OP_RUONLY (IC_RESULT (dic)))
2495 OP_SYMBOL (op)->ruonly = 1;
2500 /*-----------------------------------------------------------------*/
2501 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2502 /*-----------------------------------------------------------------*/
2504 isBitwiseOptimizable (iCode * ic)
2506 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2507 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2509 debugLog ("%s\n", __FUNCTION__);
2510 /* bitwise operations are considered optimizable
2511 under the following conditions (Jean-Louis VERN)
2523 if (IS_LITERAL (rtype) ||
2524 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2530 /*-----------------------------------------------------------------*/
2531 /* packRegsForAccUse - pack registers for acc use */
2532 /*-----------------------------------------------------------------*/
2534 packRegsForAccUse (iCode * ic)
2538 debugLog ("%s\n", __FUNCTION__);
2539 /* if + or - then it has to be one byte result */
2540 if ((ic->op == '+' || ic->op == '-')
2541 && getSize (operandType (IC_RESULT (ic))) > 1)
2544 /* if shift operation make sure right side is not a literal */
2545 if (ic->op == RIGHT_OP &&
2546 (isOperandLiteral (IC_RIGHT (ic)) ||
2547 getSize (operandType (IC_RESULT (ic))) > 1))
2550 if (ic->op == LEFT_OP &&
2551 (isOperandLiteral (IC_RIGHT (ic)) ||
2552 getSize (operandType (IC_RESULT (ic))) > 1))
2555 if (IS_BITWISE_OP (ic) &&
2556 getSize (operandType (IC_RESULT (ic))) > 1)
2560 /* has only one definition */
2561 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2564 /* has only one use */
2565 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2568 /* and the usage immediately follows this iCode */
2569 if (!(uic = hTabItemWithKey (iCodehTab,
2570 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2573 if (ic->next != uic)
2576 /* if it is a conditional branch then we definitely can */
2580 if (uic->op == JUMPTABLE)
2583 /* if the usage is not is an assignment
2584 or an arithmetic / bitwise / shift operation then not */
2585 if (POINTER_SET (uic) &&
2586 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2589 if (uic->op != '=' &&
2590 !IS_ARITHMETIC_OP (uic) &&
2591 !IS_BITWISE_OP (uic) &&
2592 uic->op != LEFT_OP &&
2593 uic->op != RIGHT_OP)
2596 /* if used in ^ operation then make sure right is not a
2598 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2601 /* if shift operation make sure right side is not a literal */
2602 if (uic->op == RIGHT_OP &&
2603 (isOperandLiteral (IC_RIGHT (uic)) ||
2604 getSize (operandType (IC_RESULT (uic))) > 1))
2607 if (uic->op == LEFT_OP &&
2608 (isOperandLiteral (IC_RIGHT (uic)) ||
2609 getSize (operandType (IC_RESULT (uic))) > 1))
2612 /* make sure that the result of this icode is not on the
2613 stack, since acc is used to compute stack offset */
2614 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2615 OP_SYMBOL (IC_RESULT (uic))->onStack)
2618 /* if either one of them in far space then we cannot */
2619 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2620 isOperandInFarSpace (IC_LEFT (uic))) ||
2621 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2622 isOperandInFarSpace (IC_RIGHT (uic))))
2625 /* if the usage has only one operand then we can */
2626 if (IC_LEFT (uic) == NULL ||
2627 IC_RIGHT (uic) == NULL)
2630 /* make sure this is on the left side if not
2631 a '+' since '+' is commutative */
2632 if (ic->op != '+' &&
2633 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2636 /* if one of them is a literal then we can */
2637 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2638 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2640 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2644 /* if the other one is not on stack then we can */
2645 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2646 (IS_ITEMP (IC_RIGHT (uic)) ||
2647 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2648 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2651 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2652 (IS_ITEMP (IC_LEFT (uic)) ||
2653 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2654 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2660 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2665 /*-----------------------------------------------------------------*/
2666 /* packForPush - hueristics to reduce iCode for pushing */
2667 /*-----------------------------------------------------------------*/
2669 packForReceive (iCode * ic, eBBlock * ebp)
2673 debugLog ("%s\n", __FUNCTION__);
2674 debugAopGet (" result:", IC_RESULT (ic));
2675 debugAopGet (" left:", IC_LEFT (ic));
2676 debugAopGet (" right:", IC_RIGHT (ic));
2681 for (dic = ic->next; dic; dic = dic->next)
2686 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
2687 debugLog (" used on left\n");
2688 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
2689 debugLog (" used on right\n");
2690 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
2691 debugLog (" used on result\n");
2693 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
2694 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
2699 debugLog (" hey we can remove this unnecessary assign\n");
2701 /*-----------------------------------------------------------------*/
2702 /* packForPush - hueristics to reduce iCode for pushing */
2703 /*-----------------------------------------------------------------*/
2705 packForPush (iCode * ic, eBBlock * ebp)
2709 debugLog ("%s\n", __FUNCTION__);
2710 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2713 /* must have only definition & one usage */
2714 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2715 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2718 /* find the definition */
2719 if (!(dic = hTabItemWithKey (iCodehTab,
2720 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2723 if (dic->op != '=' || POINTER_SET (dic))
2726 /* we now we know that it has one & only one def & use
2727 and the that the definition is an assignment */
2728 IC_LEFT (ic) = IC_RIGHT (dic);
2730 remiCodeFromeBBlock (ebp, dic);
2731 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2734 /*-----------------------------------------------------------------*/
2735 /* packRegisters - does some transformations to reduce register */
2737 /*-----------------------------------------------------------------*/
2739 packRegisters (eBBlock * ebp)
2744 debugLog ("%s\n", __FUNCTION__);
2751 /* look for assignments of the form */
2752 /* iTempNN = TRueSym (someoperation) SomeOperand */
2754 /* TrueSym := iTempNN:1 */
2755 for (ic = ebp->sch; ic; ic = ic->next)
2758 /* find assignment of the form TrueSym := iTempNN:1 */
2759 if (ic->op == '=' && !POINTER_SET (ic))
2760 change += packRegsForAssign (ic, ebp);
2764 if (POINTER_SET (ic))
2765 debugLog ("pointer is set\n");
2766 debugAopGet (" result:", IC_RESULT (ic));
2767 debugAopGet (" left:", IC_LEFT (ic));
2768 debugAopGet (" right:", IC_RIGHT (ic));
2777 for (ic = ebp->sch; ic; ic = ic->next)
2780 /* if this is an itemp & result of a address of a true sym
2781 then mark this as rematerialisable */
2782 if (ic->op == ADDRESS_OF &&
2783 IS_ITEMP (IC_RESULT (ic)) &&
2784 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2785 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2786 !OP_SYMBOL (IC_LEFT (ic))->onStack)
2789 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2790 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2791 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2795 /* if straight assignment then carry remat flag if
2796 this is the only definition */
2797 if (ic->op == '=' &&
2798 !POINTER_SET (ic) &&
2799 IS_SYMOP (IC_RIGHT (ic)) &&
2800 OP_SYMBOL (IC_RIGHT (ic))->remat &&
2801 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2804 OP_SYMBOL (IC_RESULT (ic))->remat =
2805 OP_SYMBOL (IC_RIGHT (ic))->remat;
2806 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2807 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2810 /* if this is a +/- operation with a rematerizable
2811 then mark this as rematerializable as well */
2812 if ((ic->op == '+' || ic->op == '-') &&
2813 (IS_SYMOP (IC_LEFT (ic)) &&
2814 IS_ITEMP (IC_RESULT (ic)) &&
2815 OP_SYMBOL (IC_LEFT (ic))->remat &&
2816 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2817 IS_OP_LITERAL (IC_RIGHT (ic))))
2821 operandLitValue (IC_RIGHT (ic));
2822 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2823 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2824 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2827 /* mark the pointer usages */
2828 if (POINTER_SET (ic))
2830 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2831 debugLog (" marking as a pointer (set)\n");
2833 if (POINTER_GET (ic))
2835 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2836 debugLog (" marking as a pointer (get)\n");
2841 /* if we are using a symbol on the stack
2842 then we should say pic14_ptrRegReq */
2843 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2844 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2845 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2846 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2847 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2848 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2851 if (IS_SYMOP (IC_LEFT (ic)))
2852 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2853 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2854 if (IS_SYMOP (IC_RIGHT (ic)))
2855 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2856 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2857 if (IS_SYMOP (IC_RESULT (ic)))
2858 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2859 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2863 /* if the condition of an if instruction
2864 is defined in the previous instruction then
2865 mark the itemp as a conditional */
2866 if ((IS_CONDITIONAL (ic) ||
2867 ((ic->op == BITWISEAND ||
2870 isBitwiseOptimizable (ic))) &&
2871 ic->next && ic->next->op == IFX &&
2872 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2873 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2876 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2880 /* reduce for support function calls */
2881 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2882 packRegsForSupport (ic, ebp);
2884 /* if a parameter is passed, it's in W, so we may not
2885 need to place a copy in a register */
2886 if (ic->op == RECEIVE)
2887 packForReceive (ic, ebp);
2889 /* some cases the redundant moves can
2890 can be eliminated for return statements */
2891 if ((ic->op == RETURN || ic->op == SEND) &&
2892 !isOperandInFarSpace (IC_LEFT (ic)) &&
2894 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2896 /* if pointer set & left has a size more than
2897 one and right is not in far space */
2898 if (POINTER_SET (ic) &&
2899 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2900 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2901 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2902 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2904 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2906 /* if pointer get */
2907 if (POINTER_GET (ic) &&
2908 !isOperandInFarSpace (IC_RESULT (ic)) &&
2909 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2910 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2911 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2913 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2916 /* if this is cast for intergral promotion then
2917 check if only use of the definition of the
2918 operand being casted/ if yes then replace
2919 the result of that arithmetic operation with
2920 this result and get rid of the cast */
2923 sym_link *fromType = operandType (IC_RIGHT (ic));
2924 sym_link *toType = operandType (IC_LEFT (ic));
2926 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2927 getSize (fromType) != getSize (toType))
2930 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2933 if (IS_ARITHMETIC_OP (dic))
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);
2942 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2948 /* if the type from and type to are the same
2949 then if this is the only use then packit */
2950 if (compareType (operandType (IC_RIGHT (ic)),
2951 operandType (IC_LEFT (ic))) == 1)
2953 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2956 IC_RESULT (dic) = IC_RESULT (ic);
2957 remiCodeFromeBBlock (ebp, ic);
2958 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2959 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2967 iTempNN := (some variable in farspace) V1
2972 if (ic->op == IPUSH)
2974 packForPush (ic, ebp);
2978 /* pack registers for accumulator use, when the
2979 result of an arithmetic or bit wise operation
2980 has only one use, that use is immediately following
2981 the defintion and the using iCode has only one
2982 operand or has two operands but one is literal &
2983 the result of that operation is not on stack then
2984 we can leave the result of this operation in acc:b
2986 if ((IS_ARITHMETIC_OP (ic)
2988 || IS_BITWISE_OP (ic)
2990 || ic->op == LEFT_OP || ic->op == RIGHT_OP
2993 IS_ITEMP (IC_RESULT (ic)) &&
2994 getSize (operandType (IC_RESULT (ic))) <= 2)
2996 packRegsForAccUse (ic);
3002 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3006 if (!debug || !debugF)
3009 for (i = 0; i < count; i++)
3011 fprintf (debugF, "\n----------------------------------------------------------------\n");
3012 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3013 ebbs[i]->entryLabel->name,
3016 ebbs[i]->isLastInLoop);
3017 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3022 fprintf (debugF, "visited %d : hasFcall = %d\n",
3026 fprintf (debugF, "\ndefines bitVector :");
3027 bitVectDebugOn (ebbs[i]->defSet, debugF);
3028 fprintf (debugF, "\nlocal defines bitVector :");
3029 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3030 fprintf (debugF, "\npointers Set bitvector :");
3031 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3032 fprintf (debugF, "\nin pointers Set bitvector :");
3033 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3034 fprintf (debugF, "\ninDefs Set bitvector :");
3035 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3036 fprintf (debugF, "\noutDefs Set bitvector :");
3037 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3038 fprintf (debugF, "\nusesDefs Set bitvector :");
3039 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3040 fprintf (debugF, "\n----------------------------------------------------------------\n");
3041 printiCChain (ebbs[i]->sch, debugF);
3044 /*-----------------------------------------------------------------*/
3045 /* assignRegisters - assigns registers to each live range as need */
3046 /*-----------------------------------------------------------------*/
3048 pic14_assignRegisters (eBBlock ** ebbs, int count)
3053 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3054 debugLog ("ebbs before optimizing:\n");
3055 dumpEbbsToDebug (ebbs, count);
3057 setToNull ((void *) &_G.funcrUsed);
3058 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3061 /* change assignments this will remove some
3062 live ranges reducing some register pressure */
3063 for (i = 0; i < count; i++)
3064 packRegisters (ebbs[i]);
3066 if (options.dump_pack)
3067 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3069 /* first determine for each live range the number of
3070 registers & the type of registers required for each */
3073 /* and serially allocate registers */
3074 serialRegAssign (ebbs, count);
3076 /* if stack was extended then tell the user */
3079 /* werror(W_TOOMANY_SPILS,"stack", */
3080 /* _G.stackExtend,currFunc->name,""); */
3086 /* werror(W_TOOMANY_SPILS,"data space", */
3087 /* _G.dataExtend,currFunc->name,""); */
3091 /* after that create the register mask
3092 for each of the instruction */
3093 createRegMask (ebbs, count);
3095 /* redo that offsets for stacked automatic variables */
3096 redoStackOffsets ();
3098 if (options.dump_rassgn)
3099 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3101 /* now get back the chain */
3102 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3104 debugLog ("ebbs after optimizing:\n");
3105 dumpEbbsToDebug (ebbs, count);
3110 /* free up any _G.stackSpil locations allocated */
3111 applyToSet (_G.stackSpil, deallocStackSpil);
3113 setToNull ((void **) &_G.stackSpil);
3114 setToNull ((void **) &_G.spiltSet);
3115 /* mark all registers as free */
3116 pic14_freeAllRegs ();
3118 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");