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 - requesting index = 0x%x\n", __FUNCTION__,idx);
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 bitVectDebugOn(_G.regAssigned, debugF);
1615 for (j = 0; j < sym->nRegs; j++)
1617 if (sym->regType == REG_PTR)
1618 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1620 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1622 /* if the allocation falied which means
1623 this was spilt then break */
1627 debugLog (" %d - \n", __LINE__);
1629 /* if it shares registers with operands make sure
1630 that they are in the same position */
1631 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1632 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1633 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1634 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1635 /* do the same for the right operand */
1636 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1637 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
1638 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1639 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1641 debugLog (" %d - \n", __LINE__);
1644 debugLog (" %d - \n", __LINE__);
1654 /*-----------------------------------------------------------------*/
1655 /* rUmaskForOp :- returns register mask for an operand */
1656 /*-----------------------------------------------------------------*/
1658 rUmaskForOp (operand * op)
1664 debugLog ("%s\n", __FUNCTION__);
1665 /* only temporaries are assigned registers */
1669 sym = OP_SYMBOL (op);
1671 /* if spilt or no registers assigned to it
1673 if (sym->isspilt || !sym->nRegs)
1676 rumask = newBitVect (pic14_nRegs);
1678 for (j = 0; j < sym->nRegs; j++)
1680 rumask = bitVectSetBit (rumask,
1681 sym->regs[j]->rIdx);
1687 /*-----------------------------------------------------------------*/
1688 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1689 /*-----------------------------------------------------------------*/
1691 regsUsedIniCode (iCode * ic)
1693 bitVect *rmask = newBitVect (pic14_nRegs);
1695 debugLog ("%s\n", __FUNCTION__);
1696 /* do the special cases first */
1699 rmask = bitVectUnion (rmask,
1700 rUmaskForOp (IC_COND (ic)));
1704 /* for the jumptable */
1705 if (ic->op == JUMPTABLE)
1707 rmask = bitVectUnion (rmask,
1708 rUmaskForOp (IC_JTCOND (ic)));
1713 /* of all other cases */
1715 rmask = bitVectUnion (rmask,
1716 rUmaskForOp (IC_LEFT (ic)));
1720 rmask = bitVectUnion (rmask,
1721 rUmaskForOp (IC_RIGHT (ic)));
1724 rmask = bitVectUnion (rmask,
1725 rUmaskForOp (IC_RESULT (ic)));
1731 /*-----------------------------------------------------------------*/
1732 /* createRegMask - for each instruction will determine the regsUsed */
1733 /*-----------------------------------------------------------------*/
1735 createRegMask (eBBlock ** ebbs, int count)
1739 debugLog ("%s\n", __FUNCTION__);
1740 /* for all blocks */
1741 for (i = 0; i < count; i++)
1745 if (ebbs[i]->noPath &&
1746 (ebbs[i]->entryLabel != entryLabel &&
1747 ebbs[i]->entryLabel != returnLabel))
1750 /* for all instructions */
1751 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1756 if (SKIP_IC2 (ic) || !ic->rlive)
1759 /* first mark the registers used in this
1761 ic->rUsed = regsUsedIniCode (ic);
1762 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1764 /* now create the register mask for those
1765 registers that are in use : this is a
1766 super set of ic->rUsed */
1767 ic->rMask = newBitVect (pic14_nRegs + 1);
1769 /* for all live Ranges alive at this point */
1770 for (j = 1; j < ic->rlive->size; j++)
1775 /* if not alive then continue */
1776 if (!bitVectBitValue (ic->rlive, j))
1779 /* find the live range we are interested in */
1780 if (!(sym = hTabItemWithKey (liveRanges, j)))
1782 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1783 "createRegMask cannot find live range");
1787 /* if no register assigned to it */
1788 if (!sym->nRegs || sym->isspilt)
1791 /* for all the registers allocated to it */
1792 for (k = 0; k < sym->nRegs; k++)
1795 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1801 /*-----------------------------------------------------------------*/
1802 /* rematStr - returns the rematerialized string for a remat var */
1803 /*-----------------------------------------------------------------*/
1805 rematStr (symbol * sym)
1808 iCode *ic = sym->rematiCode;
1810 debugLog ("%s\n", __FUNCTION__);
1815 /* if plus or minus print the right hand side */
1817 if (ic->op == '+' || ic->op == '-') {
1818 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1821 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1825 if (ic->op == '+' || ic->op == '-')
1827 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1828 sprintf (s, "(%s %c 0x%04x)",
1829 OP_SYMBOL (IC_LEFT (ric))->rname,
1831 (int) operandLitValue (IC_RIGHT (ic)));
1834 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1839 /* we reached the end */
1840 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1844 printf ("%s\n", buffer);
1848 /*-----------------------------------------------------------------*/
1849 /* regTypeNum - computes the type & number of registers required */
1850 /*-----------------------------------------------------------------*/
1858 debugLog ("%s\n", __FUNCTION__);
1859 /* for each live range do */
1860 for (sym = hTabFirstItem (liveRanges, &k); sym;
1861 sym = hTabNextItem (liveRanges, &k)) {
1863 debugLog (" %d - %s\n", __LINE__, sym->rname);
1865 /* if used zero times then no registers needed */
1866 if ((sym->liveTo - sym->liveFrom) == 0)
1870 /* if the live range is a temporary */
1873 debugLog (" %d - itemp register\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) {
1882 if (IS_AGGREGATE (sym->type) || sym->isptr)
1883 sym->type = aggrToPtr (sym->type, FALSE);
1884 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
1889 /* if the symbol has only one definition &
1890 that definition is a get_pointer and the
1891 pointer we are getting is rematerializable and
1894 if (bitVectnBitsOn (sym->defs) == 1 &&
1895 (ic = hTabItemWithKey (iCodehTab,
1896 bitVectFirstBit (sym->defs))) &&
1899 !IS_BITVAR (sym->etype)) {
1902 debugLog (" %d - \n", __LINE__);
1904 /* if remat in data space */
1905 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1906 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
1908 /* create a psuedo symbol & force a spil */
1909 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1910 psym->type = sym->type;
1911 psym->etype = sym->etype;
1912 strcpy (psym->rname, psym->name);
1914 sym->usl.spillLoc = psym;
1918 /* if in data space or idata space then try to
1919 allocate pointer register */
1923 /* if not then we require registers */
1924 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1925 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1926 getSize (sym->type));
1928 if (sym->nRegs > 4) {
1929 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1930 printTypeChain (sym->type, stderr);
1931 fprintf (stderr, "\n");
1934 /* determine the type of register required */
1935 if (sym->nRegs == 1 &&
1936 IS_PTR (sym->type) &&
1938 sym->regType = REG_PTR;
1940 sym->regType = REG_GPR;
1943 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
1947 /* for the first run we don't provide */
1948 /* registers for true symbols we will */
1949 /* see how things go */
1955 /*-----------------------------------------------------------------*/
1956 /* freeAllRegs - mark all registers as free */
1957 /*-----------------------------------------------------------------*/
1959 pic14_freeAllRegs ()
1963 debugLog ("%s\n", __FUNCTION__);
1964 for (i = 0; i < pic14_nRegs; i++)
1965 regspic14[i].isFree = 1;
1968 /*-----------------------------------------------------------------*/
1969 /*-----------------------------------------------------------------*/
1971 pic14_deallocateAllRegs ()
1975 debugLog ("%s\n", __FUNCTION__);
1976 for (i = 0; i < pic14_nRegs; i++) {
1977 regspic14[i].isFree = 1;
1978 regspic14[i].wasUsed = 0;
1983 /*-----------------------------------------------------------------*/
1984 /* deallocStackSpil - this will set the stack pointer back */
1985 /*-----------------------------------------------------------------*/
1987 DEFSETFUNC (deallocStackSpil)
1991 debugLog ("%s\n", __FUNCTION__);
1996 /*-----------------------------------------------------------------*/
1997 /* farSpacePackable - returns the packable icode for far variables */
1998 /*-----------------------------------------------------------------*/
2000 farSpacePackable (iCode * ic)
2004 debugLog ("%s\n", __FUNCTION__);
2005 /* go thru till we find a definition for the
2006 symbol on the right */
2007 for (dic = ic->prev; dic; dic = dic->prev)
2010 /* if the definition is a call then no */
2011 if ((dic->op == CALL || dic->op == PCALL) &&
2012 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2017 /* if shift by unknown amount then not */
2018 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2019 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2022 /* if pointer get and size > 1 */
2023 if (POINTER_GET (dic) &&
2024 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2027 if (POINTER_SET (dic) &&
2028 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2031 /* if any three is a true symbol in far space */
2032 if (IC_RESULT (dic) &&
2033 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2034 isOperandInFarSpace (IC_RESULT (dic)))
2037 if (IC_RIGHT (dic) &&
2038 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2039 isOperandInFarSpace (IC_RIGHT (dic)) &&
2040 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2043 if (IC_LEFT (dic) &&
2044 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2045 isOperandInFarSpace (IC_LEFT (dic)) &&
2046 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2049 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2051 if ((dic->op == LEFT_OP ||
2052 dic->op == RIGHT_OP ||
2054 IS_OP_LITERAL (IC_RIGHT (dic)))
2064 /*-----------------------------------------------------------------*/
2065 /* packRegsForAssign - register reduction for assignment */
2066 /*-----------------------------------------------------------------*/
2068 packRegsForAssign (iCode * ic, eBBlock * ebp)
2073 debugLog ("%s\n", __FUNCTION__);
2075 debugAopGet (" result:", IC_RESULT (ic));
2076 debugAopGet (" left:", IC_LEFT (ic));
2077 debugAopGet (" right:", IC_RIGHT (ic));
2079 if (!IS_ITEMP (IC_RIGHT (ic)) ||
2080 OP_SYMBOL (IC_RIGHT (ic))->isind ||
2081 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2083 debugLog (" %d - not packing - right side fails \n", __LINE__);
2087 /* if the true symbol is defined in far space or on stack
2088 then we should not since this will increase register pressure */
2089 if (isOperandInFarSpace (IC_RESULT (ic)))
2091 if ((dic = farSpacePackable (ic)))
2097 /* find the definition of iTempNN scanning backwards if we find a
2098 a use of the true symbol before we find the definition then
2100 for (dic = ic->prev; dic; dic = dic->prev)
2103 /* if there is a function call and this is
2104 a parameter & not my parameter then don't pack it */
2105 if ((dic->op == CALL || dic->op == PCALL) &&
2106 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2107 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2109 debugLog (" %d - \n", __LINE__);
2117 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2118 IS_OP_VOLATILE (IC_RESULT (dic)))
2120 debugLog (" %d - \n", __LINE__);
2125 if (IS_SYMOP (IC_RESULT (dic)) &&
2126 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2128 debugLog (" %d - dic key == ic key -- pointer set=%c\n", __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2129 if (POINTER_SET (dic))
2135 if (IS_SYMOP (IC_RIGHT (dic)) &&
2136 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2137 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2139 debugLog (" %d - \n", __LINE__);
2144 if (IS_SYMOP (IC_LEFT (dic)) &&
2145 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2146 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2148 debugLog (" %d - \n", __LINE__);
2153 if (POINTER_SET (dic) &&
2154 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2156 debugLog (" %d - \n", __LINE__);
2163 return 0; /* did not find */
2165 /* if the result is on stack or iaccess then it must be
2166 the same atleast one of the operands */
2167 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2168 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2171 /* the operation has only one symbol
2172 operator then we can pack */
2173 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2174 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2177 if (!((IC_LEFT (dic) &&
2178 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2180 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2184 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2185 /* found the definition */
2186 /* replace the result with the result of */
2187 /* this assignment and remove this assignment */
2188 IC_RESULT (dic) = IC_RESULT (ic);
2190 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2192 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2194 /* delete from liverange table also
2195 delete from all the points inbetween and the new
2197 for (sic = dic; sic != ic; sic = sic->next)
2199 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2200 if (IS_ITEMP (IC_RESULT (dic)))
2201 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2204 remiCodeFromeBBlock (ebp, ic);
2205 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2206 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2212 /*-----------------------------------------------------------------*/
2213 /* findAssignToSym : scanning backwards looks for first assig found */
2214 /*-----------------------------------------------------------------*/
2216 findAssignToSym (operand * op, iCode * ic)
2220 debugLog ("%s\n", __FUNCTION__);
2221 for (dic = ic->prev; dic; dic = dic->prev)
2224 /* if definition by assignment */
2225 if (dic->op == '=' &&
2226 !POINTER_SET (dic) &&
2227 IC_RESULT (dic)->key == op->key
2228 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2232 /* we are interested only if defined in far space */
2233 /* or in stack space in case of + & - */
2235 /* if assigned to a non-symbol then return
2237 if (!IS_SYMOP (IC_RIGHT (dic)))
2240 /* if the symbol is in far space then
2242 if (isOperandInFarSpace (IC_RIGHT (dic)))
2245 /* for + & - operations make sure that
2246 if it is on the stack it is the same
2247 as one of the three operands */
2248 if ((ic->op == '+' || ic->op == '-') &&
2249 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2252 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2253 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2254 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2262 /* if we find an usage then we cannot delete it */
2263 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2266 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2269 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2273 /* now make sure that the right side of dic
2274 is not defined between ic & dic */
2277 iCode *sic = dic->next;
2279 for (; sic != ic; sic = sic->next)
2280 if (IC_RESULT (sic) &&
2281 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2290 /*-----------------------------------------------------------------*/
2291 /* packRegsForSupport :- reduce some registers for support calls */
2292 /*-----------------------------------------------------------------*/
2294 packRegsForSupport (iCode * ic, eBBlock * ebp)
2298 debugLog ("%s\n", __FUNCTION__);
2299 /* for the left & right operand :- look to see if the
2300 left was assigned a true symbol in far space in that
2301 case replace them */
2302 if (IS_ITEMP (IC_LEFT (ic)) &&
2303 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2305 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2311 debugAopGet ("removing left:", IC_LEFT (ic));
2313 /* found it we need to remove it from the
2315 for (sic = dic; sic != ic; sic = sic->next)
2316 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2318 IC_LEFT (ic)->operand.symOperand =
2319 IC_RIGHT (dic)->operand.symOperand;
2320 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2321 remiCodeFromeBBlock (ebp, dic);
2322 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2326 /* do the same for the right operand */
2329 IS_ITEMP (IC_RIGHT (ic)) &&
2330 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2332 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2338 /* if this is a subtraction & the result
2339 is a true symbol in far space then don't pack */
2340 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2342 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2343 if (IN_FARSPACE (SPEC_OCLS (etype)))
2347 debugAopGet ("removing right:", IC_RIGHT (ic));
2349 /* found it we need to remove it from the
2351 for (sic = dic; sic != ic; sic = sic->next)
2352 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2354 IC_RIGHT (ic)->operand.symOperand =
2355 IC_RIGHT (dic)->operand.symOperand;
2356 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2358 remiCodeFromeBBlock (ebp, dic);
2359 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2366 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2369 /*-----------------------------------------------------------------*/
2370 /* packRegsForOneuse : - will reduce some registers for single Use */
2371 /*-----------------------------------------------------------------*/
2373 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2378 debugLog ("%s\n", __FUNCTION__);
2379 /* if returning a literal then do nothing */
2383 /* only upto 2 bytes since we cannot predict
2384 the usage of b, & acc */
2385 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2390 /* this routine will mark the a symbol as used in one
2391 instruction use only && if the definition is local
2392 (ie. within the basic block) && has only one definition &&
2393 that definition is either a return value from a
2394 function or does not contain any variables in
2396 uses = bitVectCopy (OP_USES (op));
2397 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2398 if (!bitVectIsZero (uses)) /* has other uses */
2401 /* if it has only one defintion */
2402 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2403 return NULL; /* has more than one definition */
2405 /* get that definition */
2407 hTabItemWithKey (iCodehTab,
2408 bitVectFirstBit (OP_DEFS (op)))))
2411 /* found the definition now check if it is local */
2412 if (dic->seq < ebp->fSeq ||
2413 dic->seq > ebp->lSeq)
2414 return NULL; /* non-local */
2416 /* now check if it is the return from
2418 if (dic->op == CALL || dic->op == PCALL)
2420 if (ic->op != SEND && ic->op != RETURN)
2422 OP_SYMBOL (op)->ruonly = 1;
2429 /* otherwise check that the definition does
2430 not contain any symbols in far space */
2431 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2432 isOperandInFarSpace (IC_RIGHT (dic)) ||
2433 IS_OP_RUONLY (IC_LEFT (ic)) ||
2434 IS_OP_RUONLY (IC_RIGHT (ic)))
2439 /* if pointer set then make sure the pointer
2441 if (POINTER_SET (dic) &&
2442 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2445 if (POINTER_GET (dic) &&
2446 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2451 /* also make sure the intervenening instructions
2452 don't have any thing in far space */
2453 for (dic = dic->next; dic && dic != ic; dic = dic->next)
2456 /* if there is an intervening function call then no */
2457 if (dic->op == CALL || dic->op == PCALL)
2459 /* if pointer set then make sure the pointer
2461 if (POINTER_SET (dic) &&
2462 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2465 if (POINTER_GET (dic) &&
2466 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2469 /* if address of & the result is remat then okay */
2470 if (dic->op == ADDRESS_OF &&
2471 OP_SYMBOL (IC_RESULT (dic))->remat)
2474 /* if operand has size of three or more & this
2475 operation is a '*','/' or '%' then 'b' may
2477 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2478 getSize (operandType (op)) >= 3)
2481 /* if left or right or result is in far space */
2482 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2483 isOperandInFarSpace (IC_RIGHT (dic)) ||
2484 isOperandInFarSpace (IC_RESULT (dic)) ||
2485 IS_OP_RUONLY (IC_LEFT (dic)) ||
2486 IS_OP_RUONLY (IC_RIGHT (dic)) ||
2487 IS_OP_RUONLY (IC_RESULT (dic)))
2493 OP_SYMBOL (op)->ruonly = 1;
2498 /*-----------------------------------------------------------------*/
2499 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2500 /*-----------------------------------------------------------------*/
2502 isBitwiseOptimizable (iCode * ic)
2504 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2505 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2507 debugLog ("%s\n", __FUNCTION__);
2508 /* bitwise operations are considered optimizable
2509 under the following conditions (Jean-Louis VERN)
2521 if (IS_LITERAL (rtype) ||
2522 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2528 /*-----------------------------------------------------------------*/
2529 /* packRegsForAccUse - pack registers for acc use */
2530 /*-----------------------------------------------------------------*/
2532 packRegsForAccUse (iCode * ic)
2536 debugLog ("%s\n", __FUNCTION__);
2537 /* if + or - then it has to be one byte result */
2538 if ((ic->op == '+' || ic->op == '-')
2539 && getSize (operandType (IC_RESULT (ic))) > 1)
2542 /* if shift operation make sure right side is not a literal */
2543 if (ic->op == RIGHT_OP &&
2544 (isOperandLiteral (IC_RIGHT (ic)) ||
2545 getSize (operandType (IC_RESULT (ic))) > 1))
2548 if (ic->op == LEFT_OP &&
2549 (isOperandLiteral (IC_RIGHT (ic)) ||
2550 getSize (operandType (IC_RESULT (ic))) > 1))
2553 if (IS_BITWISE_OP (ic) &&
2554 getSize (operandType (IC_RESULT (ic))) > 1)
2558 /* has only one definition */
2559 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2562 /* has only one use */
2563 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2566 /* and the usage immediately follows this iCode */
2567 if (!(uic = hTabItemWithKey (iCodehTab,
2568 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2571 if (ic->next != uic)
2574 /* if it is a conditional branch then we definitely can */
2578 if (uic->op == JUMPTABLE)
2581 /* if the usage is not is an assignment
2582 or an arithmetic / bitwise / shift operation then not */
2583 if (POINTER_SET (uic) &&
2584 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2587 if (uic->op != '=' &&
2588 !IS_ARITHMETIC_OP (uic) &&
2589 !IS_BITWISE_OP (uic) &&
2590 uic->op != LEFT_OP &&
2591 uic->op != RIGHT_OP)
2594 /* if used in ^ operation then make sure right is not a
2596 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2599 /* if shift operation make sure right side is not a literal */
2600 if (uic->op == RIGHT_OP &&
2601 (isOperandLiteral (IC_RIGHT (uic)) ||
2602 getSize (operandType (IC_RESULT (uic))) > 1))
2605 if (uic->op == LEFT_OP &&
2606 (isOperandLiteral (IC_RIGHT (uic)) ||
2607 getSize (operandType (IC_RESULT (uic))) > 1))
2610 /* make sure that the result of this icode is not on the
2611 stack, since acc is used to compute stack offset */
2612 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2613 OP_SYMBOL (IC_RESULT (uic))->onStack)
2616 /* if either one of them in far space then we cannot */
2617 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2618 isOperandInFarSpace (IC_LEFT (uic))) ||
2619 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2620 isOperandInFarSpace (IC_RIGHT (uic))))
2623 /* if the usage has only one operand then we can */
2624 if (IC_LEFT (uic) == NULL ||
2625 IC_RIGHT (uic) == NULL)
2628 /* make sure this is on the left side if not
2629 a '+' since '+' is commutative */
2630 if (ic->op != '+' &&
2631 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2634 /* if one of them is a literal then we can */
2635 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2636 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2638 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2642 /* if the other one is not on stack then we can */
2643 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2644 (IS_ITEMP (IC_RIGHT (uic)) ||
2645 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2646 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2649 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2650 (IS_ITEMP (IC_LEFT (uic)) ||
2651 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2652 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2658 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2663 /*-----------------------------------------------------------------*/
2664 /* packForPush - hueristics to reduce iCode for pushing */
2665 /*-----------------------------------------------------------------*/
2667 packForReceive (iCode * ic, eBBlock * ebp)
2671 debugLog ("%s\n", __FUNCTION__);
2672 debugAopGet (" result:", IC_RESULT (ic));
2673 debugAopGet (" left:", IC_LEFT (ic));
2674 debugAopGet (" right:", IC_RIGHT (ic));
2679 for (dic = ic->next; dic; dic = dic->next)
2684 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
2685 debugLog (" used on left\n");
2686 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
2687 debugLog (" used on right\n");
2688 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
2689 debugLog (" used on result\n");
2691 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
2692 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
2697 debugLog (" hey we can remove this unnecessary assign\n");
2699 /*-----------------------------------------------------------------*/
2700 /* packForPush - hueristics to reduce iCode for pushing */
2701 /*-----------------------------------------------------------------*/
2703 packForPush (iCode * ic, eBBlock * ebp)
2707 debugLog ("%s\n", __FUNCTION__);
2708 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2711 /* must have only definition & one usage */
2712 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2713 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2716 /* find the definition */
2717 if (!(dic = hTabItemWithKey (iCodehTab,
2718 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2721 if (dic->op != '=' || POINTER_SET (dic))
2724 /* we now we know that it has one & only one def & use
2725 and the that the definition is an assignment */
2726 IC_LEFT (ic) = IC_RIGHT (dic);
2728 remiCodeFromeBBlock (ebp, dic);
2729 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2732 /*-----------------------------------------------------------------*/
2733 /* packRegisters - does some transformations to reduce register */
2735 /*-----------------------------------------------------------------*/
2737 packRegisters (eBBlock * ebp)
2742 debugLog ("%s\n", __FUNCTION__);
2749 /* look for assignments of the form */
2750 /* iTempNN = TRueSym (someoperation) SomeOperand */
2752 /* TrueSym := iTempNN:1 */
2753 for (ic = ebp->sch; ic; ic = ic->next)
2756 /* find assignment of the form TrueSym := iTempNN:1 */
2757 if (ic->op == '=' && !POINTER_SET (ic))
2758 change += packRegsForAssign (ic, ebp);
2762 if (POINTER_SET (ic))
2763 debugLog ("pointer is set\n");
2764 debugAopGet (" result:", IC_RESULT (ic));
2765 debugAopGet (" left:", IC_LEFT (ic));
2766 debugAopGet (" right:", IC_RIGHT (ic));
2775 for (ic = ebp->sch; ic; ic = ic->next)
2778 /* if this is an itemp & result of a address of a true sym
2779 then mark this as rematerialisable */
2780 if (ic->op == ADDRESS_OF &&
2781 IS_ITEMP (IC_RESULT (ic)) &&
2782 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2783 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2784 !OP_SYMBOL (IC_LEFT (ic))->onStack)
2787 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
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)
2803 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
2805 OP_SYMBOL (IC_RESULT (ic))->remat =
2806 OP_SYMBOL (IC_RIGHT (ic))->remat;
2807 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2808 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2811 /* if this is a +/- operation with a rematerizable
2812 then mark this as rematerializable as well */
2813 if ((ic->op == '+' || ic->op == '-') &&
2814 (IS_SYMOP (IC_LEFT (ic)) &&
2815 IS_ITEMP (IC_RESULT (ic)) &&
2816 OP_SYMBOL (IC_LEFT (ic))->remat &&
2817 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2818 IS_OP_LITERAL (IC_RIGHT (ic))))
2820 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
2822 operandLitValue (IC_RIGHT (ic));
2823 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2824 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2825 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2828 /* mark the pointer usages */
2829 if (POINTER_SET (ic))
2831 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2832 debugLog (" marking as a pointer (set) =>");
2833 debugAopGet (" result:", IC_RESULT (ic));
2835 if (POINTER_GET (ic))
2837 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2838 debugLog (" marking as a pointer (get) =>");
2839 debugAopGet (" left:", IC_LEFT (ic));
2844 /* if we are using a symbol on the stack
2845 then we should say pic14_ptrRegReq */
2846 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2847 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2848 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2849 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2850 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2851 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2854 if (IS_SYMOP (IC_LEFT (ic)))
2855 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2856 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2857 if (IS_SYMOP (IC_RIGHT (ic)))
2858 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2859 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2860 if (IS_SYMOP (IC_RESULT (ic)))
2861 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2862 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2866 /* if the condition of an if instruction
2867 is defined in the previous instruction then
2868 mark the itemp as a conditional */
2869 if ((IS_CONDITIONAL (ic) ||
2870 ((ic->op == BITWISEAND ||
2873 isBitwiseOptimizable (ic))) &&
2874 ic->next && ic->next->op == IFX &&
2875 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2876 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2879 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2883 /* reduce for support function calls */
2884 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2885 packRegsForSupport (ic, ebp);
2887 /* if a parameter is passed, it's in W, so we may not
2888 need to place a copy in a register */
2889 if (ic->op == RECEIVE)
2890 packForReceive (ic, ebp);
2892 /* some cases the redundant moves can
2893 can be eliminated for return statements */
2894 if ((ic->op == RETURN || ic->op == SEND) &&
2895 !isOperandInFarSpace (IC_LEFT (ic)) &&
2897 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2899 /* if pointer set & left has a size more than
2900 one and right is not in far space */
2901 if (POINTER_SET (ic) &&
2902 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2903 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2904 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2905 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2907 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2909 /* if pointer get */
2910 if (POINTER_GET (ic) &&
2911 !isOperandInFarSpace (IC_RESULT (ic)) &&
2912 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2913 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2914 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2916 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2919 /* if this is cast for intergral promotion then
2920 check if only use of the definition of the
2921 operand being casted/ if yes then replace
2922 the result of that arithmetic operation with
2923 this result and get rid of the cast */
2926 sym_link *fromType = operandType (IC_RIGHT (ic));
2927 sym_link *toType = operandType (IC_LEFT (ic));
2929 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2930 getSize (fromType) != getSize (toType))
2933 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2936 if (IS_ARITHMETIC_OP (dic))
2938 IC_RESULT (dic) = IC_RESULT (ic);
2939 remiCodeFromeBBlock (ebp, ic);
2940 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2941 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2945 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2951 /* if the type from and type to are the same
2952 then if this is the only use then packit */
2953 if (compareType (operandType (IC_RIGHT (ic)),
2954 operandType (IC_LEFT (ic))) == 1)
2956 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2959 IC_RESULT (dic) = IC_RESULT (ic);
2960 remiCodeFromeBBlock (ebp, ic);
2961 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2962 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2970 iTempNN := (some variable in farspace) V1
2975 if (ic->op == IPUSH)
2977 packForPush (ic, ebp);
2981 /* pack registers for accumulator use, when the
2982 result of an arithmetic or bit wise operation
2983 has only one use, that use is immediately following
2984 the defintion and the using iCode has only one
2985 operand or has two operands but one is literal &
2986 the result of that operation is not on stack then
2987 we can leave the result of this operation in acc:b
2989 if ((IS_ARITHMETIC_OP (ic)
2991 || IS_BITWISE_OP (ic)
2993 || ic->op == LEFT_OP || ic->op == RIGHT_OP
2996 IS_ITEMP (IC_RESULT (ic)) &&
2997 getSize (operandType (IC_RESULT (ic))) <= 2)
2999 packRegsForAccUse (ic);
3005 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3009 if (!debug || !debugF)
3012 for (i = 0; i < count; i++)
3014 fprintf (debugF, "\n----------------------------------------------------------------\n");
3015 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3016 ebbs[i]->entryLabel->name,
3019 ebbs[i]->isLastInLoop);
3020 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3025 fprintf (debugF, "visited %d : hasFcall = %d\n",
3029 fprintf (debugF, "\ndefines bitVector :");
3030 bitVectDebugOn (ebbs[i]->defSet, debugF);
3031 fprintf (debugF, "\nlocal defines bitVector :");
3032 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3033 fprintf (debugF, "\npointers Set bitvector :");
3034 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3035 fprintf (debugF, "\nin pointers Set bitvector :");
3036 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3037 fprintf (debugF, "\ninDefs Set bitvector :");
3038 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3039 fprintf (debugF, "\noutDefs Set bitvector :");
3040 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3041 fprintf (debugF, "\nusesDefs Set bitvector :");
3042 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3043 fprintf (debugF, "\n----------------------------------------------------------------\n");
3044 printiCChain (ebbs[i]->sch, debugF);
3047 /*-----------------------------------------------------------------*/
3048 /* assignRegisters - assigns registers to each live range as need */
3049 /*-----------------------------------------------------------------*/
3051 pic14_assignRegisters (eBBlock ** ebbs, int count)
3056 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3057 debugLog ("ebbs before optimizing:\n");
3058 dumpEbbsToDebug (ebbs, count);
3060 setToNull ((void *) &_G.funcrUsed);
3061 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3064 /* change assignments this will remove some
3065 live ranges reducing some register pressure */
3066 for (i = 0; i < count; i++)
3067 packRegisters (ebbs[i]);
3069 if (options.dump_pack)
3070 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3072 /* first determine for each live range the number of
3073 registers & the type of registers required for each */
3076 /* and serially allocate registers */
3077 serialRegAssign (ebbs, count);
3079 /* if stack was extended then tell the user */
3082 /* werror(W_TOOMANY_SPILS,"stack", */
3083 /* _G.stackExtend,currFunc->name,""); */
3089 /* werror(W_TOOMANY_SPILS,"data space", */
3090 /* _G.dataExtend,currFunc->name,""); */
3094 /* after that create the register mask
3095 for each of the instruction */
3096 createRegMask (ebbs, count);
3098 /* redo that offsets for stacked automatic variables */
3099 redoStackOffsets ();
3101 if (options.dump_rassgn)
3102 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3104 /* now get back the chain */
3105 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3107 debugLog ("ebbs after optimizing:\n");
3108 dumpEbbsToDebug (ebbs, count);
3113 /* free up any _G.stackSpil locations allocated */
3114 applyToSet (_G.stackSpil, deallocStackSpil);
3116 setToNull ((void **) &_G.stackSpil);
3117 setToNull ((void **) &_G.spiltSet);
3118 /* mark all registers as free */
3119 pic14_freeAllRegs ();
3121 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");