X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fpcoderegs.c;h=1de9fbe1b0c8b35e7b4cae7be11711a1a00e5e06;hb=7b2461d22f66cb8f296e2faef4aa075e2aa8a6ca;hp=ffa28c93add7d197d4ed5f3b115826fc21744634;hpb=5bc044cc26d5c7120689edffd312cb2774fc1c29;p=fw%2Fsdcc diff --git a/src/pic16/pcoderegs.c b/src/pic16/pcoderegs.c index ffa28c93..1de9fbe1 100644 --- a/src/pic16/pcoderegs.c +++ b/src/pic16/pcoderegs.c @@ -37,6 +37,11 @@ #include "pcoderegs.h" #include "pcodeflow.h" + +#define DEBUG_REMOVE1PCODE 0 +#define HAVE_DBGREGUSAGE 0 + + extern void pic16_pCodeInsertAfter(pCode *pc1, pCode *pc2); extern pCode * pic16_findPrevInstruction(pCode *pci); extern pBranch * pic16_pBranchAppend(pBranch *h, pBranch *n); @@ -66,7 +71,8 @@ void AddRegToFlow(regs *reg, pCodeFlow *pcfl) /*-----------------------------------------------------------------* * *-----------------------------------------------------------------*/ -#if 0 + +#if HAVE_DBGREGUSAGE static void dbg_regusage(set *fregs) { regs *reg; @@ -119,13 +125,13 @@ static void dbg_regusage(set *fregs) } } } -#endif /*-----------------------------------------------------------------* * *-----------------------------------------------------------------*/ -#if 0 -static void dbg_dumpregusage(void) + +//static +void dbg_dumpregusage(void) { fprintf(stderr,"*** Register Usage ***\n"); @@ -187,7 +193,9 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl) if(PCC_REGISTER & PCI(pc)->outCond) addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl); - addSetIfnotP(& (reg->reglives.usedpCodes), pc); + addSetIfnotP(& (reg->reglives.usedpCodes), pc); + +// reg->wasUsed=1; #if 1 /* check to see if this pCode has 2 memory operands, @@ -205,6 +213,8 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl) addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl); addSetIfnotP(& (reg->reglives.usedpCodes), pc); + +// reg->wasUsed=1; } } #endif @@ -254,7 +264,9 @@ void pic16_pCodeRegMapLiveRanges(pBlock *pb) } #endif -// dbg_dumpregusage(); +#if HAVE_DBGREGUSAGE + dbg_dumpregusage(); +#endif } @@ -271,7 +283,7 @@ static void Remove1pcode(pCode *pc, regs *reg) deleteSetItem (&(reg->reglives.usedpCodes),pc); -#if 0 +#if DEBUG_REMOVE1PCODE fprintf(stderr,"removing instruction:\n"); pc->print(stderr,pc); #endif @@ -289,8 +301,12 @@ static void Remove1pcode(pCode *pc, regs *reg) if(pcn) { if(PCI(pcn)->cline) { - //fprintf(stderr, "source line has been optimized completely out\n"); - //pc->print(stderr,pc); + +#if DEBUG_REMOVE1PCODE + fprintf(stderr, "source line has been optimized completely out\n"); + pc->print(stderr,pc); +#endif + } else { PCI(pcn)->cline = PCI(pc)->cline; } @@ -322,7 +338,7 @@ static void RemoveRegsFromSet(set *regset) if(used == 0) { -// fprintf(stderr,"%s:%d: getting rid of reg %s\n",__FILE__, __LINE__, reg->name); +// fprintf(stderr,"%s:%d: getting rid of reg %s\n",__FILE__, __LINE__, reg->name); reg->isFree = 1; reg->wasUsed = 0; @@ -359,12 +375,6 @@ static void RemoveRegsFromSet(set *regset) fprintf(stderr,"reg %s, type =%d\n",r->name, r->type); } - - pc->print(stderr, pc); - - fprintf(stderr,"%s:%d: removing reg %s because it is used only once\n",__FILE__, __LINE__, reg->name); - - Remove1pcode(pc, reg); /* pic16_unlinkpCode(pc); @@ -400,6 +410,68 @@ void pic16_RemoveUnusedRegisters(void) fprintf(stderr, " *** Saved %d registers ***\n", total_registers_saved); } +static int insideLRBlock(pCode *pc) +{ + pCode *pc1; + int t1=-1, t2=-1; + + pc1 = pc->prev; + while(pc1) { + if(isPCINFO(pc1) && (PCINF(pc1)->type == INF_LOCALREGS)) { + t1 = PCOLR (PCINF (pc1)->oper1)->type; + break; + } + pc1 = pc1->prev; + } + + pc1 = pc->next; + while(pc1) { + if(isPCINFO(pc1) && (PCINF(pc1)->type == INF_LOCALREGS)) { + t2 = PCOLR (PCINF (pc1)->oper1)->type; + break; + } + pc1 = pc1->next; + } + + if((t1 == LR_ENTRY_BEGIN && t2 == LR_ENTRY_END) + || (t1 == LR_EXIT_BEGIN && t2 == LR_EXIT_END)) + return 1; + + return 0; +} + + +static void RemoveRegFromLRBlock(regs *reg) +{ + if(elementsInSet(reg->reglives.usedpCodes) == 2) { + pCode *pc1; + + /* only continue if there are just 2 uses of the register, + * in in the local *entry* block and one in the local *exit* block */ + + /* search for entry block */ + pc1 = indexSet(reg->reglives.usedpCodes, 1); + + if(insideLRBlock( pc1 )) { + fprintf(stderr, "usedpCodes[0] inside LR block\n"); + deleteSetItem(&pc1->pb->tregisters, PCOR(PCI(pc1)->pcop)->r); + Remove1pcode(pc1, reg); + } + + pc1 = indexSet(reg->reglives.usedpCodes, 0); + if(insideLRBlock( pc1 )) { + fprintf(stderr, "usedpCodes[1] inside LR block\n"); + deleteSetItem(&pc1->pb->tregisters, PCOR(PCI(pc1)->pcop)->r); + Remove1pcode(pc1, reg); + } + + /* remove r0x00 */ + reg->isFree = 1; + reg->wasUsed = 0; + } +} + + /*-----------------------------------------------------------------* * @@ -430,6 +502,15 @@ static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg, int } pCodeRegMapLiveRangesInFlow(PCFL(pcflow)); + +#if 1 +// fprintf(stderr, "register %s is used in %d pCodes, assigned in %d pCodes\n", reg->name, +// elementsInSet(reg->reglives.usedpCodes), +// elementsInSet(reg->reglives.assignedpFlows)); + + RemoveRegFromLRBlock(reg); +#endif + } /*-----------------------------------------------------------------* @@ -446,6 +527,13 @@ static int regUsedinRange(pCode *pc1, pCode *pc2, regs *reg) return 1; } + if(PCI(pc1)->is2MemOp) { + testreg = pic16_getRegFromInstruction2(pc1); + if(testreg && (testreg->rIdx == reg->rIdx)) { + return 1; + } + } + pc1 = pic16_findNextInstruction(pc1->next); } while (pc1 && (pc1 != pc2) && (i++ < 100)) ; @@ -595,19 +683,19 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re if(usesW(pct3)) ; // Remove2pcodes(pcfl_used, pc1, NULL, reg, can_free); - else + else { Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free); - - total_registers_saved++; // debugging stats. - return 1; - } else { - //fprintf(stderr,"didn't optimize because Z bit is used\n"); - } + total_registers_saved++; // debugging stats. + return 1; + } + } else { +// fprintf(stderr,"didn't optimize because Z bit is used\n"); + } } #if 0 fprintf(stderr, " couldn't optimize\n"); if(reg2) - fprintf(stderr, " %s is used in range\n",reg2->name); + fprintf(stderr, " %s is used in range\n", reg2->name); else fprintf(stderr, " reg2 is NULL\n"); #endif @@ -622,10 +710,11 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re reg1 = pic16_getRegFromInstruction(pct1); if(reg1 && !regUsedinRange(pc1,pc2,reg1)) { - /* + +#if 0 fprintf(stderr, " MOVF/MOVFW. \n"); fprintf(stderr, " ...optimizing\n"); - */ +#endif /* Change: @@ -851,42 +940,44 @@ void pic16_pCodeRegOptimizeRegUsage(int level) int saved = 0; int t = total_registers_saved; - if(!register_optimization) - return; + if(getenv("NO_REG_OPT")) + return; -#define OPT_PASSES 4 - passes = OPT_PASSES; + if(!register_optimization) + return; - do { - saved = total_registers_saved; +#define OPT_PASSES 8 + passes = OPT_PASSES; - /* Identify registers used in one flow sequence */ - OptimizeRegUsage(pic16_dynAllocRegs,level, (OPT_PASSES-passes)); - OptimizeRegUsage(pic16_dynStackRegs,level, (OPT_PASSES-passes)); - OptimizeRegUsage(pic16_dynDirectRegs,0, (OPT_PASSES-passes)); + do { + saved = total_registers_saved; - if((total_registers_saved != saved) - && (pic16_pcode_verbose)) - fprintf(stderr, " *** pass %d, Saved %d registers, total saved %d ***\n", - (1+OPT_PASSES-passes),total_registers_saved-saved,total_registers_saved); - - passes--; + /* Identify registers used in one flow sequence */ + OptimizeRegUsage(pic16_dynAllocRegs,level, (OPT_PASSES-passes)); + OptimizeRegUsage(pic16_dynStackRegs,level, (OPT_PASSES-passes)); + OptimizeRegUsage(pic16_dynDirectRegs,0, (OPT_PASSES-passes)); - } while( passes && ((total_registers_saved != saved) || (passes==OPT_PASSES-1)) ); + if((total_registers_saved != saved) + && (pic16_pcode_verbose)) + fprintf(stderr, " *** pass %d, Saved %d registers, total saved %d ***\n", + (1+OPT_PASSES-passes),total_registers_saved-saved,total_registers_saved); + + passes--; - if(total_registers_saved == t) + } while( passes && ((total_registers_saved != saved) || (passes==OPT_PASSES-1)) ); - if(pic16_debug_verbose) - fprintf(stderr, "No registers saved on this pass\n"); + if(total_registers_saved == t) + if(pic16_debug_verbose) + fprintf(stderr, "No registers saved on this pass\n"); #if 0 - fprintf(stderr,"dynamically allocated regs:\n"); - dbg_regusage(pic16_dynAllocRegs); - fprintf(stderr,"stack regs:\n"); - dbg_regusage(pic16_dynStackRegs); - fprintf(stderr,"direct regs:\n"); - dbg_regusage(pic16_dynDirectRegs); + fprintf(stderr,"dynamically allocated regs:\n"); + dbg_regusage(pic16_dynAllocRegs); + fprintf(stderr,"stack regs:\n"); + dbg_regusage(pic16_dynStackRegs); + fprintf(stderr,"direct regs:\n"); + dbg_regusage(pic16_dynDirectRegs); #endif } @@ -902,7 +993,6 @@ static void RegsSetUnMapLiveRanges(set *regset) while(regset) { reg = regset->item; regset = regset->next; - deleteSet(®->reglives.usedpCodes); deleteSet(®->reglives.usedpFlows); @@ -914,12 +1004,10 @@ static void RegsSetUnMapLiveRanges(set *regset) void pic16_RegsUnMapLiveRanges(void) { - RegsSetUnMapLiveRanges(pic16_dynAllocRegs); RegsSetUnMapLiveRanges(pic16_dynStackRegs); RegsSetUnMapLiveRanges(pic16_dynDirectRegs); RegsSetUnMapLiveRanges(pic16_dynProcessorRegs); RegsSetUnMapLiveRanges(pic16_dynDirectBitRegs); RegsSetUnMapLiveRanges(pic16_dynInternalRegs); - }