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; } }
/*-----------------------------------------------------------------*/ void deleteFromSeg(symbol *sym) { if (SPEC_OCLS(sym->etype)) { memmap *segment = SPEC_OCLS (sym->etype); deleteSetItem(&segment->syms,sym); } }
/*-----------------------------------------------------------------* * *-----------------------------------------------------------------*/ static void Remove1pcode(pCode *pc, regs *reg) { pCode *pcn=NULL; if(!reg || !pc) return; deleteSetItem (&(reg->reglives.usedpCodes),pc); #if DEBUG_REMOVE1PCODE fprintf(stderr,"removing instruction:\n"); pc->print(stderr,pc); #endif if(PCI(pc)->label) { pcn = pic16_findNextInstruction(pc->next); if(pcn) PCI(pcn)->label = pic16_pBranchAppend(PCI(pcn)->label,PCI(pc)->label); } if(PCI(pc)->cline) { if(!pcn) pcn = pic16_findNextInstruction(pc->next); if(pcn) { if(PCI(pcn)->cline) { #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; } } } pc->destruct(pc); }
/*-----------------------------------------------------------------*/ eBBlock * immedDom (ebbIndex * ebbi, eBBlock * ebp) { /* first delete self from the list */ set *iset = domSetFromVect (ebbi, ebp->domVect); eBBlock *loop; eBBlock *idom = NULL; deleteSetItem (&iset, ebp); /* then just return the one with the greatest */ /* depthfirst number, this will be the immed dominator */ if ((loop = setFirstItem (iset))) idom = loop; for (; loop; loop = setNextItem (iset)) if (loop->dfnum > idom->dfnum) idom = loop; setToNull ((void *) &iset); return idom; }
/*-----------------------------------------------------------------* * *-----------------------------------------------------------------*/ static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg, int can_free) { 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); if(pc2) { Remove1pcode(pc2, reg); deleteSetItem (&(PCFL(pcflow)->registers), reg); if(can_free) { reg->isFree = 1; reg->wasUsed = 0; } } 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 }
/*-----------------------------------------------------------------* * void pCodeRegOptimeRegUsage(pBlock *pb) *-----------------------------------------------------------------*/ static void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_level) { regs *reg; int used; pCode *pc1=NULL, *pc2=NULL; while(fregs) { pCode *pcfl_used, *pcfl_assigned; /* Step through the set by directly accessing the 'next' pointer. * We could also step through by using the set API, but the * the (debug) calls to print instructions affect the state * of the set pointers */ reg = fregs->item; fregs = fregs->next; 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) { /* * In this section, all registers that are used in only in two * 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); if(pcfl_used && pcfl_assigned) { /* expected case - the register has been assigned a value and is subsequently used */ //fprintf(stderr," used only twice\n"); if(pcfl_used->seq == pcfl_assigned->seq && !(setNextItem(reg->reglives.usedpFlows)) && !(setNextItem(reg->reglives.assignedpFlows))) { //fprintf(stderr, " and used in same flow\n"); pCodeOptime2pCodes(pc1, pc2, pcfl_used, reg, 1,optimize_level); } else { // fprintf(stderr, " and used in different flows\n"); } } else if(pcfl_used) { /* register has been used twice without ever being assigned */ //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); Remove2pcodes(pcfl_assigned, pc1, pc2, reg, 1); total_registers_saved++; // debugging stats. } } else { /* register has been used either once, or more than twice */ if(used && !pcfl_used && pcfl_assigned) { pCode *pc; fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name); pc = setFirstItem(reg->reglives.usedpCodes); while(pc) { pcfl_assigned = PCODE(PCI(pc)->pcflow); Remove1pcode(pc, reg); deleteSetItem (&(PCFL(pcfl_assigned)->registers), reg); /* deleteSetItem (&(reg->reglives.usedpCodes),pc); pc->destruct(pc); */ pc = setNextItem(reg->reglives.usedpCodes); } reg->isFree = 1; reg->wasUsed = 0; total_registers_saved++; // debugging stats. } else if( (used > 2) && optimize_multi_uses) { set *rset1=NULL; set *rset2=NULL; int searching=1; pCodeFlow *pcfl1=NULL, *pcfl2=NULL; /* examine the number of times this register is used */ rset1 = reg->reglives.usedpCodes; while(rset1 && searching) { pc1 = rset1->item; rset2 = rset1->next; if(pc1 && isPCI(pc1) && ( (pcfl1 = PCI(pc1)->pcflow) != NULL) ) { //while(rset2 && searching) { if(rset2) { pc2 = rset2->item; if(pc2 && isPCI(pc2) && ( (pcfl2 = PCI(pc2)->pcflow) != NULL) ) { if(pcfl2 == pcfl1) { if(pCodeOptime2pCodes(pc1, pc2, pcfl_used, reg, 0,optimize_level)) searching = 0; } } //rset2 = rset2->next; } } rset1 = rset1->next; } } } } }