/*-------------------------------------------------------------------------
- pcoderegs.c - post code generation register optimizations
+ pcoderegs.c - post code generation register optimizations
Written By - Scott Dattalo scott@dattalo.com
Ported To PIC16 By - m.dubuc@rogers.com
/*-----------------------------------------------------------------*
*
*-----------------------------------------------------------------*/
+#if 0
static void dbg_regusage(set *fregs)
{
regs *reg;
}
}
}
+#endif
/*-----------------------------------------------------------------*
*
*-----------------------------------------------------------------*/
+#if 0
static void dbg_dumpregusage(void)
{
dbg_regusage(pic16_dynProcessorRegs);
}
-
+#endif
/*-----------------------------------------------------------------*
* void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
reg = pic16_getRegFromInstruction(pc);
if(reg) {
-/*
+#if 0
+ fprintf(stderr, "reg= %p\n", reg);
fprintf(stderr, "flow seq %d, inst seq %d %s ",PCODE(pcfl)->seq,pc->seq,reg->name);
- fprintf(stderr, "addr = 0x%03x, type = %d rIdx=0x%03x\n",
- reg->address,reg->type,reg->rIdx);
-*/
+ fprintf(stderr, "addr = 0x%03x, type = %d rIdx=0x%03x ",
+ reg->address,reg->type,reg->rIdx);
+ fprintf(stderr, "command = %s\n", PCI(pc)->mnemonic);
+
+#endif
+// fprintf(stderr, "trying to get first operand from pCode reg= %s\n", reg->name);
addSetIfnotP(& (PCFL(pcfl)->registers), reg);
if((PCC_REGISTER | PCC_LITERAL) & PCI(pc)->inCond)
addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl);
addSetIfnotP(& (reg->reglives.usedpCodes), pc);
+
+#if 1
+ /* check to see if this pCode has 2 memory operands,
+ and set up the second operand too */
+ if(PCI(pc)->is2MemOp) {
+ reg = pic16_getRegFromInstruction2(pc);
+ if(reg) {
+// fprintf(stderr, "trying to get second operand from pCode reg= %s\n", reg->name);
+ addSetIfnotP(& (PCFL(pcfl)->registers), reg);
+
+ if((PCC_REGISTER | PCC_LITERAL) & PCI(pc)->inCond)
+ addSetIfnotP(& (reg->reglives.usedpFlows), pcfl);
+
+ if((PCC_REGISTER | PCC_REGISTER2) & PCI(pc)->outCond)
+ addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl);
+
+ addSetIfnotP(& (reg->reglives.usedpCodes), pc);
+ }
+ }
+#endif
+
}
return;
deleteSetItem (&(reg->reglives.usedpCodes),pc);
-/*
+
+#if 0
fprintf(stderr,"removing instruction:\n");
pc->print(stderr,pc);
-*/
+#endif
+
if(PCI(pc)->label) {
pcn = pic16_findNextInstruction(pc->next);
if(used <= 1) {
- //fprintf(stderr," reg %s isfree=%d, wasused=%d\n",reg->name,reg->isFree,reg->wasUsed);
+// fprintf(stderr," reg %s isfree=%d, wasused=%d\n",reg->name,reg->isFree,reg->wasUsed);
+
if(used == 0) {
- //fprintf(stderr," getting rid of reg %s\n",reg->name);
+
+// fprintf(stderr,"%s:%d: getting rid of reg %s\n",__FILE__, __LINE__, reg->name);
+
reg->isFree = 1;
reg->wasUsed = 0;
} else {
pc = setFirstItem(reg->reglives.usedpCodes);
if(reg->type == REG_SFR) {
- //fprintf(stderr, "not removing SFR reg %s even though used only once\n",reg->name);
+ fprintf(stderr, "not removing SFR reg %s even though used only once\n", reg->name);
continue;
}
-
if(isPCI(pc)) {
if(PCI(pc)->label) {
pCode *pcn = pic16_findNextInstruction(pc->next);
pc->print(stderr,pc);
fprintf(stderr,"reg %s, type =%d\n",r->name, r->type);
}
- //fprintf(stderr," removing reg %s because it is used only once\n",reg->name);
+
+ fprintf(stderr,"%s:%d: removing reg %s because it is used only once\n",__FILE__, __LINE__, reg->name);
+
+
Remove1pcode(pc, reg);
/*
pic16_unlinkpCode(pc);
*/
RemoveRegsFromSet(pic16_dynDirectBitRegs);
- if(total_registers_saved) fprintf(stderr, " *** Saved %d registers ***\n", total_registers_saved);
+ if(total_registers_saved && pic16_pcode_verbose)
+ fprintf(stderr, " *** Saved %d registers ***\n", total_registers_saved);
}
if(!reg)
return;
+#if 0
+ fprintf(stderr,"removing 2 instructions:\n");
+ pc1->print(stderr,pc1);
+ pc2->print(stderr,pc2);
+#endif
+
if(pc1)
Remove1pcode(pc1, reg);
reg = fregs->item;
fregs = fregs->next;
- if(reg->type == REG_SFR) {
- //fprintf(stderr,"skipping SFR: %s\n",reg->name);
- continue;
- }
+ if(reg->type == REG_SFR) {
+// fprintf(stderr,"skipping SFR: %s\n",reg->name);
+ continue;
+ }
pcfl_used = setFirstItem(reg->reglives.usedpFlows);
pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows);
used = elementsInSet(reg->reglives.usedpCodes);
+// fprintf(stderr, "%s:%d register %s used %d times in pCode\n", __FILE__, __LINE__, reg->name, used);
if(used == 2) {
/*
* instructions are examined. If possible, they're optimized out.
*/
-/*
+#if 0
fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x type=%d used=%d\n",
reg->name,
reg->address,
reg->rIdx, reg->type, used);
-*/
+#endif
+
pc1 = setFirstItem(reg->reglives.usedpCodes);
pc2 = setNextItem(reg->reglives.usedpCodes);
//fprintf(stderr,"WARNING %s: reg %s used without being assigned\n",__FUNCTION__,reg->name);
} else {
- //fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
+// fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
Remove2pcodes(pcfl_assigned, pc1, pc2, reg, 1);
total_registers_saved++; // debugging stats.
}
if(used && !pcfl_used && pcfl_assigned) {
pCode *pc;
- //fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
+ fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
pc = setFirstItem(reg->reglives.usedpCodes);
while(pc) {
OptimizeRegUsage(pic16_dynStackRegs,level, (OPT_PASSES-passes));
OptimizeRegUsage(pic16_dynDirectRegs,0, (OPT_PASSES-passes));
- if(total_registers_saved != 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);
} while( passes && ((total_registers_saved != saved) || (passes==OPT_PASSES-1)) );
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);
-*/
+#endif
}