1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (8051) specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
32 #define __FUNCTION__ __FILE__
35 /*-----------------------------------------------------------------*/
36 /* At this point we start getting processor specific although */
37 /* some routines are non-processor specific & can be reused when */
38 /* targetting other processors. The decision for this will have */
39 /* to be made on a routine by routine basis */
40 /* routines used to pack registers are most definitely not reusable*/
41 /* since the pack the registers depending strictly on the MCU */
42 /*-----------------------------------------------------------------*/
44 extern void genpic14Code(iCode *);
53 bitVect *funcrUsed; /* registers used in a function */
58 /* Shared with gen.c */
59 int pic14_ptrRegReq; /* one byte pointer register required */
65 {REG_GPR, 0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0},
66 {REG_GPR, 0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0},
67 {REG_GPR, 0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0},
68 {REG_GPR, 0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0},
69 {REG_GPR, 0x10, "r0x10", "r0x10", 0x10, 1, 0},
70 {REG_GPR, 0x11, "r0x11", "r0x11", 0x11, 1, 0},
71 {REG_GPR, 0x12, "r0x12", "r0x12", 0x12, 1, 0},
72 {REG_GPR, 0x13, "r0x13", "r0x13", 0x13, 1, 0},
73 {REG_GPR, 0x14, "r0x14", "r0x14", 0x14, 1, 0},
74 {REG_GPR, 0x15, "r0x15", "r0x15", 0x15, 1, 0},
75 {REG_GPR, 0x16, "r0x16", "r0x16", 0x16, 1, 0},
76 {REG_GPR, 0x17, "r0x17", "r0x17", 0x17, 1, 0},
77 {REG_GPR, 0x18, "r0x18", "r0x18", 0x18, 1, 0},
78 {REG_GPR, 0x19, "r0x19", "r0x19", 0x19, 1, 0},
79 {REG_GPR, 0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0},
80 {REG_GPR, 0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0},
81 {REG_GPR, 0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0},
82 {REG_GPR, 0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0},
83 {REG_GPR, 0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0},
84 {REG_GPR, 0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0},
85 {REG_PTR, 4, "FSR", "FSR", 4, 1,0},
89 int pic14_nRegs = sizeof(regspic14) / sizeof(regs);
90 static void spillThis (symbol *);
92 static FILE *debugF=NULL;
93 /*-----------------------------------------------------------------*/
94 /* debugLog - open a file for debugging information */
95 /*-----------------------------------------------------------------*/
96 //static void debugLog(char *inst,char *fmt, ...)
97 static void debugLog(char *fmt, ...)
99 static int append = 0; // First time through, open the file without append.
101 //char *bufferP=buffer;
109 /* create the file name */
110 strcpy(buffer,srcFileName);
113 if( !(debugF = fopen(buffer, (append ? "a+" : "w") ))) {
114 werror(E_FILE_OPEN_ERR,buffer);
117 append = 1; // Next time debubLog is called, we'll append the debug info
122 vsprintf(buffer,fmt,ap);
124 fprintf(debugF,"%s",buffer);
126 while (isspace(*bufferP)) bufferP++;
128 if (bufferP && *bufferP)
129 lineCurr = (lineCurr ?
130 connectLine(lineCurr,newLineNode(lb)) :
131 (lineHead = newLineNode(lb)));
132 lineCurr->isInline = _G.inLine;
133 lineCurr->isDebug = _G.debugLine;
139 static void debugNewLine(void)
144 /*-----------------------------------------------------------------*/
145 /* debugLogClose - closes the debug log file (if opened) */
146 /*-----------------------------------------------------------------*/
147 static void debugLogClose(void)
154 #define AOP(op) op->aop
156 static char *debugAopGet(char *str,operand *op)
161 printOperand(op,debugF);debugNewLine();
167 static char * decodeOp(unsigned int op)
170 if(op<128 && op>' ') {
171 buffer[0] = (op & 0xff);
184 return "STRING_LITERAL";
220 return "LEFT_ASSIGN";
222 return "RIGHT_ASSIGN";
351 case GET_VALUE_AT_ADDRESS:
352 return "GET_VALUE_AT_ADDRESS";
370 return "ENDFUNCTION";
394 sprintf(buffer,"unkown op %d %c",op, op&0xff);
397 /*-----------------------------------------------------------------*/
398 /*-----------------------------------------------------------------*/
399 static char * debugLogRegType(short type)
411 sprintf(buffer,"unkown reg type %d",type);
415 /*-----------------------------------------------------------------*/
416 /* allocReg - allocates register of given type */
417 /*-----------------------------------------------------------------*/
418 static regs *allocReg (short type)
422 debugLog("%s of type %s\n",__FUNCTION__,debugLogRegType(type));
424 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
426 /* if type is given as 0 then any
427 free register will do */
429 regspic14[i].isFree ) {
430 regspic14[i].isFree = 0;
431 regspic14[i].wasUsed = 1;
434 bitVectSetBit(currFunc->regsUsed,i);
435 debugLog(" returning %s\n",regspic14[i].name);
436 return ®spic14[i];
438 /* other wise look for specific type
440 if (regspic14[i].isFree &&
441 regspic14[i].type == type) {
442 regspic14[i].isFree = 0;
443 regspic14[i].wasUsed = 1;
446 bitVectSetBit(currFunc->regsUsed,i);
447 debugLog(" returning %s\n",regspic14[i].name);
448 return ®spic14[i];
454 /*-----------------------------------------------------------------*/
455 /* pic14_regWithIdx - returns pointer to register wit index number */
456 /*-----------------------------------------------------------------*/
457 regs *pic14_regWithIdx (int idx)
461 debugLog("%s\n",__FUNCTION__);
463 for (i=0;i < pic14_nRegs;i++)
464 if (regspic14[i].rIdx == idx)
465 return ®spic14[i];
467 return ®spic14[0];
469 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
470 "regWithIdx not found");
474 /*-----------------------------------------------------------------*/
475 /* freeReg - frees a register */
476 /*-----------------------------------------------------------------*/
477 static void freeReg (regs *reg)
479 debugLog("%s\n",__FUNCTION__);
484 /*-----------------------------------------------------------------*/
485 /* nFreeRegs - returns number of free registers */
486 /*-----------------------------------------------------------------*/
487 static int nFreeRegs (int type)
492 debugLog("%s\n",__FUNCTION__);
493 for (i = 0 ; i < pic14_nRegs; i++ )
494 if (regspic14[i].isFree && regspic14[i].type == type)
499 /*-----------------------------------------------------------------*/
500 /* nfreeRegsType - free registers with type */
501 /*-----------------------------------------------------------------*/
502 static int nfreeRegsType (int type)
505 debugLog("%s\n",__FUNCTION__);
506 if (type == REG_PTR) {
507 if ((nfr = nFreeRegs(type)) == 0)
508 return nFreeRegs(REG_GPR);
511 return nFreeRegs(type);
515 /*-----------------------------------------------------------------*/
516 /* allDefsOutOfRange - all definitions are out of a range */
517 /*-----------------------------------------------------------------*/
518 static bool allDefsOutOfRange (bitVect *defs,int fseq, int toseq)
522 debugLog("%s\n",__FUNCTION__);
526 for ( i = 0 ;i < defs->size ; i++ ) {
529 if (bitVectBitValue(defs,i) &&
530 (ic = hTabItemWithKey(iCodehTab,i)) &&
531 ( ic->seq >= fseq && ic->seq <= toseq))
540 /*-----------------------------------------------------------------*/
541 /* computeSpillable - given a point find the spillable live ranges */
542 /*-----------------------------------------------------------------*/
543 static bitVect *computeSpillable (iCode *ic)
547 debugLog("%s\n",__FUNCTION__);
548 /* spillable live ranges are those that are live at this
549 point . the following categories need to be subtracted
551 a) - those that are already spilt
552 b) - if being used by this one
553 c) - defined by this one */
555 spillable = bitVectCopy(ic->rlive);
557 bitVectCplAnd(spillable,_G.spiltSet); /* those already spilt */
559 bitVectCplAnd(spillable,ic->uses); /* used in this one */
560 bitVectUnSetBit(spillable,ic->defKey);
561 spillable = bitVectIntersect(spillable,_G.regAssigned);
566 /*-----------------------------------------------------------------*/
567 /* noSpilLoc - return true if a variable has no spil location */
568 /*-----------------------------------------------------------------*/
569 static int noSpilLoc (symbol *sym, eBBlock *ebp,iCode *ic)
571 debugLog("%s\n",__FUNCTION__);
572 return (sym->usl.spillLoc ? 0 : 1);
575 /*-----------------------------------------------------------------*/
576 /* hasSpilLoc - will return 1 if the symbol has spil location */
577 /*-----------------------------------------------------------------*/
578 static int hasSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
580 debugLog("%s\n",__FUNCTION__);
581 return (sym->usl.spillLoc ? 1 : 0);
584 /*-----------------------------------------------------------------*/
585 /* directSpilLoc - will return 1 if the splilocation is in direct */
586 /*-----------------------------------------------------------------*/
587 static int directSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
589 debugLog("%s\n",__FUNCTION__);
590 if ( sym->usl.spillLoc &&
591 (IN_DIRSPACE(SPEC_OCLS(sym->usl.spillLoc->etype))))
597 /*-----------------------------------------------------------------*/
598 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location*/
599 /* but is not used as a pointer */
600 /*-----------------------------------------------------------------*/
601 static int hasSpilLocnoUptr (symbol *sym, eBBlock *ebp, iCode *ic)
603 debugLog("%s\n",__FUNCTION__);
604 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
607 /*-----------------------------------------------------------------*/
608 /* rematable - will return 1 if the remat flag is set */
609 /*-----------------------------------------------------------------*/
610 static int rematable (symbol *sym, eBBlock *ebp, iCode *ic)
612 debugLog("%s\n",__FUNCTION__);
616 /*-----------------------------------------------------------------*/
617 /* notUsedInBlock - not used in this block */
618 /*-----------------------------------------------------------------*/
619 static int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic)
621 debugLog("%s\n",__FUNCTION__);
622 return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs) &&
623 allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
624 /* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
627 /*-----------------------------------------------------------------*/
628 /* notUsedInRemaining - not used or defined in remain of the block */
629 /*-----------------------------------------------------------------*/
630 static int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
632 debugLog("%s\n",__FUNCTION__);
633 return ((usedInRemaining (operandFromSymbol(sym),ic) ? 0 : 1) &&
634 allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
637 /*-----------------------------------------------------------------*/
638 /* allLRs - return true for all */
639 /*-----------------------------------------------------------------*/
640 static int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
642 debugLog("%s\n",__FUNCTION__);
646 /*-----------------------------------------------------------------*/
647 /* liveRangesWith - applies function to a given set of live range */
648 /*-----------------------------------------------------------------*/
649 static set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *),
650 eBBlock *ebp, iCode *ic)
655 debugLog("%s\n",__FUNCTION__);
656 if (!lrs || !lrs->size)
659 for ( i = 1 ; i < lrs->size ; i++ ) {
661 if (!bitVectBitValue(lrs,i))
664 /* if we don't find it in the live range
665 hash table we are in serious trouble */
666 if (!(sym = hTabItemWithKey(liveRanges,i))) {
667 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
668 "liveRangesWith could not find liveRange");
672 if (func(sym,ebp,ic) && bitVectBitValue(_G.regAssigned,sym->key))
673 addSetHead(&rset,sym);
680 /*-----------------------------------------------------------------*/
681 /* leastUsedLR - given a set determines which is the least used */
682 /*-----------------------------------------------------------------*/
683 static symbol *leastUsedLR (set *sset)
685 symbol *sym = NULL, *lsym = NULL ;
687 debugLog("%s\n",__FUNCTION__);
688 sym = lsym = setFirstItem(sset);
693 for (; lsym; lsym = setNextItem(sset)) {
695 /* if usage is the same then prefer
696 the spill the smaller of the two */
697 if ( lsym->used == sym->used )
698 if (getSize(lsym->type) < getSize(sym->type))
702 if (lsym->used < sym->used )
707 setToNull((void **)&sset);
712 /*-----------------------------------------------------------------*/
713 /* noOverLap - will iterate through the list looking for over lap */
714 /*-----------------------------------------------------------------*/
715 static int noOverLap (set *itmpStack, symbol *fsym)
718 debugLog("%s\n",__FUNCTION__);
721 for (sym = setFirstItem(itmpStack); sym;
722 sym = setNextItem(itmpStack)) {
723 if (sym->liveTo > fsym->liveFrom )
731 /*-----------------------------------------------------------------*/
732 /* isFree - will return 1 if the a free spil location is found */
733 /*-----------------------------------------------------------------*/
734 static DEFSETFUNC(isFree)
737 V_ARG(symbol **,sloc);
738 V_ARG(symbol *,fsym);
740 debugLog("%s\n",__FUNCTION__);
741 /* if already found */
745 /* if it is free && and the itmp assigned to
746 this does not have any overlapping live ranges
747 with the one currently being assigned and
748 the size can be accomodated */
750 noOverLap(sym->usl.itmpStack,fsym) &&
751 getSize(sym->type) >= getSize(fsym->type)) {
759 /*-----------------------------------------------------------------*/
760 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
761 /*-----------------------------------------------------------------*/
762 static void spillLRWithPtrReg (symbol *forSym)
768 debugLog("%s\n",__FUNCTION__);
769 if (!_G.regAssigned ||
770 bitVectIsZero(_G.regAssigned))
773 r0 = pic14_regWithIdx(R0_IDX);
774 r1 = pic14_regWithIdx(R1_IDX);
776 /* for all live ranges */
777 for (lrsym = hTabFirstItem(liveRanges,&k) ; lrsym ;
778 lrsym = hTabNextItem(liveRanges,&k) ) {
781 /* if no registers assigned to it or
783 /* if it does not overlap with this then
784 not need to spill it */
786 if (lrsym->isspilt || !lrsym->nRegs ||
787 (lrsym->liveTo < forSym->liveFrom))
790 /* go thru the registers : if it is either
791 r0 or r1 then spil it */
792 for (j = 0 ; j < lrsym->nRegs ; j++ )
793 if (lrsym->regs[j] == r0 ||
794 lrsym->regs[j] == r1 ) {
802 /*-----------------------------------------------------------------*/
803 /* createStackSpil - create a location on the stack to spil */
804 /*-----------------------------------------------------------------*/
805 static symbol *createStackSpil (symbol *sym)
808 int useXstack, model, noOverlay;
811 debugLog("%s\n",__FUNCTION__);
813 /* first go try and find a free one that is already
814 existing on the stack */
815 if (applyToSet(_G.stackSpil,isFree,&sloc, sym)) {
816 /* found a free one : just update & return */
817 sym->usl.spillLoc = sloc;
820 addSetHead(&sloc->usl.itmpStack,sym);
824 /* could not then have to create one , this is the hard part
825 we need to allocate this on the stack : this is really a
826 hack!! but cannot think of anything better at this time */
828 if (sprintf(slocBuffer,"sloc%d",_G.slocNum++) >= sizeof(slocBuffer))
830 fprintf(stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
835 sloc = newiTemp(slocBuffer);
837 /* set the type to the spilling symbol */
838 sloc->type = copyLinkChain(sym->type);
839 sloc->etype = getSpec(sloc->type);
840 SPEC_SCLS(sloc->etype) = S_DATA ;
841 SPEC_EXTR(sloc->etype) = 0;
843 /* we don't allow it to be allocated`
844 onto the external stack since : so we
845 temporarily turn it off ; we also
846 turn off memory model to prevent
847 the spil from going to the external storage
848 and turn off overlaying
851 useXstack = options.useXstack;
852 model = options.model;
853 noOverlay = options.noOverlay;
854 options.noOverlay = 1;
855 options.model = options.useXstack = 0;
859 options.useXstack = useXstack;
860 options.model = model;
861 options.noOverlay = noOverlay;
862 sloc->isref = 1; /* to prevent compiler warning */
864 /* if it is on the stack then update the stack */
865 if (IN_STACK(sloc->etype)) {
866 currFunc->stack += getSize(sloc->type);
867 _G.stackExtend += getSize(sloc->type);
869 _G.dataExtend += getSize(sloc->type);
871 /* add it to the _G.stackSpil set */
872 addSetHead(&_G.stackSpil,sloc);
873 sym->usl.spillLoc = sloc;
876 /* add it to the set of itempStack set
877 of the spill location */
878 addSetHead(&sloc->usl.itmpStack,sym);
882 /*-----------------------------------------------------------------*/
883 /* isSpiltOnStack - returns true if the spil location is on stack */
884 /*-----------------------------------------------------------------*/
885 static bool isSpiltOnStack (symbol *sym)
889 debugLog("%s\n",__FUNCTION__);
896 /* if (sym->_G.stackSpil) */
899 if (!sym->usl.spillLoc)
902 etype = getSpec(sym->usl.spillLoc->type);
909 /*-----------------------------------------------------------------*/
910 /* spillThis - spils a specific operand */
911 /*-----------------------------------------------------------------*/
912 static void spillThis (symbol *sym)
915 debugLog("%s : %s\n",__FUNCTION__, sym->rname);
917 /* if this is rematerializable or has a spillLocation
918 we are okay, else we need to create a spillLocation
920 if (!(sym->remat || sym->usl.spillLoc))
921 createStackSpil (sym);
924 /* mark it has spilt & put it in the spilt set */
926 _G.spiltSet = bitVectSetBit(_G.spiltSet,sym->key);
928 bitVectUnSetBit(_G.regAssigned,sym->key);
930 for (i = 0 ; i < sym->nRegs ; i++)
933 freeReg(sym->regs[i]);
937 /* if spilt on stack then free up r0 & r1
938 if they could have been assigned to some
940 if (!pic14_ptrRegReq && isSpiltOnStack(sym)) {
942 spillLRWithPtrReg(sym);
945 if (sym->usl.spillLoc && !sym->remat)
946 sym->usl.spillLoc->allocreq = 1;
950 /*-----------------------------------------------------------------*/
951 /* selectSpil - select a iTemp to spil : rather a simple procedure */
952 /*-----------------------------------------------------------------*/
953 static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
955 bitVect *lrcs= NULL ;
959 debugLog("%s\n",__FUNCTION__);
960 /* get the spillable live ranges */
961 lrcs = computeSpillable (ic);
963 /* get all live ranges that are rematerizable */
964 if ((selectS = liveRangesWith(lrcs,rematable,ebp,ic))) {
966 /* return the least used of these */
967 return leastUsedLR(selectS);
970 /* get live ranges with spillLocations in direct space */
971 if ((selectS = liveRangesWith(lrcs,directSpilLoc,ebp,ic))) {
972 sym = leastUsedLR(selectS);
973 strcpy(sym->rname,(sym->usl.spillLoc->rname[0] ?
974 sym->usl.spillLoc->rname :
975 sym->usl.spillLoc->name));
977 /* mark it as allocation required */
978 sym->usl.spillLoc->allocreq = 1;
982 /* if the symbol is local to the block then */
983 if (forSym->liveTo < ebp->lSeq) {
985 /* check if there are any live ranges allocated
986 to registers that are not used in this block */
987 if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) {
988 sym = leastUsedLR(selectS);
989 /* if this is not rematerializable */
997 /* check if there are any live ranges that not
998 used in the remainder of the block */
999 if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
1000 sym = leastUsedLR (selectS);
1002 sym->remainSpil = 1;
1009 /* find live ranges with spillocation && not used as pointers */
1010 if ((selectS = liveRangesWith(lrcs,hasSpilLocnoUptr,ebp,ic))) {
1012 sym = leastUsedLR(selectS);
1013 /* mark this as allocation required */
1014 sym->usl.spillLoc->allocreq = 1;
1018 /* find live ranges with spillocation */
1019 if ((selectS = liveRangesWith(lrcs,hasSpilLoc,ebp,ic))) {
1021 sym = leastUsedLR(selectS);
1022 sym->usl.spillLoc->allocreq = 1;
1026 /* couldn't find then we need to create a spil
1027 location on the stack , for which one? the least
1029 if ((selectS = liveRangesWith(lrcs,noSpilLoc,ebp,ic))) {
1031 /* return a created spil location */
1032 sym = createStackSpil(leastUsedLR(selectS));
1033 sym->usl.spillLoc->allocreq = 1;
1037 /* this is an extreme situation we will spill
1038 this one : happens very rarely but it does happen */
1039 spillThis ( forSym );
1044 /*-----------------------------------------------------------------*/
1045 /* spilSomething - spil some variable & mark registers as free */
1046 /*-----------------------------------------------------------------*/
1047 static bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
1052 debugLog("%s\n",__FUNCTION__);
1053 /* get something we can spil */
1054 ssym = selectSpil(ic,ebp,forSym);
1056 /* mark it as spilt */
1058 _G.spiltSet = bitVectSetBit(_G.spiltSet,ssym->key);
1060 /* mark it as not register assigned &
1061 take it away from the set */
1062 bitVectUnSetBit(_G.regAssigned,ssym->key);
1064 /* mark the registers as free */
1065 for (i = 0 ; i < ssym->nRegs ;i++ )
1067 freeReg(ssym->regs[i]);
1069 /* if spilt on stack then free up r0 & r1
1070 if they could have been assigned to as gprs */
1071 if (!pic14_ptrRegReq && isSpiltOnStack(ssym) ) {
1073 spillLRWithPtrReg(ssym);
1076 /* if this was a block level spil then insert push & pop
1077 at the start & end of block respectively */
1078 if (ssym->blockSpil) {
1079 iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
1080 /* add push to the start of the block */
1081 addiCodeToeBBlock(ebp,nic,( ebp->sch->op == LABEL ?
1082 ebp->sch->next : ebp->sch));
1083 nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
1084 /* add pop to the end of the block */
1085 addiCodeToeBBlock(ebp,nic,NULL);
1088 /* if spilt because not used in the remainder of the
1089 block then add a push before this instruction and
1090 a pop at the end of the block */
1091 if (ssym->remainSpil) {
1093 iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
1094 /* add push just before this instruction */
1095 addiCodeToeBBlock(ebp,nic,ic);
1097 nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
1098 /* add pop to the end of the block */
1099 addiCodeToeBBlock(ebp,nic,NULL);
1102 if (ssym == forSym )
1108 /*-----------------------------------------------------------------*/
1109 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1110 /*-----------------------------------------------------------------*/
1111 static regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
1115 debugLog("%s\n",__FUNCTION__);
1117 /* try for a ptr type */
1118 if ((reg = allocReg(REG_PTR)))
1121 /* try for gpr type */
1122 if ((reg = allocReg(REG_GPR)))
1125 /* we have to spil */
1126 if (!spilSomething (ic,ebp,sym))
1129 /* this looks like an infinite loop but
1130 in really selectSpil will abort */
1134 /*-----------------------------------------------------------------*/
1135 /* getRegGpr - will try for GPR if not spil */
1136 /*-----------------------------------------------------------------*/
1137 static regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
1141 debugLog("%s\n",__FUNCTION__);
1143 /* try for gpr type */
1144 if ((reg = allocReg(REG_GPR)))
1147 if (!pic14_ptrRegReq)
1148 if ((reg = allocReg(REG_PTR)))
1151 /* we have to spil */
1152 if (!spilSomething (ic,ebp,sym))
1155 /* this looks like an infinite loop but
1156 in really selectSpil will abort */
1160 /*-----------------------------------------------------------------*/
1161 /* symHasReg - symbol has a given register */
1162 /*-----------------------------------------------------------------*/
1163 static bool symHasReg(symbol *sym,regs *reg)
1167 debugLog("%s\n",__FUNCTION__);
1168 for ( i = 0 ; i < sym->nRegs ; i++)
1169 if (sym->regs[i] == reg)
1175 /*-----------------------------------------------------------------*/
1176 /* deassignLRs - check the live to and if they have registers & are*/
1177 /* not spilt then free up the registers */
1178 /*-----------------------------------------------------------------*/
1179 static void deassignLRs (iCode *ic, eBBlock *ebp)
1185 debugLog("%s\n",__FUNCTION__);
1186 for (sym = hTabFirstItem(liveRanges,&k); sym;
1187 sym = hTabNextItem(liveRanges,&k)) {
1190 /* if it does not end here */
1191 if (sym->liveTo > ic->seq )
1194 /* if it was spilt on stack then we can
1195 mark the stack spil location as free */
1196 if (sym->isspilt ) {
1197 if (sym->stackSpil) {
1198 sym->usl.spillLoc->isFree = 1;
1204 if (!bitVectBitValue(_G.regAssigned,sym->key))
1207 /* special case check if this is an IFX &
1208 the privious one was a pop and the
1209 previous one was not spilt then keep track
1211 if (ic->op == IFX && ic->prev &&
1212 ic->prev->op == IPOP &&
1213 !ic->prev->parmPush &&
1214 !OP_SYMBOL(IC_LEFT(ic->prev))->isspilt)
1215 psym = OP_SYMBOL(IC_LEFT(ic->prev));
1220 bitVectUnSetBit(_G.regAssigned,sym->key);
1222 /* if the result of this one needs registers
1223 and does not have it then assign it right
1225 if (IC_RESULT(ic) &&
1226 ! (SKIP_IC2(ic) || /* not a special icode */
1227 ic->op == JUMPTABLE ||
1233 (result = OP_SYMBOL(IC_RESULT(ic))) && /* has a result */
1234 result->liveTo > ic->seq && /* and will live beyond this */
1235 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1236 result->regType == sym->regType && /* same register types */
1237 result->nRegs && /* which needs registers */
1238 ! result->isspilt && /* and does not already have them */
1240 ! bitVectBitValue(_G.regAssigned,result->key) &&
1241 /* the number of free regs + number of regs in this LR
1242 can accomodate the what result Needs */
1243 ((nfreeRegsType(result->regType) +
1244 sym->nRegs) >= result->nRegs)
1247 for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++)
1248 if (i < sym->nRegs )
1249 result->regs[i] = sym->regs[i] ;
1251 result->regs[i] = getRegGpr (ic,ebp,result);
1253 _G.regAssigned = bitVectSetBit(_G.regAssigned,result->key);
1257 /* free the remaining */
1258 for (; i < sym->nRegs ; i++) {
1260 if (!symHasReg(psym,sym->regs[i]))
1261 freeReg(sym->regs[i]);
1263 freeReg(sym->regs[i]);
1270 /*-----------------------------------------------------------------*/
1271 /* reassignLR - reassign this to registers */
1272 /*-----------------------------------------------------------------*/
1273 static void reassignLR (operand *op)
1275 symbol *sym = OP_SYMBOL(op);
1278 debugLog("%s\n",__FUNCTION__);
1279 /* not spilt any more */
1280 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1281 bitVectUnSetBit(_G.spiltSet,sym->key);
1283 _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
1287 for (i=0;i<sym->nRegs;i++)
1288 sym->regs[i]->isFree = 0;
1291 /*-----------------------------------------------------------------*/
1292 /* willCauseSpill - determines if allocating will cause a spill */
1293 /*-----------------------------------------------------------------*/
1294 static int willCauseSpill ( int nr, int rt)
1296 debugLog("%s\n",__FUNCTION__);
1297 /* first check if there are any avlb registers
1298 of te type required */
1299 if (rt == REG_PTR) {
1300 /* special case for pointer type
1301 if pointer type not avlb then
1302 check for type gpr */
1303 if (nFreeRegs(rt) >= nr)
1305 if (nFreeRegs(REG_GPR) >= nr)
1308 if (pic14_ptrRegReq) {
1309 if (nFreeRegs(rt) >= nr)
1312 if (nFreeRegs(REG_PTR) +
1313 nFreeRegs(REG_GPR) >= nr)
1318 debugLog(" ... yep it will (cause a spill)\n");
1319 /* it will cause a spil */
1323 /*-----------------------------------------------------------------*/
1324 /* positionRegs - the allocator can allocate same registers to res-*/
1325 /* ult and operand, if this happens make sure they are in the same */
1326 /* position as the operand otherwise chaos results */
1327 /*-----------------------------------------------------------------*/
1328 static void positionRegs (symbol *result, symbol *opsym, int lineno)
1330 int count = min(result->nRegs,opsym->nRegs);
1331 int i , j = 0, shared = 0;
1333 debugLog("%s\n",__FUNCTION__);
1334 /* if the result has been spilt then cannot share */
1339 /* first make sure that they actually share */
1340 for ( i = 0 ; i < count; i++ ) {
1341 for (j = 0 ; j < count ; j++ ) {
1342 if (result->regs[i] == opsym->regs[j] && i !=j) {
1350 regs *tmp = result->regs[i];
1351 result->regs[i] = result->regs[j];
1352 result->regs[j] = tmp;
1357 /*-----------------------------------------------------------------*/
1358 /* serialRegAssign - serially allocate registers to the variables */
1359 /*-----------------------------------------------------------------*/
1360 static void serialRegAssign (eBBlock **ebbs, int count)
1364 debugLog("%s\n",__FUNCTION__);
1365 /* for all blocks */
1366 for (i = 0; i < count ; i++ ) {
1370 if (ebbs[i]->noPath &&
1371 (ebbs[i]->entryLabel != entryLabel &&
1372 ebbs[i]->entryLabel != returnLabel ))
1375 /* of all instructions do */
1376 for (ic = ebbs[i]->sch ; ic ; ic = ic->next) {
1378 debugLog(" op: %s\n", decodeOp(ic->op));
1380 /* if this is an ipop that means some live
1381 range will have to be assigned again */
1383 reassignLR (IC_LEFT(ic));
1385 /* if result is present && is a true symbol */
1386 if (IC_RESULT(ic) && ic->op != IFX &&
1387 IS_TRUE_SYMOP(IC_RESULT(ic)))
1388 OP_SYMBOL(IC_RESULT(ic))->allocreq = 1;
1390 /* take away registers from live
1391 ranges that end at this instruction */
1392 deassignLRs (ic, ebbs[i]) ;
1394 /* some don't need registers */
1396 ic->op == JUMPTABLE ||
1400 (IC_RESULT(ic) &&POINTER_SET(ic)) )
1403 /* now we need to allocate registers
1404 only for the result */
1405 if (IC_RESULT(ic)) {
1406 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
1412 /* if it does not need or is spilt
1413 or is already assigned to registers
1414 or will not live beyond this instructions */
1417 bitVectBitValue(_G.regAssigned,sym->key) ||
1418 sym->liveTo <= ic->seq)
1421 /* if some liverange has been spilt at the block level
1422 and this one live beyond this block then spil this
1424 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1428 /* if trying to allocate this will cause
1429 a spill and there is nothing to spill
1430 or this one is rematerializable then
1432 willCS = willCauseSpill(sym->nRegs,sym->regType);
1433 spillable = computeSpillable(ic);
1435 (willCS && bitVectIsZero(spillable) ) ) {
1442 /* if it has a spillocation & is used less than
1443 all other live ranges then spill this */
1444 if ( willCS && sym->usl.spillLoc ) {
1447 leastUsedLR(liveRangesWith (spillable ,
1452 leastUsed->used > sym->used) {
1458 if(ic->op == RECEIVE)
1459 debugLog("When I get clever, I'll optimize the receive logic\n");
1461 /* if we need ptr regs for the right side
1463 if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type)
1469 /* else we assign registers to it */
1470 _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
1472 debugLog(" %d - \n",__LINE__);
1474 for (j = 0 ; j < sym->nRegs ;j++ ) {
1475 if (sym->regType == REG_PTR)
1476 sym->regs[j] = getRegPtr(ic,ebbs[i],sym);
1478 sym->regs[j] = getRegGpr(ic,ebbs[i],sym);
1480 /* if the allocation falied which means
1481 this was spilt then break */
1485 debugLog(" %d - \n",__LINE__);
1487 /* if it shares registers with operands make sure
1488 that they are in the same position */
1489 if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
1490 OP_SYMBOL(IC_LEFT(ic))->nRegs && ic->op != '=')
1491 positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1492 OP_SYMBOL(IC_LEFT(ic)),ic->lineno);
1493 /* do the same for the right operand */
1494 if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
1495 OP_SYMBOL(IC_RIGHT(ic))->nRegs && ic->op != '=')
1496 positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1497 OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
1499 debugLog(" %d - \n",__LINE__);
1501 debugLog(" %d - \n",__LINE__);
1511 /*-----------------------------------------------------------------*/
1512 /* rUmaskForOp :- returns register mask for an operand */
1513 /*-----------------------------------------------------------------*/
1514 static bitVect *rUmaskForOp (operand *op)
1520 debugLog("%s\n",__FUNCTION__);
1521 /* only temporaries are assigned registers */
1525 sym = OP_SYMBOL(op);
1527 /* if spilt or no registers assigned to it
1529 if (sym->isspilt || !sym->nRegs)
1532 rumask = newBitVect(pic14_nRegs);
1534 for (j = 0; j < sym->nRegs; j++) {
1535 rumask = bitVectSetBit(rumask,
1536 sym->regs[j]->rIdx);
1542 /*-----------------------------------------------------------------*/
1543 /* regsUsedIniCode :- returns bit vector of registers used in iCode*/
1544 /*-----------------------------------------------------------------*/
1545 static bitVect *regsUsedIniCode (iCode *ic)
1547 bitVect *rmask = newBitVect(pic14_nRegs);
1549 debugLog("%s\n",__FUNCTION__);
1550 /* do the special cases first */
1551 if (ic->op == IFX ) {
1552 rmask = bitVectUnion(rmask,
1553 rUmaskForOp(IC_COND(ic)));
1557 /* for the jumptable */
1558 if (ic->op == JUMPTABLE) {
1559 rmask = bitVectUnion(rmask,
1560 rUmaskForOp(IC_JTCOND(ic)));
1565 /* of all other cases */
1567 rmask = bitVectUnion(rmask,
1568 rUmaskForOp(IC_LEFT(ic)));
1572 rmask = bitVectUnion(rmask,
1573 rUmaskForOp(IC_RIGHT(ic)));
1576 rmask = bitVectUnion(rmask,
1577 rUmaskForOp(IC_RESULT(ic)));
1583 /*-----------------------------------------------------------------*/
1584 /* createRegMask - for each instruction will determine the regsUsed*/
1585 /*-----------------------------------------------------------------*/
1586 static void createRegMask (eBBlock **ebbs, int count)
1590 debugLog("%s\n",__FUNCTION__);
1591 /* for all blocks */
1592 for (i = 0; i < count ; i++ ) {
1595 if ( ebbs[i]->noPath &&
1596 ( ebbs[i]->entryLabel != entryLabel &&
1597 ebbs[i]->entryLabel != returnLabel ))
1600 /* for all instructions */
1601 for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
1605 if (SKIP_IC2(ic) || !ic->rlive)
1608 /* first mark the registers used in this
1610 ic->rUsed = regsUsedIniCode(ic);
1611 _G.funcrUsed = bitVectUnion(_G.funcrUsed,ic->rUsed);
1613 /* now create the register mask for those
1614 registers that are in use : this is a
1615 super set of ic->rUsed */
1616 ic->rMask = newBitVect(pic14_nRegs+1);
1618 /* for all live Ranges alive at this point */
1619 for (j = 1; j < ic->rlive->size; j++ ) {
1623 /* if not alive then continue */
1624 if (!bitVectBitValue(ic->rlive,j))
1627 /* find the live range we are interested in */
1628 if (!(sym = hTabItemWithKey(liveRanges,j))) {
1629 werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
1630 "createRegMask cannot find live range");
1634 /* if no register assigned to it */
1635 if (!sym->nRegs || sym->isspilt)
1638 /* for all the registers allocated to it */
1639 for (k = 0 ; k < sym->nRegs ;k++)
1642 bitVectSetBit(ic->rMask,sym->regs[k]->rIdx);
1648 /*-----------------------------------------------------------------*/
1649 /* rematStr - returns the rematerialized string for a remat var */
1650 /*-----------------------------------------------------------------*/
1651 static char *rematStr (symbol *sym)
1654 iCode *ic = sym->rematiCode;
1656 debugLog("%s\n",__FUNCTION__);
1660 /* if plus or minus print the right hand side */
1662 if (ic->op == '+' || ic->op == '-') {
1663 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1666 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1670 if (ic->op == '+' || ic->op == '-') {
1671 iCode *ric = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1672 sprintf(s,"(%s %c 0x%04x)",
1673 OP_SYMBOL(IC_LEFT(ric))->rname,
1675 (int) operandLitValue(IC_RIGHT(ic)));
1678 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1683 /* we reached the end */
1684 sprintf(s,"%s\n",OP_SYMBOL(IC_LEFT(ic))->rname);
1688 printf("%s\n",buffer);
1692 /*-----------------------------------------------------------------*/
1693 /* regTypeNum - computes the type & number of registers required */
1694 /*-----------------------------------------------------------------*/
1695 static void regTypeNum ()
1701 debugLog("%s\n",__FUNCTION__);
1702 /* for each live range do */
1703 for ( sym = hTabFirstItem(liveRanges,&k); sym ;
1704 sym = hTabNextItem(liveRanges,&k)) {
1706 debugLog(" %d - %s\n",__LINE__ , sym->rname);
1708 /* if used zero times then no registers needed */
1709 if ((sym->liveTo - sym->liveFrom) == 0)
1713 /* if the live range is a temporary */
1716 debugLog(" %d - \n",__LINE__);
1718 /* if the type is marked as a conditional */
1719 if (sym->regType == REG_CND)
1722 /* if used in return only then we don't
1724 if (sym->ruonly || sym->accuse) {
1725 if (IS_AGGREGATE(sym->type) || sym->isptr)
1726 sym->type = aggrToPtr(sym->type,FALSE);
1727 debugLog(" %d - \n",__LINE__);
1732 /* if the symbol has only one definition &
1733 that definition is a get_pointer and the
1734 pointer we are getting is rematerializable and
1737 if (bitVectnBitsOn(sym->defs) == 1 &&
1738 (ic = hTabItemWithKey(iCodehTab,
1739 bitVectFirstBit(sym->defs))) &&
1741 !IS_BITVAR(sym->etype)) {
1743 debugLog(" %d - \n",__LINE__);
1745 /* if remat in data space */
1746 if (OP_SYMBOL(IC_LEFT(ic))->remat &&
1747 DCL_TYPE(aggrToPtr(sym->type,FALSE)) == POINTER) {
1749 /* create a psuedo symbol & force a spil */
1750 symbol *psym = newSymbol(rematStr(OP_SYMBOL(IC_LEFT(ic))),1);
1751 psym->type = sym->type;
1752 psym->etype = sym->etype;
1753 strcpy(psym->rname,psym->name);
1755 sym->usl.spillLoc = psym;
1759 /* if in data space or idata space then try to
1760 allocate pointer register */
1764 /* if not then we require registers */
1765 sym->nRegs = ((IS_AGGREGATE(sym->type) || sym->isptr ) ?
1766 getSize(sym->type = aggrToPtr(sym->type,FALSE)) :
1767 getSize(sym->type));
1769 if (sym->nRegs > 4) {
1770 fprintf(stderr,"allocated more than 4 or 0 registers for type ");
1771 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1774 debugLog(" %d - \n",__LINE__);
1776 /* determine the type of register required */
1777 if (sym->nRegs == 1 &&
1778 IS_PTR(sym->type) &&
1780 sym->regType = REG_PTR ;
1782 sym->regType = REG_GPR ;
1783 debugLog(" reg type %s\n",debugLogRegType(sym->regType));
1786 /* for the first run we don't provide */
1787 /* registers for true symbols we will */
1788 /* see how things go */
1794 /*-----------------------------------------------------------------*/
1795 /* freeAllRegs - mark all registers as free */
1796 /*-----------------------------------------------------------------*/
1797 static void freeAllRegs()
1801 debugLog("%s\n",__FUNCTION__);
1802 for (i=0;i< pic14_nRegs;i++ )
1803 regspic14[i].isFree = 1;
1806 /*-----------------------------------------------------------------*/
1807 /* deallocStackSpil - this will set the stack pointer back */
1808 /*-----------------------------------------------------------------*/
1809 static DEFSETFUNC(deallocStackSpil)
1813 debugLog("%s\n",__FUNCTION__);
1818 /*-----------------------------------------------------------------*/
1819 /* farSpacePackable - returns the packable icode for far variables */
1820 /*-----------------------------------------------------------------*/
1821 static iCode *farSpacePackable (iCode *ic)
1825 debugLog("%s\n",__FUNCTION__);
1826 /* go thru till we find a definition for the
1827 symbol on the right */
1828 for ( dic = ic->prev ; dic ; dic = dic->prev) {
1830 /* if the definition is a call then no */
1831 if ((dic->op == CALL || dic->op == PCALL) &&
1832 IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1836 /* if shift by unknown amount then not */
1837 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1838 IC_RESULT(dic)->key == IC_RIGHT(ic)->key)
1841 /* if pointer get and size > 1 */
1842 if (POINTER_GET(dic) &&
1843 getSize(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)) > 1)
1846 if (POINTER_SET(dic) &&
1847 getSize(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)) > 1)
1850 /* if any three is a true symbol in far space */
1851 if (IC_RESULT(dic) &&
1852 IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1853 isOperandInFarSpace(IC_RESULT(dic)))
1856 if (IC_RIGHT(dic) &&
1857 IS_TRUE_SYMOP(IC_RIGHT(dic)) &&
1858 isOperandInFarSpace(IC_RIGHT(dic)) &&
1859 !isOperandEqual(IC_RIGHT(dic),IC_RESULT(ic)))
1863 IS_TRUE_SYMOP(IC_LEFT(dic)) &&
1864 isOperandInFarSpace(IC_LEFT(dic)) &&
1865 !isOperandEqual(IC_LEFT(dic),IC_RESULT(ic)))
1868 if (isOperandEqual(IC_RIGHT(ic),IC_RESULT(dic))) {
1869 if ( (dic->op == LEFT_OP ||
1870 dic->op == RIGHT_OP ||
1872 IS_OP_LITERAL(IC_RIGHT(dic)))
1882 /*-----------------------------------------------------------------*/
1883 /* packRegsForAssign - register reduction for assignment */
1884 /*-----------------------------------------------------------------*/
1885 static int packRegsForAssign (iCode *ic,eBBlock *ebp)
1890 debugLog("%s\n",__FUNCTION__);
1892 debugAopGet(" result:",IC_RESULT(ic));
1893 debugAopGet(" left:",IC_LEFT(ic));
1894 debugAopGet(" right:",IC_RIGHT(ic));
1896 if (!IS_ITEMP(IC_RIGHT(ic)) ||
1897 OP_SYMBOL(IC_RIGHT(ic))->isind ||
1898 OP_LIVETO(IC_RIGHT(ic)) > ic->seq) {
1902 /* if the true symbol is defined in far space or on stack
1903 then we should not since this will increase register pressure */
1904 if (isOperandInFarSpace(IC_RESULT(ic))) {
1905 if ((dic = farSpacePackable(ic)))
1911 /* find the definition of iTempNN scanning backwards if we find a
1912 a use of the true symbol before we find the definition then
1914 for ( dic = ic->prev ; dic ; dic = dic->prev) {
1916 /* if there is a function call and this is
1917 a parameter & not my parameter then don't pack it */
1918 if ( (dic->op == CALL || dic->op == PCALL) &&
1919 (OP_SYMBOL(IC_RESULT(ic))->_isparm &&
1920 !OP_SYMBOL(IC_RESULT(ic))->ismyparm)) {
1921 debugLog(" %d - \n",__LINE__);
1929 if (IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1930 IS_OP_VOLATILE(IC_RESULT(dic))) {
1931 debugLog(" %d - \n",__LINE__);
1936 if (IS_SYMOP(IC_RESULT(dic)) &&
1937 IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1938 debugLog(" %d - dic key == ic key -- pointer set=%c\n",__LINE__,((POINTER_SET(dic)) ? 'Y' :'N') );
1939 if (POINTER_SET(dic))
1945 if (IS_SYMOP(IC_RIGHT(dic)) &&
1946 (IC_RIGHT(dic)->key == IC_RESULT(ic)->key ||
1947 IC_RIGHT(dic)->key == IC_RIGHT(ic)->key)) {
1948 debugLog(" %d - \n",__LINE__);
1953 if (IS_SYMOP(IC_LEFT(dic)) &&
1954 (IC_LEFT(dic)->key == IC_RESULT(ic)->key ||
1955 IC_LEFT(dic)->key == IC_RIGHT(ic)->key)) {
1956 debugLog(" %d - \n",__LINE__);
1961 if (POINTER_SET(dic) &&
1962 IC_RESULT(dic)->key == IC_RESULT(ic)->key ) {
1963 debugLog(" %d - \n",__LINE__);
1970 return 0 ; /* did not find */
1972 /* if the result is on stack or iaccess then it must be
1973 the same atleast one of the operands */
1974 if (OP_SYMBOL(IC_RESULT(ic))->onStack ||
1975 OP_SYMBOL(IC_RESULT(ic))->iaccess ) {
1977 /* the operation has only one symbol
1978 operator then we can pack */
1979 if ((IC_LEFT(dic) && !IS_SYMOP(IC_LEFT(dic))) ||
1980 (IC_RIGHT(dic) && !IS_SYMOP(IC_RIGHT(dic))))
1983 if (!((IC_LEFT(dic) &&
1984 IC_RESULT(ic)->key == IC_LEFT(dic)->key) ||
1986 IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
1990 debugLog(" packing. removing %s\n",OP_SYMBOL(IC_RIGHT(ic))->rname);
1991 /* found the definition */
1992 /* replace the result with the result of */
1993 /* this assignment and remove this assignment */
1994 IC_RESULT(dic) = IC_RESULT(ic) ;
1996 if (IS_ITEMP(IC_RESULT(dic)) && OP_SYMBOL(IC_RESULT(dic))->liveFrom > dic->seq) {
1997 OP_SYMBOL(IC_RESULT(dic))->liveFrom = dic->seq;
1999 /* delete from liverange table also
2000 delete from all the points inbetween and the new
2002 for ( sic = dic; sic != ic ; sic = sic->next ) {
2003 bitVectUnSetBit(sic->rlive,IC_RESULT(ic)->key);
2004 if (IS_ITEMP(IC_RESULT(dic)))
2005 bitVectSetBit(sic->rlive,IC_RESULT(dic)->key);
2008 remiCodeFromeBBlock(ebp,ic);
2009 hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2010 OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
2016 /*-----------------------------------------------------------------*/
2017 /* findAssignToSym : scanning backwards looks for first assig found*/
2018 /*-----------------------------------------------------------------*/
2019 static iCode *findAssignToSym (operand *op,iCode *ic)
2023 debugLog("%s\n",__FUNCTION__);
2024 for (dic = ic->prev ; dic ; dic = dic->prev) {
2026 /* if definition by assignment */
2027 if (dic->op == '=' &&
2028 !POINTER_SET(dic) &&
2029 IC_RESULT(dic)->key == op->key
2030 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2033 /* we are interested only if defined in far space */
2034 /* or in stack space in case of + & - */
2036 /* if assigned to a non-symbol then return
2038 if (!IS_SYMOP(IC_RIGHT(dic)))
2041 /* if the symbol is in far space then
2043 if (isOperandInFarSpace(IC_RIGHT(dic)))
2046 /* for + & - operations make sure that
2047 if it is on the stack it is the same
2048 as one of the three operands */
2049 if ((ic->op == '+' || ic->op == '-') &&
2050 OP_SYMBOL(IC_RIGHT(dic))->onStack) {
2052 if ( IC_RESULT(ic)->key != IC_RIGHT(dic)->key &&
2053 IC_LEFT(ic)->key != IC_RIGHT(dic)->key &&
2054 IC_RIGHT(ic)->key != IC_RIGHT(dic)->key)
2062 /* if we find an usage then we cannot delete it */
2063 if (IC_LEFT(dic) && IC_LEFT(dic)->key == op->key)
2066 if (IC_RIGHT(dic) && IC_RIGHT(dic)->key == op->key)
2069 if (POINTER_SET(dic) && IC_RESULT(dic)->key == op->key)
2073 /* now make sure that the right side of dic
2074 is not defined between ic & dic */
2076 iCode *sic = dic->next ;
2078 for (; sic != ic ; sic = sic->next)
2079 if (IC_RESULT(sic) &&
2080 IC_RESULT(sic)->key == IC_RIGHT(dic)->key)
2089 /*-----------------------------------------------------------------*/
2090 /* packRegsForSupport :- reduce some registers for support calls */
2091 /*-----------------------------------------------------------------*/
2092 static int packRegsForSupport (iCode *ic, eBBlock *ebp)
2096 debugLog("%s\n",__FUNCTION__);
2097 /* for the left & right operand :- look to see if the
2098 left was assigned a true symbol in far space in that
2099 case replace them */
2100 if (IS_ITEMP(IC_LEFT(ic)) &&
2101 OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) {
2102 iCode *dic = findAssignToSym(IC_LEFT(ic),ic);
2108 debugAopGet("removing left:",IC_LEFT(ic));
2110 /* found it we need to remove it from the
2112 for ( sic = dic; sic != ic ; sic = sic->next )
2113 bitVectUnSetBit(sic->rlive,IC_LEFT(ic)->key);
2115 IC_LEFT(ic)->operand.symOperand =
2116 IC_RIGHT(dic)->operand.symOperand;
2117 IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
2118 remiCodeFromeBBlock(ebp,dic);
2119 hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
2123 /* do the same for the right operand */
2126 IS_ITEMP(IC_RIGHT(ic)) &&
2127 OP_SYMBOL(IC_RIGHT(ic))->liveTo <= ic->seq) {
2128 iCode *dic = findAssignToSym(IC_RIGHT(ic),ic);
2134 /* if this is a subtraction & the result
2135 is a true symbol in far space then don't pack */
2136 if (ic->op == '-' && IS_TRUE_SYMOP(IC_RESULT(dic))) {
2137 sym_link *etype =getSpec(operandType(IC_RESULT(dic)));
2138 if (IN_FARSPACE(SPEC_OCLS(etype)))
2142 debugAopGet("removing right:",IC_RIGHT(ic));
2144 /* found it we need to remove it from the
2146 for ( sic = dic; sic != ic ; sic = sic->next )
2147 bitVectUnSetBit(sic->rlive,IC_RIGHT(ic)->key);
2149 IC_RIGHT(ic)->operand.symOperand =
2150 IC_RIGHT(dic)->operand.symOperand;
2151 IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
2153 remiCodeFromeBBlock(ebp,dic);
2154 hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
2161 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2164 /*-----------------------------------------------------------------*/
2165 /* packRegsForOneuse : - will reduce some registers for single Use */
2166 /*-----------------------------------------------------------------*/
2167 static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
2172 debugLog("%s\n",__FUNCTION__);
2173 /* if returning a literal then do nothing */
2177 /* only upto 2 bytes since we cannot predict
2178 the usage of b, & acc */
2179 if (getSize(operandType(op)) > (fReturnSize - 2) &&
2184 /* this routine will mark the a symbol as used in one
2185 instruction use only && if the definition is local
2186 (ie. within the basic block) && has only one definition &&
2187 that definition is either a return value from a
2188 function or does not contain any variables in
2190 uses = bitVectCopy(OP_USES(op));
2191 bitVectUnSetBit(uses,ic->key); /* take away this iCode */
2192 if (!bitVectIsZero(uses)) /* has other uses */
2195 /* if it has only one defintion */
2196 if (bitVectnBitsOn(OP_DEFS(op)) > 1)
2197 return NULL ; /* has more than one definition */
2199 /* get that definition */
2201 hTabItemWithKey(iCodehTab,
2202 bitVectFirstBit(OP_DEFS(op)))))
2205 /* found the definition now check if it is local */
2206 if (dic->seq < ebp->fSeq ||
2207 dic->seq > ebp->lSeq)
2208 return NULL ; /* non-local */
2210 /* now check if it is the return from
2212 if (dic->op == CALL || dic->op == PCALL ) {
2213 if (ic->op != SEND && ic->op != RETURN) {
2214 OP_SYMBOL(op)->ruonly = 1;
2221 /* otherwise check that the definition does
2222 not contain any symbols in far space */
2223 if (isOperandInFarSpace(IC_LEFT(dic)) ||
2224 isOperandInFarSpace(IC_RIGHT(dic)) ||
2225 IS_OP_RUONLY(IC_LEFT(ic)) ||
2226 IS_OP_RUONLY(IC_RIGHT(ic)) ) {
2230 /* if pointer set then make sure the pointer
2232 if (POINTER_SET(dic) &&
2233 !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
2236 if (POINTER_GET(dic) &&
2237 !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
2242 /* also make sure the intervenening instructions
2243 don't have any thing in far space */
2244 for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
2246 /* if there is an intervening function call then no */
2247 if (dic->op == CALL || dic->op == PCALL)
2249 /* if pointer set then make sure the pointer
2251 if (POINTER_SET(dic) &&
2252 !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
2255 if (POINTER_GET(dic) &&
2256 !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
2259 /* if address of & the result is remat then okay */
2260 if (dic->op == ADDRESS_OF &&
2261 OP_SYMBOL(IC_RESULT(dic))->remat)
2264 /* if operand has size of three or more & this
2265 operation is a '*','/' or '%' then 'b' may
2267 if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2268 getSize(operandType(op)) >= 3)
2271 /* if left or right or result is in far space */
2272 if (isOperandInFarSpace(IC_LEFT(dic)) ||
2273 isOperandInFarSpace(IC_RIGHT(dic)) ||
2274 isOperandInFarSpace(IC_RESULT(dic)) ||
2275 IS_OP_RUONLY(IC_LEFT(dic)) ||
2276 IS_OP_RUONLY(IC_RIGHT(dic)) ||
2277 IS_OP_RUONLY(IC_RESULT(dic)) ) {
2282 OP_SYMBOL(op)->ruonly = 1;
2287 /*-----------------------------------------------------------------*/
2288 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2289 /*-----------------------------------------------------------------*/
2290 static bool isBitwiseOptimizable (iCode *ic)
2292 sym_link *ltype = getSpec(operandType(IC_LEFT(ic)));
2293 sym_link *rtype = getSpec(operandType(IC_RIGHT(ic)));
2295 debugLog("%s\n",__FUNCTION__);
2296 /* bitwise operations are considered optimizable
2297 under the following conditions (Jean-Louis VERN)
2309 if ( IS_LITERAL(rtype) ||
2310 (IS_BITVAR(ltype) && IN_BITSPACE(SPEC_OCLS(ltype))))
2316 /*-----------------------------------------------------------------*/
2317 /* packRegsForAccUse - pack registers for acc use */
2318 /*-----------------------------------------------------------------*/
2319 static void packRegsForAccUse (iCode *ic)
2323 debugLog("%s\n",__FUNCTION__);
2324 /* if + or - then it has to be one byte result */
2325 if ((ic->op == '+' || ic->op == '-')
2326 && getSize(operandType(IC_RESULT(ic))) > 1)
2329 /* if shift operation make sure right side is not a literal */
2330 if (ic->op == RIGHT_OP &&
2331 ( isOperandLiteral(IC_RIGHT(ic)) ||
2332 getSize(operandType(IC_RESULT(ic))) > 1))
2335 if (ic->op == LEFT_OP &&
2336 ( isOperandLiteral(IC_RIGHT(ic)) ||
2337 getSize(operandType(IC_RESULT(ic))) > 1))
2340 if (IS_BITWISE_OP(ic) &&
2341 getSize(operandType(IC_RESULT(ic))) > 1)
2345 /* has only one definition */
2346 if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
2349 /* has only one use */
2350 if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
2353 /* and the usage immediately follows this iCode */
2354 if (!(uic = hTabItemWithKey(iCodehTab,
2355 bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
2358 if (ic->next != uic)
2361 /* if it is a conditional branch then we definitely can */
2362 if (uic->op == IFX )
2365 if ( uic->op == JUMPTABLE )
2368 /* if the usage is not is an assignment
2369 or an arithmetic / bitwise / shift operation then not */
2370 if (POINTER_SET(uic) &&
2371 getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1)
2374 if (uic->op != '=' &&
2375 !IS_ARITHMETIC_OP(uic) &&
2376 !IS_BITWISE_OP(uic) &&
2377 uic->op != LEFT_OP &&
2378 uic->op != RIGHT_OP )
2381 /* if used in ^ operation then make sure right is not a
2383 if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic)))
2386 /* if shift operation make sure right side is not a literal */
2387 if (uic->op == RIGHT_OP &&
2388 ( isOperandLiteral(IC_RIGHT(uic)) ||
2389 getSize(operandType(IC_RESULT(uic))) > 1))
2392 if (uic->op == LEFT_OP &&
2393 ( isOperandLiteral(IC_RIGHT(uic)) ||
2394 getSize(operandType(IC_RESULT(uic))) > 1))
2397 /* make sure that the result of this icode is not on the
2398 stack, since acc is used to compute stack offset */
2399 if (IS_TRUE_SYMOP(IC_RESULT(uic)) &&
2400 OP_SYMBOL(IC_RESULT(uic))->onStack)
2403 /* if either one of them in far space then we cannot */
2404 if ((IS_TRUE_SYMOP(IC_LEFT(uic)) &&
2405 isOperandInFarSpace(IC_LEFT(uic))) ||
2406 (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
2407 isOperandInFarSpace(IC_RIGHT(uic))))
2410 /* if the usage has only one operand then we can */
2411 if (IC_LEFT(uic) == NULL ||
2412 IC_RIGHT(uic) == NULL)
2415 /* make sure this is on the left side if not
2416 a '+' since '+' is commutative */
2417 if (ic->op != '+' &&
2418 IC_LEFT(uic)->key != IC_RESULT(ic)->key)
2421 /* if one of them is a literal then we can */
2422 if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) ||
2423 (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) {
2424 OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
2428 /* if the other one is not on stack then we can */
2429 if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2430 (IS_ITEMP(IC_RIGHT(uic)) ||
2431 (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
2432 !OP_SYMBOL(IC_RIGHT(uic))->onStack)))
2435 if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2436 (IS_ITEMP(IC_LEFT(uic)) ||
2437 (IS_TRUE_SYMOP(IC_LEFT(uic)) &&
2438 !OP_SYMBOL(IC_LEFT(uic))->onStack)))
2444 OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
2449 /*-----------------------------------------------------------------*/
2450 /* packForPush - hueristics to reduce iCode for pushing */
2451 /*-----------------------------------------------------------------*/
2452 static void packForReceive(iCode *ic, eBBlock *ebp)
2455 bool can_remove=1; // assume that we can remove temporary
2457 debugLog("%s\n",__FUNCTION__);
2458 debugAopGet(" result:",IC_RESULT(ic));
2459 debugAopGet(" left:",IC_LEFT(ic));
2460 debugAopGet(" right:",IC_RIGHT(ic));
2465 for ( dic = ic->next ; dic ; dic = dic->next ) {
2469 if(IC_LEFT(dic) && (IC_RESULT(ic)->key == IC_LEFT(dic)->key) )
2470 debugLog(" used on left\n");
2471 if(IC_RIGHT(dic) && IC_RESULT(ic)->key == IC_RIGHT(dic)->key)
2472 debugLog(" used on right\n");
2473 if(IC_RESULT(dic) && IC_RESULT(ic)->key == IC_RESULT(dic)->key)
2474 debugLog(" used on result\n");
2476 if( (IC_LEFT(dic) && (IC_RESULT(ic)->key == IC_LEFT(dic)->key) ) ||
2477 (IC_RESULT(dic) && IC_RESULT(ic)->key == IC_RESULT(dic)->key) )
2482 debugLog(" hey we can remove this unnecessary assign\n");
2484 /*-----------------------------------------------------------------*/
2485 /* packForPush - hueristics to reduce iCode for pushing */
2486 /*-----------------------------------------------------------------*/
2487 static void packForPush(iCode *ic, eBBlock *ebp)
2491 debugLog("%s\n",__FUNCTION__);
2492 if (ic->op != IPUSH || !IS_ITEMP(IC_LEFT(ic)))
2495 /* must have only definition & one usage */
2496 if (bitVectnBitsOn(OP_DEFS(IC_LEFT(ic))) != 1 ||
2497 bitVectnBitsOn(OP_USES(IC_LEFT(ic))) != 1 )
2500 /* find the definition */
2501 if (!(dic = hTabItemWithKey(iCodehTab,
2502 bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
2505 if (dic->op != '=' || POINTER_SET(dic))
2508 /* we now we know that it has one & only one def & use
2509 and the that the definition is an assignment */
2510 IC_LEFT(ic) = IC_RIGHT(dic);
2512 remiCodeFromeBBlock(ebp,dic);
2513 hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
2516 /*-----------------------------------------------------------------*/
2517 /* packRegisters - does some transformations to reduce register */
2519 /*-----------------------------------------------------------------*/
2520 static void packRegisters (eBBlock *ebp)
2525 debugLog("%s\n",__FUNCTION__);
2531 /* look for assignments of the form */
2532 /* iTempNN = TRueSym (someoperation) SomeOperand */
2534 /* TrueSym := iTempNN:1 */
2535 for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2537 /* find assignment of the form TrueSym := iTempNN:1 */
2538 if (ic->op == '=' && !POINTER_SET(ic))
2539 change += packRegsForAssign(ic,ebp);
2541 if (ic->op == '=') {
2543 debugLog("pointer is set\n");
2544 debugAopGet(" result:",IC_RESULT(ic));
2545 debugAopGet(" left:",IC_LEFT(ic));
2546 debugAopGet(" right:",IC_RIGHT(ic));
2555 for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2557 /* if this is an itemp & result of a address of a true sym
2558 then mark this as rematerialisable */
2559 if (ic->op == ADDRESS_OF &&
2560 IS_ITEMP(IC_RESULT(ic)) &&
2561 IS_TRUE_SYMOP(IC_LEFT(ic)) &&
2562 bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2563 !OP_SYMBOL(IC_LEFT(ic))->onStack ) {
2565 OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2566 OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2567 OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2571 /* if straight assignment then carry remat flag if
2572 this is the only definition */
2573 if (ic->op == '=' &&
2575 IS_SYMOP(IC_RIGHT(ic)) &&
2576 OP_SYMBOL(IC_RIGHT(ic))->remat &&
2577 bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->defs) <= 1) {
2579 OP_SYMBOL(IC_RESULT(ic))->remat =
2580 OP_SYMBOL(IC_RIGHT(ic))->remat;
2581 OP_SYMBOL(IC_RESULT(ic))->rematiCode =
2582 OP_SYMBOL(IC_RIGHT(ic))->rematiCode ;
2585 /* if this is a +/- operation with a rematerizable
2586 then mark this as rematerializable as well */
2587 if ((ic->op == '+' || ic->op == '-') &&
2588 (IS_SYMOP(IC_LEFT(ic)) &&
2589 IS_ITEMP(IC_RESULT(ic)) &&
2590 OP_SYMBOL(IC_LEFT(ic))->remat &&
2591 bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2592 IS_OP_LITERAL(IC_RIGHT(ic))) ) {
2595 operandLitValue(IC_RIGHT(ic));
2596 OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2597 OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2598 OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2601 /* mark the pointer usages */
2602 if (POINTER_SET(ic)) {
2603 OP_SYMBOL(IC_RESULT(ic))->uptr = 1;
2604 debugLog(" marking as a pointer (set)\n");
2606 if (POINTER_GET(ic)) {
2607 OP_SYMBOL(IC_LEFT(ic))->uptr = 1;
2608 debugLog(" marking as a pointer (get)\n");
2611 if (!SKIP_IC2(ic)) {
2612 /* if we are using a symbol on the stack
2613 then we should say pic14_ptrRegReq */
2614 if (ic->op == IFX && IS_SYMOP(IC_COND(ic)))
2615 pic14_ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack ||
2616 OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0);
2618 if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic)))
2619 pic14_ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack ||
2620 OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0);
2622 if (IS_SYMOP(IC_LEFT(ic)))
2623 pic14_ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack ||
2624 OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0);
2625 if (IS_SYMOP(IC_RIGHT(ic)))
2626 pic14_ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack ||
2627 OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0);
2628 if (IS_SYMOP(IC_RESULT(ic)))
2629 pic14_ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack ||
2630 OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0);
2634 /* if the condition of an if instruction
2635 is defined in the previous instruction then
2636 mark the itemp as a conditional */
2637 if ((IS_CONDITIONAL(ic) ||
2638 ( ( ic->op == BITWISEAND ||
2641 isBitwiseOptimizable(ic))) &&
2642 ic->next && ic->next->op == IFX &&
2643 isOperandEqual(IC_RESULT(ic),IC_COND(ic->next)) &&
2644 OP_SYMBOL(IC_RESULT(ic))->liveTo <= ic->next->seq) {
2646 OP_SYMBOL(IC_RESULT(ic))->regType = REG_CND;
2650 /* reduce for support function calls */
2651 if (ic->supportRtn || ic->op == '+' || ic->op == '-' )
2652 packRegsForSupport (ic,ebp);
2654 /* if a parameter is passed, it's in W, so we may not
2655 need to place a copy in a register */
2656 if(ic->op == RECEIVE)
2657 packForReceive(ic,ebp);
2659 /* some cases the redundant moves can
2660 can be eliminated for return statements */
2661 if ((ic->op == RETURN || ic->op == SEND) &&
2662 !isOperandInFarSpace(IC_LEFT(ic)) &&
2664 packRegsForOneuse (ic,IC_LEFT(ic),ebp);
2666 /* if pointer set & left has a size more than
2667 one and right is not in far space */
2668 if (POINTER_SET(ic) &&
2669 !isOperandInFarSpace(IC_RIGHT(ic)) &&
2670 !OP_SYMBOL(IC_RESULT(ic))->remat &&
2671 !IS_OP_RUONLY(IC_RIGHT(ic)) &&
2672 getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 )
2674 packRegsForOneuse (ic,IC_RESULT(ic),ebp);
2676 /* if pointer get */
2677 if (POINTER_GET(ic) &&
2678 !isOperandInFarSpace(IC_RESULT(ic))&&
2679 !OP_SYMBOL(IC_LEFT(ic))->remat &&
2680 !IS_OP_RUONLY(IC_RESULT(ic)) &&
2681 getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 )
2683 packRegsForOneuse (ic,IC_LEFT(ic),ebp);
2686 /* if this is cast for intergral promotion then
2687 check if only use of the definition of the
2688 operand being casted/ if yes then replace
2689 the result of that arithmetic operation with
2690 this result and get rid of the cast */
2691 if (ic->op == CAST) {
2692 sym_link *fromType = operandType(IC_RIGHT(ic));
2693 sym_link *toType = operandType(IC_LEFT(ic));
2695 if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
2696 getSize(fromType) != getSize(toType) ) {
2698 iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
2700 if (IS_ARITHMETIC_OP(dic)) {
2701 IC_RESULT(dic) = IC_RESULT(ic);
2702 remiCodeFromeBBlock(ebp,ic);
2703 hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2704 OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
2707 OP_SYMBOL(IC_RIGHT(ic))->ruonly = 0;
2711 /* if the type from and type to are the same
2712 then if this is the only use then packit */
2713 if (checkType(operandType(IC_RIGHT(ic)),
2714 operandType(IC_LEFT(ic))) == 1) {
2715 iCode *dic = packRegsForOneuse (ic,IC_RIGHT(ic),ebp);
2717 IC_RESULT(dic) = IC_RESULT(ic);
2718 remiCodeFromeBBlock(ebp,ic);
2719 hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2720 OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
2728 iTempNN := (some variable in farspace) V1
2733 if (ic->op == IPUSH ) {
2734 packForPush(ic,ebp);
2738 /* pack registers for accumulator use, when the
2739 result of an arithmetic or bit wise operation
2740 has only one use, that use is immediately following
2741 the defintion and the using iCode has only one
2742 operand or has two operands but one is literal &
2743 the result of that operation is not on stack then
2744 we can leave the result of this operation in acc:b
2746 if ((IS_ARITHMETIC_OP(ic)
2748 || IS_BITWISE_OP(ic)
2750 || ic->op == LEFT_OP || ic->op == RIGHT_OP
2753 IS_ITEMP(IC_RESULT(ic)) &&
2754 getSize(operandType(IC_RESULT(ic))) <= 2)
2756 packRegsForAccUse (ic);
2761 static void dumpEbbsToDebug(eBBlock **ebbs, int count)
2765 if(!debug || !debugF)
2768 for (i=0; i < count ; i++ ) {
2769 fprintf(debugF,"\n----------------------------------------------------------------\n");
2770 fprintf(debugF,"Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
2771 ebbs[i]->entryLabel->name,
2774 ebbs[i]->isLastInLoop);
2775 fprintf(debugF,"depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
2780 fprintf(debugF,"visited %d : hasFcall = %d\n",
2784 fprintf(debugF,"\ndefines bitVector :");
2785 bitVectDebugOn(ebbs[i]->defSet,debugF);
2786 fprintf(debugF,"\nlocal defines bitVector :");
2787 bitVectDebugOn(ebbs[i]->ldefs,debugF);
2788 fprintf(debugF,"\npointers Set bitvector :");
2789 bitVectDebugOn(ebbs[i]->ptrsSet,debugF);
2790 fprintf(debugF,"\nin pointers Set bitvector :");
2791 bitVectDebugOn(ebbs[i]->inPtrsSet,debugF);
2792 fprintf(debugF,"\ninDefs Set bitvector :");
2793 bitVectDebugOn(ebbs[i]->inDefs,debugF);
2794 fprintf(debugF,"\noutDefs Set bitvector :");
2795 bitVectDebugOn(ebbs[i]->outDefs,debugF);
2796 fprintf(debugF,"\nusesDefs Set bitvector :");
2797 bitVectDebugOn(ebbs[i]->usesDefs,debugF);
2798 fprintf(debugF,"\n----------------------------------------------------------------\n");
2799 printiCChain(ebbs[i]->sch,debugF);
2802 /*-----------------------------------------------------------------*/
2803 /* assignRegisters - assigns registers to each live range as need */
2804 /*-----------------------------------------------------------------*/
2805 void pic14_assignRegisters (eBBlock **ebbs, int count)
2810 debugLog("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s",__FILE__,__FUNCTION__);
2811 debugLog("ebbs before optimizing:\n");
2812 dumpEbbsToDebug(ebbs,count);
2814 setToNull((void *)&_G.funcrUsed);
2815 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2818 /* change assignments this will remove some
2819 live ranges reducing some register pressure */
2820 for (i = 0 ; i < count ;i++ )
2821 packRegisters (ebbs[i]);
2823 if (options.dump_pack)
2824 dumpEbbsToFileExt(".dumppack",ebbs,count);
2826 /* first determine for each live range the number of
2827 registers & the type of registers required for each */
2830 /* and serially allocate registers */
2831 serialRegAssign(ebbs,count);
2833 /* if stack was extended then tell the user */
2834 if (_G.stackExtend) {
2835 /* werror(W_TOOMANY_SPILS,"stack", */
2836 /* _G.stackExtend,currFunc->name,""); */
2837 _G.stackExtend = 0 ;
2840 if (_G.dataExtend) {
2841 /* werror(W_TOOMANY_SPILS,"data space", */
2842 /* _G.dataExtend,currFunc->name,""); */
2846 /* after that create the register mask
2847 for each of the instruction */
2848 createRegMask (ebbs,count);
2850 /* redo that offsets for stacked automatic variables */
2851 redoStackOffsets ();
2853 if (options.dump_rassgn)
2854 dumpEbbsToFileExt(".dumprassgn",ebbs,count);
2856 /* now get back the chain */
2857 ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));
2859 debugLog("ebbs after optimizing:\n");
2860 dumpEbbsToDebug(ebbs,count);
2865 /* free up any _G.stackSpil locations allocated */
2866 applyToSet(_G.stackSpil,deallocStackSpil);
2868 setToNull((void **)&_G.stackSpil);
2869 setToNull((void **)&_G.spiltSet);
2870 /* mark all registers as free */
2873 debugLog("leaving\n<><><><><><><><><><><><><><><><><>\n");