示例#1
0
/*-----------------------------------------------------------------*/
static void 
discardDeadParamReceives (eBBlock ** ebbs, int count)
{
  int i;
  iCode *ic;
  iCode dummyIcode;

  for (i = 0; i < count; i++)
    {
      for (ic = ebbs[i]->sch; ic; ic = ic->next)
	{
	  if (ic->op == RECEIVE)
	    {
	      if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
		  && !OP_SYMBOL (IC_RESULT (ic))->used)
		{
#if 0
		  fprintf (stderr, "discarding dead receive for %s\n",
			   OP_SYMBOL (IC_RESULT (ic))->name);
#endif
		  dummyIcode.next = ic->next;
		  remiCodeFromeBBlock (ebbs[i], ic);
		  ic = &dummyIcode;
		}
	    }
	}
    }
}
示例#2
0
/*-----------------------------------------------------------------*/
static void
incUsed (iCode *ic, operand *op)
{
  if (ic->depth)
    OP_SYMBOL (op)->used += (((unsigned int) 1 << ic->depth) + 1);
  else
    OP_SYMBOL (op)->used += 1;
}
示例#3
0
/*-----------------------------------------------------------------*/
static int
findNextUse (eBBlock *ebp, iCode *ic, operand *op)
{
  if (op->isaddr)
    OP_SYMBOL (op)->isptr = 1;

  OP_SYMBOL (op)->key = op->key;

  return findNextUseSym (ebp, ic, OP_SYMBOL(op));
}
示例#4
0
void dumpSymInfo(char *pcName, memmap *memItem)
{
  symbol *sym;

  if (!memItem)
    return;

  printf("--------------------------------------------\n");
  printf(" %s\n", pcName);

  for(sym = setFirstItem(memItem->syms); 
      sym;       sym = setNextItem(memItem->syms))
    {          
      printf("   %s, isReqv:%d, reqv:0x%p, onStack:%d, Stack:%d, nRegs:%d, [", 
	     sym->rname, sym->isreqv, sym->reqv, sym->onStack, sym->stack, sym->nRegs);

      if(sym->reqv)
      {	
	  int i;
	  symbol *TempSym = OP_SYMBOL (sym->reqv);
	 
	  for (i = 0; i < 4; i++)	    
	    if(TempSym->regs[i])
	      printf("%s,", port->getRegName(TempSym->regs[i]));	       
      }
          
      printf("]\n");
    }

  printf("\n");
}
示例#5
0
/*-----------------------------------------------------------------*/
static void
markLiveRanges (eBBlock **ebbs, int count)
{
  int i, key;
  symbol *sym;

  for (i = 0; i < count; i++)
    {
      iCode *ic;

      for (ic = ebbs[i]->sch; ic; ic = ic->next)
        {
	  if (ic->op == CALL || ic->op == PCALL)
	    if (bitVectIsZero (OP_SYMBOL (IC_RESULT (ic))->uses))
              bitVectUnSetBit (ebbs[i]->defSet, ic->key);

	  /* for all iTemps alive at this iCode */
	  for (key = 1; key < ic->rlive->size; key++)
	    {
	      if (!bitVectBitValue(ic->rlive, key))
	        continue;

	      sym = hTabItemWithKey(liveRanges, key);
	      setLiveTo(sym, ic->seq);
	      setLiveFrom(sym, ic->seq);
	    }

	}
    }
}
示例#6
0
/*------------------------------------------------------------------*/
static void
verifyRegsAssigned (operand * op, iCode * ic)
{
  symbol *sym;
  int i;
  bool completly_in_regs;

  if (!op)
    return;
  if (!IS_ITEMP (op))
    return;

  sym = OP_SYMBOL (op);

  if (sym->regType == REG_CND)
    return;

  if (sym->isspilt && !sym->remat && sym->usl.spillLoc && !sym->usl.spillLoc->allocreq)
    sym->usl.spillLoc->allocreq++;

  if (sym->isspilt)
    return;

  for(i = 0, completly_in_regs = TRUE; i < sym->nRegs; i++)
    if (!sym->regs[i])
      completly_in_regs = FALSE;
  if (completly_in_regs)
    return;

  spillThis (sym, FALSE);
}
示例#7
0
static void
setFromRange (operand * op, int from)
{
  /* only for compiler defined temporaries */
  if (!IS_ITEMP (op))
    return;

  hTabAddItemIfNotP (&liveRanges, op->key, OP_SYMBOL (op));

  if (op->isaddr)
    OP_SYMBOL (op)->isptr = 1;

  if (!OP_LIVEFROM (op) ||
      OP_LIVEFROM (op) > from)
    OP_LIVEFROM (op) = from;
}
示例#8
0
/*-----------------------------------------------------------------*/
void
setToRange (operand * op, int to, bool check)
{
  /* only for compiler defined temps */
  if (!IS_ITEMP (op))
    return;

  OP_SYMBOL (op)->key = op->key;
  hTabAddItemIfNotP (&liveRanges, op->key, OP_SYMBOL (op));

  if (op->isaddr)
    OP_SYMBOL (op)->isptr = 1;

  if (check)
    if (!OP_LIVETO (op))
      OP_LIVETO (op) = to;
    else;
  else
    OP_LIVETO (op) = to;
}
示例#9
0
/*-----------------------------------------------------------------*/
static void
printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf)
{
  symbol *sym;

  if (!map)
    return;
  if (!map->syms)
    return;

  for (sym = setFirstItem (map->syms); sym;
       sym = setNextItem (map->syms))
    {

      if (sym->level == 0)
        continue;
      if (sym->localof != func)
        continue;

      dbuf_printf (oBuf, ";%-25s Allocated ", sym->name);

      /* if assigned to registers */
      if (!sym->allocreq && sym->reqv)
        {
          int i;

          sym = OP_SYMBOL (sym->reqv);
          if (!sym->isspilt || sym->remat)
            {
              dbuf_append_str (oBuf, "to registers ");
              for (i = 0; i < 4 && sym->regs[i]; i++)
                dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i]));
              dbuf_append_char (oBuf, '\n');
              continue;
            }
          else
            {
              sym = sym->usl.spillLoc;
            }
        }

      /* if on stack */
      if (sym->onStack)
        {
          dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack);
          continue;
        }

      /* otherwise give rname */
      dbuf_printf (oBuf, "with name '%s'\n", sym->rname);
    }
}
示例#10
0
/*--------------------------------------------------------------------*/
symbol *
ptrBaseRematSym (symbol *ptrsym)
{
  iCode * ric;
  
  if (!ptrsym->remat)
    return NULL;
  
  ric = ptrsym->rematiCode;
  while (ric)
    {
      if (ric->op == '+' || ric->op == '-')
        ric = OP_SYMBOL (IC_LEFT (ric))->rematiCode;
      else if (IS_CAST_ICODE (ric))
        ric = OP_SYMBOL (IC_RIGHT (ric))->rematiCode;
      else
        break;
    }
  
  if (ric && IS_SYMOP (IC_LEFT (ric)))
    return OP_SYMBOL (IC_LEFT (ric));
  else
    return NULL;
}
示例#11
0
/*------------------------------------------------------------------*/
static void
findPrevUse (eBBlock *ebp, iCode *ic, operand *op,
             eBBlock ** ebbs, int count,
             bool emitWarnings)
{
  unvisitBlocks (ebbs, count);

  if (op->isaddr)
    OP_SYMBOL (op)->isptr = 1;
  OP_SYMBOL (op)->key = op->key;

  /* There must be a definition in each branch of predecessors */
  if (!findPrevUseSym (ebp, ic->prev, OP_SYMBOL(op)))
    {
      /* computeLiveRanges() is called at least twice */
      if (emitWarnings)
        {
          if (IS_ITEMP (op))
            {
              if (OP_SYMBOL (op)->prereqv)
                {
                  werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
                            OP_SYMBOL (op)->prereqv->name);
                  OP_SYMBOL (op)->prereqv->reqv = NULL;
                  OP_SYMBOL (op)->prereqv->allocreq = 1;
                }
            }
          else
            {
              werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
                        OP_SYMBOL (op)->name);
            }
        }
      /* is this block part of a loop? */
      if (IS_ITEMP (op) && ebp->depth != 0)
        {
          /* extend the life range to the outermost loop */
          unvisitBlocks(ebbs, count);
          markWholeLoop (ebp, op->key);
        }
    }
}
示例#12
0
/*-----------------------------------------------------------------------*/
static int addPattern1(iCode *ic)
{
        iCode *dic;
        operand *tmp;
        /* transform :
           iTempAA = iTempBB + iTempCC
           iTempDD = iTempAA + CONST
           to
           iTempAA = iTempBB + CONST
           iTempDD = iTempAA + iTempCC
        */
        if (!isOperandLiteral(IC_RIGHT(ic))) return 0;
        if ((dic=findBackwardDef(IC_LEFT(ic),ic->prev)) == NULL) return 0;
        if (bitVectnBitsOn(OP_SYMBOL(IC_RESULT(dic))->uses) > 1) return 0;
        if (dic->op != '+') return 0;
        tmp = IC_RIGHT(ic);
        IC_RIGHT(ic) = IC_RIGHT(dic);
        IC_RIGHT(dic) = tmp;
        return 1;
}
示例#13
0
/*--------------------------------------------------------------------*/
void
ptrPseudoSymConvert (symbol *sym, iCode *dic, char *name)
{
  symbol *psym = newSymbol (name, 1);
  psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (dic)));
  psym->type = sym->type;
  psym->etype = psym->psbase->etype;

  strcpy (psym->rname, psym->name);
  sym->isspilt = 1;
  sym->usl.spillLoc = psym;
#if 0 // an alternative fix for bug #480076
  /* now this is a useless assignment to itself */
  remiCodeFromeBBlock (ebbs, dic);
#else
  /* now this really is an assignment to itself, make it so;
     it will be optimized out later */
  dic->op='=';
  ReplaceOpWithCheaperOp(&IC_RIGHT(dic), IC_RESULT(dic));
  IC_LEFT(dic)=NULL;
#endif
}
示例#14
0
/*-----------------------------------------------------------------*/
iCode *
ifxForOp (operand * op, const iCode * ic)
{
  iCode *ifxIc;

  /* if true symbol then needs to be assigned */
  if (!IS_TRUE_SYMOP (op))
    {
      /* if this has register type condition and
         while skipping ipop's (see bug 1509084),
         the next instruction is ifx with the same operand
         and live to of the operand is upto the ifx only then */
      for (ifxIc = ic->next; ifxIc && ifxIc->op == IPOP; ifxIc = ifxIc->next)
        ;

      if (ifxIc && ifxIc->op == IFX &&
        IC_COND (ifxIc)->key == op->key &&
        OP_SYMBOL (op)->liveTo <= ifxIc->seq)
        return ifxIc;
    }

  return NULL;
}
示例#15
0
/*--------------------------------------------------------------------*/
int
ptrPseudoSymSafe (symbol *sym, iCode *dic)
{
  symbol * ptrsym;
  symbol * basesym;
  iCode * ric;
  iCode * ic;
  int ptrsymDclType;
  //int isGlobal;
  
  assert(POINTER_GET (dic));

  /* Can't if spills to this symbol are prohibited */
  if (sym->noSpilLoc)
    return 0;
  
  /* Get the pointer */
  if (!IS_SYMOP (IC_LEFT (dic)))
    return 0;
  ptrsym = OP_SYMBOL (IC_LEFT (dic));
  
  /* Must be a rematerializable pointer */
  if (!ptrsym->remat)
    return 0;
  
  /* The pointer type must be uncasted */
  if (IS_CAST_ICODE (ptrsym->rematiCode))
    return 0;
  
  /* The symbol's live range must not preceed its definition */
  if (dic->seq > sym->liveFrom)
    return 0;
        
  /* Ok, this is a good candidate for a pseudo symbol.      */
  /* However, we must check for two hazards:                */
  /*   1) The symbol's live range must not include a CALL   */
  /*      or PCALL iCode.                                   */
  /*   2) The symbol's live range must not include any      */
  /*      writes to the variable the pointer rematerializes */
  /*      within (to avoid aliasing problems)               */
  
  /* Find the base symbol the rematerialization is based on */
  ric = ptrsym->rematiCode;
  while (ric->op == '+' || ric->op == '-')
    ric = OP_SYMBOL (IC_LEFT (ric))->rematiCode;
  if (IS_CAST_ICODE(ric))
    return 0;
  basesym = OP_SYMBOL (IC_LEFT (ric));

  //isGlobal = !basesym->islocal && !basesym->ismyparm;
  ptrsymDclType = aggrToPtrDclType (ptrsym->type, FALSE);

  ic = dic->next;
  while (ic && ic->seq <= sym->liveTo)
    {
      if (!(SKIP_IC3 (ic) || ic->op == IFX))
        {
          /* Check for hazard #1 */
          if ((ic->op == CALL || ic->op == PCALL) /* && isGlobal */ )
            {
              if (ic->seq <= sym->liveTo)
                return 0;
            }
          /* Check for hazard #2 */
          else if (POINTER_SET (ic))
            {
              symbol * ptrsym2 = OP_SYMBOL (IC_RESULT (ic));
          
              if (ptrsym2->remat)
                {
                  /* Must not be the same base symbol */
                  if (basesym == ptrBaseRematSym (ptrsym2))
                    return 0;
                }
              else
                {
                  int ptrsym2DclType = aggrToPtrDclType (ptrsym2->type, FALSE);

                  /* Pointer must have no memory space in common */
                  if (ptrsym2DclType == ptrsymDclType
                      || ptrsym2DclType == GPOINTER
                      || ptrsymDclType == GPOINTER)
                    return 0;
                }
            }
          else if (IC_RESULT (ic))
            {
              symbol * rsym = OP_SYMBOL (IC_RESULT (ic));
          
              /* Make sure there is no conflict with another pseudo symbol */
              if (rsym->psbase == basesym)
                return 0;
              if (rsym->isspilt && rsym->usl.spillLoc)
                rsym = rsym->usl.spillLoc;
              if (rsym->psbase == basesym)
                return 0;
            }
        }
        
      if (ic->seq == sym->liveTo)
         break;
      ic = ic->next;
    }

  /* If the live range went past the end of the defining basic */
  /* block, then a full analysis is too complicated to attempt */
  /* here. To be safe, we must assume the worst.               */
  if (!ic)
    return 0;
    
  /* Ok, looks safe */
  return 1;
}
示例#16
0
文件: SDCCmem.c 项目: doniexun/kcc
/*-----------------------------------------------------------------*/
static int
printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf)
{
  symbol *sym;
  int flg = FALSE;

  if (!map || !map->syms)
    return 0;

  for (sym = setFirstItem (map->syms); sym;
       sym = setNextItem (map->syms))
    {
      if (sym->level == 0)
        continue;
      if (sym->localof != func)
        continue;

      dbuf_printf (oBuf, ";%-25s Allocated ", sym->name);
      flg = TRUE;

      /* if assigned to registers */
      if (!sym->allocreq && sym->reqv)
        {
          int i;

          sym = OP_SYMBOL (sym->reqv);
          if (!sym->isspilt || sym->remat)
            {
              dbuf_append_str (oBuf, "to registers ");
              for (i = 0; i < 4 && sym->regs[i]; i++)
                dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i]));
              dbuf_append_char (oBuf, '\n');
              continue;
            }
          else
            {
              sym = sym->usl.spillLoc;
            }
        }

      /* if on stack */
      if (sym->onStack)
        {
          int stack_offset = 0;

          if (options.omitFramePtr)
            {
              if (SPEC_OCLS (sym->etype)->paged)
                stack_offset = func->xstack;
              else
                stack_offset = func->stack;
            }

          dbuf_printf (oBuf, "to stack - %s %+d\n", SYM_BP (sym), sym->stack - stack_offset);
          continue;
        }

      /* otherwise give rname */
      dbuf_printf (oBuf, "with name '%s'\n", sym->rname);
    }

  return flg;
}
示例#17
0
/** Register reduction for assignment.
 */
static int
packRegsForAssign (iCode *ic, eBBlock *ebp)
{
  iCode *dic, *sic;

  if (!IS_ITEMP (IC_RIGHT (ic)) || OP_SYMBOL (IC_RIGHT (ic))->isind || OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
    return 0;
  
  /* Avoid having multiple named address spaces in one iCode. */
  if (IS_SYMOP (IC_RESULT (ic)) && SPEC_ADDRSPACE (OP_SYMBOL (IC_RESULT (ic))->etype))
    return 0;

  /* find the definition of iTempNN scanning backwards if we find a
     a use of the true symbol in before we find the definition then
     we cannot */
  for (dic = ic->prev; dic; dic = dic->prev)
    {
      /* PENDING: Don't pack across function calls. */
      if (dic->op == CALL || dic->op == PCALL)
        {
          dic = NULL;
          break;
        }

      if (SKIP_IC2 (dic))
        continue;

      if (dic->op == IFX)
        {
          if (IS_SYMOP (IC_COND (dic)) &&
              (IC_COND (dic)->key == IC_RESULT (ic)->key || IC_COND (dic)->key == IC_RIGHT (ic)->key))
            {
              dic = NULL;
              break;
            }
        }
      else
        {
          if (IS_TRUE_SYMOP (IC_RESULT (dic)) && IS_OP_VOLATILE (IC_RESULT (dic)))
            {
              dic = NULL;
              break;
            }

          if (IS_SYMOP (IC_RESULT (dic)) && IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
            {
              if (POINTER_SET (dic))
                dic = NULL;

              break;
            }

          if (IS_SYMOP (IC_RIGHT (dic)) &&
              (IC_RIGHT (dic)->key == IC_RESULT (ic)->key || IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
            {
              dic = NULL;
              break;
            }

          if (IS_SYMOP (IC_LEFT (dic)) &&
              (IC_LEFT (dic)->key == IC_RESULT (ic)->key || IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
            {
              dic = NULL;
              break;
            }

          if (IS_SYMOP (IC_RESULT (dic)) && IC_RESULT (dic)->key == IC_RESULT (ic)->key)
            {
              dic = NULL;
              break;
            }
        }
    }

  if (!dic)
    return 0;                   /* did not find */

  /* if assignment then check that right is not a bit */
  if (ASSIGNMENT (ic) && !POINTER_SET (ic))
    {
      sym_link *etype = operandType (IC_RESULT (dic));
      if (IS_BITFIELD (etype))
        {
          /* if result is a bit too then it's ok */
          etype = operandType (IC_RESULT (ic));
          if (!IS_BITFIELD (etype))
            {
              return 0;
            }
        }
    }

  /* if the result is on stack or iaccess then it must be
     the same atleast one of the operands */
  if (OP_SYMBOL (IC_RESULT (ic))->onStack || OP_SYMBOL (IC_RESULT (ic))->iaccess)
    {
      /* the operation has only one symbol
         operator then we can pack */
      if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) || (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
        goto pack;

      if (!((IC_LEFT (dic) &&
             IC_RESULT (ic)->key == IC_LEFT (dic)->key) || (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
        return 0;
    }
pack:
  /* found the definition */
  /* replace the result with the result of */
  /* this assignment and remove this assignment */
  bitVectUnSetBit (OP_SYMBOL (IC_RESULT (dic))->defs, dic->key);
  IC_RESULT (dic) = IC_RESULT (ic);

  if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
    {
      OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
    }
  /* delete from liverange table also
     delete from all the points inbetween and the new
     one */
  for (sic = dic; sic != ic; sic = sic->next)
    {
      bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
      if (IS_ITEMP (IC_RESULT (dic)))
        bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
    }

  remiCodeFromeBBlock (ebp, ic);
  // PENDING: Check vs mcs51
  bitVectUnSetBit (OP_SYMBOL (IC_RESULT (ic))->defs, ic->key);
  hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
  OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
  return 1;
}
示例#18
0
/*-----------------------------------------------------------------*/
static void 
replaceRegEqv (eBBlock ** ebbs, int count)
{
  int i;

  for (i = 0; i < count; i++)
    {

      iCode *ic;

      for (ic = ebbs[i]->sch; ic; ic = ic->next)
	{

	  if (SKIP_IC2 (ic))
	    continue;

	  if (ic->op == IFX)
	    {

	      if (IS_TRUE_SYMOP (IC_COND (ic)) &&
		  OP_REQV (IC_COND (ic)))
		IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
					     OP_SYMBOL (IC_COND (ic))->defs,
					    OP_SYMBOL (IC_COND (ic))->uses);

	      continue;
	    }

	  if (ic->op == JUMPTABLE)
	    {
	      if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
		  OP_REQV (IC_JTCOND (ic)))
		IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
					   OP_SYMBOL (IC_JTCOND (ic))->defs,
					  OP_SYMBOL (IC_JTCOND (ic))->uses);
	      continue;
	    }

	  if (ic->op == RECEIVE)
	    {
	      if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
		OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
	    }

	  /* general case */
	  if (IC_RESULT (ic) &&
	      IS_TRUE_SYMOP (IC_RESULT (ic)) &&
	      OP_REQV (IC_RESULT (ic)))
	    {
	      if (POINTER_SET (ic))
		{
		  IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
					   OP_SYMBOL (IC_RESULT (ic))->defs,
					  OP_SYMBOL (IC_RESULT (ic))->uses);
		  IC_RESULT (ic)->isaddr = 1;
		}
	      else
		IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
					   OP_SYMBOL (IC_RESULT (ic))->defs,
					  OP_SYMBOL (IC_RESULT (ic))->uses);
	    }

	  if (IC_RIGHT (ic) &&
	      IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
	      OP_REQV (IC_RIGHT (ic)))
	    {
	      IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
					    OP_SYMBOL (IC_RIGHT (ic))->defs,
					   OP_SYMBOL (IC_RIGHT (ic))->uses);
	      IC_RIGHT (ic)->isaddr = 0;
	    }

	  if (IC_LEFT (ic) &&
	      IS_TRUE_SYMOP (IC_LEFT (ic)) &&
	      OP_REQV (IC_LEFT (ic)))
	    {
	      IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
					     OP_SYMBOL (IC_LEFT (ic))->defs,
					     OP_SYMBOL (IC_LEFT (ic))->uses);
	      IC_LEFT (ic)->isaddr = 0;
	    }
	}
    }
}
示例#19
0
/*-----------------------------------------------------------------*/
int 
killDeadCode (eBBlock ** ebbs, int count)
{
  int change = 1;
  int gchange = 0;
  int i = 0;


  /* basic algorithm :-                                          */
  /* first the exclusion rules :-                                */
  /*  1. if result is a global or volatile then skip             */
  /*  2. if assignment and result is a temp & isaddr  then skip  */
  /*     since this means array & pointer access, will be taken  */
  /*     care of by alias analysis.                              */
  /*  3. if the result is used in the remainder of the block skip */
  /*  4. if this definition does not reach the end of the block  */
  /*     i.e. the result is not present in the outExprs then KILL */
  /*  5. if it reaches the end of block & is used by some success */
  /*     or then skip                                            */
  /*     else            KILL                                    */
  /* this whole process is carried on iteratively till no change */
  while (1)
    {

      change = 0;
      /* for all blocks do */
      for (i = 0; i < count; i++)
	{
	  iCode *ic;

	  /* for all instructions in the block do */
	  for (ic = ebbs[i]->sch; ic; ic = ic->next)
	    {
	      int kill, j;
	      kill = 0;

	      if (SKIP_IC (ic) ||
		  ic->op == IFX ||
		  ic->op == RETURN)
		continue;

	      /* if the result is volatile then continue */
	      if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
		continue;

	      /* if the result is a temp & isaddr then skip */
	      if (IC_RESULT (ic) && POINTER_SET (ic))
		continue;

	      /* if the result is used in the remainder of the */
	      /* block then skip */
	      if (usedInRemaining (IC_RESULT (ic), ic->next))
		continue;

	      /* does this definition reach the end of the block 
	         or the usage is zero then we can kill */
	      if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
		kill = 1;	/* if not we can kill it */
	      else
		{
		  /* if this is a global variable or function parameter */
		  /* we cannot kill anyway             */
		  if (isOperandGlobal (IC_RESULT (ic)) ||
		      (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
		       !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
		    continue;

		  /* if we are sure there are no usages */
		  if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
		    {
		      kill = 1;
		      goto kill;
		    }

		  /* reset visited flag */
		  for (j = 0; j < count; ebbs[j++]->visited = 0);

		  /* find out if this definition is alive */
		  if (applyToSet (ebbs[i]->succList,
				  isDefAlive,
				  ic))
		    continue;

		  kill = 1;
		}

	    kill:
	      /* kill this one if required */
	      if (kill)
		{
		  change = 1;
		  gchange++;
		  /* eliminate this */
		  remiCodeFromeBBlock (ebbs[i], ic);

		  /* now delete from defUseSet */
		  deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
		  bitVectUnSetBit (ebbs[i]->outDefs, ic->key);

		  /* and defset of the block */
		  bitVectUnSetBit (ebbs[i]->defSet, ic->key);

		  /* for the left & right remove the usage */
		  if (IS_SYMOP (IC_LEFT (ic)))
		    bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);

		  if (IS_SYMOP (IC_RIGHT (ic)))
		    bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
		}

	    }			/* end of all instructions */

	  if (!ebbs[i]->sch && !ebbs[i]->noPath)
	    disconBBlock (ebbs[i], ebbs, count);

	}			/* end of for all blocks */

      if (!change)
	break;
    }				/* end of while(1) */

  return gchange;
}
示例#20
0
/*-----------------------------------------------------------------*/
void
separateLiveRanges (iCode *sic, ebbIndex *ebbi)
{
  iCode *ic;
  set *candidates = 0;
  symbol *sym;

  // printf("separateLiveRanges()\n");

  for (ic = sic; ic; ic = ic->next)
    {
      if (ic->op == IFX || ic->op == GOTO || ic->op == JUMPTABLE || !IC_RESULT (ic) || !IS_ITEMP (IC_RESULT (ic)) || bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) <= 1 || isinSet (candidates, OP_SYMBOL (IC_RESULT (ic))))
        continue;

      addSet (&candidates, OP_SYMBOL (IC_RESULT (ic)));
    }

  if (!candidates)
    return;

  for(sym = setFirstItem (candidates); sym; sym = setNextItem (candidates))
    {
      // printf("Looking at %s, %d definitions\n", sym->name, bitVectnBitsOn (sym->defs));

      int i;
      set *defs = 0;

      for (i = 0; i < sym->defs->size; i++)
        if (bitVectBitValue (sym->defs, i))
          {
            iCode *dic;
            if(dic = hTabItemWithKey (iCodehTab, i))
              addSet (&defs, hTabItemWithKey (iCodehTab, i));
            else
              {
                werror (W_INTERNAL_ERROR, __FILE__, __LINE__, "Definition not found");
                return;
              }
          }

      do
        {
          set *visited = 0;
          set *newdefs = 0;
          int oldsize;

          wassert (defs);
          wassert (setFirstItem (defs));

          // printf("Looking at def at %d now\n", ((iCode *)(setFirstItem (defs)))->key);

          if (!bitVectBitValue (((iCode *)(setFirstItem (defs)))->rlive, sym->key))
            {
              werror (W_INTERNAL_ERROR, __FILE__, __LINE__, "Variable is not alive at one of its definitions");
              break;
            }
 
          visit (&visited, setFirstItem (defs), sym->key);
          addSet (&newdefs, setFirstItem (defs));

          do
            {
              oldsize = elementsInSet(visited);
              ic = setFirstItem (defs);
              for(ic = setNextItem (defs); ic; ic = setNextItem (defs))
                {
                  // printf("Looking at other def at %d now\n", ic->key);
                  set *visited2 = 0;
                  set *intersection = 0;
                  visit (&visited2, ic, sym->key);
                  intersection = intersectSets (visited, visited2, THROW_NONE);
                  intersection = subtractFromSet (intersection, defs, THROW_DEST);
                  if (intersection)
                    {
                      visited = unionSets (visited, visited2, THROW_DEST);
                      addSet (&newdefs, ic);
                    }
                  deleteSet (&intersection);
                  deleteSet (&visited2);
                }
             }
          while (oldsize < elementsInSet(visited));

          defs = subtractFromSet (defs, newdefs, THROW_DEST);

          if (newdefs && defs)
            {
              operand *tmpop = newiTempOperand (operandType (IC_RESULT ((iCode *)(setFirstItem (newdefs)))), TRUE);

              // printf("Splitting %s from %s, using def at %d, op %d\n", OP_SYMBOL_CONST(tmpop)->name, sym->name, ((iCode *)(setFirstItem (newdefs)))->key, ((iCode *)(setFirstItem (newdefs)))->op);

              for (ic = setFirstItem (visited); ic; ic = setNextItem (visited))
                {
                  if (IC_LEFT (ic) && IS_ITEMP (IC_LEFT (ic)) && OP_SYMBOL (IC_LEFT (ic)) == sym)
                    IC_LEFT (ic) = operandFromOperand (tmpop);
                  if (IC_RIGHT (ic) && IS_ITEMP (IC_RIGHT (ic)) && OP_SYMBOL (IC_RIGHT (ic)) == sym)
                      IC_RIGHT (ic) = operandFromOperand (tmpop);
                  if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)) && OP_SYMBOL (IC_RESULT (ic)) == sym && !POINTER_SET(ic) && ic->next && !isinSet (visited, ic->next))
                    continue;
                  if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)) && OP_SYMBOL (IC_RESULT (ic)) == sym)
                    {
                      bool pset = POINTER_SET(ic);
                      IC_RESULT (ic) = operandFromOperand (tmpop);
                      if (pset)
                        IC_RESULT(ic)->isaddr = TRUE;
                    }
                  bitVectUnSetBit (sym->uses, ic->key);
                }
            }
          deleteSet (&newdefs);
          deleteSet (&visited);
        }
      while (elementsInSet(defs) > 1);

      deleteSet (&defs);
    }

  deleteSet (&candidates);
}
示例#21
0
/**
  Mark variables for assignment by the register allocator.
 */
static void
serialRegMark (eBBlock ** ebbs, int count)
{
  int i;
  short int max_alloc_bytes = SHRT_MAX; // Byte limit. Set this to a low value to pass only few variables to the register allocator. This can be useful for debugging.

  stm8_call_stack_size = 2; // Saving of register to stack temporarily.

  /* for all blocks */
  for (i = 0; i < count; i++)
    {
      iCode *ic;

      if (ebbs[i]->noPath && (ebbs[i]->entryLabel != entryLabel && ebbs[i]->entryLabel != returnLabel))
        continue;

      /* for all instructions do */
      for (ic = ebbs[i]->sch; ic; ic = ic->next)
        {
          if ((ic->op == CALL || ic->op == PCALL) && ic->parmBytes + 5 > stm8_call_stack_size)
            {
              sym_link *dtype = operandType (IC_LEFT (ic));
              sym_link *ftype = IS_FUNCPTR (dtype) ? dtype->next : dtype;

              /* 5 for saving all registers at call site + 2 for big return value */
              stm8_call_stack_size = ic->parmBytes + 5 + 2 * (getSize (ftype->next) > 4);
            }

          if (ic->op == IPOP)
            wassert (0);

          /* if result is present && is a true symbol */
          if (IC_RESULT (ic) && ic->op != IFX && IS_TRUE_SYMOP (IC_RESULT (ic)))
            OP_SYMBOL (IC_RESULT (ic))->allocreq++;

          /* some don't need registers, since there is no result. */
          if (SKIP_IC2 (ic) ||
              ic->op == JUMPTABLE || ic->op == IFX || ic->op == IPUSH || ic->op == IPOP || (IC_RESULT (ic) && POINTER_SET (ic)))
            continue;

          /* now we need to allocate registers only for the result */
          if (IC_RESULT (ic))
            {
              symbol *sym = OP_SYMBOL (IC_RESULT (ic));

              D (D_ALLOC, ("serialRegAssign: in loop on result %p\n", sym));

              if (sym->isspilt && sym->usl.spillLoc) // todo: Remove once remat is supported!
                {
                  sym->usl.spillLoc->allocreq--;
                  sym->isspilt = FALSE;
                }

              /* Make sure any spill location is definately allocated */
              if (sym->isspilt && !sym->remat && sym->usl.spillLoc && !sym->usl.spillLoc->allocreq)
                sym->usl.spillLoc->allocreq++;

              /* if it does not need or is spilt
                 or is already marked for the new allocator
                 or will not live beyond this instructions */
              if (!sym->nRegs ||
                  sym->isspilt || sym->for_newralloc || sym->liveTo <= ic->seq)
                {
                  D (D_ALLOC, ("serialRegAssign: won't live long enough.\n"));
                  continue;
                }

              if (sym->nRegs > 4 && ic->op == CALL)
                {
                  spillThis (sym, TRUE);
                }
              else if (max_alloc_bytes >= sym->nRegs)
                {
                  sym->for_newralloc = 1;
                  max_alloc_bytes -= sym->nRegs;
                }
              else if (!sym->for_newralloc)
                {
                  spillThis (sym, TRUE);
                  printf ("Spilt %s due to byte limit.\n", sym->name);
                }
            }
        }
    }
}
示例#22
0
/*-----------------------------------------------------------------*/
static void
computeClash (eBBlock ** ebbs, int count)
{
  int i;

  /* for all blocks do */
  for (i = 0; i < count; i++)
    {
      iCode *ic;

      /* for every iCode do */
      for (ic = ebbs[i]->sch; ic; ic = ic->next)
	{
	  symbol *sym1, *sym2;
	  int key1, key2;

	  /* for all iTemps alive at this iCode */
	  for (key1 = 1; key1 < ic->rlive->size; key1++)
	    {
	      if (!bitVectBitValue(ic->rlive, key1))
	        continue;

	      sym1 = hTabItemWithKey(liveRanges, key1);

	      if (!sym1->isitmp)
	        continue;

	      /* for all other iTemps alive at this iCode */
	      for (key2 = key1+1; key2 < ic->rlive->size; key2++)
	        {
		  if (!bitVectBitValue(ic->rlive, key2))
		    continue;

		  sym2 = hTabItemWithKey(liveRanges, key2);

		  if (!sym2->isitmp)
		    continue;

		  /* if the result and left or right is an iTemp */
		  /* than possibly the iTemps do not clash */
		  if ((ic->op != JUMPTABLE) && (ic->op != IFX) &&
		      IS_ITEMP(IC_RESULT(ic)) &&
		      (IS_ITEMP(IC_LEFT(ic)) || IS_ITEMP(IC_RIGHT(ic))))
		    {
		      if (OP_SYMBOL(IC_RESULT(ic))->key == key1
			  && sym1->liveFrom == ic->seq
			  && sym2->liveTo == ic->seq)
		        {
		          if (IS_SYMOP(IC_LEFT(ic)))
			    if (OP_SYMBOL(IC_LEFT(ic))->key == key2)
			      continue;
		          if (IS_SYMOP(IC_RIGHT(ic)))
			    if (OP_SYMBOL(IC_RIGHT(ic))->key == key2)
			      continue;
			}

		      if (OP_SYMBOL(IC_RESULT(ic))->key == key2
			  && sym2->liveFrom == ic->seq
			  && sym1->liveTo == ic->seq)
		        {
		          if (IS_SYMOP(IC_LEFT(ic)))
			    if (OP_SYMBOL(IC_LEFT(ic))->key == key1)
			      continue;
		          if (IS_SYMOP(IC_RIGHT(ic)))
			    if (OP_SYMBOL(IC_RIGHT(ic))->key == key1)
			      continue;
			}
		    }

		  /* the iTemps do clash. set the bits in clashes */
		  sym1->clashes = bitVectSetBit (sym1->clashes, key2);
		  sym2->clashes = bitVectSetBit (sym2->clashes, key1);

		  /* check if they share the same spill location */
		  /* what is this good for? */
	          if (SYM_SPIL_LOC(sym1) && SYM_SPIL_LOC(sym2) &&
		      SYM_SPIL_LOC(sym1) == SYM_SPIL_LOC(sym2))
		    {
		      if (sym1->reqv && !sym2->reqv) SYM_SPIL_LOC(sym2)=NULL;
		      else if (sym2->reqv && !sym1->reqv) SYM_SPIL_LOC(sym1)=NULL;
		      else if (sym1->used > sym2->used) SYM_SPIL_LOC(sym2)=NULL;
		      else SYM_SPIL_LOC(sym1)=NULL;
		    }
		}
	    }
	}
    }
}
示例#23
0
int
cdbWriteBasicSymbol (symbol *sym, int isStructSym, int isFunc)
{
  memmap *map;
  symbol *sym2;

  if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
    fprintf (stderr, "cdbFile.c:cdbWriteBasicSymbol()\n");

  if (!cdbFilePtr) return 0;

  if (!sym) return 0;

  /* WRITE HEADER, Function or Symbol */
  if (isFunc)
    fprintf (cdbFilePtr, "F:");   
  else
    fprintf (cdbFilePtr, "S:");

  /* STRUCTS do not have scope info.. */

  if (!isStructSym)
    {
      if (sym->level && sym->localof)   /* symbol is local */
        {
          fprintf (cdbFilePtr, "L%s.%s$", moduleName, sym->localof->name);
        }
      else if (IS_STATIC (sym->etype))  /* scope is file */
        {
          fprintf (cdbFilePtr, "F%s$", moduleName);
        }
      else                              /* scope is global */
        {
          fprintf (cdbFilePtr, "G$");
        }
    }
  else
    {
      fprintf (cdbFilePtr, "S$");       /* scope is structure */
    }

  /* print the name, & mangled name */
  fprintf (cdbFilePtr, "%s$%d$%d(", sym->name, sym->level, sym->block);

  cdbTypeInfo (sym->type);

  fprintf (cdbFilePtr, "),");

  /* CHECK FOR REGISTER SYMBOL... */ 
  if (!sym->allocreq && sym->reqv)
    {
      int a;
      symbol *TempSym = OP_SYMBOL (sym->reqv);

      if (!TempSym->isspilt || TempSym->remat)
        {
          fprintf (cdbFilePtr, "R,0,0,[");

          for (a = 0; a < 4; a++)
            {
              if (TempSym->regs[a])
                {
                  fprintf (cdbFilePtr, "%s%s", port->getRegName(TempSym->regs[a]),
                           ((a < 3) && (TempSym->regs[a+1])) ? "," : "");
                }
            }

          fprintf (cdbFilePtr, "]");
          sym2 = NULL;
        }
      else
        {
          sym2 = TempSym->usl.spillLoc;
        }
    }
  else
    {
      sym2 = sym;
    }

  if (sym2)
    {
      /* print the address space */
      map = SPEC_OCLS (sym2->etype);

      fprintf (cdbFilePtr, "%c,%d,%d",
               (map ? map->dbName : 'Z'), sym2->onStack, SPEC_STAK (sym2->etype));
    }

  /* if assigned to registers then output register names */
  /* if this is a function then print
     if is it an interrupt routine & interrupt number
     and the register bank it is using */
  if (isFunc)
    fprintf (cdbFilePtr, ",%d,%d,%d", FUNC_ISISR (sym->type),
             FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
  
/* alternate location to find this symbol @ : eg registers
     or spillocation */

  if (!isStructSym)
    fprintf (cdbFilePtr, "\n");

  return 1;
}
示例#24
0
/*-----------------------------------------------------------------*/
void
dumpEbbsToFileExt (int id, ebbIndex * ebbi)
{
  FILE *of;
  int i;
  eBBlock *bb;
  set *cseSet;
  eBBlock ** ebbs = ebbi->dfOrder ? ebbi->dfOrder : ebbi->bbOrder;
  int count = ebbi->count;

  if (id) {
    of=createDumpFile(id);
  } else {
    of = stdout;
  }

  for (i = 0; i < count; i++)
    {
      fprintf (of, "\n----------------------------------------------------------------\n");
      fprintf (of, "Basic Block %s (df:%d bb:%d lvl:%d): loopDepth=%d%s%s%s\n",
               ebbs[i]->entryLabel->name,
               ebbs[i]->dfnum, ebbs[i]->bbnum, ebbs[i]->entryLabel->level,
               ebbs[i]->depth,
               ebbs[i]->noPath ? " noPath" : "",
               ebbs[i]->partOfLoop ? " partOfLoop" : "",
               ebbs[i]->isLastInLoop ? " isLastInLoop" : "");

      // a --nolabelopt makes this more readable
      fprintf (of, "\nsuccessors: ");
      for (bb=setFirstItem(ebbs[i]->succList);
           bb;
           bb=setNextItem(ebbs[i]->succList)) {
        fprintf (of, "%s ", bb->entryLabel->name);
      }
      fprintf (of, "\npredecessors: ");
      for (bb=setFirstItem(ebbs[i]->predList);
           bb;
           bb=setNextItem(ebbs[i]->predList)) {
        fprintf (of, "%s ", bb->entryLabel->name);
      }
      {
        int d;
        fprintf (of, "\ndominators: ");
        for (d=0; d<ebbs[i]->domVect->size; d++) {
          if (bitVectBitValue(ebbs[i]->domVect, d)) {
            fprintf (of, "%s ", ebbi->bbOrder[d]->entryLabel->name); //ebbs[d]->entryLabel->name);
          }
        }
      }
      fprintf (of, "\n");

      fprintf (of, "\ndefines bitVector :");
      bitVectDebugOn (ebbs[i]->defSet, of);
      fprintf (of, "\nlocal defines bitVector :");
      bitVectDebugOn (ebbs[i]->ldefs, of);
      fprintf (of, "\npointers Set bitvector :");
      bitVectDebugOn (ebbs[i]->ptrsSet, of);
#if 0
      fprintf (of, "\nin coming definitions :");
      bitVectDebugOn (ebbs[i]->inDefs, of);
      fprintf (of, "\nout going definitions :");
      bitVectDebugOn (ebbs[i]->outDefs, of);
      fprintf (of, "\ndefines used :");
      bitVectDebugOn (ebbs[i]->usesDefs, of);
#endif

      if (ebbs[i]->isLastInLoop) {
              fprintf (of, "\nInductions Set bitvector :");
              bitVectDebugOn (ebbs[i]->linds, of);
      }

      fprintf (of, "\ninExprs:");
      for (cseSet = ebbs[i]->inExprs; cseSet; cseSet=cseSet->next) {
        cseDef *item=cseSet->item;
        fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
        if (item->fromGlobal)
          fprintf (of, "g");
      }
      fprintf (of, "\noutExprs:");
      for (cseSet = ebbs[i]->outExprs; cseSet; cseSet=cseSet->next) {
        cseDef *item=cseSet->item;
        fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
        if (item->fromGlobal)
          fprintf (of, "g");
      }
      fprintf (of, "\nkilledExprs:");
      for (cseSet = ebbs[i]->killedExprs; cseSet; cseSet=cseSet->next) {
        cseDef *item=cseSet->item;
        fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
        if (item->fromGlobal)
          fprintf (of, "g");
      }

      fprintf (of, "\n----------------------------------------------------------------\n");
      printiCChain (ebbs[i]->sch, of);
    }
  fflush(of);
}