+2006-02-08 Raphael Neider <rneider AT web.de>
+
+ * src/pic/pcode.c (pciTRIS): fixed typo,
+ (BuildFlow,LinkFlow_pCode): added (disabled) debug output,
+ (LinkFlow): fixed handling of flows that end in a call,
+ (ReuseReg): perform safety check earlier
+ * src/pic/pcoderegs.c (pCodeRegMapLiveRangesInFlow): fixed
+ to work with flows at the beginning of a pBlock,
+ fixes #1426557 (Symbol not previously defined),
+ (pic14_ReMapLiveRanges): NEW, destroy and rebuild register
+ usage information
+ (RemoveUnusedRegisters): update register usage info
+ * src/pic/ralloc.c (newReg): prevent duplicate registers from being
+ created, reuse existing ones instead
+ * src/pic/gen.c (genPcall): fixed #1424719
+
2006-02-01 Borut Razem <borut.razem AT siol.net>
* src/regression/add.c, src/regression/add2.c, src/regression/add3.c,
*/
emitpcode(POC_CALL,popGetLabel(albl->key));
pcop = popGetLabel(blbl->key);
- emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
+ emitpcode(POC_PAGESEL,pcop); /* Must restore PCLATH before goto, without destroying W */
emitpcode(POC_GOTO,pcop);
emitpLabel(albl->key);
0, // literal operand
POC_NOP,
PCC_NONE, // inCond /* FIXME: what's TRIS doing? */
- PCC_REGISTER // outCond /* FIXME: what's TIS doing */
+ PCC_REGISTER // outCond /* FIXME: what's TRIS doing */
};
pCodeInstruction pciXORWF = {
PCI(pc)->pcflow = PCFL(pflow);
//fprintf(stderr," build: ");
+ //pc->print(stderr, pc);
//pflow->print(stderr,pflow);
if (checkLabel(pc)) {
void LinkFlow_pCode(pCodeInstruction *from, pCodeInstruction *to)
{
pCodeFlowLink *fromLink, *toLink;
-
+#if 0
+ fprintf(stderr, "%s: linking ", __FUNCTION__ );
+ if (from) from->pc.print(stderr, &from->pc);
+ else fprintf(stderr, "(null)");
+ fprintf(stderr, " -(%u)-> with -(%u)-> ",
+ from && from->pcflow ? from->pcflow->pc.seq : 0,
+ to && to->pcflow ? to->pcflow->pc.seq : 0);
+ if (to) to->pc.print(stderr, &to->pc);
+ else fprintf(stderr, "(null)");
+#endif
+
if(!from || !to || !to->pcflow || !from->pcflow)
return;
/* find last instruction in flow */
pc = findPrevInstruction (PCFL(pcflow)->end);
- if (!pc) continue;
+ if (!pc) {
+ fprintf(stderr, "%s: flow without end (%u)?\n",
+ __FUNCTION__, pcflow->seq );
+ continue;
+ }
//fprintf(stderr, "LinkFlow - flow block (seq=%d) ", pcflow->seq);
+ //pc->print(stderr, pc);
if(isPCI_SKIP(pc)) {
//fprintf(stderr, "ends with skip\n");
//pc->print(stderr,pc);
//pc->print(stderr,pc);
if(!(pcol && isPCOLAB(pcol))) {
- if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) {
+ if((PCI(pc)->op != POC_RETLW)
+ && (PCI(pc)->op != POC_RETURN)
+ && (PCI(pc)->op != POC_CALL)
+ && (PCI(pc)->op != POC_RETFIE) )
+ {
pc->print(stderr,pc);
fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
}
- continue;
- }
-
- if( (pct = findLabelinpBlock(pb,pcol)) != NULL)
- LinkFlow_pCode(PCI(pc),PCI(pct));
- else
- fprintf(stderr, "ERROR: %s, couldn't find label. key=%d,lab=%s\n",
- __FUNCTION__,pcol->key,((PCOP(pcol)->name)?PCOP(pcol)->name:"-"));
- //fprintf(stderr,"newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:""));
+ } else {
+ if( (pct = findLabelinpBlock(pb,pcol)) != NULL)
+ LinkFlow_pCode(PCI(pc),PCI(pct));
+ else
+ fprintf(stderr, "ERROR: %s, couldn't find label. key=%d,lab=%s\n",
+ __FUNCTION__,pcol->key,((PCOP(pcol)->name)?PCOP(pcol)->name:"-"));
+ //fprintf(stderr,"newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:""));
+ }
/* link CALLs to next instruction */
if (PCI(pc)->op != POC_CALL) continue;
}
}
if(pc) {
- fprintf(stderr, "ends with unknown\n");
- pc->print(stderr,pc);
+ //fprintf(stderr, "ends with unknown\n");
+ //pc->print(stderr,pc);
continue;
}
void ReuseReg(void)
{
pBlock *pb;
- InitReuseReg();
if (!the_pFile) return;
+ InitReuseReg();
for(pb = the_pFile->pbHead; pb; pb = pb->next) {
/* Non static functions can be called from other modules so their registers must reassign */
if (pb->function_entries&&(PCF(setFirstItem(pb->function_entries))->isPublic||!pb->visited))
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);
}
- pc = findNextInstruction(pc->next);
+ //pc = findNextInstruction(pc->next);
+ pc = pc->next;
}
-
+
}
/*-----------------------------------------------------------------*
}
}
+
+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 (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)
pCodeInsertAfter (&pc->pc, &newpc->pc);
/* FIXME: replacing pc will break the liverange maps (usedpCodes, ...) */
+ pCodeRegMapLiveRanges( pc->pBlock ); /*FIXME:UNTESTED*/
if (comment)
{
}
+static regs *regWithIdx (set *dRegs, int idx, int fixed);
/*-----------------------------------------------------------------*/
/* newReg - allocate and init memory for a new register */
/*-----------------------------------------------------------------*/
{
regs *dReg;
+
+ /* check whether a matching register already exists */
+ dReg = dirregWithName( name );
+ if (dReg) {
+ //printf( "%s: already present: %s\n", __FUNCTION__, name );
+ return (dReg);
+ }
+ dReg = regWithIdx( dynDirectRegs, rIdx, 0 );
+ if (!dReg) dReg = regWithIdx( dynDirectRegs, rIdx, 1 );
+ if (dReg)
+ {
+ //printf( "%s: already present %s (idx:%d/%x)", __FUNCTION__, name, rIdx, rIdx );
+ return (dReg);
+ }
dReg = Safe_calloc(1,sizeof(regs));
dReg->type = type;