void unlinkpCode(pCode *pc);
extern int pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip);
char *pCode2str(char *str, int size, pCode *pc);
-void SAFE_snprintf(char **str, size_t *size, const char *format, ...);
//static int sameRegs (const regs *reg1, const regs *reg2);
int total_registers_saved=0;
pc = findNextInstruction(pcfl->pc.next);
- while(isPCinFlow(pc,PCODE(pcfl))) {
-
-
+ while(pc && !isPCFL(pc)) {
+ while (pc && !isPCI(pc) && !isPCFL(pc))
+ {
+ pc = pc->next;
+ } // while
+ if (!pc || isPCFL(pc)) continue;
+ assert( isPCI(pc) );
+
reg = getRegFromInstruction(pc);
-
+ #if 0
+ pc->print(stderr, pc);
+ fprintf( stderr, "--> reg %p (%s,%u), inCond/outCond: %x/%x\n",
+ reg, reg ? reg->name : "(null)", reg ? reg->rIdx : -1,
+ PCI(pc)->inCond, PCI(pc)->outCond );
+ #endif
if(reg) {
/*
fprintf(stderr, "flow seq %d, inst seq %d %s ",PCODE(pcfl)->seq,pc->seq,reg->name);
addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl);
addSetIfnotP(& (reg->reglives.usedpCodes), pc);
+ reg->wasUsed = 1;
}
- pc = findNextInstruction(pc->next);
+ //pc = findNextInstruction(pc->next);
+ pc = pc->next;
}
-
+
}
/*-----------------------------------------------------------------*
}
- if(1){
- /*
- Debug stuff. Comment out the instruction we're about to delete.
- */
+ if(1) {
+ /*
+ * Debug stuff. Comment out the instruction we're about to delete.
+ */
char buff1[256];
size_t size = 256;
- char *pbuff,**ppbuff;
- pbuff = buff1;
- ppbuff = &pbuff;
+ char *pbuff;
+ pbuff = &buff1[0];
- SAFE_snprintf(ppbuff,&size, ";%d", debug_code);
- pCode2str(*ppbuff, size, pc);
+ SNPRINTF(pbuff, size, ";%d", debug_code);
+ size -= strlen(pbuff);
+ pbuff += strlen(pbuff);
+ pCode2str(pbuff, size, pc);
pCodeInsertBefore(pc, newpCodeCharP(buff1));
//fprintf(stderr,"removing instruction:\n%s\n",buff1);
}
}
}
+
+void RegsUnMapLiveRanges(void);
+extern pFile *the_pFile;
+void pic14_ReMapLiveRanges(void)
+{
+ pBlock *pb;
+ if (!the_pFile) return;
+ RegsUnMapLiveRanges();
+ for (pb = the_pFile->pbHead; pb; pb = pb->next)
+ {
+ #if 0
+ pCode *pc = findNextpCode(pb->pcHead, PC_FLOW);
+ if (pc) {
+ pc->print( stderr, pc );
+ } else {
+ fprintf( stderr, "unnamed pBlock\n");
+ }
+ pc = findNextInstruction(pb->pcHead);
+ while (pc) {
+ pc->print( stderr, pc );
+ pc = findNextInstruction(pc->next);;
+ }
+ #endif
+ pCodeRegMapLiveRanges(pb);
+ } // for
+}
+
/*-----------------------------------------------------------------*
* void RemoveUnusedRegisters(void)
*
void RemoveUnusedRegisters(void)
{
/* First, get rid of registers that are used only one time */
+ pic14_ReMapLiveRanges();
//RemoveRegsFromSet(dynInternalRegs);
RemoveRegsFromSet(dynAllocRegs);
if (!isPCI(pc1) || !isPCI(pc2)) return 0;
if (PCI(pc1)->pcflow != PCI(pc2)->pcflow) return 0;
- if(pc2->seq < pc1->seq) {
+ if (pc2->seq < pc1->seq) {
pct1 = pc2;
pc2 = pc1;
pc1 = pct1;
}
/* disable this optimization for now -- it's buggy */
- if(pic14_options.disable_df) return 0;
+ if (pic14_options.disable_df) return 0;
//fprintf(stderr,"pCodeOptime2pCodes\n");
//pc1->print(stderr,pc1);
//pc2->print(stderr,pc2);
if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_MOVFW) ){
+ /*
+ * CLRF sets Z
+ * MOVFW affects Z
+ * MOVWF does not touch Z
+ * MOVLW does not touch Z
+ */
pCode *newpc;
- int regUsed = 0;
- int wUsed = 0;
- int wSaved = 0;
/*
clrf reg ; pc1
stuff...
*/
DFPRINTF((stderr, " optimising CLRF reg ... MOVF reg,W to ... MOVLW 0\n"));
pct2 = findNextInstruction(pc2->next);
-
- if(pct2 && PCI(pct2)->op == POC_MOVWF) {
- wSaved = wUsed = 1; /* Maybe able to replace with clrf pc2->next->reg. */
- } else {
- wUsed = pCodeSearchCondition(pct2,PCC_W,1) != -1;
- }
- regUsed = regUsedinRange(pct2,0,reg);
- if ((regUsed&&wUsed) || (pCodeSearchCondition(pct2,PCC_Z,0) != -1)) {
- /* Do not optimise as exisiting code is required. */
- } else {
- /* Can optimise. */
- if(regUsed) {
- newpc = newpCode(POC_CLRF, PCI(pc1)->pcop);
- } else if(wSaved && !wUsed) {
- newpc = newpCode(POC_CLRF, PCI(pct2)->pcop);
- pct2->destruct(pct2);
- } else {
- newpc = newpCode(POC_MOVLW, newpCodeOpLit(0));
- }
+ if (pCodeSearchCondition(pct2, PCC_Z, 0) == -1) {
+ /* Z is definitely overwritten before use */
+ newpc = newpCode(POC_MOVLW, newpCodeOpLit(0));
pCodeInsertAfter(pc2, newpc);
PCI(newpc)->pcflow = PCFL(pcfl_used);
newpc->seq = pc2->seq;
//fprintf (stderr, "%s:%d(%s): Remove2pcodes (CLRF reg, ..., MOVF reg,W)\n", __FILE__, __LINE__, __FUNCTION__);
- Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
- total_registers_saved++; // debugging stats.
+ //Remove2pcodes(pcfl_used, pc2, NULL, reg, 0);
+ pc2->destruct(pc2);
+ //total_registers_saved++; // debugging stats.
}
} else if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_IORFW) ){
DFPRINTF((stderr, " optimising CLRF/IORFW\n"));
pct2 = findNextInstruction(pc2->next);
- /* We must ensure that is destroyed before being read---IORLW must be performed unless this is proven. */
- if(pCodeSearchCondition(pct2, PCC_Z,0) != -1) {
+ /* We must ensure that Z is destroyed before being read---IORLW must be performed unless this is proven. */
+ if (pCodeSearchCondition(pct2, PCC_Z, 0) != -1) {
pct2 = newpCode(POC_IORLW, newpCodeOpLit(0));
pct2->seq = pc2->seq;
PCI(pct2)->pcflow = PCFL(pcfl_used);
fprintf(stderr,"Reg: %s\n",reg->name);
*/
+ /* Catch inconsistently set-up live ranges
+ * (see tracker items #1469504 + #1474602)
+ * FIXME: Actually we should rather fix the
+ * computation of the liveranges instead...
+ */
+ if (!reg || !reg->reglives.usedpFlows
+ || !reg->reglives.assignedpFlows)
+ {
+ //fprintf( stderr, "skipping reg w/o liveranges: %s\n", reg ? reg->name : "(unknown)");
+ continue;
+ }
+
if(reg->type == REG_SFR || reg->type == REG_STK || reg->isPublic || reg->isExtern|| reg->isFixed) {
//fprintf(stderr,"skipping SFR: %s\n",reg->name);
continue;
}
-
+
pcfl_used = setFirstItem(reg->reglives.usedpFlows);
pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows);
}
}
- rset1 = rset1->next;
+ rset1 = rset2;
}
}
}
if (reg && reg->type == REG_SFR && reg->pc_type != PO_STATUS) return result;
}
- /* MUST SUCEED FROM NOW ON (or ervert the changes done since NOW ;-)) */
+ /* MUST SUCEED FROM NOW ON (or revert the changes done since NOW ;-)) */
/* fix flow */
if (PCI(pc)->pcflow && PCI(pc)->pcflow->end == pc)
else
{
fprintf (stderr, "Cannot move a label...\n");
- exit(-1);
+ exit(EXIT_FAILURE);
}
if (comment)
int size = 512;
char *pbuff = &buffer[0];
- SAFE_snprintf (&pbuff, &size, "; %s:%u(%s): %s", __FILE__, __LINE__, __FUNCTION__, comment);
+ SNPRINTF (pbuff, size, "; %s:%u(%s): %s", __FILE__, __LINE__, __FUNCTION__, comment);
pCodeInsertAfter(pc->prev, newpCodeCharP (&buffer[0]));
} // if
int size = 512;
char *pbuff = &buffer[0];
- SAFE_snprintf (&pbuff, &size, "; %s:%u(%s): ", __FILE__, __LINE__, __FUNCTION__);
+ SNPRINTF (pbuff, size, "; %s:%u(%s): ", __FILE__, __LINE__, __FUNCTION__);
+ size -= strlen(pbuff);
+ pbuff += strlen(pbuff);
pCode2str (pbuff, size, pc);
pCodeInsertAfter(pc->prev, newpCodeCharP (&buffer[0]));
}
pCodeInsertAfter (&pc->pc, &newpc->pc);
/* FIXME: replacing pc will break the liverange maps (usedpCodes, ...) */
+ pCodeRegMapLiveRanges( pc->pBlock ); /*FIXME:UNTESTED*/
if (comment)
{
char *pbuff = &buffer[0];
int size=1024;
pCode2str (&buffer2[0],1024,&pc->pc);
- SAFE_snprintf (&pbuff,&size,"%s:%u(%s): removed pCode was %s\t", __FILE__, __LINE__, __FUNCTION__, &buffer2[0]);
+ SNPRINTF (pbuff,size,"%s:%u(%s): removed pCode was %s\t", __FILE__, __LINE__, __FUNCTION__, &buffer2[0]);
pCodeInsertAfter (&pc->pc, newpCodeCharP (&buffer[0]));
} // if
#if 0
/* This is currently broken (need rewrite to correctly
- * hamdle arbitrary pCodeOps instead of registers only). */
+ * handle arbitrary pCodeOps instead of registers only). */
if (!pic14_options.disable_df)
optimizeDataflow ();
#endif