예제 #1
0
파일: pcoderegs.c 프로젝트: TronicLabs/sdcc
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;
  }
}
예제 #2
0
/*-----------------------------------------------------------------*/
void deleteFromSeg(symbol *sym)
{
    if (SPEC_OCLS(sym->etype)) {
        memmap *segment = SPEC_OCLS (sym->etype);
        deleteSetItem(&segment->syms,sym);
    }
}
예제 #3
0
파일: pcoderegs.c 프로젝트: TronicLabs/sdcc
/*-----------------------------------------------------------------*
 *
 *-----------------------------------------------------------------*/
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);

}
예제 #4
0
파일: SDCCcflow.c 프로젝트: Jason-K/sdcc
/*-----------------------------------------------------------------*/
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;

}
예제 #5
0
파일: pcoderegs.c 프로젝트: TronicLabs/sdcc
/*-----------------------------------------------------------------*
 *
 *-----------------------------------------------------------------*/
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
  
}
예제 #6
0
파일: pcoderegs.c 프로젝트: TronicLabs/sdcc
/*-----------------------------------------------------------------*
 * 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;
	}
      }
    }

  }

}